Bug 1043695 - Add a frame reorder queue. r=cpearce

This fixes the frame drops on test.mp4. For now it just
assumes a reorder depth of 3, but we need to plumb the
actual value through the demuxer.

Based on now-removed code from Edwin's FFmpegH264Decoder.
This commit is contained in:
Ralph Giles 2014-07-24 17:08:00 -07:00
Родитель 6d3a2ab236
Коммит 394b0b1cf2
3 изменённых файлов: 52 добавлений и 2 удалений

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

@ -110,6 +110,7 @@ AppleVTDecoder::Input(mp4_demuxer::MP4Sample* aSample)
nsresult
AppleVTDecoder::Flush()
{
mReorderQueue.Clear();
return Drain();
}
@ -121,7 +122,7 @@ AppleVTDecoder::Drain()
LOG("Error %d draining frames", rv);
return NS_ERROR_FAILURE;
}
return NS_OK;
return DrainReorderedFrames();
}
//
@ -189,6 +190,15 @@ PlatformCallback(void* decompressionOutputRefCon,
decoder->OutputFrame(image, frameRef);
}
nsresult
AppleVTDecoder::DrainReorderedFrames()
{
while (!mReorderQueue.IsEmpty()) {
mCallback->Output(mReorderQueue.Pop());
}
return NS_OK;
}
// Copy and return a decoded frame.
nsresult
AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
@ -270,7 +280,14 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
// Unlock the returned image data.
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
mCallback->Output(data.forget());
// Frames come out in DTS order but we need to output them
// in composition order.
mReorderQueue.Push(data.forget());
if (mReorderQueue.Length() > 2) {
VideoData* readyData = mReorderQueue.Pop();
mCallback->Output(readyData);
}
return NS_OK;
}

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

@ -11,6 +11,8 @@
#include "mozilla/RefPtr.h"
#include "mozilla/ReentrantMonitor.h"
#include "nsIThread.h"
#include "ReorderQueue.h"
#include "VideoToolbox/VideoToolbox.h"
namespace mozilla {
@ -44,11 +46,13 @@ private:
layers::ImageContainer* mImageContainer;
CMVideoFormatDescriptionRef mFormat;
VTDecompressionSessionRef mSession;
ReorderQueue mReorderQueue;
// Method to pass a frame to VideoToolbox for decoding.
nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample);
// Method to set up the decompression session.
nsresult InitializeSession();
nsresult DrainReorderedFrames();
};
} // namespace mozilla

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

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Queue for ordering decoded video frames by presentation time.
// Decoders often return frames out of order, which we need to
// buffer so we can forward them in correct presentation order.
#ifndef mozilla_ReorderQueue_h
#define mozilla_ReorderQueue_h
#include <MediaData.h>
#include <nsTPriorityQueue.h>
namespace mozilla {
struct ReorderQueueComparator
{
bool LessThan(VideoData* const& a, VideoData* const& b) const
{
return a->mTime < b->mTime;
}
};
typedef nsTPriorityQueue<VideoData*, ReorderQueueComparator> ReorderQueue;
} // namespace mozilla
#endif // mozilla_ReorderQueue_h