[FFmpeg-cvslog] lavc/qsvdec: fix pts

Haihao Xiang git at videolan.org
Sun Jun 20 18:05:29 EEST 2021


ffmpeg | branch: master | Haihao Xiang <haihao.xiang at intel.com> | Fri Jun 11 10:19:45 2021 +0800| [971b4ac733630e8d913e17151ce8e01d3c75d1a1] | committer: Zhong Li

lavc/qsvdec: fix pts

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

Signed-off-by: Zhong Li <zhongli_dev at 126.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=971b4ac733630e8d913e17151ce8e01d3c75d1a1
---

 libavcodec/qsvdec.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

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);



More information about the ffmpeg-cvslog mailing list