void ChannelMediaDecoder::NotifyDownloadEnded(nsresult aStatus) { MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); AbstractThread::AutoEnter context(AbstractMainThread()); LOG("NotifyDownloadEnded, status=%" PRIx32, static_cast<uint32_t>(aStatus)); if (aStatus == NS_BINDING_ABORTED) { // Download has been cancelled by user. GetOwner()->LoadAborted(); return; } UpdatePlaybackRate(); if (NS_SUCCEEDED(aStatus)) { // A final progress event will be fired by the MediaResource calling // DownloadSuspended on the element. // Also NotifySuspendedStatusChanged() will be called to update readyState // if download ended with success. } else if (aStatus != NS_BASE_STREAM_CLOSED) { NetworkError(); } }
void ChannelMediaDecoder::DownloadProgressed() { MOZ_ASSERT(NS_IsMainThread()); AbstractThread::AutoEnter context(AbstractMainThread()); MediaDecoder::DownloadProgressed(); UpdatePlaybackRate(); mResource->ThrottleReadahead(ShouldThrottleDownload()); }
void ChannelMediaDecoder::DurationChanged() { MOZ_ASSERT(NS_IsMainThread()); AbstractThread::AutoEnter context(AbstractMainThread()); MediaDecoder::DurationChanged(); // Duration has changed so we should recompute playback rate UpdatePlaybackRate(); }
void ChannelMediaDecoder::DurationChanged() { MOZ_ASSERT(NS_IsMainThread()); AbstractThread::AutoEnter context(AbstractMainThread()); MediaDecoder::DurationChanged(); // Duration has changed so we should recompute playback rate nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("ChannelMediaDecoder::UpdatePlaybackRate", [ stats = mPlaybackStatistics, res = RefPtr<BaseMediaResource>(mResource), duration = mDuration ]() { auto rate = ComputePlaybackRate(stats, res, duration); UpdatePlaybackRate(rate, res); }); nsresult rv = GetStateMachine()->OwnerThread()->Dispatch(r.forget()); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); Unused << rv; }
void ChannelMediaDecoder::NotifyDownloadEnded(nsresult aStatus) { MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); AbstractThread::AutoEnter context(AbstractMainThread()); LOG("NotifyDownloadEnded, status=%" PRIx32, static_cast<uint32_t>(aStatus)); if (NS_SUCCEEDED(aStatus)) { // Download ends successfully. This is a stream with a finite length. GetStateMachine()->DispatchIsLiveStream(false); } MediaDecoderOwner* owner = GetOwner(); if (NS_SUCCEEDED(aStatus) || aStatus == NS_BASE_STREAM_CLOSED) { nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("ChannelMediaDecoder::UpdatePlaybackRate", [ stats = mPlaybackStatistics, res = RefPtr<BaseMediaResource>(mResource), duration = mDuration ]() { auto rate = ComputePlaybackRate(stats, res, duration); UpdatePlaybackRate(rate, res); }); nsresult rv = GetStateMachine()->OwnerThread()->Dispatch(r.forget()); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); Unused << rv; owner->DownloadSuspended(); // NotifySuspendedStatusChanged will tell the element that download // has been suspended "by the cache", which is true since we never // download anything. The element can then transition to HAVE_ENOUGH_DATA. owner->NotifySuspendedByCache(true); } else if (aStatus == NS_BINDING_ABORTED) { // Download has been cancelled by user. owner->LoadAborted(); } else { NetworkError(MediaResult(aStatus, "Download aborted")); } }
void ChannelMediaDecoder::DownloadProgressed() { MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); GetOwner()->DownloadProgressed(); using StatsPromise = MozPromise<MediaStatistics, bool, true>; InvokeAsync(GetStateMachine()->OwnerThread(), __func__, [ playbackStats = mPlaybackStatistics, res = RefPtr<BaseMediaResource>(mResource), duration = mDuration, pos = mPlaybackPosition ]() { auto rate = ComputePlaybackRate(playbackStats, res, duration); UpdatePlaybackRate(rate, res); MediaStatistics stats = GetStatistics(rate, res, pos); return StatsPromise::CreateAndResolve(stats, __func__); }) ->Then( mAbstractMainThread, __func__, [ =, self = RefPtr<ChannelMediaDecoder>(this) ](MediaStatistics aStats) { if (IsShutdown()) { return; } mCanPlayThrough = aStats.CanPlayThrough(); GetStateMachine()->DispatchCanPlayThrough(mCanPlayThrough); mResource->ThrottleReadahead(ShouldThrottleDownload(aStats)); // Update readyState since mCanPlayThrough might have changed. GetOwner()->UpdateReadyState(); }, []() { MOZ_ASSERT_UNREACHABLE("Promise not resolved"); }); }