mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
Use LibAV/FFmpeg logic to detect invalid pts
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:
@@ -21,6 +21,45 @@ typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
FFmpegH264Decoder<LIBAV_VER>::PtsCorrectionContext::PtsCorrectionContext()
|
||||
: mNumFaultyPts(0)
|
||||
, mNumFaultyDts(0)
|
||||
, mLastPts(INT64_MIN)
|
||||
, mLastDts(INT64_MIN)
|
||||
{
|
||||
}
|
||||
|
||||
int64_t
|
||||
FFmpegH264Decoder<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
|
||||
FFmpegH264Decoder<LIBAV_VER>::PtsCorrectionContext::Reset()
|
||||
{
|
||||
mNumFaultyPts = 0;
|
||||
mNumFaultyDts = 0;
|
||||
mLastPts = INT64_MIN;
|
||||
mLastDts = INT64_MIN;
|
||||
}
|
||||
|
||||
FFmpegH264Decoder<LIBAV_VER>::FFmpegH264Decoder(
|
||||
FlushableMediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
|
||||
const VideoInfo& aConfig,
|
||||
@@ -53,20 +92,6 @@ FFmpegH264Decoder<LIBAV_VER>::Init()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int64_t
|
||||
FFmpegH264Decoder<LIBAV_VER>::GetPts(const AVPacket& packet)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
@@ -107,7 +132,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);
|
||||
|
||||
@@ -310,6 +335,7 @@ FFmpegH264Decoder<LIBAV_VER>::Drain()
|
||||
nsresult
|
||||
FFmpegH264Decoder<LIBAV_VER>::Flush()
|
||||
{
|
||||
mPtsContext.Reset();
|
||||
nsresult rv = FFmpegDataDecoder::Flush();
|
||||
// Even if the above fails we may as well clear our frame queue.
|
||||
return rv;
|
||||
|
||||
@@ -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);
|
||||
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
nsRefPtr<ImageContainer> mImageContainer;
|
||||
@@ -67,6 +66,21 @@ private:
|
||||
uint32_t mPictureHeight;
|
||||
uint32_t mDisplayWidth;
|
||||
uint32_t mDisplayHeight;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
Reference in New Issue
Block a user