Bug 1070216 - Properly manage lifetime of allocated CaptureDevices. r=jib

We currently avoid Deallocating a CaptureDevice used for multiple gUMStreams
when one of them calls Deallocate() by keeping track of how many called
Start().

The normal lifetime sequence however, is:
Allocate()
Start()
Stop()
Deallocate()

This patches fixes the lifetime management by keeping track of how many
users of the CaptureDevice called Allocate().

--HG--
extra : commitid : J9Hj3Lffpg
extra : rebase_source : 0f9928a45c4810b3d6236bdf8a71587ad46de601
This commit is contained in:
Andreas Pehrson 2015-10-15 01:08:33 +08:00
parent f6ecc34621
commit 21f95c0d4a
4 changed files with 23 additions and 15 deletions

View File

@ -28,6 +28,7 @@ public:
, mHeight(0)
, mInitDone(false)
, mHasDirectListeners(false)
, mNrAllocations(0)
, mCaptureIndex(aIndex)
, mTrackID(0)
{}
@ -115,6 +116,7 @@ static void LogCapability(const char* aHeader,
bool mInitDone;
bool mHasDirectListeners;
int mNrAllocations; // When this becomes 0, we shut down HW
int mCaptureIndex;
TrackID mTrackID;

View File

@ -97,7 +97,12 @@ MediaEngineRemoteVideoSource::Allocate(const dom::MediaTrackConstraints& aConstr
{
LOG((__PRETTY_FUNCTION__));
if (mState == kReleased && mInitDone) {
if (!mInitDone) {
LOG(("Init not done"));
return NS_ERROR_FAILURE;
}
if (mState == kReleased) {
// Note: if shared, we don't allow a later opener to affect the resolution.
// (This may change depending on spec changes for Constraints/settings)
@ -121,19 +126,20 @@ MediaEngineRemoteVideoSource::Allocate(const dom::MediaTrackConstraints& aConstr
}
}
++mNrAllocations;
return NS_OK;
}
nsresult
MediaEngineRemoteVideoSource::Deallocate()
{
LOG((__FUNCTION__));
bool empty;
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
}
if (empty) {
LOG((__PRETTY_FUNCTION__));
--mNrAllocations;
MOZ_ASSERT(mNrAllocations >= 0, "Double-deallocations are prohibited");
if (mNrAllocations == 0) {
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}

View File

@ -135,6 +135,7 @@ public:
, mThread(aThread)
, mCapIndex(aIndex)
, mChannel(-1)
, mNrAllocations(0)
, mInitDone(false)
, mStarted(false)
, mSampleFrequency(MediaEngine::DEFAULT_SAMPLE_RATE)
@ -215,10 +216,11 @@ private:
// from kStarted to kStopped (which are combined with EndTrack()).
// mSources[] is accessed from webrtc threads.
Monitor mMonitor;
nsTArray<nsRefPtr<SourceMediaStream>> mSources; // When this goes empty, we shut down HW
nsTArray<nsRefPtr<SourceMediaStream>> mSources;
nsCOMPtr<nsIThread> mThread;
int mCapIndex;
int mChannel;
int mNrAllocations; // When this becomes 0, we shut down HW
TrackID mTrackID;
bool mInitDone;
bool mStarted;

View File

@ -305,18 +305,16 @@ MediaEngineWebRTCMicrophoneSource::Allocate(const dom::MediaTrackConstraints &aC
LOG(("Audio device %d allocated shared", mCapIndex));
}
}
++mNrAllocations;
return NS_OK;
}
nsresult
MediaEngineWebRTCMicrophoneSource::Deallocate()
{
bool empty;
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
}
if (empty) {
--mNrAllocations;
MOZ_ASSERT(mNrAllocations >= 0, "Double-deallocations are prohibited");
if (mNrAllocations == 0) {
// If empty, no callbacks to deliver data should be occuring
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;