mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 912342 - Move code MediaOperationTask from .h to .cpp. r=jesup
This commit is contained in:
parent
a0aeb846e8
commit
7575061788
@ -214,6 +214,151 @@ HostHasPermission(nsIURI &docURI)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generic class for running long media operations like Start off the main
|
||||||
|
// thread, and then (because nsDOMMediaStreams aren't threadsafe),
|
||||||
|
// ProxyReleases mStream since it's cycle collected.
|
||||||
|
class MediaOperationTask : public Task
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// so we can send Stop without AddRef()ing from the MSG thread
|
||||||
|
MediaOperationTask(MediaOperation aType,
|
||||||
|
GetUserMediaCallbackMediaStreamListener* aListener,
|
||||||
|
DOMMediaStream* aStream,
|
||||||
|
DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback,
|
||||||
|
MediaEngineSource* aAudioSource,
|
||||||
|
MediaEngineSource* aVideoSource,
|
||||||
|
bool aBool,
|
||||||
|
uint64_t aWindowID,
|
||||||
|
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
|
||||||
|
: mType(aType)
|
||||||
|
, mStream(aStream)
|
||||||
|
, mOnTracksAvailableCallback(aOnTracksAvailableCallback)
|
||||||
|
, mAudioSource(aAudioSource)
|
||||||
|
, mVideoSource(aVideoSource)
|
||||||
|
, mListener(aListener)
|
||||||
|
, mBool(aBool)
|
||||||
|
, mWindowID(aWindowID)
|
||||||
|
, mOnFailure(aError)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~MediaOperationTask()
|
||||||
|
{
|
||||||
|
// MediaStreams can be released on any thread.
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReturnCallbackError(nsresult rv, const char* errorLog);
|
||||||
|
|
||||||
|
void
|
||||||
|
Run()
|
||||||
|
{
|
||||||
|
SourceMediaStream *source = mListener->GetSourceStream();
|
||||||
|
// No locking between these is required as all the callbacks for the
|
||||||
|
// same MediaStream will occur on the same thread.
|
||||||
|
if (!source) // means the stream was never Activated()
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (mType) {
|
||||||
|
case MEDIA_START:
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
if (mAudioSource) {
|
||||||
|
rv = mAudioSource->Start(source, kAudioTrack);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
ReturnCallbackError(rv, "Starting audio failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mVideoSource) {
|
||||||
|
rv = mVideoSource->Start(source, kVideoTrack);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
ReturnCallbackError(rv, "Starting video failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Start() queued the tracks to be added synchronously to avoid races
|
||||||
|
source->FinishAddTracks();
|
||||||
|
|
||||||
|
source->SetPullEnabled(true);
|
||||||
|
source->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
||||||
|
|
||||||
|
MM_LOG(("started all sources"));
|
||||||
|
// Forward mOnTracksAvailableCallback to GetUserMediaNotificationEvent,
|
||||||
|
// because mOnTracksAvailableCallback needs to be added to mStream
|
||||||
|
// on the main thread.
|
||||||
|
nsIRunnable *event =
|
||||||
|
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STARTING,
|
||||||
|
mStream.forget(),
|
||||||
|
mOnTracksAvailableCallback.forget(),
|
||||||
|
mAudioSource != nullptr,
|
||||||
|
mVideoSource != nullptr,
|
||||||
|
mWindowID, mOnFailure.forget());
|
||||||
|
// event must always be released on mainthread due to the JS callbacks
|
||||||
|
// in the TracksAvailableCallback
|
||||||
|
NS_DispatchToMainThread(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEDIA_STOP:
|
||||||
|
case MEDIA_STOP_TRACK:
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
||||||
|
if (mAudioSource) {
|
||||||
|
mAudioSource->Stop(source, kAudioTrack);
|
||||||
|
mAudioSource->Deallocate();
|
||||||
|
}
|
||||||
|
if (mVideoSource) {
|
||||||
|
mVideoSource->Stop(source, kVideoTrack);
|
||||||
|
mVideoSource->Deallocate();
|
||||||
|
}
|
||||||
|
// Do this after stopping all tracks with EndTrack()
|
||||||
|
if (mBool) {
|
||||||
|
source->Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIRunnable *event =
|
||||||
|
new GetUserMediaNotificationEvent(mListener,
|
||||||
|
mType == MEDIA_STOP ?
|
||||||
|
GetUserMediaNotificationEvent::STOPPING :
|
||||||
|
GetUserMediaNotificationEvent::STOPPED_TRACK,
|
||||||
|
mAudioSource != nullptr,
|
||||||
|
mVideoSource != nullptr,
|
||||||
|
mWindowID);
|
||||||
|
// event must always be released on mainthread due to the JS callbacks
|
||||||
|
// in the TracksAvailableCallback
|
||||||
|
NS_DispatchToMainThread(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEDIA_DIRECT_LISTENERS:
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
||||||
|
if (mVideoSource) {
|
||||||
|
mVideoSource->SetDirectListeners(mBool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_ASSERT(false,"invalid MediaManager operation");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MediaOperation mType;
|
||||||
|
nsRefPtr<DOMMediaStream> mStream;
|
||||||
|
nsAutoPtr<DOMMediaStream::OnTracksAvailableCallback> mOnTracksAvailableCallback;
|
||||||
|
nsRefPtr<MediaEngineSource> mAudioSource; // threadsafe
|
||||||
|
nsRefPtr<MediaEngineSource> mVideoSource; // threadsafe
|
||||||
|
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe
|
||||||
|
bool mBool;
|
||||||
|
uint64_t mWindowID;
|
||||||
|
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an error back to content.
|
* Send an error back to content.
|
||||||
* Do this only on the main thread. The onSuccess callback is also passed here
|
* Do this only on the main thread. The onSuccess callback is also passed here
|
||||||
|
@ -310,151 +310,6 @@ private:
|
|||||||
nsAutoPtr<DOMMediaStream::OnTracksAvailableCallback> mOnTracksAvailableCallback;
|
nsAutoPtr<DOMMediaStream::OnTracksAvailableCallback> mOnTracksAvailableCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic class for running long media operations like Start off the main
|
|
||||||
// thread, and then (because nsDOMMediaStreams aren't threadsafe),
|
|
||||||
// ProxyReleases mStream since it's cycle collected.
|
|
||||||
class MediaOperationTask : public Task
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// so we can send Stop without AddRef()ing from the MSG thread
|
|
||||||
MediaOperationTask(MediaOperation aType,
|
|
||||||
GetUserMediaCallbackMediaStreamListener* aListener,
|
|
||||||
DOMMediaStream* aStream,
|
|
||||||
DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback,
|
|
||||||
MediaEngineSource* aAudioSource,
|
|
||||||
MediaEngineSource* aVideoSource,
|
|
||||||
bool aBool,
|
|
||||||
uint64_t aWindowID,
|
|
||||||
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
|
|
||||||
: mType(aType)
|
|
||||||
, mStream(aStream)
|
|
||||||
, mOnTracksAvailableCallback(aOnTracksAvailableCallback)
|
|
||||||
, mAudioSource(aAudioSource)
|
|
||||||
, mVideoSource(aVideoSource)
|
|
||||||
, mListener(aListener)
|
|
||||||
, mBool(aBool)
|
|
||||||
, mWindowID(aWindowID)
|
|
||||||
, mOnFailure(aError)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~MediaOperationTask()
|
|
||||||
{
|
|
||||||
// MediaStreams can be released on any thread.
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReturnCallbackError(nsresult rv, const char* errorLog);
|
|
||||||
|
|
||||||
void
|
|
||||||
Run()
|
|
||||||
{
|
|
||||||
SourceMediaStream *source = mListener->GetSourceStream();
|
|
||||||
// No locking between these is required as all the callbacks for the
|
|
||||||
// same MediaStream will occur on the same thread.
|
|
||||||
if (!source) // means the stream was never Activated()
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (mType) {
|
|
||||||
case MEDIA_START:
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (mAudioSource) {
|
|
||||||
rv = mAudioSource->Start(source, kAudioTrack);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
ReturnCallbackError(rv, "Starting audio failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mVideoSource) {
|
|
||||||
rv = mVideoSource->Start(source, kVideoTrack);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
ReturnCallbackError(rv, "Starting video failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Start() queued the tracks to be added synchronously to avoid races
|
|
||||||
source->FinishAddTracks();
|
|
||||||
|
|
||||||
source->SetPullEnabled(true);
|
|
||||||
source->AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
|
||||||
|
|
||||||
MM_LOG(("started all sources"));
|
|
||||||
// Forward mOnTracksAvailableCallback to GetUserMediaNotificationEvent,
|
|
||||||
// because mOnTracksAvailableCallback needs to be added to mStream
|
|
||||||
// on the main thread.
|
|
||||||
nsIRunnable *event =
|
|
||||||
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STARTING,
|
|
||||||
mStream.forget(),
|
|
||||||
mOnTracksAvailableCallback.forget(),
|
|
||||||
mAudioSource != nullptr,
|
|
||||||
mVideoSource != nullptr,
|
|
||||||
mWindowID, mOnFailure.forget());
|
|
||||||
// event must always be released on mainthread due to the JS callbacks
|
|
||||||
// in the TracksAvailableCallback
|
|
||||||
NS_DispatchToMainThread(event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MEDIA_STOP:
|
|
||||||
case MEDIA_STOP_TRACK:
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
|
||||||
if (mAudioSource) {
|
|
||||||
mAudioSource->Stop(source, kAudioTrack);
|
|
||||||
mAudioSource->Deallocate();
|
|
||||||
}
|
|
||||||
if (mVideoSource) {
|
|
||||||
mVideoSource->Stop(source, kVideoTrack);
|
|
||||||
mVideoSource->Deallocate();
|
|
||||||
}
|
|
||||||
// Do this after stopping all tracks with EndTrack()
|
|
||||||
if (mBool) {
|
|
||||||
source->Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIRunnable *event =
|
|
||||||
new GetUserMediaNotificationEvent(mListener,
|
|
||||||
mType == MEDIA_STOP ?
|
|
||||||
GetUserMediaNotificationEvent::STOPPING :
|
|
||||||
GetUserMediaNotificationEvent::STOPPED_TRACK,
|
|
||||||
mAudioSource != nullptr,
|
|
||||||
mVideoSource != nullptr,
|
|
||||||
mWindowID);
|
|
||||||
// event must always be released on mainthread due to the JS callbacks
|
|
||||||
// in the TracksAvailableCallback
|
|
||||||
NS_DispatchToMainThread(event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MEDIA_DIRECT_LISTENERS:
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
|
||||||
if (mVideoSource) {
|
|
||||||
mVideoSource->SetDirectListeners(mBool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT(false,"invalid MediaManager operation");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
MediaOperation mType;
|
|
||||||
nsRefPtr<DOMMediaStream> mStream;
|
|
||||||
nsAutoPtr<DOMMediaStream::OnTracksAvailableCallback> mOnTracksAvailableCallback;
|
|
||||||
nsRefPtr<MediaEngineSource> mAudioSource; // threadsafe
|
|
||||||
nsRefPtr<MediaEngineSource> mVideoSource; // threadsafe
|
|
||||||
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe
|
|
||||||
bool mBool;
|
|
||||||
uint64_t mWindowID;
|
|
||||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners;
|
typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners;
|
||||||
typedef nsClassHashtable<nsUint64HashKey, StreamListeners> WindowTable;
|
typedef nsClassHashtable<nsUint64HashKey, StreamListeners> WindowTable;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user