Bug 1219134: P2. Use LibAV/FFmpeg logic to detect invalid pts. r=edwin

The logic was extracted from LibAV cmdutils.c. FFmpeg provides an API for that (av_frame_get_best_effort_timestamp()) unfortunately this isn't provided by LibAV.
So copy the logic instead in order to keep compatibility with the two forks.
This commit is contained in:
Jean-Yves Avenard 2015-10-28 21:56:22 +11:00
Родитель b9466da3da
Коммит 12142482c6
4 изменённых файлов: 56 добавлений и 17 удалений

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

@ -21,6 +21,45 @@ namespace mozilla
bool FFmpegDataDecoder<LIBAV_VER>::sFFmpegInitDone = false;
StaticMutex FFmpegDataDecoder<LIBAV_VER>::sMonitor;
FFmpegDataDecoder<LIBAV_VER>::PtsCorrectionContext::PtsCorrectionContext()
: mNumFaultyPts(0)
, mNumFaultyDts(0)
, mLastPts(INT64_MIN)
, mLastDts(INT64_MIN)
{
}
int64_t
FFmpegDataDecoder<LIBAV_VER>::PtsCorrectionContext::GuessCorrectPts(int64_t aPts, int64_t aDts)
{
int64_t pts = AV_NOPTS_VALUE;
if (aDts != int64_t(AV_NOPTS_VALUE)) {
mNumFaultyDts += aDts <= mLastDts;
mLastDts = aDts;
}
if (aPts != int64_t(AV_NOPTS_VALUE)) {
mNumFaultyPts += aPts <= mLastPts;
mLastPts = aPts;
}
if ((mNumFaultyPts <= mNumFaultyDts || aDts == int64_t(AV_NOPTS_VALUE)) &&
aPts != int64_t(AV_NOPTS_VALUE)) {
pts = aPts;
} else {
pts = aDts;
}
return pts;
}
void
FFmpegDataDecoder<LIBAV_VER>::PtsCorrectionContext::Reset()
{
mNumFaultyPts = 0;
mNumFaultyDts = 0;
mLastPts = INT64_MIN;
mLastDts = INT64_MIN;
}
FFmpegDataDecoder<LIBAV_VER>::FFmpegDataDecoder(FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
AVCodecID aCodecID)
@ -184,6 +223,7 @@ FFmpegDataDecoder<LIBAV_VER>::ProcessFlush()
if (mCodecContext) {
avcodec_flush_buffers(mCodecContext);
}
mPtsContext.Reset();
MonitorAutoLock mon(mMonitor);
mIsFlushing = false;
mon.NotifyAll();

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

@ -63,6 +63,21 @@ protected:
Atomic<bool> mIsFlushing;
AVCodecParserContext* mCodecParser;
class PtsCorrectionContext {
public:
PtsCorrectionContext();
int64_t GuessCorrectPts(int64_t aPts, int64_t aDts);
void Reset();
private:
int64_t mNumFaultyPts; /// Number of incorrect PTS values so far
int64_t mNumFaultyDts; /// Number of incorrect DTS values so far
int64_t mLastPts; /// PTS of the last frame
int64_t mLastDts; /// DTS of the last frame
};
PtsCorrectionContext mPtsContext;
private:
static bool sFFmpegInitDone;
static StaticMutex sMonitor;

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

@ -54,21 +54,6 @@ FFmpegH264Decoder<LIBAV_VER>::Init()
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
}
int64_t
FFmpegH264Decoder<LIBAV_VER>::GetPts(const AVPacket& packet)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
#if LIBAVCODEC_VERSION_MAJOR == 53
if (mFrame->pkt_pts == 0) {
return mFrame->pkt_dts;
} else {
return mFrame->pkt_pts;
}
#else
return mFrame->pkt_pts;
#endif
}
FFmpegH264Decoder<LIBAV_VER>::DecodeResult
FFmpegH264Decoder<LIBAV_VER>::DoDecodeFrame(MediaRawData* aSample)
{
@ -158,7 +143,7 @@ FFmpegH264Decoder<LIBAV_VER>::DoDecodeFrame(MediaRawData* aSample,
// If we've decoded a frame then we need to output it
if (decoded) {
int64_t pts = GetPts(packet);
int64_t pts = mPtsContext.GuessCorrectPts(mFrame->pkt_pts, mFrame->pkt_dts);
FFMPEG_LOG("Got one frame output with pts=%lld opaque=%lld",
pts, mCodecContext->reordered_opaque);

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

@ -59,7 +59,6 @@ private:
static int AllocateBufferCb(AVCodecContext* aCodecContext, AVFrame* aFrame);
static void ReleaseBufferCb(AVCodecContext* aCodecContext, AVFrame* aFrame);
int64_t GetPts(const AVPacket& packet);
RefPtr<ImageContainer> mImageContainer;
uint32_t mPictureWidth;