--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -581,21 +581,21 @@ public:
break;
case MEDIA_STOP:
case MEDIA_STOP_TRACK:
{
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
if (mAudioDevice) {
mAudioDevice->GetSource()->Stop(source, kAudioTrack);
- mAudioDevice->GetSource()->Deallocate();
+ mAudioDevice->Deallocate();
}
if (mVideoDevice) {
mVideoDevice->GetSource()->Stop(source, kVideoTrack);
- mVideoDevice->GetSource()->Deallocate();
+ mVideoDevice->Deallocate();
}
if (mType == MEDIA_STOP) {
source->EndAllTrackAndFinish();
}
nsIRunnable *event =
new GetUserMediaNotificationEvent(mListener,
mType == MEDIA_STOP ?
@@ -881,36 +881,30 @@ VideoDevice::GetSource()
}
AudioDevice::Source*
AudioDevice::GetSource()
{
return static_cast<Source*>(&*mSource);
}
-nsresult VideoDevice::Allocate(const dom::MediaTrackConstraints &aConstraints,
+nsresult MediaDevice::Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsACString& aOrigin) {
- return GetSource()->Allocate(aConstraints, aPrefs, mID, aOrigin);
+ return GetSource()->Allocate(aConstraints, aPrefs, mID, aOrigin,
+ getter_AddRefs(mAllocationHandle));
}
-nsresult AudioDevice::Allocate(const dom::MediaTrackConstraints &aConstraints,
- const MediaEnginePrefs &aPrefs,
- const nsACString& aOrigin) {
- return GetSource()->Allocate(aConstraints, aPrefs, mID, aOrigin);
-}
-
-nsresult VideoDevice::Restart(const dom::MediaTrackConstraints &aConstraints,
+nsresult MediaDevice::Restart(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs) {
return GetSource()->Restart(aConstraints, aPrefs, mID);
}
-nsresult AudioDevice::Restart(const dom::MediaTrackConstraints &aConstraints,
- const MediaEnginePrefs &aPrefs) {
- return GetSource()->Restart(aConstraints, aPrefs, mID);
+nsresult MediaDevice::Deallocate() {
+ return GetSource()->Deallocate(mAllocationHandle);
}
void
MediaOperationTask::ReturnCallbackError(nsresult rv, const char* errorLog)
{
MM_LOG(("%s , rv=%d", errorLog, rv));
NS_DispatchToMainThread(do_AddRef(new ReleaseMediaOperationResource(mStream.forget(),
mOnTracksAvailableCallback.forget())));
@@ -1439,17 +1433,17 @@ public:
}
}
if (mVideoDevice) {
rv = mVideoDevice->Allocate(GetInvariant(mConstraints.mVideo),
mPrefs, mOrigin);
if (NS_FAILED(rv)) {
LOG(("Failed to allocate videosource %d\n",rv));
if (mAudioDevice) {
- mAudioDevice->GetSource()->Deallocate();
+ mAudioDevice->Deallocate();
}
Fail(NS_LITERAL_STRING("NotReadableError"),
NS_LITERAL_STRING("Failed to allocate videosource"));
return NS_OK;
}
}
PeerIdentity* peerIdentity = nullptr;
if (!mConstraints.mPeerIdentity.IsEmpty()) {
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -58,72 +58,73 @@ class GetUserMediaCallbackMediaStreamLis
class GetUserMediaTask;
extern LogModule* GetMediaManagerLog();
#define MM_LOG(msg) MOZ_LOG(GetMediaManagerLog(), mozilla::LogLevel::Debug, msg)
class MediaDevice : public nsIMediaDevice
{
public:
+ typedef MediaEngineSource Source;
+
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEDIADEVICE
void SetId(const nsAString& aID);
virtual uint32_t GetBestFitnessDistance(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets);
+ virtual Source* GetSource() = 0;
+ nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
+ const MediaEnginePrefs &aPrefs,
+ const nsACString& aOrigin);
+ nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
+ const MediaEnginePrefs &aPrefs);
+ nsresult Deallocate();
protected:
virtual ~MediaDevice() {}
explicit MediaDevice(MediaEngineSource* aSource, bool aIsVideo);
+
static uint32_t FitnessDistance(nsString aN,
const dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters& aConstraint);
private:
static bool StringsContain(const dom::OwningStringOrStringSequence& aStrings,
nsString aN);
static uint32_t FitnessDistance(nsString aN,
const dom::ConstrainDOMStringParameters& aParams);
protected:
nsString mName;
nsString mID;
dom::MediaSourceEnum mMediaSource;
RefPtr<MediaEngineSource> mSource;
+ RefPtr<MediaEngineSource::BaseAllocationHandle> mAllocationHandle;
public:
dom::MediaSourceEnum GetMediaSource() {
return mMediaSource;
}
bool mIsVideo;
};
class VideoDevice : public MediaDevice
{
public:
typedef MediaEngineVideoSource Source;
explicit VideoDevice(Source* aSource);
- NS_IMETHOD GetType(nsAString& aType);
- Source* GetSource();
- nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
- const MediaEnginePrefs &aPrefs,
- const nsACString& aOrigin);
- nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
- const MediaEnginePrefs &aPrefs);
+ NS_IMETHOD GetType(nsAString& aType) override;
+ Source* GetSource() override;
};
class AudioDevice : public MediaDevice
{
public:
typedef MediaEngineAudioSource Source;
explicit AudioDevice(Source* aSource);
- NS_IMETHOD GetType(nsAString& aType);
- Source* GetSource();
- nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
- const MediaEnginePrefs &aPrefs,
- const nsACString& aOrigin);
- nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
- const MediaEnginePrefs &aPrefs);
+ NS_IMETHOD GetType(nsAString& aType) override;
+ Source* GetSource() override;
};
class GetUserMediaNotificationEvent: public Runnable
{
public:
enum GetUserMediaStatus {
STARTING,
STOPPING,
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -114,18 +114,26 @@ public:
virtual void Shutdown() = 0;
/* Populate the human readable name of this device in the nsAString */
virtual void GetName(nsAString&) = 0;
/* Populate the UUID of this device in the nsACString */
virtual void GetUUID(nsACString&) = 0;
+ class BaseAllocationHandle
+ {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BaseAllocationHandle);
+ protected:
+ virtual ~BaseAllocationHandle() {}
+ };
+
/* Release the device back to the system. */
- virtual nsresult Deallocate() = 0;
+ virtual nsresult Deallocate(BaseAllocationHandle* aHandle) = 0;
/* Start the device and add the track to the provided SourceMediaStream, with
* the provided TrackID. You may start appending data to the track
* immediately after. */
virtual nsresult Start(SourceMediaStream*, TrackID, const PrincipalHandle&) = 0;
/* tell the source if there are any direct listeners attached */
virtual void SetDirectListeners(bool) = 0;
@@ -174,17 +182,18 @@ public:
void SetHasFakeTracks(bool aHasFakeTracks) {
mHasFakeTracks = aHasFakeTracks;
}
/* This call reserves but does not start the device. */
virtual nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin) = 0;
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) = 0;
virtual uint32_t GetBestFitnessDistance(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
const nsString& aDeviceId) = 0;
protected:
// Only class' own members can be initialized in constructor initializer list.
explicit MediaEngineSource(MediaEngineState aState)
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -84,38 +84,41 @@ MediaEngineDefaultVideoSource::GetBestFi
#endif
return distance;
}
nsresult
MediaEngineDefaultVideoSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin)
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle)
{
if (mState != kReleased) {
return NS_ERROR_FAILURE;
}
// Mock failure for automated tests.
if (aConstraints.mDeviceId.IsString() &&
aConstraints.mDeviceId.GetAsString().EqualsASCII("bad device")) {
return NS_ERROR_FAILURE;
}
mOpts = aPrefs;
mOpts.mWidth = mOpts.mWidth ? mOpts.mWidth : MediaEngine::DEFAULT_43_VIDEO_WIDTH;
mOpts.mHeight = mOpts.mHeight ? mOpts.mHeight : MediaEngine::DEFAULT_43_VIDEO_HEIGHT;
mState = kAllocated;
+ aOutHandle = nullptr;
return NS_OK;
}
nsresult
-MediaEngineDefaultVideoSource::Deallocate()
+MediaEngineDefaultVideoSource::Deallocate(BaseAllocationHandle* aHandle)
{
+ MOZ_ASSERT(!aHandle);
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
mState = kReleased;
mImage = nullptr;
return NS_OK;
}
@@ -405,38 +408,41 @@ MediaEngineDefaultAudioSource::GetBestFi
#endif
return distance;
}
nsresult
MediaEngineDefaultAudioSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin)
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle)
{
if (mState != kReleased) {
return NS_ERROR_FAILURE;
}
// Mock failure for automated tests.
if (aConstraints.mDeviceId.IsString() &&
aConstraints.mDeviceId.GetAsString().EqualsASCII("bad device")) {
return NS_ERROR_FAILURE;
}
mState = kAllocated;
// generate sine wave (default 1KHz)
mSineGenerator = new SineWaveGenerator(AUDIO_RATE,
static_cast<uint32_t>(aPrefs.mFreq ? aPrefs.mFreq : 1000));
+ aOutHandle = nullptr;
return NS_OK;
}
nsresult
-MediaEngineDefaultAudioSource::Deallocate()
+MediaEngineDefaultAudioSource::Deallocate(BaseAllocationHandle* aHandle)
{
+ MOZ_ASSERT(!aHandle);
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
mState = kReleased;
return NS_OK;
}
nsresult
--- a/dom/media/webrtc/MediaEngineDefault.h
+++ b/dom/media/webrtc/MediaEngineDefault.h
@@ -42,18 +42,19 @@ public:
void Shutdown() override {};
void GetName(nsAString&) override;
void GetUUID(nsACString&) override;
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin) override;
- nsresult Deallocate() override;
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) override;
+ nsresult Deallocate(BaseAllocationHandle* aHandle) override;
nsresult Start(SourceMediaStream*, TrackID, const PrincipalHandle&) override;
nsresult Stop(SourceMediaStream*, TrackID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
@@ -113,18 +114,19 @@ public:
void Shutdown() override {};
void GetName(nsAString&) override;
void GetUUID(nsACString&) override;
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin) override;
- nsresult Deallocate() override;
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) override;
+ nsresult Deallocate(BaseAllocationHandle* aHandle) override;
nsresult Start(SourceMediaStream*, TrackID, const PrincipalHandle&) override;
nsresult Stop(SourceMediaStream*, TrackID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
void AppendToSegment(AudioSegment& aSegment,
TrackTicks aSamples);
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -82,39 +82,45 @@ MediaEngineRemoteVideoSource::Shutdown()
}
source = mSources[0];
}
Stop(source, kVideoTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}
- if (mState == kAllocated || mState == kStopped) {
- Deallocate();
+ for (auto& registered : mRegisteredHandles) {
+ MOZ_ASSERT(mState == kAllocated || mState == kStopped);
+ Deallocate(registered.get());
}
- mState = kReleased;
+ MOZ_ASSERT(mState == kReleased);
mInitDone = false;
return;
}
nsresult
-MediaEngineRemoteVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints,
- const MediaEnginePrefs& aPrefs,
- const nsString& aDeviceId,
- const nsACString& aOrigin)
+MediaEngineRemoteVideoSource::Allocate(
+ const dom::MediaTrackConstraints& aConstraints,
+ const MediaEnginePrefs& aPrefs,
+ const nsString& aDeviceId,
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle)
{
LOG((__PRETTY_FUNCTION__));
AssertIsOnOwningThread();
if (!mInitDone) {
LOG(("Init not done"));
return NS_ERROR_FAILURE;
}
+ RefPtr<AllocationHandle> handle = new AllocationHandle(aConstraints);
+ mRegisteredHandles.AppendElement(handle);
+
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)
if (!ChooseCapability(aConstraints, aPrefs, aDeviceId)) {
return NS_ERROR_UNEXPECTED;
}
@@ -132,26 +138,38 @@ MediaEngineRemoteVideoSource::Allocate(c
MOZ_ASSERT(mPrincipalHandles.IsEmpty());
LOG(("Video device %d reallocated", mCaptureIndex));
} else {
LOG(("Video device %d allocated shared", mCaptureIndex));
}
}
++mNrAllocations;
-
+ handle.forget(aOutHandle);
return NS_OK;
}
nsresult
-MediaEngineRemoteVideoSource::Deallocate()
+MediaEngineRemoteVideoSource::Deallocate(BaseAllocationHandle* aHandle)
{
LOG((__PRETTY_FUNCTION__));
AssertIsOnOwningThread();
+ MOZ_ASSERT(aHandle);
+ RefPtr<AllocationHandle> handle = static_cast<AllocationHandle*>(aHandle);
+ class Comparator {
+ public:
+ static bool Equals(const RefPtr<AllocationHandle>& a,
+ const RefPtr<AllocationHandle>& b) {
+ return a.get() == b.get();
+ }
+ };
+ MOZ_ASSERT(mRegisteredHandles.Contains(handle, Comparator()));
+ mRegisteredHandles.RemoveElementAt(mRegisteredHandles.IndexOf(handle, 0,
+ Comparator()));
--mNrAllocations;
MOZ_ASSERT(mNrAllocations >= 0, "Double-deallocations are prohibited");
if (mNrAllocations == 0) {
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
mozilla::camera::GetChildAndCall(
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -66,21 +66,33 @@ public:
int DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame) override { return 0; };
bool IsTextureSupported() override { return false; };
// MediaEngineCameraVideoSource
MediaEngineRemoteVideoSource(int aIndex, mozilla::camera::CaptureEngine aCapEngine,
dom::MediaSourceEnum aMediaSource,
const char* aMonitorName = "RemoteVideo.Monitor");
+ class AllocationHandle : public BaseAllocationHandle
+ {
+ public:
+ AllocationHandle(const dom::MediaTrackConstraints& aConstraints)
+ : mConstraints(aConstraints) {}
+ private:
+ ~AllocationHandle() override {}
+ public:
+ dom::MediaTrackConstraints mConstraints;
+ };
+
nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin) override;
- nsresult Deallocate() override;;
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) override;
+ nsresult Deallocate(BaseAllocationHandle* aHandle) override;;
nsresult Start(SourceMediaStream*, TrackID, const PrincipalHandle&) override;
nsresult Stop(SourceMediaStream*, TrackID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream* aSource,
TrackID aId,
@@ -104,13 +116,15 @@ protected:
private:
// Initialize the needed Video engine interfaces.
void Init();
size_t NumCapabilities() override;
void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut) override;
dom::MediaSourceEnum mMediaSource; // source of media (camera | application | screen)
mozilla::camera::CaptureEngine mCapEngine;
+
+ nsTArray<RefPtr<AllocationHandle>> mRegisteredHandles;
};
}
#endif /* MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ */
--- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp
@@ -134,24 +134,25 @@ MediaEngineTabVideoSource::GetUUID(nsACS
#define DEFAULT_TABSHARE_VIDEO_MAX_WIDTH 4096
#define DEFAULT_TABSHARE_VIDEO_MAX_HEIGHT 4096
#define DEFAULT_TABSHARE_VIDEO_FRAMERATE 30
nsresult
MediaEngineTabVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin)
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle)
{
// windowId is not a proper constraint, so just read it.
// It has no well-defined behavior in advanced, so ignore it there.
mWindowId = aConstraints.mBrowserWindow.WasPassed() ?
aConstraints.mBrowserWindow.Value() : -1;
-
+ aOutHandle = nullptr;
return Restart(aConstraints, aPrefs, aDeviceId);
}
nsresult
MediaEngineTabVideoSource::Restart(const dom::MediaTrackConstraints& aConstraints,
const mozilla::MediaEnginePrefs& aPrefs,
const nsString& aDeviceId)
{
@@ -173,18 +174,19 @@ MediaEngineTabVideoSource::Restart(const
mViewportOffsetY = c.mViewportOffsetY.Get(0);
mViewportWidth = c.mViewportWidth.Get(INT32_MAX);
mViewportHeight = c.mViewportHeight.Get(INT32_MAX);
}
return NS_OK;
}
nsresult
-MediaEngineTabVideoSource::Deallocate()
+MediaEngineTabVideoSource::Deallocate(BaseAllocationHandle* aHandle)
{
+ MOZ_ASSERT(!aHandle);
return NS_OK;
}
nsresult
MediaEngineTabVideoSource::Start(SourceMediaStream* aStream, TrackID aID,
const PrincipalHandle& aPrincipalHandle)
{
nsCOMPtr<nsIRunnable> runnable;
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -20,18 +20,19 @@ class MediaEngineTabVideoSource : public
MediaEngineTabVideoSource();
void Shutdown() override {};
void GetName(nsAString_internal&) override;
void GetUUID(nsACString_internal&) override;
nsresult Allocate(const dom::MediaTrackConstraints &,
const mozilla::MediaEnginePrefs&,
const nsString& aDeviceId,
- const nsACString& aOrigin) override;
- nsresult Deallocate() override;
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) override;
+ nsresult Deallocate(BaseAllocationHandle* aHandle) override;
nsresult Start(mozilla::SourceMediaStream*, mozilla::TrackID, const mozilla::PrincipalHandle&) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
void NotifyPull(mozilla::MediaStreamGraph*, mozilla::SourceMediaStream*, mozilla::TrackID, mozilla::StreamTime, const mozilla::PrincipalHandle& aPrincipalHandle) override;
nsresult Stop(mozilla::SourceMediaStream*, mozilla::TrackID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const mozilla::MediaEnginePrefs& aPrefs,
const nsString& aDeviceId) override;
bool IsFake() override;
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -72,24 +72,27 @@ public:
: MediaEngineAudioSource(kReleased)
{
}
void GetName(nsAString& aName) override;
void GetUUID(nsACString& aUUID) override;
nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin) override
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) override
{
// Nothing to do here, everything is managed in MediaManager.cpp
+ aOutHandle = nullptr;
return NS_OK;
}
- nsresult Deallocate() override
+ nsresult Deallocate(BaseAllocationHandle* aHandle) override
{
// Nothing to do here, everything is managed in MediaManager.cpp
+ MOZ_ASSERT(!aHandle);
return NS_OK;
}
void Shutdown() override
{
// Nothing to do here, everything is managed in MediaManager.cpp
}
nsresult Start(SourceMediaStream* aMediaStream,
TrackID aId,
@@ -446,18 +449,19 @@ public:
}
void GetName(nsAString& aName) override;
void GetUUID(nsACString& aUUID) override;
nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin) override;
- nsresult Deallocate() override;
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle) override;
+ nsresult Deallocate(BaseAllocationHandle* aHandle) override;
nsresult Start(SourceMediaStream* aStream,
TrackID aID,
const PrincipalHandle& aPrincipalHandle) override;
nsresult Stop(SourceMediaStream* aSource, TrackID aID) override;
nsresult Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
void SetDirectListeners(bool aHasDirectListeners) override {};
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -217,17 +217,18 @@ uint32_t MediaEngineWebRTCMicrophoneSour
}
return distance;
}
nsresult
MediaEngineWebRTCMicrophoneSource::Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId,
- const nsACString& aOrigin)
+ const nsACString& aOrigin,
+ BaseAllocationHandle** aOutHandle)
{
AssertIsOnOwningThread();
if (mState == kReleased) {
if (sChannelsOpen == 0) {
if (!InitEngine()) {
LOG(("Audio engine is not initalized"));
return NS_ERROR_FAILURE;
}
@@ -253,16 +254,17 @@ MediaEngineWebRTCMicrophoneSource::Alloc
MonitorAutoLock lock(mMonitor);
if (mSources.IsEmpty()) {
LOG(("Audio device %d reallocated", mCapIndex));
} else {
LOG(("Audio device %d allocated shared", mCapIndex));
}
}
++mNrAllocations;
+ aOutHandle = nullptr;
return Restart(aConstraints, aPrefs, aDeviceId);
}
nsresult
MediaEngineWebRTCMicrophoneSource::Restart(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId)
{
@@ -304,19 +306,20 @@ MediaEngineWebRTCMicrophoneSource::Resta
if (mSkipProcessing) {
mSampleFrequency = MediaEngine::USE_GRAPH_RATE;
}
return NS_OK;
}
nsresult
-MediaEngineWebRTCMicrophoneSource::Deallocate()
+MediaEngineWebRTCMicrophoneSource::Deallocate(BaseAllocationHandle* aHandle)
{
AssertIsOnOwningThread();
+ MOZ_ASSERT(!aHandle);
--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;
}
@@ -727,18 +730,19 @@ MediaEngineWebRTCMicrophoneSource::Shutd
}
source = mSources[0];
}
Stop(source, kAudioTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}
- if (mState == kAllocated || mState == kStopped) {
- Deallocate();
+ while (mNrAllocations) {
+ MOZ_ASSERT(mState == kAllocated || mState == kStopped);
+ Deallocate(nullptr); // XXX Extend concurrent constraints code to mics.
}
FreeChannel();
DeInitEngine();
mAudioInput = nullptr;
}