Bug 1043710 - Reorder frames by comparing pts to dts. r=ajones

Pull frames out of the reorder queue in presentation
timestamp order when those timestamps are prior to
the latest decode timestamp.

The idea here is that when we see a frame with a decode
timestamp after the presentation timestamp of a frame
in the reorder buffer, that buffered frame can't be a
dependency of any more frames, and so decode timestamp
sample ordering ensures we've buffered all the frames
which need reordering up to that point.
This commit is contained in:
Ralph Giles 2014-08-27 15:17:00 -07:00
parent 8853744c3f
commit ccedb97186

View File

@ -145,7 +145,8 @@ AppleVTDecoder::Drain()
// Context object to hold a copy of sample metadata.
class FrameRef {
public:
Microseconds timestamp;
Microseconds decode_timestamp;
Microseconds composition_timestamp;
Microseconds duration;
int64_t byte_offset;
bool is_sync_point;
@ -153,7 +154,8 @@ public:
explicit FrameRef(mp4_demuxer::MP4Sample* aSample)
{
MOZ_ASSERT(aSample);
timestamp = aSample->composition_timestamp;
decode_timestamp = aSample->decode_timestamp;
composition_timestamp = aSample->composition_timestamp;
duration = aSample->duration;
byte_offset = aSample->byte_offset;
is_sync_point = aSample->is_sync_point;
@ -180,9 +182,10 @@ PlatformCallback(void* decompressionOutputRefCon,
nsAutoPtr<FrameRef> frameRef =
nsAutoPtr<FrameRef>(static_cast<FrameRef*>(sourceFrameRefCon));
LOG("mp4 output frame %lld pts %lld duration %lld us%s",
LOG("mp4 output frame %lld dts %lld pts %lld duration %lld us%s",
frameRef->byte_offset,
frameRef->timestamp,
frameRef->decode_timestamp,
frameRef->composition_timestamp,
frameRef->duration,
frameRef->is_sync_point ? " keyframe" : ""
);
@ -302,11 +305,11 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
mImageContainer,
nullptr,
aFrameRef->byte_offset,
aFrameRef->timestamp,
aFrameRef->composition_timestamp,
aFrameRef->duration,
buffer,
aFrameRef->is_sync_point,
aFrameRef->timestamp,
aFrameRef->decode_timestamp,
visible);
// Unlock the returned image data.
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
@ -320,10 +323,21 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
// Frames come out in DTS order but we need to output them
// in composition order.
mReorderQueue.Push(data.forget());
if (mReorderQueue.Length() > 2) {
// Assume a frame with a PTS <= current DTS is ready.
while (mReorderQueue.Length() > 0) {
VideoData* readyData = mReorderQueue.Pop();
mCallback->Output(readyData);
if (readyData->mTime <= aFrameRef->decode_timestamp) {
LOG("returning queued frame with pts %lld", readyData->mTime);
mCallback->Output(readyData);
} else {
LOG("requeued frame with pts %lld > %lld",
readyData->mTime, aFrameRef->decode_timestamp);
mReorderQueue.Push(readyData);
break;
}
}
LOG("%llu decoded frames queued",
static_cast<unsigned long long>(mReorderQueue.Length()));
return NS_OK;
}