Bug 1299105 - Part 1: Check if the decoder support recycling to prevent from recreating decoder. r=jya

MozReview-Commit-ID: 7Xj6tSnGM81

--HG--
extra : rebase_source : 9f4f6f5161c6bee34bffa0da4aa7b77052c1239c
This commit is contained in:
James Cheng 2016-11-25 14:22:40 +08:00
parent 0a478a1d75
commit 71d701898a
6 changed files with 48 additions and 11 deletions

View File

@ -264,6 +264,10 @@ public:
{
mDecoder->SetSeekThreshold(aTime);
}
bool SupportDecoderRecycling() const override
{
return mDecoder->SupportDecoderRecycling();
}
void Shutdown() override
{
mDecoder->Shutdown();
@ -1302,29 +1306,38 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
return;
}
bool supportRecycling = decoder.mDecoder->SupportDecoderRecycling();
if (decoder.mNextStreamSourceID.isNothing() ||
decoder.mNextStreamSourceID.ref() != info->GetID()) {
LOG("%s stream id has changed from:%d to:%d, draining decoder.",
if (!supportRecycling) {
LOG("%s stream id has changed from:%d to:%d, draining decoder.",
TrackTypeToStr(aTrack), decoder.mLastStreamSourceID,
info->GetID());
decoder.mNeedDraining = true;
decoder.mNextStreamSourceID = Some(info->GetID());
ScheduleUpdate(aTrack);
return;
decoder.mNeedDraining = true;
decoder.mNextStreamSourceID = Some(info->GetID());
ScheduleUpdate(aTrack);
return;
}
}
LOG("%s stream id has changed from:%d to:%d, recreating decoder.",
LOG("%s stream id has changed from:%d to:%d.",
TrackTypeToStr(aTrack), decoder.mLastStreamSourceID,
info->GetID());
decoder.mLastStreamSourceID = info->GetID();
decoder.mNextStreamSourceID.reset();
// Reset will clear our array of queued samples. So make a copy now.
nsTArray<RefPtr<MediaRawData>> samples{decoder.mQueuedSamples};
Reset(aTrack);
decoder.ShutdownDecoder();
if (!supportRecycling) {
LOG("Decoder does not support recycling, recreate decoder.");
// Reset will clear our array of queued samples. So make a copy now.
nsTArray<RefPtr<MediaRawData>> samples{decoder.mQueuedSamples};
Reset(aTrack);
decoder.ShutdownDecoder();
if (sample->mKeyframe) {
decoder.mQueuedSamples.AppendElements(Move(samples));
}
}
decoder.mInfo = info;
if (sample->mKeyframe) {
decoder.mQueuedSamples.AppendElements(Move(samples));
ScheduleUpdate(aTrack);
} else {
TimeInterval time =

View File

@ -297,6 +297,12 @@ public:
// video decoder implements this API to improve seek performance.
// Note: it should be called before Input() or after Flush().
virtual void SetSeekThreshold(const media::TimeUnit& aTime) {}
// When playing adaptive playback, recreating an Android video decoder will
// cause the transition not smooth during resolution change.
// Reuse the decoder if the decoder support recycling.
// Currently, only Android video decoder will return true.
virtual bool SupportDecoderRecycling() const { return false; }
};
} // namespace mozilla

View File

@ -123,6 +123,8 @@ public:
return NS_OK;
}
bool SupportDecoderRecycling() const override { return true; }
protected:
layers::ImageContainer* mImageContainer;
const VideoInfo& mConfig;

View File

@ -245,6 +245,8 @@ public:
mInputDurations.Put(aSample->mDuration);
}
bool SupportDecoderRecycling() const override { return true; }
private:
class DurationQueue {
public:

View File

@ -285,6 +285,13 @@ H264Converter::CheckForSPSChange(MediaRawData* aSample)
mCurrentConfig.mExtraData)) {
return NS_OK;
}
if (mDecoder->SupportDecoderRecycling()) {
// Do not recreate the decoder, reuse it.
UpdateConfigFromExtraData(extra_data);
mNeedKeyframe = true;
return NS_OK;
}
// The SPS has changed, signal to flush the current decoder and create a
// new one.
mDecoder->Flush();

View File

@ -39,6 +39,13 @@ public:
return "H264Converter decoder (pending)";
}
void SetSeekThreshold(const media::TimeUnit& aTime) override;
bool SupportDecoderRecycling() const override
{
if (mDecoder) {
return mDecoder->SupportDecoderRecycling();
}
return false;
}
nsresult GetLastError() const { return mLastError; }