зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1274626 part 3 - make the blank video decoder return samples in PTS order; r=jya
MozReview-Commit-ID: EULu34WIcw0 --HG-- rename : dom/media/platforms/apple/ReorderQueue.h => dom/media/platforms/ReorderQueue.h extra : transplant_source : %05%DF%05%26%B4B%CF%CEv_%A7%3C9%EDo%1B%C6%B0%1Eh
This commit is contained in:
Родитель
99c0ebc056
Коммит
3ea8ae9a44
|
@ -11,9 +11,12 @@
|
|||
#include "mozilla/mozalloc.h" // for operator new, and new (fallible)
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
#include "mp4_demuxer/H264.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsRect.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "ReorderQueue.h"
|
||||
#include "TimeUnits.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
|
@ -29,6 +32,10 @@ public:
|
|||
const CreateDecoderParams& aParams)
|
||||
: mCreator(aCreator)
|
||||
, mCallback(aParams.mCallback)
|
||||
, mMaxRefFrames(aParams.mConfig.GetType() == TrackInfo::kVideoTrack &&
|
||||
MP4Decoder::IsH264(aParams.mConfig.mMimeType)
|
||||
? mp4_demuxer::H264::ComputeMaxRefFrames(aParams.VideoConfig().mExtraData)
|
||||
: 0)
|
||||
, mType(aParams.mConfig.GetType())
|
||||
{
|
||||
}
|
||||
|
@ -47,19 +54,25 @@ public:
|
|||
mCreator->Create(media::TimeUnit::FromMicroseconds(aSample->mTime),
|
||||
media::TimeUnit::FromMicroseconds(aSample->mDuration),
|
||||
aSample->mOffset);
|
||||
if (!data) {
|
||||
mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
|
||||
} else {
|
||||
mCallback->Output(data);
|
||||
|
||||
OutputFrame(data);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Flush() override
|
||||
{
|
||||
mReorderQueue.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Drain() override
|
||||
{
|
||||
while (!mReorderQueue.IsEmpty()) {
|
||||
mCallback->Output(mReorderQueue.Pop().get());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Flush() override {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Drain() override {
|
||||
mCallback->DrainComplete();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -69,9 +82,32 @@ public:
|
|||
return "blank media data decoder";
|
||||
}
|
||||
|
||||
private:
|
||||
void OutputFrame(MediaData* aData)
|
||||
{
|
||||
if (!aData) {
|
||||
mCallback->Error(MediaDataDecoderError::FATAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Frames come out in DTS order but we need to output them in PTS order.
|
||||
mReorderQueue.Push(aData);
|
||||
|
||||
while (mReorderQueue.Length() > mMaxRefFrames) {
|
||||
mCallback->Output(mReorderQueue.Pop().get());
|
||||
}
|
||||
|
||||
if (mReorderQueue.Length() <= mMaxRefFrames) {
|
||||
mCallback->InputExhausted();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoPtr<BlankMediaDataCreator> mCreator;
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
const uint32_t mMaxRefFrames;
|
||||
ReorderQueue mReorderQueue;
|
||||
TrackInfo::TrackType mType;
|
||||
};
|
||||
|
||||
|
@ -233,7 +269,11 @@ public:
|
|||
ConversionRequired
|
||||
DecoderNeedsConversion(const TrackInfo& aConfig) const override
|
||||
{
|
||||
return kNeedNone;
|
||||
if (aConfig.IsVideo() && MP4Decoder::IsH264(aConfig.mMimeType)) {
|
||||
return kNeedAVCC;
|
||||
} else {
|
||||
return kNeedNone;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
#include "AppleUtils.h"
|
||||
#include "AppleVTDecoder.h"
|
||||
#include "AppleVTLinker.h"
|
||||
#include "mp4_demuxer/H264.h"
|
||||
#include "MediaData.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mp4_demuxer/H264.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Logging.h"
|
||||
|
@ -24,22 +24,6 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
static uint32_t ComputeMaxRefFrames(const MediaByteBuffer* aExtraData)
|
||||
{
|
||||
uint32_t maxRefFrames = 4;
|
||||
// Retrieve video dimensions from H264 SPS NAL.
|
||||
mp4_demuxer::SPSData spsdata;
|
||||
if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtraData, spsdata)) {
|
||||
// max_num_ref_frames determines the size of the sliding window
|
||||
// we need to queue that many frames in order to guarantee proper
|
||||
// pts frames ordering. Use a minimum of 4 to ensure proper playback of
|
||||
// non compliant videos.
|
||||
maxRefFrames =
|
||||
std::min(std::max(maxRefFrames, spsdata.max_num_ref_frames + 1), 16u);
|
||||
}
|
||||
return maxRefFrames;
|
||||
}
|
||||
|
||||
AppleVTDecoder::AppleVTDecoder(const VideoInfo& aConfig,
|
||||
TaskQueue* aTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback,
|
||||
|
@ -52,7 +36,7 @@ AppleVTDecoder::AppleVTDecoder(const VideoInfo& aConfig,
|
|||
, mDisplayHeight(aConfig.mDisplay.height)
|
||||
, mQueuedSamples(0)
|
||||
, mTaskQueue(aTaskQueue)
|
||||
, mMaxRefFrames(ComputeMaxRefFrames(aConfig.mExtraData))
|
||||
, mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData))
|
||||
, mImageContainer(aImageContainer)
|
||||
, mInputIncoming(0)
|
||||
, mIsShutDown(false)
|
||||
|
|
|
@ -531,4 +531,21 @@ H264::EnsureSPSIsSane(SPSData& aSPS)
|
|||
return valid;
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
H264::ComputeMaxRefFrames(const mozilla::MediaByteBuffer* aExtraData)
|
||||
{
|
||||
uint32_t maxRefFrames = 4;
|
||||
// Retrieve video dimensions from H264 SPS NAL.
|
||||
SPSData spsdata;
|
||||
if (DecodeSPSFromExtraData(aExtraData, spsdata)) {
|
||||
// max_num_ref_frames determines the size of the sliding window
|
||||
// we need to queue that many frames in order to guarantee proper
|
||||
// pts frames ordering. Use a minimum of 4 to ensure proper playback of
|
||||
// non compliant videos.
|
||||
maxRefFrames =
|
||||
std::min(std::max(maxRefFrames, spsdata.max_num_ref_frames + 1), 16u);
|
||||
}
|
||||
return maxRefFrames;
|
||||
}
|
||||
|
||||
} // namespace mp4_demuxer
|
||||
|
|
|
@ -332,17 +332,24 @@ class H264
|
|||
{
|
||||
public:
|
||||
static bool DecodeSPSFromExtraData(const mozilla::MediaByteBuffer* aExtraData, SPSData& aDest);
|
||||
|
||||
/* Extract RAW BYTE SEQUENCE PAYLOAD from NAL content.
|
||||
Returns nullptr if invalid content.
|
||||
This is compliant to ITU H.264 7.3.1 Syntax in tabular form NAL unit syntax
|
||||
*/
|
||||
static already_AddRefed<mozilla::MediaByteBuffer> DecodeNALUnit(const mozilla::MediaByteBuffer* aNAL);
|
||||
|
||||
/* Decode SPS NAL RBSP and fill SPSData structure */
|
||||
static bool DecodeSPS(const mozilla::MediaByteBuffer* aSPS, SPSData& aDest);
|
||||
|
||||
// Ensure that SPS data makes sense, Return true if SPS data was, and false
|
||||
// otherwise. If false, then content will be adjusted accordingly.
|
||||
static bool EnsureSPSIsSane(SPSData& aSPS);
|
||||
|
||||
// If the given aExtraData is valid, return the aExtraData.max_num_ref_frames
|
||||
// clamped to be in the range of [4, 16]; otherwise return 4.
|
||||
static uint32_t ComputeMaxRefFrames(const mozilla::MediaByteBuffer* aExtraData);
|
||||
|
||||
private:
|
||||
static void vui_parameters(BitReader& aBr, SPSData& aDest);
|
||||
// Read HRD parameters, all data is ignored.
|
||||
|
|
Загрузка…
Ссылка в новой задаче