diff --git a/dom/media/webm/NesteggPacketHolder.h b/dom/media/webm/NesteggPacketHolder.h index 00a7b12cfb..0f8f9b63ab 100644 --- a/dom/media/webm/NesteggPacketHolder.h +++ b/dom/media/webm/NesteggPacketHolder.h @@ -22,10 +22,11 @@ public: : mPacket(nullptr) , mOffset(-1) , mTimestamp(-1) + , mDefaultDuration(-1) , mDuration(-1) , 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) { @@ -44,6 +45,9 @@ public: 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; } @@ -51,6 +55,7 @@ public: int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; } int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; } int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; } + int64_t DefaultDuration() const { MOZ_ASSERT(IsInitialized()); return mDefaultDuration; } unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; } bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; } @@ -60,7 +65,7 @@ private: nestegg_free_packet(mPacket); } - bool IsInitialized() { return mOffset >= 0; } + bool IsInitialized() const { return mOffset >= 0; } nestegg_packet* mPacket; @@ -72,8 +77,13 @@ private: int64_t mTimestamp; // Packet duration in microseconds; -1 if unknown or retrieval failed. + // https://www.webmproject.org/docs/container/#BlockDuration int64_t mDuration; + // Default duration 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 df28ee84e9..fc98db4d77 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -602,9 +602,10 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl } 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, - tstamp, duration); + 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 @@ -646,6 +647,8 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl (mIsMediaSource && mLastVideoFrameTime.isSome())) { next_tstamp = tstamp; next_tstamp += tstamp - mLastVideoFrameTime.refOr(0); + } else if (defaultDuration >= 0) { + next_tstamp = tstamp + defaultDuration; } else if (mVideoFrameEndTimeBeforeReset) { WEBM_DEBUG("Setting next timestamp to be %" PRId64 " us", mVideoFrameEndTimeBeforeReset.value()); @@ -883,7 +886,7 @@ 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)) { return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } diff --git a/layout/media/symbols.def.in b/layout/media/symbols.def.in index 6ebb26c722..7f8af25886 100644 --- a/layout/media/symbols.def.in +++ b/layout/media/symbols.def.in @@ -27,6 +27,7 @@ nestegg_track_codec_data_count nestegg_track_codec_id nestegg_track_content_enc_key_id nestegg_track_count +nestegg_track_default_duration nestegg_get_cue_point nestegg_track_seek nestegg_track_type