All features are implemented in vpp_qsv filter now, so deinterlace_qsv can be taken as a specical case of vpp_qsv filter, we re-use VPPContext with a different option array and pix formats for deinterlace_qsv filter
A new option -rate is used to control the output frame rate, by default it will output frame for each field --- libavfilter/Makefile | 2 +- libavfilter/vf_deinterlace_qsv.c | 179 ------------------------------- libavfilter/vf_vpp_qsv.c | 35 +++++- 3 files changed, 35 insertions(+), 181 deletions(-) delete mode 100644 libavfilter/vf_deinterlace_qsv.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 760099ba2c..dafd0c610c 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -230,7 +230,7 @@ OBJS-$(CONFIG_DECONVOLVE_FILTER) += vf_convolve.o framesync.o OBJS-$(CONFIG_DEDOT_FILTER) += vf_dedot.o OBJS-$(CONFIG_DEFLATE_FILTER) += vf_neighbor.o OBJS-$(CONFIG_DEFLICKER_FILTER) += vf_deflicker.o -OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER) += vf_deinterlace_qsv.o +OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER) += vf_vpp_qsv.o OBJS-$(CONFIG_DEINTERLACE_VAAPI_FILTER) += vf_deinterlace_vaapi.o vaapi_vpp.o OBJS-$(CONFIG_DEJUDDER_FILTER) += vf_dejudder.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c deleted file mode 100644 index 50ff553e6a..0000000000 --- a/libavfilter/vf_deinterlace_qsv.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * deinterlace video filter - QSV - */ - -#include <mfx/mfxvideo.h> - -#include <stdio.h> -#include <string.h> - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_qsv.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/time.h" -#include "libavfilter/qsvvpp.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct QSVDeintContext { - QSVVPPContext qsv; - - mfxExtVPPDeinterlacing deint_conf; - - /* option for Deinterlacing algorithm to be used */ - int mode; -} QSVDeintContext; - -static av_cold void qsvdeint_uninit(AVFilterContext *ctx) -{ - ff_qsvvpp_close(ctx); -} - -static int qsvdeint_query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pixel_formats[] = { - AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, - }; - AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); - int ret; - - if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) - return ret; - - return 0; -} - -static int qsvdeint_config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - QSVDeintContext *s = ctx->priv; - QSVVPPParam param = { NULL }; - mfxExtBuffer *ext_buf[1]; - enum AVPixelFormat in_format; - - qsvdeint_uninit(ctx); - - outlink->w = inlink->w; - outlink->h = inlink->h; - outlink->frame_rate = av_mul_q(inlink->frame_rate, - (AVRational){ 2, 1 }); - outlink->time_base = av_mul_q(inlink->time_base, - (AVRational){ 1, 2 }); - - if (inlink->format == AV_PIX_FMT_QSV) { - if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data) - return AVERROR(EINVAL); - else - in_format = ((AVHWFramesContext*)inlink->hw_frames_ctx->data)->sw_format; - } else - in_format = inlink->format; - - param.out_sw_format = in_format; - param.ext_buf = ext_buf; - - memset(&s->deint_conf, 0, sizeof(mfxExtVPPDeinterlacing)); - s->deint_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING; - s->deint_conf.Header.BufferSz = sizeof(s->deint_conf); - s->deint_conf.Mode = s->mode; - param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&s->deint_conf; - - return ff_qsvvpp_init(ctx, ¶m); -} - -static int qsvdeint_filter_frame(AVFilterLink *link, AVFrame *in) -{ - AVFilterContext *ctx = link->dst; - QSVVPPContext *qsv = ctx->priv; - int ret = 0; - - ret = ff_qsvvpp_filter_frame(qsv, link, in); - av_frame_free(&in); - - return ret; -} - -static int qsvdeint_request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - - return ff_request_frame(ctx->inputs[0]); -} - -#define OFFSET(x) offsetof(QSVDeintContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -static const AVOption options[] = { - { "mode", "set deinterlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, - { "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, - { "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, - { NULL }, -}; - -static const AVClass qsvdeint_class = { - .class_name = "deinterlace_qsv", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -static const AVFilterPad qsvdeint_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = qsvdeint_filter_frame, - }, - { NULL } -}; - -static const AVFilterPad qsvdeint_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = qsvdeint_config_props, - .request_frame = qsvdeint_request_frame, - }, - { NULL } -}; - -const AVFilter ff_vf_deinterlace_qsv = { - .name = "deinterlace_qsv", - .description = NULL_IF_CONFIG_SMALL("QuickSync video deinterlacing"), - - .uninit = qsvdeint_uninit, - .query_formats = qsvdeint_query_formats, - - .priv_size = sizeof(QSVDeintContext), - .priv_class = &qsvdeint_class, - - .inputs = qsvdeint_inputs, - .outputs = qsvdeint_outputs, - - .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, -}; diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index f7854f81bf..518595d91e 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -102,6 +102,8 @@ typedef struct VPPContext{ char *cx, *cy, *cw, *ch; char *ow, *oh; char *output_format_str; + + int field_rate; /* deinterlace mode */ } VPPContext; static const char *const var_names[] = { @@ -226,6 +228,7 @@ static av_cold int vpp_preinit(AVFilterContext *ctx) vpp->saturation = 1.0; vpp->contrast = 1.0; vpp->transpose = -1; + vpp->field_rate = 1; return 0; } @@ -257,7 +260,10 @@ static int config_input(AVFilterLink *inlink) if (vpp->framerate.den == 0 || vpp->framerate.num == 0) vpp->framerate = inlink->frame_rate; - if (av_cmp_q(vpp->framerate, inlink->frame_rate)) + if (vpp->field_rate == 2) + vpp->framerate = av_mul_q(inlink->frame_rate, + (AVRational){ 2, 1 }); + else if (av_cmp_q(vpp->framerate, inlink->frame_rate)) vpp->use_frc = 1; ret = eval_expr(ctx); @@ -711,3 +717,30 @@ static const AVOption qsvscale_options[] = { }; DEFINE_QSV_FILTER(qsvscale, scale, "scaling and format conversion") + +static const AVOption qsvdeint_options[] = { + { "mode", "set deinterlace mode", OFFSET(deinterlace), AV_OPT_TYPE_INT, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, + { "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, + { "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, + + { "rate", "Generate output at frame rate or field rate", + OFFSET(field_rate), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 2, FLAGS, "rate" }, + { "frame", "Output at frame rate (one frame of output for each field-pair)", + 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "rate" }, + { "field", "Output at field rate (one frame of output for each field)", + 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "rate" }, + + { NULL }, +}; + +static int qsvdeint_query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pixel_formats[] = { + AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, + }; + AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); + + return ff_set_common_formats(ctx, pix_fmts); +} + +DEFINE_QSV_FILTER(qsvdeint, deinterlace, "deinterlacing") \ No newline at end of file -- 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".