[FFmpeg-devel] [PATCH v4 15/21] lavfi/qsvvpp: set PTS for output frame
Haihao Xiang
haihao.xiang at intel.com
Thu Jul 29 08:25:03 EEST 2021
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 e16bd09585..b234417663 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -364,6 +364,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.17.1
More information about the ffmpeg-devel
mailing list