// Create a webcompat-friendly description of a MediaResult.
static nsString
MediaResultDescription(const MediaResult& aResult, bool aIsError)
{
  nsCString name;
  GetErrorName(aResult.Code(), name);
  return NS_ConvertUTF8toUTF16(
           nsPrintfCString(
             "%s Code: %s (0x%08" PRIx32 ")%s%s",
             aIsError ? "Error" : "Warning", name.get(),
             static_cast<uint32_t>(aResult.Code()),
             aResult.Message().IsEmpty() ? "" : "\nDetails: ",
             aResult.Message().get()));
}
static bool
AllowDecodeIssue(const MediaResult& aDecodeIssue, bool aDecodeIssueIsError)
{
  if (aDecodeIssue == NS_OK) {
    // 'NS_OK' means we are not actually reporting a decode issue, so we
    // allow the report.
    return true;
  }

  // "media.decoder-doctor.decode-{errors,warnings}-allowed" controls which
  // decode issues may be dispatched to the front-end. It either contains:
  // - '*' -> Allow everything.
  // - Comma-separater list of ids -> Allow if the issue name is one of them.
  // - Nothing (missing or empty) -> Disable everything.
  nsAutoCString filter;
  Preferences::GetCString(aDecodeIssueIsError
                          ? "media.decoder-doctor.decode-errors-allowed"
                          : "media.decoder-doctor.decode-warnings-allowed",
                          filter);
  if (filter.EqualsLiteral("*")) {
    return true;
  }

  nsCString decodeIssueName;
  GetErrorName(aDecodeIssue.Code(), static_cast<nsACString&>(decodeIssueName));
  return StringListContains(filter, decodeIssueName);
}
Esempio n. 3
0
void
MediaSource::EndOfStream(const MediaResult& aError)
{
  MOZ_ASSERT(NS_IsMainThread());
  MSE_API("EndOfStream(aError=%d)", aError.Code());

  SetReadyState(MediaSourceReadyState::Ended);
  mSourceBuffers->Ended();
  mDecoder->DecodeError(aError);
}
Esempio n. 4
0
RefPtr<ReaderProxy::AudioDataPromise>
ReaderProxy::OnAudioDataRequestFailed(const MediaResult& aError)
{
  MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());

  if (mSeamlessLoopingBlocked || !mSeamlessLoopingEnabled ||
      aError.Code() != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
    return AudioDataPromise::CreateAndReject(aError, __func__);
  }

  // The data time in the audio queue is assumed to be increased linearly,
  // so we need to add the last ending time as the offset to correct the
  // audio data time in the next round when seamless looping is enabled.
  mLoopingOffset = mLastAudioEndTime;

  // Save the duration of the audio track if it hasn't been set.
  if (!mAudioDuration.IsValid()) {
    mAudioDuration = mLastAudioEndTime;
  }

  // For seamless looping, the demuxer is sought to the beginning and then
  // keep requesting decoded data in advance, upon receiving EOS.
  // The MDSM will not be aware of the EOS and keep receiving decoded data
  // as usual while looping is on.
  RefPtr<ReaderProxy> self = this;
  RefPtr<MediaFormatReader> reader = mReader;
  ResetDecode(TrackInfo::kAudioTrack);
  return SeekInternal(SeekTarget(media::TimeUnit::Zero(), SeekTarget::Accurate))
    ->Then(mReader->OwnerThread(),
           __func__,
           [reader]() { return reader->RequestAudioData(); },
           [](const SeekRejectValue& aReject) {
             return AudioDataPromise::CreateAndReject(aReject.mError, __func__);
           })
    ->Then(mOwnerThread,
           __func__,
           [self](RefPtr<AudioData> aAudio) {
             return self->OnAudioDataRequestCompleted(aAudio.forget());
           },
           [](const MediaResult& aError) {
             return AudioDataPromise::CreateAndReject(aError, __func__);
           });
}