зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1767899 - Guard some members that expect to be accessed on event target in TrackBuffersManager. r=media-playback-reviewers,alwu
Differential Revision: https://phabricator.services.mozilla.com/D145529
This commit is contained in:
Родитель
e65a048ba9
Коммит
8a8161d85b
|
@ -113,7 +113,8 @@ TrackBuffersManager::TrackBuffersManager(MediaSourceDecoder* aParentDecoder,
|
||||||
"media.mediasource.eviction_threshold.audio", 20 * 1024 * 1024)),
|
"media.mediasource.eviction_threshold.audio", 20 * 1024 * 1024)),
|
||||||
mEvictionState(EvictionState::NO_EVICTION_NEEDED),
|
mEvictionState(EvictionState::NO_EVICTION_NEEDED),
|
||||||
mMutex("TrackBuffersManager"),
|
mMutex("TrackBuffersManager"),
|
||||||
mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue()) {
|
mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue()),
|
||||||
|
mTaskQueueCapability(Some(EventTargetCapability{mTaskQueue.get()})) {
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread");
|
MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread");
|
||||||
DDLINKCHILD("parser", mParser.get());
|
DDLINKCHILD("parser", mParser.get());
|
||||||
}
|
}
|
||||||
|
@ -193,7 +194,7 @@ void TrackBuffersManager::ProcessTasks() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
typedef SourceBufferTask::Type Type;
|
typedef SourceBufferTask::Type Type;
|
||||||
|
|
||||||
if (mCurrentTask) {
|
if (mCurrentTask) {
|
||||||
|
@ -449,7 +450,7 @@ void TrackBuffersManager::Detach() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBuffersManager::CompleteResetParserState() {
|
void TrackBuffersManager::CompleteResetParserState() {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
AUTO_PROFILER_LABEL("TrackBuffersManager::CompleteResetParserState",
|
AUTO_PROFILER_LABEL("TrackBuffersManager::CompleteResetParserState",
|
||||||
MEDIA_PLAYBACK);
|
MEDIA_PLAYBACK);
|
||||||
MSE_DEBUG("");
|
MSE_DEBUG("");
|
||||||
|
@ -511,7 +512,7 @@ int64_t TrackBuffersManager::EvictionThreshold() const {
|
||||||
|
|
||||||
void TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
void TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
||||||
int64_t aSizeToEvict) {
|
int64_t aSizeToEvict) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
AUTO_PROFILER_LABEL("TrackBuffersManager::DoEvictData", MEDIA_PLAYBACK);
|
AUTO_PROFILER_LABEL("TrackBuffersManager::DoEvictData", MEDIA_PLAYBACK);
|
||||||
|
|
||||||
mEvictionState = EvictionState::EVICTION_COMPLETED;
|
mEvictionState = EvictionState::EVICTION_COMPLETED;
|
||||||
|
@ -612,7 +613,7 @@ void TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
||||||
|
|
||||||
RefPtr<TrackBuffersManager::RangeRemovalPromise>
|
RefPtr<TrackBuffersManager::RangeRemovalPromise>
|
||||||
TrackBuffersManager::CodedFrameRemovalWithPromise(TimeInterval aInterval) {
|
TrackBuffersManager::CodedFrameRemovalWithPromise(TimeInterval aInterval) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
|
|
||||||
RefPtr<RangeRemovalTask> task = new RangeRemovalTask(aInterval);
|
RefPtr<RangeRemovalTask> task = new RangeRemovalTask(aInterval);
|
||||||
RefPtr<RangeRemovalPromise> p = task->mPromise.Ensure(__func__);
|
RefPtr<RangeRemovalPromise> p = task->mPromise.Ensure(__func__);
|
||||||
|
@ -955,6 +956,7 @@ void TrackBuffersManager::SegmentParserLoop() {
|
||||||
->Then(
|
->Then(
|
||||||
TaskQueueFromTaskQueue(), __func__,
|
TaskQueueFromTaskQueue(), __func__,
|
||||||
[self](bool aNeedMoreData) {
|
[self](bool aNeedMoreData) {
|
||||||
|
self->mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
self->mProcessingRequest.Complete();
|
self->mProcessingRequest.Complete();
|
||||||
if (aNeedMoreData) {
|
if (aNeedMoreData) {
|
||||||
self->NeedMoreData();
|
self->NeedMoreData();
|
||||||
|
@ -963,6 +965,7 @@ void TrackBuffersManager::SegmentParserLoop() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[self](const MediaResult& aRejectValue) {
|
[self](const MediaResult& aRejectValue) {
|
||||||
|
self->mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
self->mProcessingRequest.Complete();
|
self->mProcessingRequest.Complete();
|
||||||
self->RejectAppend(aRejectValue, __func__);
|
self->RejectAppend(aRejectValue, __func__);
|
||||||
})
|
})
|
||||||
|
@ -1025,7 +1028,7 @@ void TrackBuffersManager::ShutdownDemuxers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBuffersManager::CreateDemuxerforMIMEType() {
|
void TrackBuffersManager::CreateDemuxerforMIMEType() {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
MSE_DEBUG("mType.OriginalString=%s", mType.OriginalString().get());
|
MSE_DEBUG("mType.OriginalString=%s", mType.OriginalString().get());
|
||||||
ShutdownDemuxers();
|
ShutdownDemuxers();
|
||||||
|
|
||||||
|
@ -1233,7 +1236,7 @@ bool TrackBuffersManager::IsRepeatInitData(
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBuffersManager::OnDemuxerInitDone(const MediaResult& aResult) {
|
void TrackBuffersManager::OnDemuxerInitDone(const MediaResult& aResult) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer, "mInputDemuxer has been destroyed");
|
MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer, "mInputDemuxer has been destroyed");
|
||||||
AUTO_PROFILER_LABEL("TrackBuffersManager::OnDemuxerInitDone", MEDIA_PLAYBACK);
|
AUTO_PROFILER_LABEL("TrackBuffersManager::OnDemuxerInitDone", MEDIA_PLAYBACK);
|
||||||
|
|
||||||
|
@ -1521,6 +1524,7 @@ void TrackBuffersManager::OnDemuxerInitDone(const MediaResult& aResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackBuffersManager::OnDemuxerInitFailed(const MediaResult& aError) {
|
void TrackBuffersManager::OnDemuxerInitFailed(const MediaResult& aError) {
|
||||||
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
MSE_DEBUG("");
|
MSE_DEBUG("");
|
||||||
MOZ_ASSERT(aError != NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
|
MOZ_ASSERT(aError != NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
|
||||||
mDemuxerInitRequest.Complete();
|
mDemuxerInitRequest.Complete();
|
||||||
|
@ -1619,7 +1623,7 @@ void TrackBuffersManager::MaybeDispatchEncryptedEvent(
|
||||||
|
|
||||||
void TrackBuffersManager::OnVideoDemuxCompleted(
|
void TrackBuffersManager::OnVideoDemuxCompleted(
|
||||||
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
|
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
MSE_DEBUG("%zu video samples demuxed", aSamples->GetSamples().Length());
|
MSE_DEBUG("%zu video samples demuxed", aSamples->GetSamples().Length());
|
||||||
mVideoTracks.mDemuxRequest.Complete();
|
mVideoTracks.mDemuxRequest.Complete();
|
||||||
mVideoTracks.mQueuedSamples.AppendElements(aSamples->GetSamples());
|
mVideoTracks.mQueuedSamples.AppendElements(aSamples->GetSamples());
|
||||||
|
@ -1643,7 +1647,7 @@ void TrackBuffersManager::DoDemuxAudio() {
|
||||||
|
|
||||||
void TrackBuffersManager::OnAudioDemuxCompleted(
|
void TrackBuffersManager::OnAudioDemuxCompleted(
|
||||||
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
|
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
MSE_DEBUG("%zu audio samples demuxed", aSamples->GetSamples().Length());
|
MSE_DEBUG("%zu audio samples demuxed", aSamples->GetSamples().Length());
|
||||||
mAudioTracks.mDemuxRequest.Complete();
|
mAudioTracks.mDemuxRequest.Complete();
|
||||||
mAudioTracks.mQueuedSamples.AppendElements(aSamples->GetSamples());
|
mAudioTracks.mQueuedSamples.AppendElements(aSamples->GetSamples());
|
||||||
|
@ -2671,7 +2675,7 @@ TimeUnit TrackBuffersManager::Seek(TrackInfo::TrackType aTrack,
|
||||||
uint32_t TrackBuffersManager::SkipToNextRandomAccessPoint(
|
uint32_t TrackBuffersManager::SkipToNextRandomAccessPoint(
|
||||||
TrackInfo::TrackType aTrack, const TimeUnit& aTimeThreadshold,
|
TrackInfo::TrackType aTrack, const TimeUnit& aTimeThreadshold,
|
||||||
const media::TimeUnit& aFuzz, bool& aFound) {
|
const media::TimeUnit& aFuzz, bool& aFound) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
AUTO_PROFILER_LABEL("TrackBuffersManager::SkipToNextRandomAccessPoint",
|
AUTO_PROFILER_LABEL("TrackBuffersManager::SkipToNextRandomAccessPoint",
|
||||||
MEDIA_PLAYBACK);
|
MEDIA_PLAYBACK);
|
||||||
uint32_t parsed = 0;
|
uint32_t parsed = 0;
|
||||||
|
@ -2772,7 +2776,7 @@ const MediaRawData* TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||||
|
|
||||||
already_AddRefed<MediaRawData> TrackBuffersManager::GetSample(
|
already_AddRefed<MediaRawData> TrackBuffersManager::GetSample(
|
||||||
TrackInfo::TrackType aTrack, const TimeUnit& aFuzz, MediaResult& aResult) {
|
TrackInfo::TrackType aTrack, const TimeUnit& aFuzz, MediaResult& aResult) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
AUTO_PROFILER_LABEL("TrackBuffersManager::GetSample", MEDIA_PLAYBACK);
|
AUTO_PROFILER_LABEL("TrackBuffersManager::GetSample", MEDIA_PLAYBACK);
|
||||||
auto& trackData = GetTracksData(aTrack);
|
auto& trackData = GetTracksData(aTrack);
|
||||||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||||
|
@ -2907,7 +2911,7 @@ uint32_t TrackBuffersManager::Evictable(TrackInfo::TrackType aTrack) const {
|
||||||
|
|
||||||
TimeUnit TrackBuffersManager::GetNextRandomAccessPoint(
|
TimeUnit TrackBuffersManager::GetNextRandomAccessPoint(
|
||||||
TrackInfo::TrackType aTrack, const TimeUnit& aFuzz) {
|
TrackInfo::TrackType aTrack, const TimeUnit& aFuzz) {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
|
|
||||||
// So first determine the current position in the track buffer if necessary.
|
// So first determine the current position in the track buffer if necessary.
|
||||||
if (NS_FAILED(SetNextGetSampleIndexIfNeeded(aTrack, aFuzz))) {
|
if (NS_FAILED(SetNextGetSampleIndexIfNeeded(aTrack, aFuzz))) {
|
||||||
|
@ -2938,6 +2942,7 @@ TimeUnit TrackBuffersManager::GetNextRandomAccessPoint(
|
||||||
|
|
||||||
nsresult TrackBuffersManager::SetNextGetSampleIndexIfNeeded(
|
nsresult TrackBuffersManager::SetNextGetSampleIndexIfNeeded(
|
||||||
TrackInfo::TrackType aTrack, const TimeUnit& aFuzz) {
|
TrackInfo::TrackType aTrack, const TimeUnit& aFuzz) {
|
||||||
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
auto& trackData = GetTracksData(aTrack);
|
auto& trackData = GetTracksData(aTrack);
|
||||||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||||
|
|
||||||
|
@ -2997,6 +3002,7 @@ RefPtr<GenericPromise> TrackBuffersManager::RequestDebugInfo(
|
||||||
return RequestDebugInfo(aInfo);
|
return RequestDebugInfo(aInfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
GetDebugInfo(aInfo);
|
GetDebugInfo(aInfo);
|
||||||
return GenericPromise::CreateAndResolve(true, __func__);
|
return GenericPromise::CreateAndResolve(true, __func__);
|
||||||
}
|
}
|
||||||
|
@ -3051,7 +3057,7 @@ void TrackBuffersManager::GetDebugInfo(
|
||||||
|
|
||||||
void TrackBuffersManager::AddSizeOfResources(
|
void TrackBuffersManager::AddSizeOfResources(
|
||||||
MediaSourceDecoder::ResourceSizes* aSizes) const {
|
MediaSourceDecoder::ResourceSizes* aSizes) const {
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
|
|
||||||
if (mInputBuffer.isSome() && mInputBuffer->Buffer()) {
|
if (mInputBuffer.isSome() && mInputBuffer->Buffer()) {
|
||||||
// mInputBuffer should be the sole owner of the underlying buffer, so this
|
// mInputBuffer should be the sole owner of the underlying buffer, so this
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#define MOZILLA_TRACKBUFFERSMANAGER_H_
|
#define MOZILLA_TRACKBUFFERSMANAGER_H_
|
||||||
|
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
|
#include "mozilla/EventTargetCapability.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/NotNull.h"
|
#include "mozilla/NotNull.h"
|
||||||
|
@ -152,7 +153,8 @@ class TrackBuffersManager final
|
||||||
const media::TimeUnit& aFuzz,
|
const media::TimeUnit& aFuzz,
|
||||||
MediaResult& aResult);
|
MediaResult& aResult);
|
||||||
int32_t FindCurrentPosition(TrackInfo::TrackType aTrack,
|
int32_t FindCurrentPosition(TrackInfo::TrackType aTrack,
|
||||||
const media::TimeUnit& aFuzz) const;
|
const media::TimeUnit& aFuzz) const
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
// Will set the next GetSample index if needed. This information is determined
|
// Will set the next GetSample index if needed. This information is determined
|
||||||
// through the value of mNextSampleTimecode. Return false if the index
|
// through the value of mNextSampleTimecode. Return false if the index
|
||||||
|
@ -160,7 +162,8 @@ class TrackBuffersManager final
|
||||||
// This occurs if either the track buffer doesn't contain the required
|
// This occurs if either the track buffer doesn't contain the required
|
||||||
// timecode or is empty.
|
// timecode or is empty.
|
||||||
nsresult SetNextGetSampleIndexIfNeeded(TrackInfo::TrackType aTrack,
|
nsresult SetNextGetSampleIndexIfNeeded(TrackInfo::TrackType aTrack,
|
||||||
const media::TimeUnit& aFuzz);
|
const media::TimeUnit& aFuzz)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
media::TimeUnit GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
media::TimeUnit GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||||
const media::TimeUnit& aFuzz);
|
const media::TimeUnit& aFuzz);
|
||||||
|
@ -180,92 +183,103 @@ class TrackBuffersManager final
|
||||||
// All following functions run on the taskqueue.
|
// All following functions run on the taskqueue.
|
||||||
RefPtr<AppendPromise> DoAppendData(already_AddRefed<MediaByteBuffer> aData,
|
RefPtr<AppendPromise> DoAppendData(already_AddRefed<MediaByteBuffer> aData,
|
||||||
const SourceBufferAttributes& aAttributes);
|
const SourceBufferAttributes& aAttributes);
|
||||||
void ScheduleSegmentParserLoop();
|
void ScheduleSegmentParserLoop() REQUIRES(mTaskQueueCapability);
|
||||||
void SegmentParserLoop();
|
void SegmentParserLoop() REQUIRES(mTaskQueueCapability);
|
||||||
void InitializationSegmentReceived();
|
void InitializationSegmentReceived() REQUIRES(mTaskQueueCapability);
|
||||||
void ShutdownDemuxers();
|
void ShutdownDemuxers() REQUIRES(mTaskQueueCapability);
|
||||||
void CreateDemuxerforMIMEType();
|
void CreateDemuxerforMIMEType() REQUIRES(mTaskQueueCapability);
|
||||||
void ResetDemuxingState();
|
void ResetDemuxingState() REQUIRES(mTaskQueueCapability);
|
||||||
void NeedMoreData();
|
void NeedMoreData() REQUIRES(mTaskQueueCapability);
|
||||||
void RejectAppend(const MediaResult& aRejectValue, const char* aName);
|
void RejectAppend(const MediaResult& aRejectValue, const char* aName)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
// Will return a promise that will be resolved once all frames of the current
|
// Will return a promise that will be resolved once all frames of the current
|
||||||
// media segment have been processed.
|
// media segment have been processed.
|
||||||
RefPtr<CodedFrameProcessingPromise> CodedFrameProcessing();
|
RefPtr<CodedFrameProcessingPromise> CodedFrameProcessing()
|
||||||
void CompleteCodedFrameProcessing();
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
void CompleteCodedFrameProcessing() REQUIRES(mTaskQueueCapability);
|
||||||
// Called by ResetParserState.
|
// Called by ResetParserState.
|
||||||
void CompleteResetParserState();
|
void CompleteResetParserState() REQUIRES(mTaskQueueCapability);
|
||||||
RefPtr<RangeRemovalPromise> CodedFrameRemovalWithPromise(
|
RefPtr<RangeRemovalPromise> CodedFrameRemovalWithPromise(
|
||||||
media::TimeInterval aInterval);
|
media::TimeInterval aInterval) REQUIRES(mTaskQueueCapability);
|
||||||
bool CodedFrameRemoval(media::TimeInterval aInterval);
|
bool CodedFrameRemoval(media::TimeInterval aInterval)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
// Removes all coded frames -- this is not to spec and should be used as a
|
// Removes all coded frames -- this is not to spec and should be used as a
|
||||||
// last resort to clear buffers only if other methods cannot.
|
// last resort to clear buffers only if other methods cannot.
|
||||||
void RemoveAllCodedFrames();
|
void RemoveAllCodedFrames() REQUIRES(mTaskQueueCapability);
|
||||||
void SetAppendState(SourceBufferAttributes::AppendState aAppendState);
|
void SetAppendState(SourceBufferAttributes::AppendState aAppendState)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
bool HasVideo() const { return mVideoTracks.mNumTracks > 0; }
|
bool HasVideo() const { return mVideoTracks.mNumTracks > 0; }
|
||||||
bool HasAudio() const { return mAudioTracks.mNumTracks > 0; }
|
bool HasAudio() const { return mAudioTracks.mNumTracks > 0; }
|
||||||
|
|
||||||
// The input buffer as per
|
// The input buffer as per
|
||||||
// http://w3c.github.io/media-source/index.html#sourcebuffer-input-buffer
|
// http://w3c.github.io/media-source/index.html#sourcebuffer-input-buffer
|
||||||
Maybe<MediaSpan> mInputBuffer;
|
Maybe<MediaSpan> mInputBuffer GUARDED_BY(mTaskQueueCapability);
|
||||||
// Buffer full flag as per
|
// Buffer full flag as per
|
||||||
// https://w3c.github.io/media-source/#sourcebuffer-buffer-full-flag. Accessed
|
// https://w3c.github.io/media-source/#sourcebuffer-buffer-full-flag. Accessed
|
||||||
// on both the main thread and the task queue.
|
// on both the main thread and the task queue.
|
||||||
Atomic<bool> mBufferFull;
|
Atomic<bool> mBufferFull;
|
||||||
bool mFirstInitializationSegmentReceived;
|
bool mFirstInitializationSegmentReceived GUARDED_BY(mTaskQueueCapability);
|
||||||
bool mChangeTypeReceived;
|
bool mChangeTypeReceived GUARDED_BY(mTaskQueueCapability);
|
||||||
// Set to true once a new segment is started.
|
// Set to true once a new segment is started.
|
||||||
bool mNewMediaSegmentStarted;
|
bool mNewMediaSegmentStarted GUARDED_BY(mTaskQueueCapability);
|
||||||
bool mActiveTrack;
|
bool mActiveTrack GUARDED_BY(mTaskQueueCapability);
|
||||||
MediaContainerType mType;
|
MediaContainerType mType GUARDED_BY(mTaskQueueCapability);
|
||||||
|
|
||||||
// ContainerParser objects and methods.
|
// ContainerParser objects and methods.
|
||||||
// Those are used to parse the incoming input buffer.
|
// Those are used to parse the incoming input buffer.
|
||||||
|
|
||||||
// Recreate the ContainerParser and if aReuseInitData is true then
|
// Recreate the ContainerParser and if aReuseInitData is true then
|
||||||
// feed it with the previous init segment found.
|
// feed it with the previous init segment found.
|
||||||
void RecreateParser(bool aReuseInitData);
|
void RecreateParser(bool aReuseInitData) REQUIRES(mTaskQueueCapability);
|
||||||
UniquePtr<ContainerParser> mParser;
|
UniquePtr<ContainerParser> mParser;
|
||||||
|
|
||||||
// Demuxer objects and methods.
|
// Demuxer objects and methods.
|
||||||
void AppendDataToCurrentInputBuffer(const MediaSpan& aData);
|
void AppendDataToCurrentInputBuffer(const MediaSpan& aData)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
RefPtr<MediaByteBuffer> mInitData;
|
RefPtr<MediaByteBuffer> mInitData GUARDED_BY(mTaskQueueCapability);
|
||||||
|
|
||||||
// Checks if a new set of init data is a repeat of the last set of init data
|
// Checks if a new set of init data is a repeat of the last set of init data
|
||||||
// received. Because streams may retransmit the same init data (or
|
// received. Because streams may retransmit the same init data (or
|
||||||
// functionally equivalent init data) we do not want to perform costly
|
// functionally equivalent init data) we do not want to perform costly
|
||||||
// operations each time we receive init data, only when it's actually
|
// operations each time we receive init data, only when it's actually
|
||||||
// different data.
|
// different data.
|
||||||
bool IsRepeatInitData(const MediaInfo& aNewMediaInfo) const;
|
bool IsRepeatInitData(const MediaInfo& aNewMediaInfo) const
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
// Temporary input buffer to handle partial media segment header.
|
// Temporary input buffer to handle partial media segment header.
|
||||||
// We store the current input buffer content into it should we need to
|
// We store the current input buffer content into it should we need to
|
||||||
// reinitialize the demuxer once we have some samples and a discontinuity is
|
// reinitialize the demuxer once we have some samples and a discontinuity is
|
||||||
// detected.
|
// detected.
|
||||||
Maybe<MediaSpan> mPendingInputBuffer;
|
Maybe<MediaSpan> mPendingInputBuffer GUARDED_BY(mTaskQueueCapability);
|
||||||
RefPtr<SourceBufferResource> mCurrentInputBuffer;
|
RefPtr<SourceBufferResource> mCurrentInputBuffer
|
||||||
RefPtr<MediaDataDemuxer> mInputDemuxer;
|
GUARDED_BY(mTaskQueueCapability);
|
||||||
|
RefPtr<MediaDataDemuxer> mInputDemuxer GUARDED_BY(mTaskQueueCapability);
|
||||||
// Length already processed in current media segment.
|
// Length already processed in current media segment.
|
||||||
uint64_t mProcessedInput;
|
uint64_t mProcessedInput GUARDED_BY(mTaskQueueCapability);
|
||||||
Maybe<media::TimeUnit> mLastParsedEndTime;
|
Maybe<media::TimeUnit> mLastParsedEndTime GUARDED_BY(mTaskQueueCapability);
|
||||||
|
|
||||||
void OnDemuxerInitDone(const MediaResult& aResult);
|
void OnDemuxerInitDone(const MediaResult& aResult);
|
||||||
void OnDemuxerInitFailed(const MediaResult& aFailure);
|
void OnDemuxerInitFailed(const MediaResult& aFailure);
|
||||||
void OnDemuxerResetDone(const MediaResult& aResult);
|
void OnDemuxerResetDone(const MediaResult& aResult)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
|
MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
|
||||||
|
|
||||||
void OnDemuxFailed(TrackType aTrack, const MediaResult& aError);
|
void OnDemuxFailed(TrackType aTrack, const MediaResult& aError)
|
||||||
void DoDemuxVideo();
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
void DoDemuxVideo() REQUIRES(mTaskQueueCapability);
|
||||||
void OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
void OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||||
void OnVideoDemuxFailed(const MediaResult& aError) {
|
void OnVideoDemuxFailed(const MediaResult& aError) {
|
||||||
mVideoTracks.mDemuxRequest.Complete();
|
mVideoTracks.mDemuxRequest.Complete();
|
||||||
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
OnDemuxFailed(TrackType::kVideoTrack, aError);
|
OnDemuxFailed(TrackType::kVideoTrack, aError);
|
||||||
}
|
}
|
||||||
void DoDemuxAudio();
|
void DoDemuxAudio() REQUIRES(mTaskQueueCapability);
|
||||||
void OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
void OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||||
void OnAudioDemuxFailed(const MediaResult& aError) {
|
void OnAudioDemuxFailed(const MediaResult& aError) {
|
||||||
mAudioTracks.mDemuxRequest.Complete();
|
mAudioTracks.mDemuxRequest.Complete();
|
||||||
|
mTaskQueueCapability->AssertOnCurrentThread();
|
||||||
OnDemuxFailed(TrackType::kAudioTrack, aError);
|
OnDemuxFailed(TrackType::kAudioTrack, aError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,9 +288,11 @@ class TrackBuffersManager final
|
||||||
void MaybeDispatchEncryptedEvent(
|
void MaybeDispatchEncryptedEvent(
|
||||||
const nsTArray<RefPtr<MediaRawData>>& aSamples);
|
const nsTArray<RefPtr<MediaRawData>>& aSamples);
|
||||||
|
|
||||||
void DoEvictData(const media::TimeUnit& aPlaybackTime, int64_t aSizeToEvict);
|
void DoEvictData(const media::TimeUnit& aPlaybackTime, int64_t aSizeToEvict)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
void GetDebugInfo(dom::TrackBuffersManagerDebugInfo& aInfo) const;
|
void GetDebugInfo(dom::TrackBuffersManagerDebugInfo& aInfo) const
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
|
||||||
struct TrackData {
|
struct TrackData {
|
||||||
TrackData() : mNumTracks(0), mNeedRandomAccessPoint(true), mSizeBuffer(0) {}
|
TrackData() : mNumTracks(0), mNeedRandomAccessPoint(true), mSizeBuffer(0) {}
|
||||||
|
@ -399,16 +415,21 @@ class TrackBuffersManager final
|
||||||
void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes) const;
|
void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void CheckSequenceDiscontinuity(const media::TimeUnit& aPresentationTime);
|
void CheckSequenceDiscontinuity(const media::TimeUnit& aPresentationTime)
|
||||||
void ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData);
|
REQUIRES(mTaskQueueCapability);
|
||||||
media::TimeInterval PresentationInterval(const TrackBuffer& aSamples) const;
|
void ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
|
media::TimeInterval PresentationInterval(const TrackBuffer& aSamples) const
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
bool CheckNextInsertionIndex(TrackData& aTrackData,
|
bool CheckNextInsertionIndex(TrackData& aTrackData,
|
||||||
const media::TimeUnit& aSampleTime);
|
const media::TimeUnit& aSampleTime)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
void InsertFrames(TrackBuffer& aSamples,
|
void InsertFrames(TrackBuffer& aSamples,
|
||||||
const media::TimeIntervals& aIntervals,
|
const media::TimeIntervals& aIntervals,
|
||||||
TrackData& aTrackData);
|
TrackData& aTrackData) REQUIRES(mTaskQueueCapability);
|
||||||
void UpdateHighestTimestamp(TrackData& aTrackData,
|
void UpdateHighestTimestamp(TrackData& aTrackData,
|
||||||
const media::TimeUnit& aHighestTime);
|
const media::TimeUnit& aHighestTime)
|
||||||
|
REQUIRES(mTaskQueueCapability);
|
||||||
// Remove all frames and their dependencies contained in aIntervals.
|
// Remove all frames and their dependencies contained in aIntervals.
|
||||||
// Return the index at which frames were first removed or 0 if no frames
|
// Return the index at which frames were first removed or 0 if no frames
|
||||||
// removed.
|
// removed.
|
||||||
|
@ -486,14 +507,15 @@ class TrackBuffersManager final
|
||||||
void ProcessTasks();
|
void ProcessTasks();
|
||||||
// Set if the TrackBuffersManager is currently processing a task.
|
// Set if the TrackBuffersManager is currently processing a task.
|
||||||
// At this stage, this task is always a AppendBufferTask.
|
// At this stage, this task is always a AppendBufferTask.
|
||||||
RefPtr<SourceBufferTask> mCurrentTask;
|
RefPtr<SourceBufferTask> mCurrentTask GUARDED_BY(mTaskQueueCapability);
|
||||||
// Current SourceBuffer state for ongoing task.
|
// Current SourceBuffer state for ongoing task.
|
||||||
// Its content is returned to the SourceBuffer once the AppendBufferTask has
|
// Its content is returned to the SourceBuffer once the AppendBufferTask has
|
||||||
// completed.
|
// completed.
|
||||||
UniquePtr<SourceBufferAttributes> mSourceBufferAttributes;
|
UniquePtr<SourceBufferAttributes> mSourceBufferAttributes
|
||||||
|
GUARDED_BY(mTaskQueueCapability);
|
||||||
// The current sourcebuffer append window. It's content is equivalent to
|
// The current sourcebuffer append window. It's content is equivalent to
|
||||||
// mSourceBufferAttributes.mAppendWindowStart/End
|
// mSourceBufferAttributes.mAppendWindowStart/End
|
||||||
media::TimeInterval mAppendWindow;
|
media::TimeInterval mAppendWindow GUARDED_BY(mTaskQueueCapability);
|
||||||
|
|
||||||
// Strong references to external objects.
|
// Strong references to external objects.
|
||||||
nsMainThreadPtrHandle<MediaSourceDecoder> mParentDecoder;
|
nsMainThreadPtrHandle<MediaSourceDecoder> mParentDecoder;
|
||||||
|
@ -530,6 +552,14 @@ class TrackBuffersManager final
|
||||||
media::TimeIntervals mAudioBufferedRanges;
|
media::TimeIntervals mAudioBufferedRanges;
|
||||||
// MediaInfo of the first init segment read.
|
// MediaInfo of the first init segment read.
|
||||||
MediaInfo mInfo;
|
MediaInfo mInfo;
|
||||||
|
// End mutex protected members.
|
||||||
|
|
||||||
|
// EventTargetCapability used to ensure we're running on the task queue
|
||||||
|
// as expected for various accesses.
|
||||||
|
// TODO: we could store only this and dispatch to it, rather than also having
|
||||||
|
// mTaskQueue. However, there's special locking around mTaskQueue, so we keep
|
||||||
|
// both for now.
|
||||||
|
Maybe<EventTargetCapability<TaskQueue>> mTaskQueueCapability;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
Загрузка…
Ссылка в новой задаче