Bug 1262727: [webm] Ensure first frame returned after seek is a keyframe. r?kinetik
Same after a reset or the first frame ever returned by the demuxer.
MozReview-Commit-ID: 6b7XlIk5GE4
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -809,16 +809,17 @@ bool WebMDemuxer::GetOffsetForTime(uint6
//WebMTrackDemuxer
WebMTrackDemuxer::WebMTrackDemuxer(WebMDemuxer* aParent,
TrackInfo::TrackType aType,
uint32_t aTrackNumber)
: mParent(aParent)
, mType(aType)
+ , mNeedKeyframe(true)
{
mInfo = mParent->GetTrackInfo(aType, aTrackNumber);
MOZ_ASSERT(mInfo);
}
WebMTrackDemuxer::~WebMTrackDemuxer()
{
mSamples.Reset();
@@ -835,16 +836,17 @@ WebMTrackDemuxer::Seek(media::TimeUnit a
{
// Seeks to aTime. Upon success, SeekPromise will be resolved with the
// actual time seeked to. Typically the random access point time
media::TimeUnit seekTime = aTime;
mSamples.Reset();
mParent->SeekInternal(aTime);
mParent->GetNextPacket(mType, &mSamples);
+ mNeedKeyframe = true;
// Check what time we actually seeked to.
if (mSamples.GetSize() > 0) {
const RefPtr<MediaRawData>& sample = mSamples.First();
seekTime = media::TimeUnit::FromMicroseconds(sample->mTime);
}
SetNextKeyFrameTime();
@@ -870,16 +872,20 @@ WebMTrackDemuxer::GetSamples(int32_t aNu
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
}
while (aNumSamples) {
RefPtr<MediaRawData> sample(NextSample());
if (!sample) {
break;
}
+ if (mNeedKeyframe && !sample->mKeyframe) {
+ continue;
+ }
+ mNeedKeyframe = false;
samples->mSamples.AppendElement(sample);
aNumSamples--;
}
if (samples->mSamples.IsEmpty()) {
return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM, __func__);
} else {
UpdateSamples(samples->mSamples);
@@ -946,16 +952,17 @@ WebMTrackDemuxer::SetNextKeyFrameTime()
}
}
void
WebMTrackDemuxer::Reset()
{
mSamples.Reset();
media::TimeIntervals buffered = GetBuffered();
+ mNeedKeyframe = true;
if (buffered.Length()) {
WEBM_DEBUG("Seek to start point: %f", buffered.Start(0).ToSeconds());
mParent->SeekInternal(buffered.Start(0));
SetNextKeyFrameTime();
} else {
mNextKeyframeTime.reset();
}
}
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -237,16 +237,17 @@ private:
~WebMTrackDemuxer();
void UpdateSamples(nsTArray<RefPtr<MediaRawData>>& aSamples);
void SetNextKeyFrameTime();
RefPtr<MediaRawData> NextSample ();
RefPtr<WebMDemuxer> mParent;
TrackInfo::TrackType mType;
UniquePtr<TrackInfo> mInfo;
Maybe<media::TimeUnit> mNextKeyframeTime;
+ bool mNeedKeyframe;
// Queued samples extracted by the demuxer, but not yet returned.
MediaRawDataQueue mSamples;
};
} // namespace mozilla
#endif