From a133c6114bcfc7ad5745d1bf4aad70202f5d0d72 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 18 Aug 2015 10:52:09 +0200 Subject: [PATCH] Backed out changesets 7610baf4a3ae, 6226b99f19bd, 157e41e32906, 60a3b1862f71 (bug 1195158). r=backout Backed out changeset 7610baf4a3ae (bug 1195158) Backed out changeset 6226b99f19bd (bug 1195158) Backed out changeset 157e41e32906 (bug 1195158) Backed out changeset 60a3b1862f71 (bug 1195158) --- dom/media/AbstractMediaDecoder.h | 42 +++++++++++++ dom/media/MediaDecoder.cpp | 18 ++---- dom/media/MediaDecoder.h | 15 ++--- dom/media/MediaDecoderReader.h | 8 --- dom/media/MediaDecoderStateMachine.cpp | 18 ++++-- dom/media/MediaDecoderStateMachine.h | 8 +-- dom/media/MediaMetadataManager.h | 62 +++++-------------- dom/media/mediasource/SourceBufferDecoder.cpp | 14 +++++ dom/media/mediasource/SourceBufferDecoder.h | 2 + dom/media/ogg/OggReader.cpp | 7 +-- dom/media/webaudio/BufferDecoder.cpp | 12 ++++ dom/media/webaudio/BufferDecoder.h | 3 + 12 files changed, 123 insertions(+), 86 deletions(-) diff --git a/dom/media/AbstractMediaDecoder.h b/dom/media/AbstractMediaDecoder.h index 230056fc48c0..4f79ecb989f1 100644 --- a/dom/media/AbstractMediaDecoder.h +++ b/dom/media/AbstractMediaDecoder.h @@ -103,8 +103,11 @@ public: virtual bool IsMediaSeekable() = 0; virtual void MetadataLoaded(nsAutoPtr aInfo, nsAutoPtr aTags, MediaDecoderEventVisibility aEventVisibility) = 0; + virtual void QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr aInfo, nsAutoPtr aTags) = 0; virtual void FirstFrameLoaded(nsAutoPtr aInfo, MediaDecoderEventVisibility aEventVisibility) = 0; + virtual void RemoveMediaTracks() = 0; + // May be called by the reader to notify this decoder that the metadata from // the media file has been read. Call on the decode thread only. virtual void OnReadMetadataCompleted() = 0; @@ -218,6 +221,45 @@ public: } }; +class MetadataUpdatedEventRunner : public nsRunnable, private MetadataContainer +{ +public: + MetadataUpdatedEventRunner(AbstractMediaDecoder* aDecoder, + nsAutoPtr aInfo, + nsAutoPtr aTags, + MediaDecoderEventVisibility aEventVisibility = MediaDecoderEventVisibility::Observable) + : MetadataContainer(aDecoder, aInfo, aTags, aEventVisibility) + {} + + NS_IMETHOD Run() override + { + nsAutoPtr info(new MediaInfo()); + *info = *mInfo; + mDecoder->MetadataLoaded(info, mTags, mEventVisibility); + mDecoder->FirstFrameLoaded(mInfo, mEventVisibility); + return NS_OK; + } +}; + +class RemoveMediaTracksEventRunner : public nsRunnable +{ +public: + explicit RemoveMediaTracksEventRunner(AbstractMediaDecoder* aDecoder) + : mDecoder(aDecoder) + {} + + NS_IMETHOD Run() override + { + MOZ_ASSERT(NS_IsMainThread()); + + mDecoder->RemoveMediaTracks(); + return NS_OK; + } + +private: + nsRefPtr mDecoder; +}; + } // namespace mozilla #endif diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 1dcf5428d156..4276097172f2 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -461,8 +461,6 @@ void MediaDecoder::Shutdown() mShuttingDown = true; - mTimedMetadataListener.Disconnect(); - // This changes the decoder state to SHUTDOWN and does other things // necessary to unblock the state machine thread if it's blocked, so // the asynchronous shutdown in nsDestroyStateMachine won't deadlock. @@ -550,8 +548,6 @@ void MediaDecoder::SetStateMachineParameters() if (mMinimizePreroll) { mDecoderStateMachine->DispatchMinimizePrerollUntilPlaybackStarts(); } - mTimedMetadataListener = mDecoderStateMachine->TimedMetadataEvent().Connect( - AbstractThread::MainThread(), this, &MediaDecoder::OnMetadataUpdate); } void MediaDecoder::SetMinimizePrerollUntilPlaybackStarts() @@ -642,15 +638,13 @@ already_AddRefed MediaDecoder::GetCurrentPrincipal() return mResource ? mResource->GetCurrentPrincipal() : nullptr; } -void MediaDecoder::OnMetadataUpdate(TimedMetadata&& aMetadata) +void MediaDecoder::QueueMetadata(const TimeUnit& aPublishTime, + nsAutoPtr aInfo, + nsAutoPtr aTags) { - MOZ_ASSERT(NS_IsMainThread()); - RemoveMediaTracks(); - MetadataLoaded(nsAutoPtr(new MediaInfo(*aMetadata.mInfo)), - Move(aMetadata.mTags), - MediaDecoderEventVisibility::Observable); - FirstFrameLoaded(Move(aMetadata.mInfo), - MediaDecoderEventVisibility::Observable); + MOZ_ASSERT(OnDecodeTaskQueue()); + GetReentrantMonitor().AssertCurrentThreadIn(); + mDecoderStateMachine->QueueMetadata(aPublishTime, aInfo, aTags); } void MediaDecoder::MetadataLoaded(nsAutoPtr aInfo, diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index f6454afadc2c..6fff7a574414 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -198,7 +198,6 @@ destroying the MediaDecoder object. #include "nsITimer.h" #include "MediaResource.h" #include "MediaDecoderOwner.h" -#include "MediaEventSource.h" #include "MediaStreamGraph.h" #include "AbstractMediaDecoder.h" #include "DecodedStream.h" @@ -580,6 +579,13 @@ public: void SetAudioChannel(dom::AudioChannel aChannel) { mAudioChannel = aChannel; } dom::AudioChannel GetAudioChannel() { return mAudioChannel; } + // Send a new set of metadata to the state machine, to be dispatched to the + // main thread to be presented when the |currentTime| of the media is greater + // or equal to aPublishTime. + void QueueMetadata(const media::TimeUnit& aPublishTime, + nsAutoPtr aInfo, + nsAutoPtr aTags) override; + /****** * The following methods must only be called on the main * thread. @@ -612,7 +618,7 @@ public: // Removes all audio tracks and video tracks that are previously added into // the track list. Call on the main thread only. - void RemoveMediaTracks(); + virtual void RemoveMediaTracks() override; // Called when the video has completed playing. // Call on the main thread only. @@ -983,8 +989,6 @@ protected: const char* PlayStateStr(); - void OnMetadataUpdate(TimedMetadata&& aMetadata); - // This should only ever be accessed from the main thread. // It is set in Init and cleared in Shutdown when the element goes away. // The decoder does not add a reference the element. @@ -1055,9 +1059,6 @@ protected: // Timer to schedule updating dormant state. nsCOMPtr mDormantTimer; - // A listener to receive metadata updates from MDSM. - MediaEventListener mTimedMetadataListener; - protected: // Whether the state machine is shut down. Mirror mStateMachineIsShutdown; diff --git a/dom/media/MediaDecoderReader.h b/dom/media/MediaDecoderReader.h index b6c864cd291a..3a338879e485 100644 --- a/dom/media/MediaDecoderReader.h +++ b/dom/media/MediaDecoderReader.h @@ -11,7 +11,6 @@ #include "AbstractMediaDecoder.h" #include "MediaInfo.h" #include "MediaData.h" -#include "MediaMetadataManager.h" #include "MediaQueue.h" #include "MediaTimer.h" #include "AudioCompactor.h" @@ -328,10 +327,6 @@ public: virtual void DisableHardwareAcceleration() {} - TimedMetadataEventSource& TimedMetadataEvent() { - return mTimedMetadataEvent; - } - protected: virtual ~MediaDecoderReader(); @@ -423,9 +418,6 @@ protected: bool mHitAudioDecodeError; bool mShutdown; - // Used to send TimedMetadata to the listener. - TimedMetadataEventProducer mTimedMetadataEvent; - private: // Promises used only for the base-class (sync->async adapter) implementation // of Request{Audio,Video}Data. diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index c974fbc93626..91ec7534b511 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -289,8 +289,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mTaskQueue, this, &MediaDecoderStateMachine::OnAudioPopped); mVideoQueueListener = VideoQueue().PopEvent().Connect( mTaskQueue, this, &MediaDecoderStateMachine::OnVideoPopped); - - mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread()); } MediaDecoderStateMachine::~MediaDecoderStateMachine() @@ -1098,7 +1096,7 @@ void MediaDecoderStateMachine::UpdatePlaybackPosition(int64_t aTime) UpdatePlaybackPositionInternal(aTime); bool fragmentEnded = mFragmentEndTime >= 0 && GetMediaTime() >= mFragmentEndTime; - mMetadataManager.DispatchMetadataIfNeeded(TimeUnit::FromMicroseconds(aTime)); + mMetadataManager.DispatchMetadataIfNeeded(mDecoder, TimeUnit::FromMicroseconds(aTime)); if (fragmentEnded) { StopPlayback(); @@ -2207,7 +2205,6 @@ MediaDecoderStateMachine::FinishShutdown() // Prevent dangling pointers by disconnecting the listeners. mAudioQueueListener.Disconnect(); mVideoQueueListener.Disconnect(); - mMetadataManager.Disconnect(); // Disconnect canonicals and mirrors before shutting down our task queue. mBuffered.DisconnectIfConnected(); @@ -3033,6 +3030,19 @@ bool MediaDecoderStateMachine::IsShutdown() return mIsShutdown; } +void MediaDecoderStateMachine::QueueMetadata(const TimeUnit& aPublishTime, + nsAutoPtr aInfo, + nsAutoPtr aTags) +{ + MOZ_ASSERT(OnDecodeTaskQueue()); + AssertCurrentThreadInMonitor(); + TimedMetadata* metadata = new TimedMetadata; + metadata->mPublishTime = aPublishTime; + metadata->mInfo = aInfo.forget(); + metadata->mTags = aTags.forget(); + mMetadataManager.QueueMetadata(metadata); +} + int64_t MediaDecoderStateMachine::AudioEndTime() const { diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index d66ffecc9323..1f9076db0a9f 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -154,10 +154,6 @@ public: // Set/Unset dormant state. void SetDormant(bool aDormant); - TimedMetadataEventSource& TimedMetadataEvent() { - return mMetadataManager.TimedMetadataEvent(); - } - private: // Initialization that needs to happen on the task queue. This is the first // task that gets run on the task queue, and is dispatched from the MDSM @@ -336,6 +332,10 @@ public: // shutting down. The decoder monitor must be held while calling this. bool IsShutdown(); + void QueueMetadata(const media::TimeUnit& aPublishTime, + nsAutoPtr aInfo, + nsAutoPtr aTags); + // Returns true if we're currently playing. The decoder monitor must // be held. bool IsPlaying() const; diff --git a/dom/media/MediaMetadataManager.h b/dom/media/MediaMetadataManager.h index 1f126c494c9e..3414f0a9ccee 100644 --- a/dom/media/MediaMetadataManager.h +++ b/dom/media/MediaMetadataManager.h @@ -7,41 +7,19 @@ #if !defined(MediaMetadataManager_h__) #define MediaMetadataManager_h__ -#include "mozilla/AbstractThread.h" #include "mozilla/LinkedList.h" #include "nsAutoPtr.h" #include "AbstractMediaDecoder.h" -#include "MediaEventSource.h" #include "TimeUnits.h" #include "VideoUtils.h" namespace mozilla { -class TimedMetadata; -typedef MediaEventProducer - TimedMetadataEventProducer; -typedef MediaEventSource - TimedMetadataEventSource; - // A struct that contains the metadata of a media, and the time at which those // metadata should start to be reported. class TimedMetadata : public LinkedListElement { public: - TimedMetadata(const media::TimeUnit& aPublishTime, - nsAutoPtr&& aTags, - nsAutoPtr&& aInfo) - : mPublishTime(aPublishTime) - , mTags(Move(aTags)) - , mInfo(Move(aInfo)) {} - - // Define our move constructor because we don't want to move the members of - // LinkedListElement to change the list. - TimedMetadata(TimedMetadata&& aOther) - : mPublishTime(aOther.mPublishTime) - , mTags(Move(aOther.mTags)) - , mInfo(Move(aOther.mInfo)) {} - // The time, in microseconds, at which those metadata should be available. media::TimeUnit mPublishTime; // The metadata. The ownership is transfered to the element when dispatching to @@ -55,7 +33,8 @@ public: // This class encapsulate the logic to give the metadata from the reader to // the content, at the right time. -class MediaMetadataManager { +class MediaMetadataManager +{ public: ~MediaMetadataManager() { TimedMetadata* element; @@ -64,41 +43,30 @@ public: } } - // Connect to an event source to receive TimedMetadata events. - void Connect(TimedMetadataEventSource& aEvent, AbstractThread* aThread) { - mListener = aEvent.Connect( - aThread, this, &MediaMetadataManager::OnMetadataQueued); + void QueueMetadata(TimedMetadata* aMetadata) { + mMetadataQueue.insertBack(aMetadata); } - // Stop receiving TimedMetadata events. - void Disconnect() { - mListener.Disconnect(); - } - - // Return an event source through which we will send TimedMetadata events - // when playback position reaches the publish time. - TimedMetadataEventSource& TimedMetadataEvent() { - return mTimedMetadataEvent; - } - - void DispatchMetadataIfNeeded(const media::TimeUnit& aCurrentTime) { + void DispatchMetadataIfNeeded(AbstractMediaDecoder* aDecoder, const media::TimeUnit& aCurrentTime) { TimedMetadata* metadata = mMetadataQueue.getFirst(); while (metadata && aCurrentTime >= metadata->mPublishTime) { - // Our listener will figure out what to do with TimedMetadata. - mTimedMetadataEvent.Notify(Move(*metadata)); + // Remove all media tracks from the list first. + nsCOMPtr removeTracksEvent = + new RemoveMediaTracksEventRunner(aDecoder); + NS_DispatchToMainThread(removeTracksEvent); + + nsCOMPtr metadataUpdatedEvent = + new MetadataUpdatedEventRunner(aDecoder, + metadata->mInfo, + metadata->mTags); + NS_DispatchToMainThread(metadataUpdatedEvent); delete mMetadataQueue.popFirst(); metadata = mMetadataQueue.getFirst(); } } protected: - void OnMetadataQueued(TimedMetadata&& aMetadata) { - mMetadataQueue.insertBack(new TimedMetadata(Move(aMetadata))); - } - LinkedList mMetadataQueue; - MediaEventListener mListener; - TimedMetadataEventProducer mTimedMetadataEvent; }; } // namespace mozilla diff --git a/dom/media/mediasource/SourceBufferDecoder.cpp b/dom/media/mediasource/SourceBufferDecoder.cpp index 16ad3fc1dac5..a17e7858bd4d 100644 --- a/dom/media/mediasource/SourceBufferDecoder.cpp +++ b/dom/media/mediasource/SourceBufferDecoder.cpp @@ -99,6 +99,20 @@ SourceBufferDecoder::FirstFrameLoaded(nsAutoPtr aInfo, MSE_DEBUG("UNIMPLEMENTED"); } +void +SourceBufferDecoder::QueueMetadata(const media::TimeUnit& aTime, + nsAutoPtr aInfo, + nsAutoPtr aTags) +{ + MSE_DEBUG("UNIMPLEMENTED"); +} + +void +SourceBufferDecoder::RemoveMediaTracks() +{ + MSE_DEBUG("UNIMPLEMENTED"); +} + bool SourceBufferDecoder::HasInitializationData() { diff --git a/dom/media/mediasource/SourceBufferDecoder.h b/dom/media/mediasource/SourceBufferDecoder.h index 4842e77103db..4183da57b659 100644 --- a/dom/media/mediasource/SourceBufferDecoder.h +++ b/dom/media/mediasource/SourceBufferDecoder.h @@ -51,6 +51,8 @@ public: virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded, uint32_t aDropped) final override; virtual void NotifyWaitingForResourcesStatusChanged() final override; virtual void OnReadMetadataCompleted() final override; + virtual void QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr aInfo, nsAutoPtr aTags) final override; + virtual void RemoveMediaTracks() final override; virtual void SetMediaSeekable(bool aMediaSeekable) final override; virtual bool HasInitializationData() final override; diff --git a/dom/media/ogg/OggReader.cpp b/dom/media/ogg/OggReader.cpp index acc9e93ce83f..e7a2f44ca5f6 100644 --- a/dom/media/ogg/OggReader.cpp +++ b/dom/media/ogg/OggReader.cpp @@ -814,11 +814,10 @@ bool OggReader::ReadOggChain() if (chained) { SetChained(true); { + nsAutoPtr info(new MediaInfo(mInfo)); + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); auto t = mDecodedAudioFrames * USECS_PER_S / mInfo.mAudio.mRate; - mTimedMetadataEvent.Notify( - TimedMetadata(media::TimeUnit::FromMicroseconds(t), - Move(tags), - nsAutoPtr(new MediaInfo(mInfo)))); + mDecoder->QueueMetadata(media::TimeUnit::FromMicroseconds(t), info, tags); } return true; } diff --git a/dom/media/webaudio/BufferDecoder.cpp b/dom/media/webaudio/BufferDecoder.cpp index 88d8d7dcf574..8018451929e8 100644 --- a/dom/media/webaudio/BufferDecoder.cpp +++ b/dom/media/webaudio/BufferDecoder.cpp @@ -129,6 +129,18 @@ BufferDecoder::FirstFrameLoaded(nsAutoPtr aInfo, MediaDecoderEventVis // ignore } +void +BufferDecoder::QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr aInfo, nsAutoPtr aTags) +{ + // ignore +} + +void +BufferDecoder::RemoveMediaTracks() +{ + // ignore +} + void BufferDecoder::OnReadMetadataCompleted() { diff --git a/dom/media/webaudio/BufferDecoder.h b/dom/media/webaudio/BufferDecoder.h index 736b49169c67..916f6853d67b 100644 --- a/dom/media/webaudio/BufferDecoder.h +++ b/dom/media/webaudio/BufferDecoder.h @@ -58,9 +58,12 @@ public: virtual void MetadataLoaded(nsAutoPtr aInfo, nsAutoPtr aTags, MediaDecoderEventVisibility aEventVisibility) final override; + virtual void QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr aInfo, nsAutoPtr aTags) final override; virtual void FirstFrameLoaded(nsAutoPtr aInfo, MediaDecoderEventVisibility aEventVisibility) final override; + virtual void RemoveMediaTracks() final override; + virtual void OnReadMetadataCompleted() final override; virtual MediaDecoderOwner* GetOwner() final override;