1. qsvdec: set output surface info correctly. 2. qsvvpp: set output surface/frame's picture struct according to input if deinterlace option is not enabled.
This fix will make interlace transcode works: ffmpeg -init_hw_device qsv=hw:/dev/dri/renderD128 -filter_hw_device \ hw -hwaccel_output_format qsv -hwaccel qsv -v debug -c:v h264_qsv -i \ 1920x1080_interlace.mp4 -vf "vpp_qsv=w=1280:h=720" -c:v h264_qsv \ -flags +ildct+ilme -preset medium -b:v 10M -y 1280x720_interlace.mp4 Signed-off-by: Fei Wang <fei.w.w...@intel.com> --- libavcodec/qsvdec.c | 2 +- libavfilter/qsvvpp.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index fc25dc73e5..4dadc3de07 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -521,7 +521,7 @@ FF_ENABLE_DEPRECATION_WARNINGS frame->key_frame = !!(out_frame->dec_info.FrameType & MFX_FRAMETYPE_IDR); /* update the surface properties */ - if (avctx->pix_fmt == AV_PIX_FMT_QSV) + if (frame->format == AV_PIX_FMT_QSV) ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info; *got_frame = 1; diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 8d5ff2eb65..3de98ca475 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -61,6 +61,7 @@ struct QSVVPPContext { int nb_surface_ptrs_out; mfxFrameSurface1 **surface_ptrs_in; mfxFrameSurface1 **surface_ptrs_out; + int out_frame_deinterlaced; /* MFXVPP extern parameters */ mfxExtOpaqueSurfaceAlloc opaque_alloc; @@ -347,7 +348,7 @@ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *p } /* get the output surface */ -static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink) +static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink, AVFrame *picref) { AVFilterContext *ctx = outlink->src; QSVFrame *out_frame; @@ -395,6 +396,27 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink) out_frame->surface->Info = s->vpp_param.vpp.Out; + if (!s->out_frame_deinterlaced) { + /* copy picture info from input to out_frame */ + out_frame->frame->repeat_pict = picref->repeat_pict; + out_frame->frame->top_field_first = picref->top_field_first; + out_frame->frame->interlaced_frame = picref->interlaced_frame; + out_frame->frame->pict_type = picref->pict_type; + + /* surfaces in pool is inited with MFX_PICSTRUCT_PROGRESSIVE, update + * it base on input frame info. */ + out_frame->surface->Info.PicStruct = + !picref->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : + (picref->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : + MFX_PICSTRUCT_FIELD_BFF); + if (picref->repeat_pict == 1) + out_frame->surface->Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; + else if (picref->repeat_pict == 2) + out_frame->surface->Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; + else if (picref->repeat_pict == 4) + out_frame->surface->Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; + } + return out_frame; } @@ -612,6 +634,12 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p goto failed; } + /* Update output's interlace state according to params */ + for (i = 0; i < param->num_ext_buf; i++) { + if (param->ext_buf[i]->BufferId == MFX_EXTBUFF_VPP_DEINTERLACING) + s->out_frame_deinterlaced = 1; + } + if (IS_OPAQUE_MEMORY(s->in_mem_mode) || IS_OPAQUE_MEMORY(s->out_mem_mode)) { s->nb_ext_buffers = param->num_ext_buf + 1; s->ext_buffers = av_mallocz_array(s->nb_ext_buffers, sizeof(*s->ext_buffers)); @@ -701,7 +729,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr } do { - out_frame = query_frame(s, outlink); + out_frame = query_frame(s, outlink, picref); if (!out_frame) { av_log(ctx, AV_LOG_ERROR, "Failed to query an output frame.\n"); return AVERROR(ENOMEM); -- 2.17.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".