From ae3cdb4be3cfe1faccf1d8a74928391570952609 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:05:52 -0500 Subject: [webm] Store LastSeenFrame dimensions as an nsIntSize This simplifies the comparison and update logic. --- dom/media/webm/WebMDemuxer.cpp | 11 +++++------ dom/media/webm/WebMDemuxer.h | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index 20ed71581..ac371fa7f 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -651,14 +651,13 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl if (isKeyframe) { // We only look for resolution changes on keyframes for both VP8 and // VP9. Other resolution changes are invalid. - if (mLastSeenFrameWidth.isSome() && mLastSeenFrameHeight.isSome() && - (si.w != mLastSeenFrameWidth.value() || - si.h != mLastSeenFrameHeight.value())) { - mInfo.mVideo.mDisplay = nsIntSize(si.w, si.h); + auto dimensions = nsIntSize(si.w, si.h); + if (mLastSeenFrameSize.isSome() + && (dimensions != mLastSeenFrameSize.value())) { + mInfo.mVideo.mDisplay = dimensions; mSharedVideoTrackInfo = new SharedTrackInfo(mInfo.mVideo, ++sStreamSourceID); } - mLastSeenFrameWidth = Some(si.w); - mLastSeenFrameHeight = Some(si.h); + mLastSeenFrameSize = Some(dimensions); } } } diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h index 6fff38e7d..a5008022f 100644 --- a/dom/media/webm/WebMDemuxer.h +++ b/dom/media/webm/WebMDemuxer.h @@ -237,8 +237,7 @@ private: int64_t mLastWebMBlockOffset; const bool mIsMediaSource; - Maybe mLastSeenFrameWidth; - Maybe mLastSeenFrameHeight; + Maybe mLastSeenFrameSize; // This will be populated only if a resolution change occurs, otherwise it // will be left as null so the original metadata is used RefPtr mSharedVideoTrackInfo; -- cgit v1.2.3 From 5a83ed9ebacfa2bd653953b359dd5456817b03c3 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:10:31 -0500 Subject: [vpx] Store VPXDecoder codec as an enum Use the enum we already have here instead of converting to an int when we pass it around, giving us better type checking. --- dom/media/platforms/agnostic/VPXDecoder.cpp | 4 ++-- dom/media/platforms/agnostic/VPXDecoder.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dom/media/platforms/agnostic/VPXDecoder.cpp b/dom/media/platforms/agnostic/VPXDecoder.cpp index 77c81b51b..42bb86020 100644 --- a/dom/media/platforms/agnostic/VPXDecoder.cpp +++ b/dom/media/platforms/agnostic/VPXDecoder.cpp @@ -22,7 +22,7 @@ namespace mozilla { using namespace gfx; using namespace layers; -static int MimeTypeToCodec(const nsACString& aMimeType) +static VPXDecoder::Codec MimeTypeToCodec(const nsACString& aMimeType) { if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) { return VPXDecoder::Codec::VP8; @@ -31,7 +31,7 @@ static int MimeTypeToCodec(const nsACString& aMimeType) } else if (aMimeType.EqualsLiteral("video/vp9")) { return VPXDecoder::Codec::VP9; } - return -1; + return VPXDecoder::Codec::Unknown; } VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams) diff --git a/dom/media/platforms/agnostic/VPXDecoder.h b/dom/media/platforms/agnostic/VPXDecoder.h index d420ec069..4d57ebf94 100644 --- a/dom/media/platforms/agnostic/VPXDecoder.h +++ b/dom/media/platforms/agnostic/VPXDecoder.h @@ -36,7 +36,8 @@ public: enum Codec: uint8_t { VP8 = 1 << 0, - VP9 = 1 << 1 + VP9 = 1 << 1, + Unknown = 1 << 7, }; // Return true if aMimeType is a one of the strings used by our demuxers to @@ -61,7 +62,7 @@ private: const VideoInfo& mInfo; - const int mCodec; + const Codec mCodec; }; } // namespace mozilla -- cgit v1.2.3 From 2a00bf1262c48b5f90b8ff2ed81ef4b0bb97e930 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:11:58 -0500 Subject: Add Span support to MediaRawData --- dom/media/MediaData.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h index a79aac6ed..905b4c1d9 100644 --- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -14,6 +14,7 @@ #include "nsIMemoryReporter.h" #include "SharedBuffer.h" #include "mozilla/RefPtr.h" +#include "mozilla/Span.h" #include "mozilla/UniquePtr.h" #include "mozilla/UniquePtrExtensions.h" #include "nsTArray.h" @@ -631,6 +632,8 @@ public: { return sizeof(*this) + mBuffer.ComputedSizeOfExcludingThis(); } + // Access the buffer as a Span. + operator Span() { return MakeSpan(Data(), Size()); } const CryptoSample& mCrypto; RefPtr mExtraData; -- cgit v1.2.3 From 55c6aa422da84f581c3bbb0d2c0fa9b282a9d669 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:14:24 -0500 Subject: Implement keyframe and framesize VPXDecoder helpers Encapsulate code from WebMDemuxer to query keyframe and frame resolution inside VPXDecoder, so we have a clean wrapper for all the libvpx functions we use. --- dom/media/platforms/agnostic/VPXDecoder.cpp | 49 +++++++++++++++++++++++------ dom/media/platforms/agnostic/VPXDecoder.h | 7 +++++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/dom/media/platforms/agnostic/VPXDecoder.cpp b/dom/media/platforms/agnostic/VPXDecoder.cpp index 42bb86020..f2f84487f 100644 --- a/dom/media/platforms/agnostic/VPXDecoder.cpp +++ b/dom/media/platforms/agnostic/VPXDecoder.cpp @@ -101,17 +101,10 @@ MediaResult VPXDecoder::DoDecode(MediaRawData* aSample) { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); + #if defined(DEBUG) - vpx_codec_stream_info_t si; - PodZero(&si); - si.sz = sizeof(si); - if (mCodec == Codec::VP8) { - vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aSample->Data(), aSample->Size(), &si); - } else if (mCodec == Codec::VP9) { - vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aSample->Data(), aSample->Size(), &si); - } - NS_ASSERTION(bool(si.is_kf) == aSample->mKeyframe, - "VPX Decode Keyframe error sample->mKeyframe and si.si_kf out of sync"); + NS_ASSERTION(IsKeyframe(*aSample, mCodec) == aSample->mKeyframe, + "VPX Decode Keyframe error sample->mKeyframe and sample data out of sync"); #endif if (vpx_codec_err_t r = vpx_codec_decode(&mVPX, aSample->Data(), aSample->Size(), nullptr, 0)) { @@ -249,5 +242,41 @@ VPXDecoder::IsVP9(const nsACString& aMimeType) return IsVPX(aMimeType, VPXDecoder::VP9); } +/* static */ +bool +VPXDecoder::IsKeyframe(Span aBuffer, Codec aCodec) +{ + vpx_codec_stream_info_t si; + PodZero(&si); + si.sz = sizeof(si); + + if (aCodec == Codec::VP8) { + vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si); + return bool(si.is_kf); + } else if (aCodec == Codec::VP9) { + vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si); + return bool(si.is_kf); + } + + return false; +} + +/* static */ +nsIntSize +VPXDecoder::GetFrameSize(Span aBuffer, Codec aCodec) +{ + vpx_codec_stream_info_t si; + PodZero(&si); + si.sz = sizeof(si); + + if (aCodec == Codec::VP8) { + vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si); + } else if (aCodec == Codec::VP9) { + vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si); + } + + return nsIntSize(si.w, si.h); +} + } // namespace mozilla #undef LOG diff --git a/dom/media/platforms/agnostic/VPXDecoder.h b/dom/media/platforms/agnostic/VPXDecoder.h index 4d57ebf94..4e8d83617 100644 --- a/dom/media/platforms/agnostic/VPXDecoder.h +++ b/dom/media/platforms/agnostic/VPXDecoder.h @@ -7,6 +7,7 @@ #define VPXDecoder_h_ #include "PlatformDecoderModule.h" +#include "mozilla/Span.h" #include #define VPX_DONT_DEFINE_STDINT_TYPES @@ -47,6 +48,12 @@ public: static bool IsVP8(const nsACString& aMimeType); static bool IsVP9(const nsACString& aMimeType); + // Return true if a sample is a keyframe for the specified codec. + static bool IsKeyframe(Span aBuffer, Codec aCodec); + + // Return the frame dimensions for a sample for the specified codec. + static nsIntSize GetFrameSize(Span aBuffer, Codec aCodec); + private: void ProcessDecode(MediaRawData* aSample); MediaResult DoDecode(MediaRawData* aSample); -- cgit v1.2.3 From 3ec54eeacb8fcb5b844aa07c803cf52d1aedb0d4 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:16:39 -0500 Subject: Call VPXDecoder libvpx wrappers for WebM Use the new helper functions instead of calling libvpx directly. This simplifies adding other codecs in the future. --- dom/media/webm/WebMDemuxer.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index ac371fa7f..b39bec661 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -9,6 +9,7 @@ #include "AbstractMediaDecoder.h" #include "MediaResource.h" #include "OpusDecoder.h" +#include "VPXDecoder.h" #include "WebMDemuxer.h" #include "WebMBufferedParser.h" #include "gfx2DGlue.h" @@ -24,12 +25,9 @@ #include "mozilla/Sprintf.h" #include +#include #include -#define VPX_DONT_DEFINE_STDINT_TYPES -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" - #define WEBM_DEBUG(arg, ...) MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, ("WebMDemuxer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__)) extern mozilla::LazyLogModule gMediaDemuxerLog; @@ -636,22 +634,25 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl // Packet is encrypted, can't peek, use packet info isKeyframe = nestegg_packet_has_keyframe(holder->Packet()) == NESTEGG_PACKET_HAS_KEYFRAME_TRUE; } else { - vpx_codec_stream_info_t si; - PodZero(&si); - si.sz = sizeof(si); + auto sample = MakeSpan(data, length); switch (mVideoCodec) { case NESTEGG_CODEC_VP8: - vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si); + isKeyframe = VPXDecoder::IsKeyframe(sample, VPXDecoder::Codec::VP8); break; case NESTEGG_CODEC_VP9: - vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si); + isKeyframe = VPXDecoder::IsKeyframe(sample, VPXDecoder::Codec::VP9); break; + default: + NS_WARNING("Cannot detect keyframes in unknown WebM video codec"); + return NS_ERROR_FAILURE; } - isKeyframe = si.is_kf; if (isKeyframe) { - // We only look for resolution changes on keyframes for both VP8 and - // VP9. Other resolution changes are invalid. - auto dimensions = nsIntSize(si.w, si.h); + // For both VP8 and VP9, we only look for resolution changes + // on keyframes. Other resolution changes are invalid. + auto codec = mVideoCodec == NESTEGG_CODEC_VP8 + ? VPXDecoder::Codec::VP8 + : VPXDecoder::Codec::VP9; + auto dimensions = VPXDecoder::GetFrameSize(sample, codec); if (mLastSeenFrameSize.isSome() && (dimensions != mLastSeenFrameSize.value())) { mInfo.mVideo.mDisplay = dimensions; -- cgit v1.2.3 From 632b67483c9d964cd84ee90d162e88b510a70707 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:43:06 -0500 Subject: [webm] Treat demuxing errors differently than EOS Otherwise the WebM demuxer makes no difference between a genuine EOS and encountering an error. --- dom/media/webm/WebMDemuxer.cpp | 105 ++++++++++++++++++++++++++--------------- dom/media/webm/WebMDemuxer.h | 11 +++-- 2 files changed, 75 insertions(+), 41 deletions(-) diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index b39bec661..395262a2e 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -547,7 +547,7 @@ WebMDemuxer::GetTrackCrypto(TrackInfo::TrackType aType, size_t aTrackNumber) { return crypto; } -bool +nsresult WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples) { if (mIsMediaSource) { @@ -555,17 +555,18 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl EnsureUpToDateIndex(); } - RefPtr holder(NextPacket(aType)); + RefPtr holder; + nsresult rv = NextPacket(aType, holder); - if (!holder) { - return false; + if (NS_FAILED(rv)) { + return rv; } int r = 0; unsigned int count = 0; r = nestegg_packet_count(holder->Packet(), &count); if (r == -1) { - return false; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } int64_t tstamp = holder->Timestamp(); int64_t duration = holder->Duration(); @@ -576,7 +577,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl // video frame. int64_t next_tstamp = INT64_MIN; if (aType == TrackInfo::kAudioTrack) { - RefPtr next_holder(NextPacket(aType)); + RefPtr next_holder; + rv = NextPacket(aType, next_holder); + if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) { + return rv; + } if (next_holder) { next_tstamp = next_holder->Timestamp(); PushAudioPacket(next_holder); @@ -591,7 +596,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl } mLastAudioFrameTime = Some(tstamp); } else if (aType == TrackInfo::kVideoTrack) { - RefPtr next_holder(NextPacket(aType)); + RefPtr next_holder; + rv = NextPacket(aType, next_holder); + if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) { + return rv; + } if (next_holder) { next_tstamp = next_holder->Timestamp(); PushVideoPacket(next_holder); @@ -608,7 +617,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl } if (mIsMediaSource && next_tstamp == INT64_MIN) { - return false; + return NS_ERROR_DOM_MEDIA_END_OF_STREAM; } int64_t discardPadding = 0; @@ -624,7 +633,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl r = nestegg_packet_data(holder->Packet(), i, &data, &length); if (r == -1) { WEBM_DEBUG("nestegg_packet_data failed r=%d", r); - return false; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } bool isKeyframe = false; if (aType == TrackInfo::kAudioTrack) { @@ -668,7 +677,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl RefPtr sample = new MediaRawData(data, length); if (length && !sample->Data()) { // OOM. - return false; + return NS_ERROR_OUT_OF_MEMORY; } sample->mTimecode = tstamp; sample->mTime = tstamp; @@ -721,11 +730,12 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl } aSamples->Push(sample); } - return true; + return NS_OK; } -RefPtr -WebMDemuxer::NextPacket(TrackInfo::TrackType aType) +nsresult +WebMDemuxer::NextPacket(TrackInfo::TrackType aType, + RefPtr& aPacket) { bool isVideo = aType == TrackInfo::kVideoTrack; @@ -734,56 +744,64 @@ WebMDemuxer::NextPacket(TrackInfo::TrackType aType) bool hasType = isVideo ? mHasVideo : mHasAudio; if (!hasType) { - return nullptr; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } // The packet queue for the type that we are interested in. WebMPacketQueue &packets = isVideo ? mVideoPackets : mAudioPackets; if (packets.GetSize() > 0) { - return packets.PopFront(); + aPacket = packets.PopFront(); + return NS_OK; } // Track we are interested in uint32_t ourTrack = isVideo ? mVideoTrack : mAudioTrack; do { - RefPtr holder = DemuxPacket(aType); + RefPtr holder; + nsresult rv = DemuxPacket(aType, holder); + if (NS_FAILED(rv)) { + return rv; + } if (!holder) { - return nullptr; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } if (ourTrack == holder->Track()) { - return holder; + aPacket = holder; + return NS_OK; } } while (true); } -RefPtr -WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType) +nsresult +WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType, + RefPtr& aPacket) { nestegg_packet* packet; int r = nestegg_read_packet(Context(aType), &packet); if (r == 0) { nestegg_read_reset(Context(aType)); - return nullptr; + return NS_ERROR_DOM_MEDIA_END_OF_STREAM; } else if (r < 0) { - return nullptr; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } unsigned int track = 0; r = nestegg_packet_track(packet, &track); if (r == -1) { - return nullptr; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } int64_t offset = Resource(aType).Tell(); RefPtr holder = new NesteggPacketHolder(); if (!holder->Init(packet, offset, track, false)) { - return nullptr; + return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } - return holder; + aPacket = holder; + return NS_OK; } void @@ -943,7 +961,10 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime) media::TimeUnit seekTime = aTime; mSamples.Reset(); mParent->SeekInternal(mType, aTime); - mParent->GetNextPacket(mType, &mSamples); + nsresult rv = mParent->GetNextPacket(mType, &mSamples); + if (NS_FAILED(rv)) { + return SeekPromise::CreateAndReject(rv, __func__); + } mNeedKeyframe = true; // Check what time we actually seeked to. @@ -956,15 +977,18 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime) return SeekPromise::CreateAndResolve(seekTime, __func__); } -RefPtr -WebMTrackDemuxer::NextSample() +nsresult +WebMTrackDemuxer::NextSample(RefPtr& aData) { - while (mSamples.GetSize() < 1 && mParent->GetNextPacket(mType, &mSamples)) { + nsresult rv; + while (mSamples.GetSize() < 1 && + NS_SUCCEEDED((rv = mParent->GetNextPacket(mType, &mSamples)))) { } if (mSamples.GetSize()) { - return mSamples.PopFront(); + aData = mSamples.PopFront(); + return NS_OK; } - return nullptr; + return rv; } RefPtr @@ -973,9 +997,12 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples) RefPtr samples = new SamplesHolder; MOZ_ASSERT(aNumSamples); + nsresult rv = NS_ERROR_DOM_MEDIA_END_OF_STREAM; + while (aNumSamples) { - RefPtr sample(NextSample()); - if (!sample) { + RefPtr sample; + rv = NextSample(sample); + if (NS_FAILED(rv)) { break; } if (mNeedKeyframe && !sample->mKeyframe) { @@ -987,7 +1014,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples) } if (samples->mSamples.IsEmpty()) { - return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__); + return SamplesPromise::CreateAndReject(rv, __func__); } else { UpdateSamples(samples->mSamples); return SamplesPromise::CreateAndResolve(samples, __func__); @@ -1022,7 +1049,8 @@ WebMTrackDemuxer::SetNextKeyFrameTime() } // Demux and buffer frames until we find a keyframe. RefPtr sample; - while (!foundKeyframe && (sample = NextSample())) { + nsresult rv = NS_OK; + while (!foundKeyframe && NS_SUCCEEDED((rv = NextSample(sample)))) { if (sample->mKeyframe) { frameTime = sample->mTime; foundKeyframe = true; @@ -1104,10 +1132,11 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold) uint32_t parsed = 0; bool found = false; RefPtr sample; + nsresult rv = NS_OK; int64_t sampleTime; WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds()); - while (!found && (sample = NextSample())) { + while (!found && NS_SUCCEEDED((rv = NextSample(sample)))) { parsed++; sampleTime = sample->mTime; if (sample->mKeyframe && sampleTime >= aTimeThreshold.ToMicroseconds()) { @@ -1116,7 +1145,9 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold) mSamples.PushFront(sample.forget()); } } - SetNextKeyFrameTime(); + if (NS_SUCCEEDED(rv)) { + SetNextKeyFrameTime(); + } if (found) { WEBM_DEBUG("next sample: %f (parsed: %d)", media::TimeUnit::FromMicroseconds(sampleTime).ToSeconds(), diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h index a5008022f..09780e8d3 100644 --- a/dom/media/webm/WebMDemuxer.h +++ b/dom/media/webm/WebMDemuxer.h @@ -111,7 +111,8 @@ public: bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset); // Demux next WebM packet and append samples to MediaRawDataQueue - bool GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples); + nsresult GetNextPacket(TrackInfo::TrackType aType, + MediaRawDataQueue *aSamples); nsresult Reset(TrackInfo::TrackType aType); @@ -175,11 +176,13 @@ private: // Read a packet from the nestegg file. Returns nullptr if all packets for // the particular track have been read. Pass TrackInfo::kVideoTrack or // TrackInfo::kVideoTrack to indicate the type of the packet we want to read. - RefPtr NextPacket(TrackInfo::TrackType aType); + nsresult NextPacket(TrackInfo::TrackType aType, + RefPtr& aPacket); // Internal method that demuxes the next packet from the stream. The caller // is responsible for making sure it doesn't get lost. - RefPtr DemuxPacket(TrackInfo::TrackType aType); + nsresult DemuxPacket(TrackInfo::TrackType aType, + RefPtr& aPacket); // libnestegg audio and video context for webm container. // Access on reader's thread only. @@ -275,7 +278,7 @@ private: ~WebMTrackDemuxer(); void UpdateSamples(nsTArray>& aSamples); void SetNextKeyFrameTime(); - RefPtr NextSample (); + nsresult NextSample(RefPtr& aData); RefPtr mParent; TrackInfo::TrackType mType; UniquePtr mInfo; -- cgit v1.2.3 From 81c39ba87667566a83febdc8c22e300ea8313897 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 8 Oct 2018 21:44:23 -0500 Subject: [webm] Don't reject seeks with EOS The MediaDecoderStateMachine treat seek's EOS as fatal errors, so instead we always resolve the seek promise, and let the next GetSample return EOS. --- dom/media/webm/WebMDemuxer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index 395262a2e..b54739c06 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -963,6 +963,10 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime) mParent->SeekInternal(mType, aTime); nsresult rv = mParent->GetNextPacket(mType, &mSamples); if (NS_FAILED(rv)) { + if (rv == NS_ERROR_DOM_MEDIA_END_OF_STREAM) { + // Ignore the error for now, the next GetSample will be rejected with EOS. + return SeekPromise::CreateAndResolve(media::TimeUnit(), __func__); + } return SeekPromise::CreateAndReject(rv, __func__); } mNeedKeyframe = true; -- cgit v1.2.3