void SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv) { if (!IsAttached() || mUpdating) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) { mMediaSource->SetReadyState(MediaSourceReadyState::Open); } // TODO: Run coded frame eviction algorithm. // TODO: Test buffer full flag. MSE_DEBUG("%p Append(ArrayBuffer=%u)", this, aLength); StartUpdating(); // XXX: For future reference: NDA call must run on the main thread. mDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData), aLength, mDecoder->GetResource()->GetLength()); // TODO: Run buffer append algorithm asynchronously (would call StopUpdating()). mDecoder->GetResource()->AppendData(aData, aLength); // Eviction uses a byte threshold. If the buffer is greater than the // number of bytes then data is evicted. The time range for this // eviction is reported back to the media source. It will then // evict data before that range across all SourceBuffer's it knows // about. const int evict_threshold = 1000000; bool evicted = mDecoder->GetResource()->EvictData(evict_threshold); if (evicted) { double start = 0.0; double end = 0.0; GetBufferedStartEndTime(&start, &end); // We notify that we've evicted from the time range 0 through to // the current start point. mMediaSource->NotifyEvicted(0.0, start); } StopUpdating(); // Schedule the state machine thread to ensure playback starts // if required when data is appended. mMediaSource->GetDecoder()->ScheduleStateMachineThread(); }
void SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv) { MSE_DEBUG("%p AppendBuffer(Data=%u bytes)", this, aLength); if (!IsAttached() || mUpdating) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) { mMediaSource->SetReadyState(MediaSourceReadyState::Open); } // TODO: Run coded frame eviction algorithm. // TODO: Test buffer full flag. StartUpdating(); // TODO: Run buffer append algorithm asynchronously (would call StopUpdating()). if (mParser->IsInitSegmentPresent(aData, aLength)) { MSE_DEBUG("%p AppendBuffer: New initialization segment.", this); if (mDecoderInitialized) { // Existing decoder has been used, time for a new one. DiscardDecoder(); } // If we've got a decoder here, it's not initialized, so we can use it // rather than creating a new one. if (!mDecoder && !InitNewDecoder()) { aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling. return; } MSE_DEBUG("%p AppendBuffer: Decoder marked as initialized.", this); mDecoderInitialized = true; } else if (!mDecoderInitialized) { MSE_DEBUG("%p AppendBuffer: Non-initialization segment appended during initialization."); Optional<MediaSourceEndOfStreamError> decodeError(MediaSourceEndOfStreamError::Decode); ErrorResult dummy; mMediaSource->EndOfStream(decodeError, dummy); aRv.Throw(NS_ERROR_FAILURE); return; } // XXX: For future reference: NDA call must run on the main thread. mDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData), aLength, mDecoder->GetResource()->GetLength()); mDecoder->GetResource()->AppendData(aData, aLength); // Eviction uses a byte threshold. If the buffer is greater than the // number of bytes then data is evicted. The time range for this // eviction is reported back to the media source. It will then // evict data before that range across all SourceBuffer's it knows // about. const int evict_threshold = 1000000; bool evicted = mDecoder->GetResource()->EvictData(evict_threshold); if (evicted) { double start = 0.0; double end = 0.0; GetBufferedStartEndTime(&start, &end); // We notify that we've evicted from the time range 0 through to // the current start point. mMediaSource->NotifyEvicted(0.0, start); } StopUpdating(); // Schedule the state machine thread to ensure playback starts // if required when data is appended. mMediaSource->GetDecoder()->ScheduleStateMachineThread(); }