コード例 #1
0
ファイル: MediaSource.cpp プロジェクト: fitzgen/gecko-dev
RefPtr<MediaSource::ActiveCompletionPromise>
MediaSource::SourceBufferIsActive(SourceBuffer* aSourceBuffer)
{
  MOZ_ASSERT(NS_IsMainThread());
  mActiveSourceBuffers->ClearSimple();
  bool initMissing = false;
  bool found = false;
  for (uint32_t i = 0; i < mSourceBuffers->Length(); i++) {
    SourceBuffer* sourceBuffer = mSourceBuffers->IndexedGetter(i, found);
    MOZ_ALWAYS_TRUE(found);
    if (sourceBuffer == aSourceBuffer) {
      mActiveSourceBuffers->Append(aSourceBuffer);
    } else if (sourceBuffer->IsActive()) {
      mActiveSourceBuffers->AppendSimple(sourceBuffer);
    } else {
      // Some source buffers haven't yet received an init segment.
      // There's nothing more we can do at this stage.
      initMissing = true;
    }
  }
  if (initMissing || !mDecoder) {
    return ActiveCompletionPromise::CreateAndResolve(true, __func__);
  }

  mDecoder->NotifyInitDataArrived();

  // Add our promise to the queue.
  // It will be resolved once the HTMLMediaElement modifies its readyState.
  MozPromiseHolder<ActiveCompletionPromise> holder;
  RefPtr<ActiveCompletionPromise> promise = holder.Ensure(__func__);
  mCompletionPromises.AppendElement(std::move(holder));
  return promise;
}
コード例 #2
0
ファイル: DecodedStream.cpp プロジェクト: SJasoria/gecko-dev
void
DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
{
  AssertOwnerThread();
  MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");

  mStartTime.emplace(aStartTime);
  mInfo = aInfo;
  mPlaying = true;
  ConnectListener();

  class R : public Runnable {
    typedef MozPromiseHolder<GenericPromise> Promise;
  public:
    R(PlaybackInfoInit&& aInit, Promise&& aPromise, OutputStreamManager* aManager)
      : mInit(Move(aInit)), mOutputStreamManager(aManager)
    {
      mPromise = Move(aPromise);
    }
    NS_IMETHOD Run() override
    {
      MOZ_ASSERT(NS_IsMainThread());
      // No need to create a source stream when there are no output streams. This
      // happens when RemoveOutput() is called immediately after StartPlayback().
      if (!mOutputStreamManager->Graph()) {
        // Resolve the promise to indicate the end of playback.
        mPromise.Resolve(true, __func__);
        return NS_OK;
      }
      mData = MakeUnique<DecodedStreamData>(
        mOutputStreamManager, Move(mInit), Move(mPromise));
      return NS_OK;
    }
    UniquePtr<DecodedStreamData> ReleaseData()
    {
      return Move(mData);
    }
  private:
    PlaybackInfoInit mInit;
    Promise mPromise;
    RefPtr<OutputStreamManager> mOutputStreamManager;
    UniquePtr<DecodedStreamData> mData;
  };

  MozPromiseHolder<GenericPromise> promise;
  mFinishPromise = promise.Ensure(__func__);
  PlaybackInfoInit init {
    aStartTime, aInfo
  };
  nsCOMPtr<nsIRunnable> r = new R(Move(init), Move(promise), mOutputStreamManager);
  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
  SyncRunnable::DispatchToThread(mainThread, r);
  mData = static_cast<R*>(r.get())->ReleaseData();

  if (mData) {
    mData->SetPlaying(mPlaying);
    SendData();
  }
}
コード例 #3
0
ファイル: TestMP4Demuxer.cpp プロジェクト: MekliCZ/positron
  RefPtr<GenericPromise>
  CheckTrackKeyFrame(MediaTrackDemuxer* aTrackDemuxer)
  {
    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());

    RefPtr<MediaTrackDemuxer> track = aTrackDemuxer;
    RefPtr<MP4DemuxerBinding> binding = this;

    int64_t time = -1;
    while (mIndex < mSamples.Length()) {
      uint32_t i = mIndex++;
      if (mSamples[i]->mKeyframe) {
        time = mSamples[i]->mTime;
        break;
      }
    }

    RefPtr<GenericPromise> p = mCheckTrackKeyFramePromise.Ensure(__func__);

    if (time == -1) {
      mCheckTrackKeyFramePromise.Resolve(true, __func__);
      return p;
    }


    DispatchTask(
      [track, time, binding] () {
        track->Seek(media::TimeUnit::FromMicroseconds(time))->Then(binding->mTaskQueue, __func__,
          [track, time, binding] () {
            track->GetSamples()->Then(binding->mTaskQueue, __func__,
              [track, time, binding] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
                EXPECT_EQ(time, aSamples->mSamples[0]->mTime);
                binding->CheckTrackKeyFrame(track);
              },
              DO_FAIL
            );
          },
          DO_FAIL
        );
      }
    );

    return p;
  }
コード例 #4
0
ファイル: DecodedStream.cpp プロジェクト: ibheem/gecko-dev
void
DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
{
  AssertOwnerThread();
  MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");

  mStartTime.emplace(aStartTime);
  mInfo = aInfo;
  mPlaying = true;
  ConnectListener();

  class R : public nsRunnable {
    typedef MozPromiseHolder<GenericPromise> Promise;
    typedef void(DecodedStream::*Method)(Promise&&);
  public:
    R(DecodedStream* aThis, Method aMethod, Promise&& aPromise)
      : mThis(aThis), mMethod(aMethod)
    {
      mPromise = Move(aPromise);
    }
    NS_IMETHOD Run() override
    {
      (mThis->*mMethod)(Move(mPromise));
      return NS_OK;
    }
  private:
    nsRefPtr<DecodedStream> mThis;
    Method mMethod;
    Promise mPromise;
  };

  MozPromiseHolder<GenericPromise> promise;
  mFinishPromise = promise.Ensure(__func__);
  nsCOMPtr<nsIRunnable> r = new R(this, &DecodedStream::CreateData, Move(promise));
  AbstractThread::MainThread()->Dispatch(r.forget());
}
コード例 #5
0
ファイル: TestMP4Demuxer.cpp プロジェクト: MekliCZ/positron
  RefPtr<GenericPromise>
  CheckTrackSamples(MediaTrackDemuxer* aTrackDemuxer)
  {
    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());

    RefPtr<MediaTrackDemuxer> track = aTrackDemuxer;
    RefPtr<MP4DemuxerBinding> binding = this;

    RefPtr<GenericPromise> p = mCheckTrackSamples.Ensure(__func__);

    DispatchTask(
      [track, binding] () {
        track->GetSamples()->Then(binding->mTaskQueue, __func__,
          [track, binding] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
            if (aSamples->mSamples.Length()) {
              binding->mSamples.AppendElements(aSamples->mSamples);
              binding->CheckTrackSamples(track);
            }
          },
          [binding] (DemuxerFailureReason aReason) {
            if (aReason == DemuxerFailureReason::DEMUXER_ERROR) {
              EXPECT_TRUE(false);
              binding->mCheckTrackSamples.Reject(NS_ERROR_FAILURE, __func__);
            } else if (aReason == DemuxerFailureReason::END_OF_STREAM) {
              EXPECT_TRUE(binding->mSamples.Length() > 1);
              for (uint32_t i = 0; i < (binding->mSamples.Length() - 1); i++) {
                EXPECT_LT(binding->mSamples[i]->mTimecode, binding->mSamples[i + 1]->mTimecode);
                if (binding->mSamples[i]->mKeyframe) {
                  binding->mKeyFrameTimecodes.AppendElement(binding->mSamples[i]->mTimecode);
                }
              }
              binding->mCheckTrackSamples.Resolve(true, __func__);
            }
          }
        );
      }
    );

    return p;
  }