From ac8d05af898765571f7f7db4b8bfc8b73907652d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 26 Jun 2024 08:17:15 +0200 Subject: Merging upstream version 127.0.2. Signed-off-by: Daniel Baumann --- dom/media/webm/NesteggPacketHolder.h | 20 +++++++++++++++++--- dom/media/webm/WebMDemuxer.cpp | 27 +++++++++++++++++++++++++-- dom/media/webm/WebMDemuxer.h | 6 +++++- 3 files changed, 47 insertions(+), 6 deletions(-) (limited to 'dom/media/webm') diff --git a/dom/media/webm/NesteggPacketHolder.h b/dom/media/webm/NesteggPacketHolder.h index 7c74f752d3..e1e7822106 100644 --- a/dom/media/webm/NesteggPacketHolder.h +++ b/dom/media/webm/NesteggPacketHolder.h @@ -25,11 +25,12 @@ class NesteggPacketHolder { mOffset(-1), mTimestamp(-1), mDuration(-1), + mDefaultDuration(-1), mTrack(0), mIsKeyframe(false) {} - bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, - bool aIsKeyframe) { + bool Init(nestegg_packet* aPacket, nestegg* aContext, int64_t aOffset, + unsigned aTrack, bool aIsKeyframe) { uint64_t timestamp_ns; if (nestegg_packet_tstamp(aPacket, ×tamp_ns) == -1) { return false; @@ -47,6 +48,10 @@ class NesteggPacketHolder { if (!nestegg_packet_duration(aPacket, &duration_ns)) { mDuration = duration_ns / 1000; } + if (!nestegg_track_default_duration(aContext, mTrack, &duration_ns)) { + mDefaultDuration = duration_ns / 1000; + } + return true; } @@ -66,6 +71,10 @@ class NesteggPacketHolder { MOZ_ASSERT(IsInitialized()); return mDuration; } + int64_t DefaultDuration() const { + MOZ_ASSERT(IsInitialized()); + return mDefaultDuration; + } unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; @@ -78,7 +87,7 @@ class NesteggPacketHolder { private: ~NesteggPacketHolder() { nestegg_free_packet(mPacket); } - bool IsInitialized() { return mOffset >= 0; } + bool IsInitialized() const { return mOffset >= 0; } nestegg_packet* mPacket; @@ -90,8 +99,13 @@ class NesteggPacketHolder { int64_t mTimestamp; // Packet duration in microseconds; -1 if unknown or retrieval failed. + // https://www.webmproject.org/docs/container/#BlockDuration int64_t mDuration; + // Default durtaion in microseconds; -1 if unknown or retrieval failed. + // https://www.webmproject.org/docs/container/#Duration + int64_t mDefaultDuration; + // Track ID. unsigned mTrack; diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index da14118205..48d3d57ed9 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -15,6 +15,7 @@ #include "gfx2DGlue.h" #include "gfxUtils.h" #include "mozilla/EndianUtils.h" +#include "mozilla/Maybe.h" #include "mozilla/SharedThreadPool.h" #include "MediaDataDemuxer.h" #include "nsAutoRef.h" @@ -150,7 +151,9 @@ int WebMDemuxer::NestEggContext::Init() { WebMDemuxer::WebMDemuxer(MediaResource* aResource) : WebMDemuxer(aResource, false) {} -WebMDemuxer::WebMDemuxer(MediaResource* aResource, bool aIsMediaSource) +WebMDemuxer::WebMDemuxer( + MediaResource* aResource, bool aIsMediaSource, + Maybe aFrameEndTimeBeforeRecreateDemuxer) : mVideoContext(this, aResource), mAudioContext(this, aResource), mBufferedState(nullptr), @@ -169,6 +172,14 @@ WebMDemuxer::WebMDemuxer(MediaResource* aResource, bool aIsMediaSource) // Audio/video contexts hold a MediaResourceIndex. DDLINKCHILD("video context", mVideoContext.GetResource()); DDLINKCHILD("audio context", mAudioContext.GetResource()); + + MOZ_ASSERT_IF(!aIsMediaSource, + aFrameEndTimeBeforeRecreateDemuxer.isNothing()); + if (aIsMediaSource && aFrameEndTimeBeforeRecreateDemuxer) { + mVideoFrameEndTimeBeforeReset = aFrameEndTimeBeforeRecreateDemuxer; + WEBM_DEBUG("Set mVideoFrameEndTimeBeforeReset=%" PRId64, + mVideoFrameEndTimeBeforeReset->ToMicroseconds()); + } } WebMDemuxer::~WebMDemuxer() { @@ -588,6 +599,12 @@ nsresult WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, } int64_t tstamp = holder->Timestamp(); int64_t duration = holder->Duration(); + int64_t defaultDuration = holder->DefaultDuration(); + if (aType == TrackInfo::TrackType::kVideoTrack) { + WEBM_DEBUG("GetNextPacket(video): tstamp=%" PRId64 ", duration=%" PRId64 + ", defaultDuration=%" PRId64, + tstamp, duration, defaultDuration); + } // The end time of this frame is the start time of the next frame. Fetch // the timestamp of the next packet for this track. If we've reached the @@ -610,6 +627,12 @@ nsresult WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, next_tstamp = tstamp + duration; } else if (lastFrameTime.isSome()) { next_tstamp = tstamp + (tstamp - lastFrameTime.ref()); + } else if (defaultDuration >= 0) { + next_tstamp = tstamp + defaultDuration; + } else if (mVideoFrameEndTimeBeforeReset) { + WEBM_DEBUG("Setting next timestamp to be %" PRId64 " us", + mVideoFrameEndTimeBeforeReset->ToMicroseconds()); + next_tstamp = mVideoFrameEndTimeBeforeReset->ToMicroseconds(); } else if (mIsMediaSource) { (this->*pushPacket)(holder); } else { @@ -930,7 +953,7 @@ nsresult WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType, int64_t offset = Resource(aType).Tell(); RefPtr holder = new NesteggPacketHolder(); - if (!holder->Init(packet, offset, track, false)) { + if (!holder->Init(packet, Context(aType), offset, track, false)) { WEBM_DEBUG("NesteggPacketHolder::Init: error"); return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h index 3b3bdc21e2..28407908a9 100644 --- a/dom/media/webm/WebMDemuxer.h +++ b/dom/media/webm/WebMDemuxer.h @@ -94,7 +94,9 @@ class WebMDemuxer : public MediaDataDemuxer, explicit WebMDemuxer(MediaResource* aResource); // Indicate if the WebMDemuxer is to be used with MediaSource. In which // case the demuxer will stop reads to the last known complete block. - WebMDemuxer(MediaResource* aResource, bool aIsMediaSource); + WebMDemuxer( + MediaResource* aResource, bool aIsMediaSource, + Maybe aFrameEndTimeBeforeRecreateDemuxer = Nothing()); RefPtr Init() override; @@ -223,6 +225,8 @@ class WebMDemuxer : public MediaDataDemuxer, Maybe mLastAudioFrameTime; Maybe mLastVideoFrameTime; + Maybe mVideoFrameEndTimeBeforeReset; + // Codec ID of audio track int mAudioCodec; // Codec ID of video track -- cgit v1.2.3