diff mbox series

[FFmpeg-devel,1/2] lavc/qsvdec: fix pts

Message ID 20210609041830.1302044-1-haihao.xiang@intel.com
State Superseded
Headers show
Series [FFmpeg-devel,1/2] lavc/qsvdec: fix pts
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Xiang, Haihao June 9, 2021, 4:18 a.m. UTC
The time base used for compressed bitstream and video frame in the SDK
is { 1, 90000 }. [1][2]

This can avoid the error message below from the muxer.

$> ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.h265 -f null -
...
[null @ 0x561c24f6f2f0] Application provided invalid, non monotonically
increasing dts to muxer in stream 0: 2 >= 2

[1]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxbitstream
[2]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxframedata
---
 libavcodec/qsvdec.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index f543defb18..622750927c 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -46,6 +46,16 @@ 
 #include "qsv.h"
 #include "qsv_internal.h"
 
+static const AVRational mfx_tb = { 1, 90000 };
+
+#define PTS_TO_MFX_PTS(pts, pts_tb) ((pts) == AV_NOPTS_VALUE ? \
+    MFX_TIMESTAMP_UNKNOWN : pts_tb.num ? \
+    av_rescale_q(pts, pts_tb, mfx_tb) : pts)
+
+#define MFX_PTS_TO_PTS(mfx_pts, pts_tb) ((mfx_pts) == MFX_TIMESTAMP_UNKNOWN ? \
+    AV_NOPTS_VALUE : pts_tb.num ? \
+    av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts)
+
 typedef struct QSVContext {
     // the session used for decoding
     mfxSession session;
@@ -308,7 +318,7 @@  static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q,
         bs.Data       = avpkt->data;
         bs.DataLength = avpkt->size;
         bs.MaxLength  = bs.DataLength;
-        bs.TimeStamp  = avpkt->pts;
+        bs.TimeStamp  = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase);
         if (avctx->field_order == AV_FIELD_PROGRESSIVE)
             bs.DataFlag   |= MFX_BITSTREAM_COMPLETE_FRAME;
     } else
@@ -456,7 +466,7 @@  static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
         bs.Data       = avpkt->data;
         bs.DataLength = avpkt->size;
         bs.MaxLength  = bs.DataLength;
-        bs.TimeStamp  = avpkt->pts;
+        bs.TimeStamp  = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase);
         if (avctx->field_order == AV_FIELD_PROGRESSIVE)
             bs.DataFlag   |= MFX_BITSTREAM_COMPLETE_FRAME;
     }
@@ -544,7 +554,7 @@  static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
         outsurf = &out_frame->surface;
 
-        frame->pts = outsurf->Data.TimeStamp;
+        frame->pts = MFX_PTS_TO_PTS(outsurf->Data.TimeStamp, avctx->pkt_timebase);
 
         frame->repeat_pict =
             outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
@@ -748,6 +758,9 @@  static av_cold int qsv_decode_init(AVCodecContext *avctx)
         goto fail;
     }
 
+    if (!avctx->pkt_timebase.num)
+        av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n");
+
     return 0;
 fail:
     qsv_decode_close(avctx);