зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
6d3a2ab236
Коммит
394b0b1cf2
|
@ -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
|
Загрузка…
Ссылка в новой задаче