From 1c55925879dca3bd930516ed4c74b40f9bb7f391 Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Wed, 13 Mar 2013 11:42:18 -0400 Subject: [PATCH] Bug 848401: switch from ReentrantMonitors and PR_Lock/Condvar to Monitor. Fix {picture:true} for desktop r=khuey,dao --- browser/modules/webrtcUI.jsm | 2 +- content/media/webrtc/MediaEngineWebRTC.h | 9 +++--- content/media/webrtc/MediaEngineWebRTCAudio.cpp | 6 ++-- content/media/webrtc/MediaEngineWebRTCVideo.cpp | 41 ++++++++++++++----------- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/browser/modules/webrtcUI.jsm b/browser/modules/webrtcUI.jsm index a67c8cb8fa71..72eb5c56e9d4 100644 --- a/browser/modules/webrtcUI.jsm +++ b/browser/modules/webrtcUI.jsm @@ -75,7 +75,7 @@ function handleRequest(aSubject, aTopic, aData) { browser.ownerDocument.defaultView.navigator.mozGetUserMediaDevices( function (devices) { - prompt(browser, callID, params.audio, params.video, devices); + prompt(browser, callID, params.audio, params.video || params.picture, devices); }, function (error) { // bug 827146 -- In the future, the UI should catch NO_DEVICES_FOUND diff --git a/content/media/webrtc/MediaEngineWebRTC.h b/content/media/webrtc/MediaEngineWebRTC.h index 7d2f20b8bb0d..72703e56c3df 100644 --- a/content/media/webrtc/MediaEngineWebRTC.h +++ b/content/media/webrtc/MediaEngineWebRTC.h @@ -11,6 +11,7 @@ #include "nsIRunnable.h" #include "mozilla/Mutex.h" +#include "mozilla/Monitor.h" #include "nsCOMPtr.h" #include "nsDOMFile.h" #include "nsThreadUtils.h" @@ -139,19 +140,17 @@ private: // 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. - mozilla::ReentrantMonitor mMonitor; // Monitor for processing WebRTC frames. + Monitor mMonitor; // Monitor for processing WebRTC frames. nsTArray mSources; // When this goes empty, we shut down HW bool mInitDone; + bool mInSnapshotMode; nsString* mSnapshotPath; nsRefPtr mImage; nsRefPtr mImageContainer; - PRLock* mSnapshotLock; - PRCondVar* mSnapshotCondVar; - // These are in UTF-8 but webrtc api uses char arrays char mDeviceName[KMaxDeviceNameLength]; char mUniqueId[KMaxUniqueIdLength]; @@ -224,7 +223,7 @@ private: // mMonitor protects mSources[] access/changes, and transitions of mState // from kStarted to kStopped (which are combined with EndTrack()). // mSources[] is accessed from webrtc threads. - mozilla::ReentrantMonitor mMonitor; + Monitor mMonitor; nsTArray mSources; // When this goes empty, we shut down HW int mCapIndex; diff --git a/content/media/webrtc/MediaEngineWebRTCAudio.cpp b/content/media/webrtc/MediaEngineWebRTCAudio.cpp index 3165cf48d77c..715a8d415e2f 100644 --- a/content/media/webrtc/MediaEngineWebRTCAudio.cpp +++ b/content/media/webrtc/MediaEngineWebRTCAudio.cpp @@ -144,7 +144,7 @@ MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID) } { - ReentrantMonitorAutoEnter enter(mMonitor); + MonitorAutoLock lock(mMonitor); mSources.AppendElement(aStream); } @@ -181,7 +181,7 @@ nsresult MediaEngineWebRTCAudioSource::Stop(SourceMediaStream *aSource, TrackID aID) { { - ReentrantMonitorAutoEnter enter(mMonitor); + MonitorAutoLock lock(mMonitor); if (!mSources.RemoveElement(aSource)) { // Already stopped - this is allowed @@ -350,7 +350,7 @@ MediaEngineWebRTCAudioSource::Process(const int channel, const webrtc::ProcessingTypes type, sample* audio10ms, const int length, const int samplingFreq, const bool isStereo) { - ReentrantMonitorAutoEnter enter(mMonitor); + MonitorAutoLock lock(mMonitor); if (mState != kStarted) return; diff --git a/content/media/webrtc/MediaEngineWebRTCVideo.cpp b/content/media/webrtc/MediaEngineWebRTCVideo.cpp index ae2841a899b5..5168f3750dc7 100644 --- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp +++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp @@ -40,12 +40,13 @@ int MediaEngineWebRTCVideoSource::DeliverFrame( unsigned char* buffer, int size, uint32_t time_stamp, int64_t render_time) { + // mInSnapshotMode can only be set before the camera is turned on and + // the renderer is started, so this amounts to a 1-shot if (mInSnapshotMode) { // Set the condition variable to false and notify Snapshot(). - PR_Lock(mSnapshotLock); + MonitorAutoLock lock(mMonitor); mInSnapshotMode = false; - PR_NotifyCondVar(mSnapshotCondVar); - PR_Unlock(mSnapshotLock); + lock.Notify(); return 0; } @@ -94,7 +95,7 @@ MediaEngineWebRTCVideoSource::DeliverFrame( // we don't touch anything in 'this' until here (except for snapshot, // which has it's own lock) - ReentrantMonitorAutoEnter enter(mMonitor); + MonitorAutoLock lock(mMonitor); // implicitly releases last image mImage = image.forget(); @@ -114,7 +115,7 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph, { VideoSegment segment; - ReentrantMonitorAutoEnter enter(mMonitor); + MonitorAutoLock lock(mMonitor); if (mState != kStarted) return; @@ -328,7 +329,7 @@ MediaEngineWebRTCVideoSource::Stop(SourceMediaStream *aSource, TrackID aID) } { - ReentrantMonitorAutoEnter enter(mMonitor); + MonitorAutoLock lock(mMonitor); mState = kStopped; aSource->EndTrack(aID); // Drop any cached image so we don't start with a stale image on next @@ -367,11 +368,10 @@ MediaEngineWebRTCVideoSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile) return NS_ERROR_FAILURE; } - mSnapshotLock = PR_NewLock(); - mSnapshotCondVar = PR_NewCondVar(mSnapshotLock); - - PR_Lock(mSnapshotLock); - mInSnapshotMode = true; + { + MonitorAutoLock lock(mMonitor); + mInSnapshotMode = true; + } // Start the rendering (equivalent to calling Start(), but without a track). int error = 0; @@ -387,18 +387,23 @@ MediaEngineWebRTCVideoSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile) return NS_ERROR_FAILURE; } + if (mViECapture->StartCapture(mCaptureIndex, mCapability) < 0) { + return NS_ERROR_FAILURE; + } + // Wait for the condition variable, will be set in DeliverFrame. - // We use a while loop, because even if PR_WaitCondVar returns, it's not + // We use a while loop, because even if Wait() returns, it's not // guaranteed that the condition variable changed. - while (mInSnapshotMode) { - PR_WaitCondVar(mSnapshotCondVar, PR_INTERVAL_NO_TIMEOUT); + // FIX: we need need a way to cancel this and to bail if it appears to not be working + // Perhaps a maximum time, though some cameras can take seconds to start. 10 seconds? + { + MonitorAutoLock lock(mMonitor); + while (mInSnapshotMode) { + lock.Wait(); + } } // If we get here, DeliverFrame received at least one frame. - PR_Unlock(mSnapshotLock); - PR_DestroyCondVar(mSnapshotCondVar); - PR_DestroyLock(mSnapshotLock); - webrtc::ViEFile* vieFile = webrtc::ViEFile::GetInterface(mVideoEngine); if (!vieFile) { return NS_ERROR_FAILURE; -- 2.11.4.GIT