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
This commit is contained in:
Jean-Yves Avenard 2016-12-02 12:28:28 +11:00
Родитель e73c9ba70f
Коммит 9c8af590a6
2 изменённых файлов: 21 добавлений и 1 удалений

Просмотреть файл

@ -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<uint32_t> sStreamSourceID(0u);
class OggHeaders
{
public:
@ -885,6 +888,9 @@ OggDemuxer::ReadOggChain(const media::TimeUnit& aLastEndTime)
Move(tags),
nsAutoPtr<MediaInfo>(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<MediaRawData> 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<MediaRawData> data = state->PacketOutAsMediaRawData();;
RefPtr<MediaRawData> 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;

Просмотреть файл

@ -340,6 +340,13 @@ private:
TimedMetadataEventProducer* mTimedMetadataEvent;
MediaEventProducer<void>* 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<SharedTrackInfo> mSharedAudioTrackInfo;
friend class OggTrackDemuxer;
};