Ejemplo n.º 1
0
void
MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
{
  MOZ_DIAGNOSTIC_ASSERT(!IsSeeking());
  mAudioRequest.Complete();

  MSE_DEBUG("aReason=%u IsEnded: %d", aReason, IsEnded());
  if (aReason == CANCELED) {
    mAudioPromise.Reject(CANCELED, __func__);
    return;
  }

  // If End of stream. Force switching past this stream to another reader by
  // switching to the end of the buffered range.
  int64_t lastAudioTime = mLastAudioTime;
  if (aReason == END_OF_STREAM && mAudioSourceDecoder) {
    AdjustEndTime(&mLastAudioTime, mAudioSourceDecoder);
  }

  SwitchSourceResult result = SwitchAudioSource(&mLastAudioTime);
  // See if we can find a different source that can pick up where we left off.
  if (result == SOURCE_NEW) {
    GetAudioReader()->ResetDecode();
    mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
                            ->RefableThen(GetTaskQueue(), __func__, this,
                                          &MediaSourceReader::CompleteAudioSeekAndDoRequest,
                                          &MediaSourceReader::CompleteAudioSeekAndRejectPromise));
    return;
  }

  // If we got a DECODE_ERROR and we have buffered data in the requested range
  // then it must be a genuine decoding error.
  // Otherwise we can assume that the data was either evicted or explicitely
  // removed from the source buffer and we should wait for new data.
  if (aReason == DECODE_ERROR && result != SOURCE_NONE) {
    mAudioPromise.Reject(DECODE_ERROR, __func__);
    return;
  }

  CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime);

  if (mLastAudioTime - lastAudioTime >= EOS_FUZZ_US) {
    // No decoders are available to switch to. We will re-attempt from the last
    // failing position.
    mLastAudioTime = lastAudioTime;
  }
}
Ejemplo n.º 2
0
nsRefPtr<MediaDecoderReader::AudioDataPromise>
MediaSourceReader::RequestAudioData()
{
  MOZ_ASSERT(OnTaskQueue());
  MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(), "No sample requests allowed while seeking");
  MOZ_DIAGNOSTIC_ASSERT(mAudioPromise.IsEmpty(), "No duplicate sample requests");
  nsRefPtr<AudioDataPromise> p = mAudioPromise.Ensure(__func__);
  MSE_DEBUGV("mLastAudioTime=%lld", mLastAudioTime);
  if (!mAudioTrack) {
    MSE_DEBUG("called with no audio track");
    mAudioPromise.Reject(DECODE_ERROR, __func__);
    return p;
  }
  if (IsSeeking()) {
    MSE_DEBUG("called mid-seek. Rejecting.");
    mAudioPromise.Reject(CANCELED, __func__);
    return p;
  }
  MOZ_DIAGNOSTIC_ASSERT(!mAudioSeekRequest.Exists());

  SwitchSourceResult ret = SwitchAudioSource(&mLastAudioTime);
  switch (ret) {
    case SOURCE_NEW:
      GetAudioReader()->ResetDecode();
      mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
                              ->Then(OwnerThread(), __func__, this,
                                     &MediaSourceReader::CompleteAudioSeekAndDoRequest,
                                     &MediaSourceReader::CompleteAudioSeekAndRejectPromise));
      break;
    case SOURCE_NONE:
      if (!mLastAudioTime) {
        // This is the first call to RequestAudioData.
        // Fallback to using decoder with earliest data.
        mAudioSourceDecoder = FirstDecoder(MediaData::AUDIO_DATA);
      }
      if (mLastAudioTime || !mAudioSourceDecoder) {
        CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime);
        break;
      }
      // Fallback to getting first frame from first decoder.
    default:
      DoAudioRequest();
      break;
  }
  return p;
}
Ejemplo n.º 3
0
void
MediaSourceReader::DoAudioSeek()
{
  int64_t seekTime = mPendingSeekTime;
  if (mSeekToEnd) {
    seekTime = LastSampleTime(MediaData::AUDIO_DATA);
  }
  if (SwitchAudioSource(&seekTime) == SOURCE_NONE) {
    // Data we need got evicted since the last time we checked for data
    // availability. Abort current seek attempt.
    mWaitingForSeekData = true;
    return;
  }
  GetAudioReader()->ResetDecode();
  mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(seekTime), 0)
                         ->RefableThen(GetTaskQueue(), __func__, this,
                                       &MediaSourceReader::OnAudioSeekCompleted,
                                       &MediaSourceReader::OnAudioSeekFailed));
  MSE_DEBUG("reader=%p", GetAudioReader());
}