// 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); }
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); }
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__); }); }