When the SDK returns MFX_ERR_MORE_SURFACE, the PTS is not set for the output frame. We assign a PTS calculated from the input frame to the output frame. After applying this patch, we may avoid the error below:
[null @ 0x56395cab4ae0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 456 >= 0 Note this patch only fixes PTS issue when deinterlacing is enabled --- libavfilter/qsvvpp.c | 21 +++++++++++++++++++-- libavfilter/qsvvpp.h | 3 +++ libavfilter/vf_vpp_qsv.c | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 82a8e29387..01d9d754d3 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -653,6 +653,7 @@ int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) int ret; QSVVPPContext *s = avctx->priv; + s->last_in_pts = AV_NOPTS_VALUE; s->filter_frame = param->filter_frame; if (!s->filter_frame) s->filter_frame = ff_filter_frame; @@ -769,6 +770,8 @@ int ff_qsvvpp_close(AVFilterContext *avctx) s->session = NULL; } + s->last_in_pts = AV_NOPTS_VALUE; + /* release all the resources */ clear_frame_list(&s->in_frame_list); clear_frame_list(&s->out_frame_list); @@ -788,6 +791,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; int ret, ret1, filter_ret; + int64_t dpts = 0; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -836,8 +840,19 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr ret = AVERROR(EAGAIN); break; } - out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp, - default_tb, outlink->time_base); + + /* TODO: calculate the PTS for other cases */ + if (s->deinterlace_enabled && + s->last_in_pts != AV_NOPTS_VALUE && + ret == MFX_ERR_MORE_SURFACE && + out_frame->surface.Data.TimeStamp == MFX_TIMESTAMP_UNKNOWN) + dpts = (in_frame->frame->pts - s->last_in_pts) / 2; + else + dpts = 0; + + out_frame->frame->pts = av_rescale_q(in_frame->frame->pts - dpts, + inlink->time_base, + outlink->time_base); out_frame->queued++; av_fifo_generic_write(s->async_fifo, &out_frame, sizeof(out_frame), NULL); @@ -870,5 +885,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr } } while(ret == MFX_ERR_MORE_SURFACE); + s->last_in_pts = in_frame->frame->pts; + return ret; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index b6fe0d3fa7..8627c8c868 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -74,8 +74,11 @@ typedef struct QSVVPPContext { int got_frame; int async_depth; int eof; + int deinterlace_enabled; /** order with frame_out, sync */ AVFifoBuffer *async_fifo; + + int64_t last_in_pts; } QSVVPPContext; typedef struct QSVVPPCrop { diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index cde1acdbb0..cdf1f61b0f 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -371,6 +371,8 @@ static int config_output(AVFilterLink *outlink) vpp->extbuf.field = value; \ } while (0) + vpp->qsv.deinterlace_enabled = !!vpp->deinterlace; + if (vpp->deinterlace) { INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? -- 2.25.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".