X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_vpp_qsv.c;h=915cf748c40572aa08b9fc17632815c289125388;hb=7549f0ac1baffabfa964962c0c0067e8da692982;hp=41a9f389627d67fdf8c6a1b98268b901e4618ef1;hpb=e427ba5c68a522b26a45bf7c61016d9349fab43d;p=ffmpeg diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 41a9f389627..915cf748c40 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -57,6 +57,10 @@ typedef struct VPPContext{ int out_width; int out_height; + /** + * Output sw format. AV_PIX_FMT_NONE for no conversion. + */ + enum AVPixelFormat out_format; AVRational framerate; /* target framerate */ int use_frc; /* use framerate conversion */ @@ -79,6 +83,7 @@ typedef struct VPPContext{ char *cx, *cy, *cw, *ch; char *ow, *oh; + char *output_format_str; } VPPContext; static const AVOption options[] = { @@ -104,6 +109,8 @@ static const AVOption options[] = { { "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, { "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, + { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, + { NULL } }; @@ -207,6 +214,23 @@ release: return ret; } +static av_cold int vpp_init(AVFilterContext *ctx) +{ + VPPContext *vpp = ctx->priv; + + if (!strcmp(vpp->output_format_str, "same")) { + vpp->out_format = AV_PIX_FMT_NONE; + } else { + vpp->out_format = av_get_pix_fmt(vpp->output_format_str); + if (vpp->out_format == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, "Unrecognized output pixel format: %s\n", vpp->output_format_str); + return AVERROR(EINVAL); + } + } + + return 0; +} + static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; @@ -251,6 +275,7 @@ static int config_output(AVFilterLink *outlink) QSVVPPCrop crop = { 0 }; mfxExtBuffer *ext_buf[ENH_FILTERS_COUNT]; AVFilterLink *inlink = ctx->inputs[0]; + enum AVPixelFormat in_format; outlink->w = vpp->out_width; outlink->h = vpp->out_height; @@ -258,10 +283,19 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = av_inv_q(vpp->framerate); param.filter_frame = NULL; - param.out_sw_format = AV_PIX_FMT_NV12; param.num_ext_buf = 0; param.ext_buf = ext_buf; + 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 = (vpp->out_format == AV_PIX_FMT_NONE) ? in_format : vpp->out_format; + if (vpp->use_crop) { crop.in_idx = 0; crop.x = vpp->crop_x; @@ -367,6 +401,7 @@ static int query_formats(AVFilterContext *ctx) }; static const enum AVPixelFormat out_pix_fmts[] = { AV_PIX_FMT_NV12, + AV_PIX_FMT_P010, AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }; @@ -421,6 +456,7 @@ AVFilter ff_vf_vpp_qsv = { .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."), .priv_size = sizeof(VPPContext), .query_formats = query_formats, + .init = vpp_init, .uninit = vpp_uninit, .inputs = vpp_inputs, .outputs = vpp_outputs,