예제 #1
0
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();
}
예제 #2
0
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();
}
예제 #3
0
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();
  }
}
예제 #4
0
void
ChannelMediaDecoder::DownloadProgressed()
{
  MOZ_ASSERT(NS_IsMainThread());
  AbstractThread::AutoEnter context(AbstractMainThread());
  MediaDecoder::DownloadProgressed();
  UpdatePlaybackRate();
  mResource->ThrottleReadahead(ShouldThrottleDownload());
}
예제 #5
0
void
ChannelMediaDecoder::DurationChanged()
{
  MOZ_ASSERT(NS_IsMainThread());
  AbstractThread::AutoEnter context(AbstractMainThread());
  MediaDecoder::DurationChanged();
  // Duration has changed so we should recompute playback rate
  UpdatePlaybackRate();
}
예제 #6
0
void
AudioDestinationNode::NotifyMainThreadStreamFinished()
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(mStream->IsFinished());

  if (mIsOffline) {
    AbstractMainThread()->Dispatch(
      NewRunnableMethod("dom::AudioDestinationNode::FireOfflineCompletionEvent",
                        this,
                        &AudioDestinationNode::FireOfflineCompletionEvent));
  }
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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"));
  }
}