From 767e69616f62f1af818169a20f44c60625fb233b Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Wed, 14 Aug 2013 17:01:16 -0400 Subject: [PATCH] Bug 905062: Clean up fake source for getUserMedia r=padenot --- content/media/webrtc/MediaEngineDefault.cpp | 81 ++++++++++----------- content/media/webrtc/MediaEngineDefault.h | 14 ++-- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/content/media/webrtc/MediaEngineDefault.cpp b/content/media/webrtc/MediaEngineDefault.cpp index 3e801ea7e14b..96bb84a53014 100644 --- a/content/media/webrtc/MediaEngineDefault.cpp +++ b/content/media/webrtc/MediaEngineDefault.cpp @@ -31,8 +31,9 @@ NS_IMPL_ISUPPORTS1(MediaEngineDefaultVideoSource, nsITimerCallback) */ MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource() - : mTimer(nullptr) + : mTimer(nullptr), mMonitor("Fake video") { + mImageContainer = layers::LayerManager::CreateImageContainer(); mState = kReleased; } @@ -120,32 +121,8 @@ MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID) return NS_ERROR_FAILURE; } - mSource = aStream; - - // Allocate a single blank Image - ImageFormat format = PLANAR_YCBCR; - mImageContainer = layers::LayerManager::CreateImageContainer(); - - nsRefPtr image = mImageContainer->CreateImage(&format, 1); - mImage = static_cast(image.get()); - - layers::PlanarYCbCrImage::Data data; - // Allocate a single blank Image - mCb = 16; - mCr = 16; - AllocateSolidColorFrame(data, mOpts.mWidth, mOpts.mHeight, 0x80, mCb, mCr); - // SetData copies data, so we can free the frame - mImage->SetData(data); - ReleaseFrame(data); - - // AddTrack takes ownership of segment - VideoSegment *segment = new VideoSegment(); - segment->AppendFrame(image.forget(), USECS_PER_S / mOpts.mFPS, - gfxIntSize(mOpts.mWidth, mOpts.mHeight)); - mSource->AddTrack(aID, VIDEO_RATE, 0, segment); - - // We aren't going to add any more tracks - mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX); + aStream->AddTrack(aID, VIDEO_RATE, 0, new VideoSegment()); + aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX); // Remember TrackID so we can end it later mTrackID = aID; @@ -238,20 +215,47 @@ MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer) // SetData copies data, so we can free the frame ReleaseFrame(data); - // AddTrack takes ownership of segment - VideoSegment segment; - segment.AppendFrame(ycbcr_image.forget(), USECS_PER_S / mOpts.mFPS, - gfxIntSize(mOpts.mWidth, mOpts.mHeight)); - mSource->AppendToTrack(mTrackID, &segment); + MonitorAutoLock lock(mMonitor); + + // implicitly releases last image + mImage = ycbcr_image.forget(); return NS_OK; } void MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph, - StreamTime aDesiredTime) + SourceMediaStream *aSource, + TrackID aID, + StreamTime aDesiredTime, + TrackTicks &aLastEndTime) { - // Ignore - we push video data + // AddTrack takes ownership of segment + VideoSegment segment; + MonitorAutoLock lock(mMonitor); + if (mState != kStarted) { + return; + } + + // Note: we're not giving up mImage here + nsRefPtr image = mImage; + TrackTicks target = TimeToTicksRoundUp(USECS_PER_S, aDesiredTime); + TrackTicks delta = target - aLastEndTime; + + if (delta > 0) { + // NULL images are allowed + if (image) { + segment.AppendFrame(image.forget(), delta, + gfxIntSize(mOpts.mWidth, mOpts.mHeight)); + } else { + segment.AppendFrame(nullptr, delta, gfxIntSize(0,0)); + } + // This can fail if either a) we haven't added the track yet, or b) + // we've removed or finished the track. + if (aSource->AppendToTrack(aID, &segment)) { + aLastEndTime = target; + } + } } @@ -269,13 +273,6 @@ MediaEngineDefaultAudioSource::MediaEngineDefaultAudioSource() MediaEngineDefaultAudioSource::~MediaEngineDefaultAudioSource() {} -void -MediaEngineDefaultAudioSource::NotifyPull(MediaStreamGraph* aGraph, - StreamTime aDesiredTime) -{ - // Ignore - we push audio data -} - void MediaEngineDefaultAudioSource::GetName(nsAString& aName) { @@ -335,7 +332,7 @@ MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID) // Remember TrackID so we can finish later mTrackID = aID; - // 1 Audio frame per Video frame + // 1 Audio frame per 10ms mTimer->InitWithCallback(this, MediaEngine::DEFAULT_AUDIO_TIMER_MS, nsITimer::TYPE_REPEATING_SLACK); mState = kStarted; diff --git a/content/media/webrtc/MediaEngineDefault.h b/content/media/webrtc/MediaEngineDefault.h index 94d2b315d186..e69aba111c79 100644 --- a/content/media/webrtc/MediaEngineDefault.h +++ b/content/media/webrtc/MediaEngineDefault.h @@ -10,6 +10,7 @@ #include "nsCOMPtr.h" #include "DOMMediaStream.h" #include "nsComponentManagerUtils.h" +#include "mozilla/Monitor.h" #include "VideoUtils.h" #include "MediaEngine.h" @@ -48,12 +49,11 @@ public: virtual nsresult Config(bool aEchoOn, uint32_t aEcho, bool aAgcOn, uint32_t aAGC, bool aNoiseOn, uint32_t aNoise) { return NS_OK; }; - virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime); virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aId, StreamTime aDesiredTime, - TrackTicks &aLastEndTime) {} + TrackTicks &aLastEndTime); virtual bool IsFake() { return true; @@ -67,10 +67,15 @@ protected: TrackID mTrackID; nsCOMPtr mTimer; + // mMonitor protects mImage access/changes, and transitions of mState + // from kStarted to kStopped (which are combined with EndTrack() and + // image changes). Note that mSources is not accessed from other threads + // for video and is not protected. + Monitor mMonitor; + nsRefPtr mImage; + nsRefPtr mImageContainer; - SourceMediaStream* mSource; - layers::PlanarYCbCrImage* mImage; MediaEnginePrefs mOpts; int mCb; int mCr; @@ -94,7 +99,6 @@ public: virtual nsresult Config(bool aEchoOn, uint32_t aEcho, bool aAgcOn, uint32_t aAGC, bool aNoiseOn, uint32_t aNoise) { return NS_OK; }; - virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime); virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aId,