Exemplo n.º 1
0
// This code used to live inside AudioStream::Init(), but on Mac (others?)
// it has been known to take 300-800 (or even 8500) ms to execute(!)
nsresult
AudioStream::OpenCubeb(cubeb_stream_params &aParams,
                       LatencyRequest aLatencyRequest)
{
  cubeb* cubebContext = CubebUtils::GetCubebContext();
  if (!cubebContext) {
    NS_WARNING("Can't get cubeb context!");
    MonitorAutoLock mon(mMonitor);
    mState = AudioStream::ERRORED;
    return NS_ERROR_FAILURE;
  }

  // If the latency pref is set, use it. Otherwise, if this stream is intended
  // for low latency playback, try to get the lowest latency possible.
  // Otherwise, for normal streams, use 100ms.
  uint32_t latency;
  if (aLatencyRequest == LowLatency && !CubebUtils::CubebLatencyPrefSet()) {
    if (cubeb_get_min_latency(cubebContext, aParams, &latency) != CUBEB_OK) {
      latency = CubebUtils::GetCubebLatency();
    }
  } else {
    latency = CubebUtils::GetCubebLatency();
  }

  {
    cubeb_stream* stream;
    if (cubeb_stream_init(cubebContext, &stream, "AudioStream", aParams,
                          latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
      MonitorAutoLock mon(mMonitor);
      MOZ_ASSERT(mState != SHUTDOWN);
      mCubebStream.reset(stream);
      // We can't cubeb_stream_start() the thread from a transient thread due to
      // cubeb API requirements (init can be called from another thread, but
      // not start/stop/destroy/etc)
    } else {
      MonitorAutoLock mon(mMonitor);
      mState = ERRORED;
      NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
      return NS_ERROR_FAILURE;
    }
  }

  cubeb_stream_register_device_changed_callback(mCubebStream.get(),
                                                AudioStream::DeviceChangedCallback_s);

  mState = INITIALIZED;

  if (!mStartTime.IsNull()) {
    TimeDuration timeDelta = TimeStamp::Now() - mStartTime;
    LOG(("AudioStream creation time %sfirst: %u ms", mIsFirst ? "" : "not ",
          (uint32_t) timeDelta.ToMilliseconds()));
    Telemetry::Accumulate(mIsFirst ? Telemetry::AUDIOSTREAM_FIRST_OPEN_MS :
        Telemetry::AUDIOSTREAM_LATER_OPEN_MS, timeDelta.ToMilliseconds());
  }

  return NS_OK;
}
Exemplo n.º 2
0
void
AudioCallbackDriver::Init()
{
  cubeb_stream_params params;
  uint32_t latency;

  MOZ_ASSERT(!NS_IsMainThread(),
      "This is blocking and should never run on the main thread.");

  mSampleRate = params.rate = CubebUtils::PreferredSampleRate();

#if defined(__ANDROID__)
#if defined(MOZ_B2G)
  params.stream_type = CubebUtils::ConvertChannelToCubebType(mAudioChannel);
#else
  params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
#endif
  if (params.stream_type == CUBEB_STREAM_TYPE_MAX) {
    NS_WARNING("Bad stream type");
    return;
  }
#else
  (void)mAudioChannel;
#endif

  params.channels = mGraphImpl->AudioChannelCount();
  if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
    params.format = CUBEB_SAMPLE_S16NE;
  } else {
    params.format = CUBEB_SAMPLE_FLOAT32NE;
  }

  if (cubeb_get_min_latency(CubebUtils::GetCubebContext(), params, &latency) != CUBEB_OK) {
    NS_WARNING("Could not get minimal latency from cubeb.");
    return;
  }

  cubeb_stream* stream;
  if (cubeb_stream_init(CubebUtils::GetCubebContext(), &stream,
                        "AudioCallbackDriver", params, latency,
                        DataCallback_s, StateCallback_s, this) == CUBEB_OK) {
    mAudioStream.own(stream);
  } else {
    NS_WARNING("Could not create a cubeb stream for MediaStreamGraph.");
    return;
  }

  cubeb_stream_register_device_changed_callback(mAudioStream,
                                                AudioCallbackDriver::DeviceChangedCallback_s);

  StartStream();

  STREAM_LOG(PR_LOG_DEBUG, ("AudioCallbackDriver started."));
}
Exemplo n.º 3
0
void
AudioCallbackDriver::Init()
{
    cubeb_stream_params params;
    uint32_t latency;

    MOZ_ASSERT(!NS_IsMainThread(),
               "This is blocking and should never run on the main thread.");

    mSampleRate = params.rate = CubebUtils::PreferredSampleRate();

#if defined(__ANDROID__)
#if defined(MOZ_B2G)
    params.stream_type = CubebUtils::ConvertChannelToCubebType(mAudioChannel);
#else
    params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
#endif
    if (params.stream_type == CUBEB_STREAM_TYPE_MAX) {
        NS_WARNING("Bad stream type");
        return;
    }
#else
    (void)mAudioChannel;
#endif

    params.channels = mGraphImpl->AudioChannelCount();
    if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
        params.format = CUBEB_SAMPLE_S16NE;
    } else {
        params.format = CUBEB_SAMPLE_FLOAT32NE;
    }

    if (cubeb_get_min_latency(CubebUtils::GetCubebContext(), params, &latency) != CUBEB_OK) {
        NS_WARNING("Could not get minimal latency from cubeb.");
        return;
    }

    cubeb_stream* stream;
    if (cubeb_stream_init(CubebUtils::GetCubebContext(), &stream,
                          "AudioCallbackDriver", params, latency,
                          DataCallback_s, StateCallback_s, this) == CUBEB_OK) {
        mAudioStream.own(stream);
    } else {
        NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
        // Fall back to a driver using a normal thread.
        mNextDriver = new SystemClockDriver(GraphImpl());
        mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
        mGraphImpl->SetCurrentDriver(mNextDriver);
        DebugOnly<bool> found = mGraphImpl->RemoveMixerCallback(this);
        NS_WARN_IF_FALSE(!found, "Mixer callback not added when switching?");
        mNextDriver->Start();
        return;
    }

    cubeb_stream_register_device_changed_callback(mAudioStream,
            AudioCallbackDriver::DeviceChangedCallback_s);

    StartStream();

    STREAM_LOG(LogLevel::Debug, ("AudioCallbackDriver started."));
}