зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 5a476e673470 (bug 1073615) for causing various intermittent failures.
This commit is contained in:
Родитель
5a82bddd3a
Коммит
1b0c318bb9
|
@ -65,7 +65,7 @@ PRLogModuleInfo* gMediaStreamGraphLog;
|
|||
/**
|
||||
* The singleton graph instance.
|
||||
*/
|
||||
static nsDataHashtable<nsUint32HashKey, MediaStreamGraphImpl*> gGraphs;
|
||||
static MediaStreamGraphImpl* gGraph;
|
||||
|
||||
MediaStreamGraphImpl::~MediaStreamGraphImpl()
|
||||
{
|
||||
|
@ -1636,10 +1636,9 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||
NS_DispatchToMainThread(event);
|
||||
|
||||
LIFECYCLE_LOG("Disconnecting MediaStreamGraph %p", this);
|
||||
MediaStreamGraphImpl* graph;
|
||||
if (gGraphs.Get(mAudioChannel, &graph) && graph == this) {
|
||||
if (this == gGraph) {
|
||||
// null out gGraph if that's the graph being shut down
|
||||
gGraphs.Remove(mAudioChannel);
|
||||
gGraph = nullptr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1790,12 +1789,9 @@ MediaStreamGraphImpl::AppendMessage(ControlMessage* aMessage)
|
|||
delete aMessage;
|
||||
if (IsEmpty() &&
|
||||
mLifecycleState >= LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION) {
|
||||
|
||||
MediaStreamGraphImpl* graph;
|
||||
if (gGraphs.Get(mAudioChannel, &graph) && graph == this) {
|
||||
gGraphs.Remove(mAudioChannel);
|
||||
if (gGraph == this) {
|
||||
gGraph = nullptr;
|
||||
}
|
||||
|
||||
Destroy();
|
||||
}
|
||||
return;
|
||||
|
@ -2745,7 +2741,6 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(bool aRealtime,
|
|||
#ifdef DEBUG
|
||||
, mCanRunMessagesSynchronously(false)
|
||||
#endif
|
||||
, mAudioChannel(static_cast<uint32_t>(aChannel))
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gMediaStreamGraphLog) {
|
||||
|
@ -2784,26 +2779,15 @@ NS_IMPL_ISUPPORTS(MediaStreamGraphShutdownObserver, nsIObserver)
|
|||
|
||||
static bool gShutdownObserverRegistered = false;
|
||||
|
||||
namespace {
|
||||
|
||||
PLDHashOperator
|
||||
ForceShutdownEnumerator(const uint32_t& /* aAudioChannel */,
|
||||
MediaStreamGraphImpl* aGraph,
|
||||
void* /* aUnused */)
|
||||
{
|
||||
aGraph->ForceShutDown();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMETHODIMP
|
||||
MediaStreamGraphShutdownObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
gGraphs.EnumerateRead(ForceShutdownEnumerator, nullptr);
|
||||
if (gGraph) {
|
||||
gGraph->ForceShutDown();
|
||||
}
|
||||
nsContentUtils::UnregisterShutdownObserver(this);
|
||||
gShutdownObserverRegistered = false;
|
||||
}
|
||||
|
@ -2815,10 +2799,7 @@ MediaStreamGraph::GetInstance(DOMMediaStream::TrackTypeHints aHint, dom::AudioCh
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
uint32_t channel = static_cast<uint32_t>(aChannel);
|
||||
MediaStreamGraphImpl* graph = nullptr;
|
||||
|
||||
if (!gGraphs.Get(channel, &graph)) {
|
||||
if (!gGraph) {
|
||||
if (!gShutdownObserverRegistered) {
|
||||
gShutdownObserverRegistered = true;
|
||||
nsContentUtils::RegisterShutdownObserver(new MediaStreamGraphShutdownObserver());
|
||||
|
@ -2826,13 +2807,12 @@ MediaStreamGraph::GetInstance(DOMMediaStream::TrackTypeHints aHint, dom::AudioCh
|
|||
|
||||
CubebUtils::InitPreferredSampleRate();
|
||||
|
||||
graph = new MediaStreamGraphImpl(true, CubebUtils::PreferredSampleRate(), aHint, aChannel);
|
||||
gGraphs.Put(channel, graph);
|
||||
gGraph = new MediaStreamGraphImpl(true, CubebUtils::PreferredSampleRate(), aHint, aChannel);
|
||||
|
||||
STREAM_LOG(PR_LOG_DEBUG, ("Starting up MediaStreamGraph %p", graph));
|
||||
STREAM_LOG(PR_LOG_DEBUG, ("Starting up MediaStreamGraph %p", gGraph));
|
||||
}
|
||||
|
||||
return graph;
|
||||
return gGraph;
|
||||
}
|
||||
|
||||
MediaStreamGraph*
|
||||
|
@ -3015,10 +2995,7 @@ MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine,
|
|||
bool
|
||||
MediaStreamGraph::IsNonRealtime() const
|
||||
{
|
||||
const MediaStreamGraphImpl* impl = static_cast<const MediaStreamGraphImpl*>(this);
|
||||
MediaStreamGraphImpl* graph;
|
||||
|
||||
return !gGraphs.Get(impl->AudioChannel(), &graph) || graph != impl;
|
||||
return this != gGraph;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -661,8 +661,6 @@ public:
|
|||
nsRefPtr<AudioOutputObserver> mFarendObserverRef;
|
||||
#endif
|
||||
|
||||
uint32_t AudioChannel() const { return mAudioChannel; }
|
||||
|
||||
private:
|
||||
virtual ~MediaStreamGraphImpl();
|
||||
|
||||
|
@ -696,9 +694,6 @@ private:
|
|||
bool mCanRunMessagesSynchronously;
|
||||
#endif
|
||||
|
||||
// We use uint32_t instead AudioChannel because this is just used as key for
|
||||
// the hashtable gGraphs.
|
||||
uint32_t mAudioChannel;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -654,6 +654,12 @@ AudioContext::MozAudioChannelType() const
|
|||
return mDestination->MozAudioChannelType();
|
||||
}
|
||||
|
||||
void
|
||||
AudioContext::SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv)
|
||||
{
|
||||
mDestination->SetMozAudioChannelType(aValue, aRv);
|
||||
}
|
||||
|
||||
AudioChannel
|
||||
AudioContext::TestAudioChannelInAudioNodeStream()
|
||||
{
|
||||
|
|
|
@ -222,6 +222,7 @@ public:
|
|||
JSObject* GetGlobalJSObject() const;
|
||||
|
||||
AudioChannel MozAudioChannelType() const;
|
||||
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
|
||||
|
||||
AudioChannel TestAudioChannelInAudioNodeStream();
|
||||
|
||||
|
|
|
@ -18,23 +18,27 @@ function test_basic() {
|
|||
// Default
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
// random wrong channel
|
||||
ac.mozAudioChannelType = "foo";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
// Unpermitted channels
|
||||
ac = new AudioContext("content");
|
||||
ac.mozAudioChannelType = "content";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
ac = new AudioContext("notification");
|
||||
ac.mozAudioChannelType = "notification";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
ac = new AudioContext("alarm");
|
||||
ac.mozAudioChannelType = "alarm";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
ac = new AudioContext("telephony");
|
||||
ac.mozAudioChannelType = "telephony";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
ac = new AudioContext("ringer");
|
||||
ac.mozAudioChannelType = "ringer";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
ac = new AudioContext("publicnotification");
|
||||
ac.mozAudioChannelType = "publicnotification";
|
||||
is(ac.mozAudioChannelType, "normal", "Default ac channel == 'normal'");
|
||||
|
||||
runTest();
|
||||
|
@ -52,7 +56,7 @@ function test_permission(aChannel) {
|
|||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "audio-channel-" + aChannel, "allow": true, "context": document }],
|
||||
function() {
|
||||
var ac = new AudioContext(aChannel);
|
||||
ac.mozAudioChannelType = aChannel;
|
||||
is(ac.mozAudioChannelType, aChannel, "Default ac channel == '" + aChannel + "'");
|
||||
|
||||
var channel = SpecialPowers.wrap(ac).testAudioChannelInAudioNodeStream();
|
||||
|
|
|
@ -78,8 +78,8 @@ interface AudioContext : EventTarget {
|
|||
// Mozilla extensions
|
||||
partial interface AudioContext {
|
||||
// Read AudioChannel.webidl for more information about this attribute.
|
||||
[Pref="media.useAudioChannelService"]
|
||||
readonly attribute AudioChannel mozAudioChannelType;
|
||||
[Pref="media.useAudioChannelService", SetterThrows]
|
||||
attribute AudioChannel mozAudioChannelType;
|
||||
|
||||
// These 2 events are dispatched when the AudioContext object is muted by
|
||||
// the AudioChannelService. It's call 'interrupt' because when this event is
|
||||
|
|
Загрузка…
Ссылка в новой задаче