nsresult ChannelMediaDecoder::Load(nsIChannel* aChannel, bool aIsPrivateBrowsing, nsIStreamListener** aStreamListener) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mResource); MOZ_ASSERT(aStreamListener); AbstractThread::AutoEnter context(AbstractMainThread()); mResource = BaseMediaResource::Create(mResourceCallback, aChannel, aIsPrivateBrowsing); if (!mResource) { return NS_ERROR_FAILURE; } DDLINKCHILD("resource", mResource.get()); nsresult rv = MediaShutdownManager::Instance().Register(this); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } rv = mResource->Open(aStreamListener); NS_ENSURE_SUCCESS(rv, rv); SetStateMachine(CreateStateMachine()); NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE); GetStateMachine()->DispatchIsLiveStream(mResource->IsLiveStream()); return InitializeStateMachine(); }
nsresult ChannelMediaDecoder::Load(BaseMediaResource* aOriginal) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mResource); AbstractThread::AutoEnter context(AbstractMainThread()); mResource = aOriginal->CloneData(mResourceCallback); if (!mResource) { return NS_ERROR_FAILURE; } DDLINKCHILD("resource", mResource.get()); nsresult rv = MediaShutdownManager::Instance().Register(this); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } SetStateMachine(CreateStateMachine()); NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE); GetStateMachine()->DispatchIsLiveStream(mResource->IsLiveStream()); return InitializeStateMachine(); }
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 AudioDestinationNode::NotifyMainThreadStreamFinished() { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mStream->IsFinished()); if (mIsOffline) { AbstractMainThread()->Dispatch( NewRunnableMethod("dom::AudioDestinationNode::FireOfflineCompletionEvent", this, &AudioDestinationNode::FireOfflineCompletionEvent)); } }
void ChannelMediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) { MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); AbstractThread::AutoEnter context(AbstractMainThread()); if (mIgnoreProgressData) { return; } MOZ_ASSERT(GetStateMachine()); if (aOffset >= mDecoderPosition) { mPlaybackStatistics.AddBytes(aBytes); } mDecoderPosition = aOffset + aBytes; }
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")); } }