From 9c8af590a6059c483799dc599b9f7c1af2abdbc2 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Fri, 2 Dec 2016 12:28:28 +1100 Subject: [PATCH] Bug 1320705: P7. Ensure audio decoder is recreated when chaining encountered. r=gerald The Opus decoder will error if we feed it new data if it has seen the last packet of a stream. MozReview-Commit-ID: Kw3cZuEKxie --HG-- extra : rebase_source : 8758ec63304677fe8ab2eeae7fc65f46de2db701 --- dom/media/ogg/OggDemuxer.cpp | 15 ++++++++++++++- dom/media/ogg/OggDemuxer.h | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dom/media/ogg/OggDemuxer.cpp b/dom/media/ogg/OggDemuxer.cpp index 0df351b4497e..3691297382ce 100644 --- a/dom/media/ogg/OggDemuxer.cpp +++ b/dom/media/ogg/OggDemuxer.cpp @@ -9,6 +9,7 @@ #include "AbstractMediaDecoder.h" #include "OggDemuxer.h" #include "OggCodecState.h" +#include "mozilla/Atomics.h" #include "mozilla/PodOperations.h" #include "mozilla/SharedThreadPool.h" #include "mozilla/Telemetry.h" @@ -50,6 +51,8 @@ static const uint32_t OGG_SEEK_FUZZ_USECS = 500000; // The specification recommends 80 ms. static const int64_t OGG_SEEK_OPUS_PREROLL = 80 * USECS_PER_MS; +static Atomic sStreamSourceID(0u); + class OggHeaders { public: @@ -885,6 +888,9 @@ OggDemuxer::ReadOggChain(const media::TimeUnit& aLastEndTime) Move(tags), nsAutoPtr(new MediaInfo(mInfo)))); } + // Setup a new TrackInfo so that the MediaFormatReader will flush the + // current decoder. + mSharedAudioTrackInfo = new SharedTrackInfo(mInfo.mAudio, ++sStreamSourceID); return true; } @@ -1488,6 +1494,9 @@ OggTrackDemuxer::NextSample() if (mQueuedSample) { RefPtr nextSample = mQueuedSample; mQueuedSample = nullptr; + if (mType == TrackInfo::kAudioTrack) { + nextSample->mTrackInfo = mParent->mSharedAudioTrackInfo; + } return nextSample; } ogg_packet* packet = mParent->GetNextPacket(mType); @@ -1497,10 +1506,14 @@ OggTrackDemuxer::NextSample() // Check the eos state in case we need to look for chained streams. bool eos = packet->e_o_s; OggCodecState* state = mParent->GetTrackCodecState(mType); - RefPtr data = state->PacketOutAsMediaRawData();; + RefPtr data = state->PacketOutAsMediaRawData(); + if (mType == TrackInfo::kAudioTrack) { + data->mTrackInfo = mParent->mSharedAudioTrackInfo; + } if (eos) { // We've encountered an end of bitstream packet; check for a chained // bitstream following this one. + // This will also update mSharedAudioTrackInfo. mParent->ReadOggChain(TimeUnit::FromMicroseconds(data->GetEndTime())); } return data; diff --git a/dom/media/ogg/OggDemuxer.h b/dom/media/ogg/OggDemuxer.h index d095fff5732a..f545ff8a455b 100644 --- a/dom/media/ogg/OggDemuxer.h +++ b/dom/media/ogg/OggDemuxer.h @@ -340,6 +340,13 @@ private: TimedMetadataEventProducer* mTimedMetadataEvent; MediaEventProducer* mOnSeekableEvent; + // This will be populated only if a content change occurs, otherwise it + // will be left as null so the original metadata is used. + // It is updated once a chained ogg is encountered. + // As Ogg chaining is only supported for audio, we only need an audio track + // info. + RefPtr mSharedAudioTrackInfo; + friend class OggTrackDemuxer; };