Пример #1
0
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
    MSE_DEBUG("SourceBuffer(%p)::AppendData(aLength=%u)", this, aLength);
    if (!PrepareAppend(aRv)) {
        return;
    }
    StartUpdating();

    if (!mTrackBuffer->AppendData(aData, aLength)) {
        Optional<MediaSourceEndOfStreamError> decodeError(MediaSourceEndOfStreamError::Decode);
        ErrorResult dummy;
        mMediaSource->EndOfStream(decodeError, dummy);
        aRv.Throw(NS_ERROR_FAILURE);
        return;
    }

    if (mTrackBuffer->HasInitSegment()) {
        mMediaSource->QueueInitializationEvent();
    }

    // Run the final step of the buffer append algorithm asynchronously to
    // ensure the SourceBuffer's updating flag transition behaves as required
    // by the spec.
    nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating);
    NS_DispatchToMainThread(event);
}
Пример #2
0
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
  MSE_DEBUG("AppendData(aLength=%u)", aLength);

  RefPtr<MediaByteBuffer> data = PrepareAppend(aData, aLength, aRv);
  if (!data) {
    return;
  }
  StartUpdating();

  mPendingAppend.Begin(mTrackBuffersManager->AppendData(data, mCurrentAttributes)
                       ->Then(AbstractThread::MainThread(), __func__, this,
                              &SourceBuffer::AppendDataCompletedWithSuccess,
                              &SourceBuffer::AppendDataErrored));
}
Пример #3
0
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
  MSE_DEBUG("AppendData(aLength=%u)", aLength);

  RefPtr<MediaByteBuffer> data = PrepareAppend(aData, aLength, aRv);
  if (!data) {
    return;
  }
  mContentManager->AppendData(data, mAttributes->GetTimestampOffset());

  StartUpdating();

  nsCOMPtr<nsIRunnable> task = new BufferAppendRunnable(this, mUpdateID);
  NS_DispatchToMainThread(task);
}
Пример #4
0
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
  MSE_DEBUG("AppendData(aLength=%u)", aLength);

  nsRefPtr<LargeDataBuffer> data = PrepareAppend(aData, aLength, aRv);
  if (!data) {
    return;
  }
  StartUpdating();

  MOZ_ASSERT(mAppendMode == SourceBufferAppendMode::Segments,
             "We don't handle timestampOffset for sequence mode yet");
  nsCOMPtr<nsIRunnable> task =
    new AppendDataRunnable(this, data, mTimestampOffset, mUpdateID);
  NS_DispatchToMainThread(task);
}
Пример #5
0
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
    MSE_DEBUG("AppendData(aLength=%u)", aLength);

    nsRefPtr<MediaByteBuffer> data = PrepareAppend(aData, aLength, aRv);
    if (!data) {
        return;
    }
    mContentManager->AppendData(data, mTimestampOffset);

    StartUpdating();

    MOZ_ASSERT(mIsUsingFormatReader || mAppendMode == SourceBufferAppendMode::Segments,
               "We don't handle timestampOffset for sequence mode yet");
    nsCOMPtr<nsIRunnable> task = new BufferAppendRunnable(this, mUpdateID);
    NS_DispatchToMainThread(task);
}
Пример #6
0
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
  MSE_DEBUG("SourceBuffer(%p)::AppendData(aLength=%u)", this, aLength);
  if (!PrepareAppend(aRv)) {
    return;
  }
  StartUpdating();
  // TODO: Run more of the buffer append algorithm asynchronously.
  if (mParser->IsInitSegmentPresent(aData, aLength)) {
    MSE_DEBUG("SourceBuffer(%p)::AppendData: New initialization segment.", this);
    mMediaSource->QueueInitializationEvent();
    mTrackBuffer->DiscardDecoder();
    if (!mTrackBuffer->NewDecoder()) {
      aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling.
      return;
    }
    MSE_DEBUG("SourceBuffer(%p)::AppendData: Decoder marked as initialized.", this);
  } else if (!mTrackBuffer->HasInitSegment()) {
    MSE_DEBUG("SourceBuffer(%p)::AppendData: Non-init segment appended during initialization.", this);
    Optional<MediaSourceEndOfStreamError> decodeError(MediaSourceEndOfStreamError::Decode);
    ErrorResult dummy;
    mMediaSource->EndOfStream(decodeError, dummy);
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }
  int64_t start, end;
  if (mParser->ParseStartAndEndTimestamps(aData, aLength, start, end)) {
    int64_t lastStart, lastEnd;
    mTrackBuffer->LastTimestamp(lastStart, lastEnd);
    if (mParser->IsMediaSegmentPresent(aData, aLength) &&
        !mParser->TimestampsFuzzyEqual(start, lastEnd)) {
      MSE_DEBUG("SourceBuffer(%p)::AppendData: Data last=[%lld, %lld] overlaps [%lld, %lld]",
                this, lastStart, lastEnd, start, end);

      // This data is earlier in the timeline than data we have already
      // processed, so we must create a new decoder to handle the decoding.
      mTrackBuffer->DiscardDecoder();

      // If we've got a decoder here, it's not initialized, so we can use it
      // rather than creating a new one.
      if (!mTrackBuffer->NewDecoder()) {
        aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling.
        return;
      }
      MSE_DEBUG("SourceBuffer(%p)::AppendData: Decoder marked as initialized.", this);
      const nsTArray<uint8_t>& initData = mParser->InitData();
      mTrackBuffer->AppendData(initData.Elements(), initData.Length());
      mTrackBuffer->SetLastStartTimestamp(start);
    }
    mTrackBuffer->SetLastEndTimestamp(end);
    MSE_DEBUG("SourceBuffer(%p)::AppendData: Segment last=[%lld, %lld] [%lld, %lld]",
              this, lastStart, lastEnd, start, end);
  }
  if (!mTrackBuffer->AppendData(aData, aLength)) {
    Optional<MediaSourceEndOfStreamError> decodeError(MediaSourceEndOfStreamError::Decode);
    ErrorResult dummy;
    mMediaSource->EndOfStream(decodeError, dummy);
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }

  // Schedule the state machine thread to ensure playback starts
  // if required when data is appended.
  mMediaSource->GetDecoder()->ScheduleStateMachineThread();

  // Run the final step of the buffer append algorithm asynchronously to
  // ensure the SourceBuffer's updating flag transition behaves as required
  // by the spec.
  nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating);
  NS_DispatchToMainThread(event);
}