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)
This commit is contained in:
Sebastian Hengst 2015-08-18 10:52:09 +02:00
parent b47fc2fd4d
commit a133c6114b
12 changed files with 123 additions and 86 deletions

View File

@ -103,8 +103,11 @@ public:
virtual bool IsMediaSeekable() = 0;
virtual void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags, MediaDecoderEventVisibility aEventVisibility) = 0;
virtual void QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) = 0;
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> 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<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags,
MediaDecoderEventVisibility aEventVisibility = MediaDecoderEventVisibility::Observable)
: MetadataContainer(aDecoder, aInfo, aTags, aEventVisibility)
{}
NS_IMETHOD Run() override
{
nsAutoPtr<MediaInfo> 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<AbstractMediaDecoder> mDecoder;
};
} // namespace mozilla
#endif

View File

@ -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<nsIPrincipal> MediaDecoder::GetCurrentPrincipal()
return mResource ? mResource->GetCurrentPrincipal() : nullptr;
}
void MediaDecoder::OnMetadataUpdate(TimedMetadata&& aMetadata)
void MediaDecoder::QueueMetadata(const TimeUnit& aPublishTime,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
MOZ_ASSERT(NS_IsMainThread());
RemoveMediaTracks();
MetadataLoaded(nsAutoPtr<MediaInfo>(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<MediaInfo> aInfo,

View File

@ -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<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> 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<nsITimer> mDormantTimer;
// A listener to receive metadata updates from MDSM.
MediaEventListener mTimedMetadataListener;
protected:
// Whether the state machine is shut down.
Mirror<bool> mStateMachineIsShutdown;

View File

@ -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.

View File

@ -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<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> 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
{

View File

@ -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<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags);
// Returns true if we're currently playing. The decoder monitor must
// be held.
bool IsPlaying() const;

View File

@ -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<TimedMetadata, ListenerMode::Exclusive>
TimedMetadataEventProducer;
typedef MediaEventSource<TimedMetadata, ListenerMode::Exclusive>
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<TimedMetadata> {
public:
TimedMetadata(const media::TimeUnit& aPublishTime,
nsAutoPtr<MetadataTags>&& aTags,
nsAutoPtr<MediaInfo>&& 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<nsIRunnable> removeTracksEvent =
new RemoveMediaTracksEventRunner(aDecoder);
NS_DispatchToMainThread(removeTracksEvent);
nsCOMPtr<nsIRunnable> 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<TimedMetadata> mMetadataQueue;
MediaEventListener mListener;
TimedMetadataEventProducer mTimedMetadataEvent;
};
} // namespace mozilla

View File

@ -99,6 +99,20 @@ SourceBufferDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::QueueMetadata(const media::TimeUnit& aTime,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::RemoveMediaTracks()
{
MSE_DEBUG("UNIMPLEMENTED");
}
bool
SourceBufferDecoder::HasInitializationData()
{

View File

@ -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<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) final override;
virtual void RemoveMediaTracks() final override;
virtual void SetMediaSeekable(bool aMediaSeekable) final override;
virtual bool HasInitializationData() final override;

View File

@ -814,11 +814,10 @@ bool OggReader::ReadOggChain()
if (chained) {
SetChained(true);
{
nsAutoPtr<MediaInfo> 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<MediaInfo>(new MediaInfo(mInfo))));
mDecoder->QueueMetadata(media::TimeUnit::FromMicroseconds(t), info, tags);
}
return true;
}

View File

@ -129,6 +129,18 @@ BufferDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo, MediaDecoderEventVis
// ignore
}
void
BufferDecoder::QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags)
{
// ignore
}
void
BufferDecoder::RemoveMediaTracks()
{
// ignore
}
void
BufferDecoder::OnReadMetadataCompleted()
{

View File

@ -58,9 +58,12 @@ public:
virtual void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags,
MediaDecoderEventVisibility aEventVisibility) final override;
virtual void QueueMetadata(const media::TimeUnit& aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) final override;
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MediaDecoderEventVisibility aEventVisibility) final override;
virtual void RemoveMediaTracks() final override;
virtual void OnReadMetadataCompleted() final override;
virtual MediaDecoderOwner* GetOwner() final override;