Bug 1248314. part 2 - move track initialization code into the constructor of DecodedStreamData. r=roc.

MozReview-Commit-ID: 2aQ7cXxRDTE
This commit is contained in:
JW Wang 2016-02-15 11:41:31 +08:00
parent e059f50498
commit c55853dea5
2 changed files with 36 additions and 47 deletions

View File

@ -19,6 +19,15 @@
namespace mozilla { namespace mozilla {
/*
* A container class to make it easier to pass the playback info all the
* way to DecodedStreamGraphListener from DecodedStream.
*/
struct PlaybackInfoInit {
int64_t mStartTime;
MediaInfo mInfo;
};
class DecodedStreamGraphListener : public MediaStreamListener { class DecodedStreamGraphListener : public MediaStreamListener {
typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent; typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent;
public: public:
@ -108,6 +117,7 @@ UpdateStreamSuspended(MediaStream* aStream, bool aBlocking)
class DecodedStreamData { class DecodedStreamData {
public: public:
DecodedStreamData(OutputStreamManager* aOutputStreamManager, DecodedStreamData(OutputStreamManager* aOutputStreamManager,
PlaybackInfoInit&& aInit,
MozPromiseHolder<GenericPromise>&& aPromise); MozPromiseHolder<GenericPromise>&& aPromise);
~DecodedStreamData(); ~DecodedStreamData();
int64_t GetPosition() const; int64_t GetPosition() const;
@ -127,9 +137,6 @@ public:
// the image. // the image.
RefPtr<layers::Image> mLastVideoImage; RefPtr<layers::Image> mLastVideoImage;
gfx::IntSize mLastVideoImageDisplaySize; gfx::IntSize mLastVideoImageDisplaySize;
// This is set to true when the stream is initialized (audio and
// video tracks added).
bool mStreamInitialized;
bool mHaveSentFinish; bool mHaveSentFinish;
bool mHaveSentFinishAudio; bool mHaveSentFinishAudio;
bool mHaveSentFinishVideo; bool mHaveSentFinishVideo;
@ -146,11 +153,11 @@ public:
}; };
DecodedStreamData::DecodedStreamData(OutputStreamManager* aOutputStreamManager, DecodedStreamData::DecodedStreamData(OutputStreamManager* aOutputStreamManager,
PlaybackInfoInit&& aInit,
MozPromiseHolder<GenericPromise>&& aPromise) MozPromiseHolder<GenericPromise>&& aPromise)
: mAudioFramesWritten(0) : mAudioFramesWritten(0)
, mNextVideoTime(-1) , mNextVideoTime(aInit.mStartTime)
, mNextAudioTime(-1) , mNextAudioTime(aInit.mStartTime)
, mStreamInitialized(false)
, mHaveSentFinish(false) , mHaveSentFinish(false)
, mHaveSentFinishAudio(false) , mHaveSentFinishAudio(false)
, mHaveSentFinishVideo(false) , mHaveSentFinishVideo(false)
@ -165,6 +172,16 @@ DecodedStreamData::DecodedStreamData(OutputStreamManager* aOutputStreamManager,
{ {
mStream->AddListener(mListener); mStream->AddListener(mListener);
mOutputStreamManager->Connect(mStream); mOutputStreamManager->Connect(mStream);
// Initialize tracks.
if (aInit.mInfo.HasAudio()) {
mStream->AddAudioTrack(aInit.mInfo.mAudio.mTrackId,
aInit.mInfo.mAudio.mRate,
0, new AudioSegment());
}
if (aInit.mInfo.HasVideo()) {
mStream->AddTrack(aInit.mInfo.mVideo.mTrackId, 0, new VideoSegment());
}
} }
DecodedStreamData::~DecodedStreamData() DecodedStreamData::~DecodedStreamData()
@ -252,27 +269,31 @@ DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
class R : public nsRunnable { class R : public nsRunnable {
typedef MozPromiseHolder<GenericPromise> Promise; typedef MozPromiseHolder<GenericPromise> Promise;
typedef void(DecodedStream::*Method)(Promise&&); typedef decltype(&DecodedStream::CreateData) Method;
public: public:
R(DecodedStream* aThis, Method aMethod, Promise&& aPromise) R(DecodedStream* aThis, Method aMethod, PlaybackInfoInit&& aInit, Promise&& aPromise)
: mThis(aThis), mMethod(aMethod) : mThis(aThis), mMethod(aMethod), mInit(Move(aInit))
{ {
mPromise = Move(aPromise); mPromise = Move(aPromise);
} }
NS_IMETHOD Run() override NS_IMETHOD Run() override
{ {
(mThis->*mMethod)(Move(mPromise)); (mThis->*mMethod)(Move(mInit), Move(mPromise));
return NS_OK; return NS_OK;
} }
private: private:
RefPtr<DecodedStream> mThis; RefPtr<DecodedStream> mThis;
Method mMethod; Method mMethod;
PlaybackInfoInit mInit;
Promise mPromise; Promise mPromise;
}; };
MozPromiseHolder<GenericPromise> promise; MozPromiseHolder<GenericPromise> promise;
mFinishPromise = promise.Ensure(__func__); mFinishPromise = promise.Ensure(__func__);
nsCOMPtr<nsIRunnable> r = new R(this, &DecodedStream::CreateData, Move(promise)); PlaybackInfoInit init {
aStartTime, aInfo
};
nsCOMPtr<nsIRunnable> r = new R(this, &DecodedStream::CreateData, Move(init), Move(promise));
AbstractThread::MainThread()->Dispatch(r.forget()); AbstractThread::MainThread()->Dispatch(r.forget());
} }
@ -322,7 +343,7 @@ DecodedStream::DestroyData(UniquePtr<DecodedStreamData> aData)
} }
void void
DecodedStream::CreateData(MozPromiseHolder<GenericPromise>&& aPromise) DecodedStream::CreateData(PlaybackInfoInit&& aInit, MozPromiseHolder<GenericPromise>&& aPromise)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
@ -334,7 +355,7 @@ DecodedStream::CreateData(MozPromiseHolder<GenericPromise>&& aPromise)
return; return;
} }
auto data = new DecodedStreamData(mOutputStreamManager, Move(aPromise)); auto data = new DecodedStreamData(mOutputStreamManager, Move(aInit), Move(aPromise));
class R : public nsRunnable { class R : public nsRunnable {
typedef void(DecodedStream::*Method)(UniquePtr<DecodedStreamData>); typedef void(DecodedStream::*Method)(UniquePtr<DecodedStreamData>);
@ -429,37 +450,6 @@ DecodedStream::SetPreservesPitch(bool aPreservesPitch)
mParams.mPreservesPitch = aPreservesPitch; mParams.mPreservesPitch = aPreservesPitch;
} }
void
DecodedStream::InitTracks()
{
AssertOwnerThread();
if (mData->mStreamInitialized) {
return;
}
SourceMediaStream* sourceStream = mData->mStream;
if (mInfo.HasAudio()) {
TrackID audioTrackId = mInfo.mAudio.mTrackId;
AudioSegment* audio = new AudioSegment();
sourceStream->AddAudioTrack(audioTrackId, mInfo.mAudio.mRate, 0, audio,
SourceMediaStream::ADDTRACK_QUEUED);
mData->mNextAudioTime = mStartTime.ref();
}
if (mInfo.HasVideo()) {
TrackID videoTrackId = mInfo.mVideo.mTrackId;
VideoSegment* video = new VideoSegment();
sourceStream->AddTrack(videoTrackId, 0, video,
SourceMediaStream::ADDTRACK_QUEUED);
mData->mNextVideoTime = mStartTime.ref();
}
sourceStream->FinishAddTracks();
mData->mStreamInitialized = true;
}
static void static void
SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime, SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
MediaData* aData, AudioSegment* aOutput, MediaData* aData, AudioSegment* aOutput,
@ -692,7 +682,6 @@ DecodedStream::SendData()
return; return;
} }
InitTracks();
SendAudio(mParams.mVolume, mSameOrigin); SendAudio(mParams.mVolume, mSameOrigin);
SendVideo(mSameOrigin); SendVideo(mSameOrigin);
AdvanceTracks(); AdvanceTracks();

View File

@ -23,6 +23,7 @@ class DecodedStreamData;
class MediaData; class MediaData;
class MediaStream; class MediaStream;
class OutputStreamManager; class OutputStreamManager;
struct PlaybackInfoInit;
class ProcessedMediaStream; class ProcessedMediaStream;
class TimeStamp; class TimeStamp;
@ -65,10 +66,9 @@ protected:
virtual ~DecodedStream(); virtual ~DecodedStream();
private: private:
void CreateData(MozPromiseHolder<GenericPromise>&& aPromise); void CreateData(PlaybackInfoInit&& aInit, MozPromiseHolder<GenericPromise>&& aPromise);
void DestroyData(UniquePtr<DecodedStreamData> aData); void DestroyData(UniquePtr<DecodedStreamData> aData);
void OnDataCreated(UniquePtr<DecodedStreamData> aData); void OnDataCreated(UniquePtr<DecodedStreamData> aData);
void InitTracks();
void AdvanceTracks(); void AdvanceTracks();
void SendAudio(double aVolume, bool aIsSameOrigin); void SendAudio(double aVolume, bool aIsSameOrigin);
void SendVideo(bool aIsSameOrigin); void SendVideo(bool aIsSameOrigin);