void
IPCBlobInputStreamThread::Initialize()
{
  if (!NS_IsMainThread()) {
    NS_DispatchToMainThread(new ThreadInitializeRunnable());
    return;
  }

  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
  if (NS_WARN_IF(!obs)) {
    return;
  }

  nsresult rv =
    obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return;
  }

  nsCOMPtr<nsIThread> thread;
  rv = NS_NewNamedThread("DOM File", getter_AddRefs(thread));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return;
  }

  mThread = thread;

  if (!mPendingActors.IsEmpty()) {
    for (uint32_t i = 0; i < mPendingActors.Length(); ++i) {
      MigrateActorInternal(mPendingActors[i]);
    }

    mPendingActors.Clear();
  }
}
Пример #2
0
void
ThreadedDriver::Start()
{
  LIFECYCLE_LOG("Starting thread for a SystemClockDriver  %p\n", mGraphImpl);
  nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
  NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event);
}
Пример #3
0
void LSPAnnotate()
{
  nsCOMPtr<nsIThread> thread;
  nsCOMPtr<nsIRunnable> runnable =
    do_QueryObject(new LSPAnnotationGatherer());
  NS_NewNamedThread("LSP Annotate", getter_AddRefs(thread), runnable);
}
Пример #4
0
nsresult
MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
{
  mDecoder = CreateDecoder(mMimeType);

  if (!mDecoder) {
    INVOKE_CALLBACK(Error,
                    MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
    return NS_ERROR_FAILURE;
  }

  // Check if the video codec supports adaptive playback or not.
  if (aSurface && java::HardwareCodecCapabilityUtils::CheckSupportsAdaptivePlayback(
                    mDecoder, nsCString(TranslateMimeType(mMimeType)))) {
      // TODO: may need to find a way to not use hard code to decide the max w/h.
      mFormat->SetInteger(MediaFormat::KEY_MAX_WIDTH, 1920);
      mFormat->SetInteger(MediaFormat::KEY_MAX_HEIGHT, 1080);
  }

  MediaCrypto::LocalRef crypto = MediaDrmProxy::GetMediaCrypto(mDrmStubId);
  bool hascrypto = !!crypto;
  LOG("Has(%d) MediaCrypto (%s)", hascrypto, NS_ConvertUTF16toUTF8(mDrmStubId).get());
  nsresult rv;
  NS_ENSURE_SUCCESS(rv = mDecoder->Configure(mFormat, aSurface, crypto, 0), rv);
  NS_ENSURE_SUCCESS(rv = mDecoder->Start(), rv);

  NS_ENSURE_SUCCESS(rv = ResetInputBuffers(), rv);
  NS_ENSURE_SUCCESS(rv = ResetOutputBuffers(), rv);

  nsCOMPtr<nsIRunnable> r = NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop);
  rv = NS_NewNamedThread("MC Decoder", getter_AddRefs(mThread), r);

  return rv;
}
Пример #5
0
MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
    : mMutex("mozilla::MediaEngineWebRTC")
    , mScreenEngine(nullptr)
    , mBrowserEngine(nullptr)
    , mWinEngine(nullptr)
    , mAppEngine(nullptr)
    , mVideoEngine(nullptr)
    , mVoiceEngine(nullptr)
    , mVideoEngineInit(false)
    , mAudioEngineInit(false)
    , mScreenEngineInit(false)
    , mBrowserEngineInit(false)
    , mAppEngineInit(false)
{
#ifndef MOZ_B2G_CAMERA
  nsCOMPtr<nsIComponentRegistrar> compMgr;
  NS_GetComponentRegistrar(getter_AddRefs(compMgr));
  if (compMgr) {
    compMgr->IsContractIDRegistered(NS_TABSOURCESERVICE_CONTRACTID, &mHasTabVideoSource);
  }
#else
  AsyncLatencyLogger::Get()->AddRef();
#endif
  // XXX
  gFarendObserver = new AudioOutputObserver();

  NS_NewNamedThread("AudioGUM", getter_AddRefs(mThread));
  MOZ_ASSERT(mThread);
}
Пример #6
0
CamerasChild*
GetCamerasChild() {
  CamerasSingleton::Mutex().AssertCurrentThreadOwns();
  if (!CamerasSingleton::Child()) {
    MOZ_ASSERT(!NS_IsMainThread(), "Should not be on the main Thread");
    MOZ_ASSERT(!CamerasSingleton::Thread());
    LOG(("No sCameras, setting up IPC Thread"));
    nsresult rv = NS_NewNamedThread("Cameras IPC",
                                    getter_AddRefs(CamerasSingleton::Thread()));
    if (NS_FAILED(rv)) {
      LOG(("Error launching IPC Thread"));
      return nullptr;
    }

    // At this point we are in the MediaManager thread, and the thread we are
    // dispatching to is the specific Cameras IPC thread that was just made
    // above, so now we will fire off a runnable to run
    // BackgroundChild::SynchronouslyCreateForCurrentThread there, while we
    // block in this thread.
    // We block until the following happens in the Cameras IPC thread:
    // 1) Creation of PBackground finishes
    // 2) Creation of PCameras finishes by sending a message to the parent
    RefPtr<InitializeIPCThread> runnable = new InitializeIPCThread();
    RefPtr<SyncRunnable> sr = new SyncRunnable(runnable);
    sr->DispatchToThread(CamerasSingleton::Thread());
    CamerasSingleton::Child() = runnable->GetCamerasChild();
  }
  if (!CamerasSingleton::Child()) {
    LOG(("Failed to set up CamerasChild, are we in shutdown?"));
  }
  return CamerasSingleton::Child();
}
Пример #7
0
// always call with getter_AddRefs, because it does
NS_IMETHODIMP
GeckoMediaPluginService::GetThread(nsIThread** aThread)
{
  MOZ_ASSERT(aThread);

  // This can be called from any thread.
  MutexAutoLock lock(mMutex);

  if (!mGMPThread) {
    // Don't allow the thread to be created after shutdown has started.
    if (mGMPThreadShutdown) {
      return NS_ERROR_FAILURE;
    }

    nsresult rv = NS_NewNamedThread("GMPThread", getter_AddRefs(mGMPThread));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Tell the thread to initialize plugins
    InitializePlugins();
  }

  nsCOMPtr<nsIThread> copy = mGMPThread;
  copy.forget(aThread);

  return NS_OK;
}
Пример #8
0
bool
StartDBus()
{
  MOZ_ASSERT(!NS_IsMainThread());
  NS_ENSURE_TRUE(!gDBusThread, true);

  nsRefPtr<DBusThread> dbusThread(new DBusThread());

  bool eventLoopStarted = dbusThread->Initialize();
  NS_ENSURE_TRUE(eventLoopStarted, false);

  nsresult rv;

  if (!gDBusServiceThread) {
    nsIThread* dbusServiceThread;
    rv = NS_NewNamedThread("DBus Thread", &dbusServiceThread);
    NS_ENSURE_SUCCESS(rv, false);
    gDBusServiceThread = dbusServiceThread;
  }

#ifdef DEBUG
  LOG("DBus Thread Starting\n");
#endif

  nsRefPtr<nsIRunnable> pollTask(new DBusPollTask(dbusThread));
  NS_ENSURE_TRUE(pollTask, false);

  rv = gDBusServiceThread->Dispatch(pollTask, NS_DISPATCH_NORMAL);
  NS_ENSURE_SUCCESS(rv, false);

  gDBusThread = dbusThread;

  return true;
}
Пример #9
0
void
anp_audio_start(ANPAudioTrack* s)
{
  if (s == nullptr || s->output_unit == nullptr) {
    return;
  }

  if (s->keepGoing) {
    // we are already playing.  Ignore.
    return;
  }

  JNIEnv* const jenv = mozilla::jni::GetEnvForThread();

  mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
  jenv->CallVoidMethod(s->output_unit, at.play);

  if (autoFrame.CheckForException()) {
    jenv->DeleteGlobalRef(s->at_class);
    delete s;
    return;
  }

  s->isStopped = false;
  s->keepGoing = true;

  // AudioRunnable now owns the ANPAudioTrack
  RefPtr<AudioRunnable> runnable = new AudioRunnable(s);

  nsCOMPtr<nsIThread> thread;
  NS_NewNamedThread("Android Audio", getter_AddRefs(thread), runnable);
}
Пример #10
0
void
MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
{
  if (mState != RecordingState::Inactive) {
    aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
    return;
  }

  if (aTimeSlice.WasPassed()) {
    if (aTimeSlice.Value() < 0) {
      aResult.Throw(NS_ERROR_INVALID_ARG);
      return;
    }
    mTimeSlice = aTimeSlice.Value();
  } else {
    mTimeSlice = 0;
  }

  // Create a TrackUnionStream to support Pause/Resume by using ChangeExplicitBlockerCount
  MediaStreamGraph* gm = mStream->GetStream()->Graph();
  mTrackUnionStream = gm->CreateTrackUnionStream(mStream);
  MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed");

  if (!CheckPrincipal()) {
    aResult.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return;
  }

  if (mEncodedBufferCache == nullptr) {
    mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER);
  }

  mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""));
  MOZ_ASSERT(mEncoder, "CreateEncoder failed");

  mTrackUnionStream->SetAutofinish(true);
  nsRefPtr<MediaInputPort> port =
    mTrackUnionStream->AllocateInputPort(mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);

  if (mEncoder) {
    mTrackUnionStream->AddListener(mEncoder);
  } else {
    aResult.Throw(NS_ERROR_DOM_ABORT_ERR);
  }

  if (!mReadThread) {
    nsresult rv = NS_NewNamedThread("Media Encoder",
                                    getter_AddRefs(mReadThread));
    if (NS_FAILED(rv)) {
      aResult.Throw(rv);
      return;
    }
    nsRefPtr<ExtractEncodedDataTask> event = new ExtractEncodedDataTask(this, mEncoder);
    mReadThread->Dispatch(event, NS_DISPATCH_NORMAL);
    mState = RecordingState::Recording;
  }
}
Пример #11
0
nsresult
nsPACMan::Init(nsISystemProxySettings *systemProxySettings)
{
  mSystemProxySettings = systemProxySettings;

  nsresult rv =
    NS_NewNamedThread("ProxyResolution", getter_AddRefs(mPACThread));

  return rv;
}
Пример #12
0
// Encoder.
WebrtcOpenH264VideoEncoder::WebrtcOpenH264VideoEncoder()
    : callback_(nullptr),
      mutex_("WebrtcOpenH264VideoEncoder") {
  nsIThread* thread;

  nsresult rv = NS_NewNamedThread("encoder-thread", &thread);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  thread_ = thread;
}
Пример #13
0
void
ThreadedDriver::Start()
{
    LIFECYCLE_LOG("Starting thread for a SystemClockDriver  %p\n", mGraphImpl);
    nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
    // Note: mThread may be null during event->Run() if we pass to NewNamedThread!  See AudioInitTask
    nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread));
    if (NS_SUCCEEDED(rv)) {
        mThread->Dispatch(event, NS_DISPATCH_NORMAL);
    }
}
nsIThread *
AudioStream::GetThread()
{
  if (!mAudioPlaybackThread) {
    NS_NewNamedThread("Audio Stream",
                      getter_AddRefs(mAudioPlaybackThread),
                      nullptr,
                      MEDIA_THREAD_STACK_SIZE);
  }
  return mAudioPlaybackThread;
}
void
InitGonkMemoryPressureMonitoring()
{
  // memoryPressureWatcher is held alive by the observer service.
  nsRefPtr<MemoryPressureWatcher> memoryPressureWatcher =
    new MemoryPressureWatcher();
  NS_ENSURE_SUCCESS_VOID(memoryPressureWatcher->Init());

  nsCOMPtr<nsIThread> thread;
  NS_NewNamedThread("MemoryPressure", getter_AddRefs(thread),
                    memoryPressureWatcher);
}
Пример #16
0
NS_IMETHODIMP
nsPicoService::Observe(nsISupports* aSubject, const char* aTopic,
                       const char16_t* aData)
{
  MOZ_ASSERT(NS_IsMainThread());
  NS_ENSURE_TRUE(!strcmp(aTopic, "profile-after-change"), NS_ERROR_UNEXPECTED);

  DebugOnly<nsresult> rv = NS_NewNamedThread("Pico Worker", getter_AddRefs(mThread));
  MOZ_ASSERT(NS_SUCCEEDED(rv));
  return mThread->Dispatch(
    NS_NewRunnableMethod(this, &nsPicoService::Init), NS_DISPATCH_NORMAL);
}
Пример #17
0
nsresult
AudioSink::Init()
{
  nsresult rv = NS_NewNamedThread("Media Audio",
                                  getter_AddRefs(mThread),
                                  nullptr,
                                  MEDIA_THREAD_STACK_SIZE);
  if (NS_FAILED(rv)) {
    return rv;
  }
  nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &AudioSink::AudioLoop);
  return mThread->Dispatch(event, NS_DISPATCH_NORMAL);
}
Пример #18
0
static bool SetupGlobalThread() {
  if (!gThread) {
    nsIThread *thread;

    nsresult rv = NS_NewNamedThread("pseudo-main",&thread);
    if (NS_FAILED(rv))
      return false;

    gThread = thread;
    sipcc::PeerConnectionCtx::InitializeGlobal(gThread);
  }
  return true;
}
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPParent *aPlugin)
    : GMPSharedMemManager(aPlugin),
      mIsOpen(false),
      mPlugin(aPlugin),
      mCallback(nullptr),
      mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
{
    MOZ_ASSERT(mPlugin);

    nsresult rv = NS_NewNamedThread("GMPEncoded", getter_AddRefs(mEncodedThread));
    if (NS_FAILED(rv)) {
        MOZ_CRASH();
    }
}
Пример #20
0
CacheStorageService::CacheStorageService()
: mLock("CacheStorageService")
, mShutdown(false)
, mMemorySize(0)
, mPurging(false)
{
  CacheFileIOManager::Init();

  MOZ_ASSERT(!sSelf);

  sSelf = this;
  sGlobalEntryTables = new GlobalEntryTables();

  NS_NewNamedThread("Cache Mngmnt", getter_AddRefs(mThread));
}
// called from main thread only
NS_IMETHODIMP
nsSocketTransportService::Init()
{
    if (!NS_IsMainThread()) {
        NS_ERROR("wrong thread");
        return NS_ERROR_UNEXPECTED;
    }

    if (mInitialized)
        return NS_OK;

    if (mShuttingDown)
        return NS_ERROR_UNEXPECTED;

    nsCOMPtr<nsIThread> thread;
    nsresult rv = NS_NewNamedThread("Socket Thread", getter_AddRefs(thread), this);
    if (NS_FAILED(rv)) return rv;
    
    {
        MutexAutoLock lock(mLock);
        // Install our mThread, protecting against concurrent readers
        thread.swap(mThread);
    }

    nsCOMPtr<nsIPrefBranch> tmpPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
    if (tmpPrefService) {
        tmpPrefService->AddObserver(SEND_BUFFER_PREF, this, false);
        tmpPrefService->AddObserver(KEEPALIVE_ENABLED_PREF, this, false);
        tmpPrefService->AddObserver(KEEPALIVE_IDLE_TIME_PREF, this, false);
        tmpPrefService->AddObserver(KEEPALIVE_RETRY_INTERVAL_PREF, this, false);
        tmpPrefService->AddObserver(KEEPALIVE_PROBE_COUNT_PREF, this, false);
        tmpPrefService->AddObserver(MAX_TIME_BETWEEN_TWO_POLLS, this, false);
        tmpPrefService->AddObserver(TELEMETRY_PREF, this, false);
        tmpPrefService->AddObserver(MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN, this, false);
    }
    UpdatePrefs();

    nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
    if (obsSvc) {
        obsSvc->AddObserver(this, "profile-initial-state", false);
        obsSvc->AddObserver(this, "last-pb-context-exited", false);
        obsSvc->AddObserver(this, NS_WIDGET_SLEEP_OBSERVER_TOPIC, true);
        obsSvc->AddObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC, true);
    }

    mInitialized = true;
    return NS_OK;
}
Пример #22
0
nsRefPtr<GenericPromise>
DecodedAudioDataSink::Init()
{
  nsRefPtr<GenericPromise> p = mEndPromise.Ensure(__func__);
  nsresult rv = NS_NewNamedThread("Media Audio",
                                  getter_AddRefs(mThread),
                                  nullptr,
                                  SharedThreadPool::kStackSize);
  if (NS_FAILED(rv)) {
    mEndPromise.Reject(rv, __func__);
    return p;
  }

  ScheduleNextLoopCrossThread();
  return p;
}
Пример #23
0
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPContentParent *aPlugin)
: GMPSharedMemManager(aPlugin),
  mIsOpen(false),
  mShuttingDown(false),
  mActorDestroyed(false),
  mPlugin(aPlugin),
  mCallback(nullptr),
  mVideoHost(this),
  mPluginId(aPlugin->GetPluginId())
{
  MOZ_ASSERT(mPlugin);

  nsresult rv = NS_NewNamedThread("GMPEncoded", getter_AddRefs(mEncodedThread));
  if (NS_FAILED(rv)) {
    MOZ_CRASH();
  }
}
Пример #24
0
nsresult
Tickler::Init()
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(!mTimer);
  MOZ_ASSERT(!mActive);
  MOZ_ASSERT(!mThread);
  MOZ_ASSERT(!mFD);

  if (AndroidBridge::HasEnv()) {
      GeckoAppShell::EnableNetworkNotifications();
  }

  mFD = PR_OpenUDPSocket(PR_AF_INET);
  if (!mFD)
    return NS_ERROR_FAILURE;

  // make sure new socket has a ttl of 1
  // failure is not fatal.
  PRSocketOptionData opt;
  opt.option = PR_SockOpt_IpTimeToLive;
  opt.value.ip_ttl = 1;
  PR_SetSocketOption(mFD, &opt);

  nsresult rv = NS_NewNamedThread("wifi tickler",
                                  getter_AddRefs(mThread));
  if (NS_FAILED(rv))
    return rv;

  nsCOMPtr<nsITimer> tmpTimer(do_CreateInstance(NS_TIMER_CONTRACTID, &rv));
  if (NS_FAILED(rv))
    return rv;

  rv = tmpTimer->SetTarget(mThread);
  if (NS_FAILED(rv))
    return rv;

  mTimer.swap(tmpTimer);

  mAddr.inet.family = PR_AF_INET;
  mAddr.inet.port = PR_htons (4886);
  mAddr.inet.ip = 0;

  return NS_OK;
}
Пример #25
0
bool
PaintThread::Init()
{
  MOZ_ASSERT(NS_IsMainThread());

  RefPtr<nsIThread> thread;
  nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
  if (NS_FAILED(rv)) {
    return false;
  }
  sThread = thread;

  nsCOMPtr<nsIRunnable> paintInitTask =
    NewRunnableMethod("PaintThread::InitOnPaintThread",
                      this, &PaintThread::InitOnPaintThread);
  SyncRunnable::DispatchToThread(sThread, paintInitTask);
  return true;
}
Пример #26
0
bool
DBusThread::StartEventLoop()
{
  // socketpair opens two sockets for the process to communicate on.
  // This is how android's implementation of the dbus event loop
  // communicates with itself in relation to IPC signals. These
  // sockets are contained sequentially in the same struct in the
  // android code, but we break them out into class members here.
  // Therefore we read into a local array and then copy.

  int sockets[2];
  if (socketpair(AF_LOCAL, SOCK_STREAM, 0, (int*)(&sockets)) < 0) {
    TearDownData();
    return false;
  }
  mControlFdR.rwget() = sockets[0];
  mControlFdW.rwget() = sockets[1];
  pollfd p;
  p.fd = mControlFdR.get();
  p.events = POLLIN;
  mPollData.AppendElement(p);

  // Due to the fact that mPollData and mWatchData have to match, we
  // push a null to the front of mWatchData since it has the control
  // fd in the first slot of mPollData.

  mWatchData.AppendElement((DBusWatch*)NULL);
  if (!SetUpEventLoop()) {
    TearDownData();
    return false;
  }
  if (NS_FAILED(NS_NewNamedThread("DBus Poll",
                                  getter_AddRefs(mThread),
                                  NS_NewNonOwningRunnableMethod(this,
                                                                &DBusThread::EventLoop)))) {
    NS_WARNING("Cannot create DBus Thread!");
    return false;    
  }
#ifdef DEBUG
  LOG("DBus Thread Starting\n");
#endif
  return true;
}
Пример #27
0
NS_IMETHODIMP
nsPicoService::Observe(nsISupports* aSubject, const char* aTopic,
                       const char16_t* aData)
{
  MOZ_ASSERT(NS_IsMainThread());
  if(NS_WARN_IF(!(!strcmp(aTopic, "profile-after-change")))) {
    return NS_ERROR_UNEXPECTED;
  }

  if (!Preferences::GetBool("media.webspeech.synth.enabled") ||
      Preferences::GetBool("media.webspeech.synth.test")) {
    return NS_OK;
  }

  DebugOnly<nsresult> rv = NS_NewNamedThread("Pico Worker", getter_AddRefs(mThread));
  MOZ_ASSERT(NS_SUCCEEDED(rv));
  return mThread->Dispatch(
    NS_NewRunnableMethod(this, &nsPicoService::Init), NS_DISPATCH_NORMAL);
}
Пример #28
0
nsresult MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
{
  mDecoder = CreateDecoder(mMimeType);
  if (!mDecoder) {
    ENVOKE_CALLBACK(Error);
    return NS_ERROR_FAILURE;
  }

  nsresult rv;
  NS_ENSURE_SUCCESS(rv = mDecoder->Configure(mFormat, aSurface, nullptr, 0), rv);
  NS_ENSURE_SUCCESS(rv = mDecoder->Start(), rv);

  NS_ENSURE_SUCCESS(rv = ResetInputBuffers(), rv);
  NS_ENSURE_SUCCESS(rv = ResetOutputBuffers(), rv);

  NS_NewNamedThread("MC Decoder", getter_AddRefs(mThread),
                    NS_NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop));

  return NS_OK;
}
Пример #29
0
nsRefPtr<GenericPromise>
AudioSink::Init()
{
  nsRefPtr<GenericPromise> p = mEndPromise.Ensure(__func__);
  nsresult rv = NS_NewNamedThread("Media Audio",
                                  getter_AddRefs(mThread),
                                  nullptr,
                                  MEDIA_THREAD_STACK_SIZE);
  if (NS_FAILED(rv)) {
    mEndPromise.Reject(rv, __func__);
    return p;
  }

  nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &AudioSink::AudioLoop);
  rv =  mThread->Dispatch(event, NS_DISPATCH_NORMAL);
  if (NS_FAILED(rv)) {
    mEndPromise.Reject(rv, __func__);
    return p;
  }

  return p;
}
bool
VsyncIOThreadHolder::Start()
{
  nsresult rv = NS_NewNamedThread("VsyncIOThread", getter_AddRefs(mThread));
  return NS_SUCCEEDED(rv);
}