mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 11:45:37 +00:00
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:
parent
8853744c3f
commit
ccedb97186
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user