[FFmpeg-devel] [Patch] Auto Insert of hwupload_cuda filter
Nicolas George
george at nsup.org
Wed Jul 26 13:04:33 EEST 2017
Le septidi 7 thermidor, an CCXXV, Yogender Gupta a écrit :
> Currently combining CPU and CUDA filters requires insertion of hwupload and download filters. I am trying to simply this by auto insertion of these filters. This patch is for hwupload_cuda, but I want to do this for hwdownload as well.
>
> The attached patch automatically inserts hwupload_cuda filter when it detects a GPU filter after a CPU component.
>
> Before the patch
> ffmpeg.exe -y -i traffic_flow_1280x720_420.y4m -vf "hwupload_cuda, scale_npp=176:144" out.h264
>
> After the patch the command line works without inserting the hwupload_cuda filter (auto inserted by ffmpeg)
> ffmpeg.exe -y -i traffic_flow_1280x720_420.y4m -vf "scale_npp=176:144" out.h264
>
> Thanks,
> Yogender
>
> -----------------------------------------------------------------------------------
> This email message is for the sole use of the intended recipient(s) and may contain
> confidential information. Any unauthorized review, use, disclosure or distribution
> is prohibited. If you are not the intended recipient, please contact the sender by
> reply email and destroy all copies of the original message.
> -----------------------------------------------------------------------------------
> From ee3079cd15315bae86c3f2ac3b48bf2512c01adc Mon Sep 17 00:00:00 2001
> From: Yogender Gupta <ygupta at nvidia.com>
> Date: Thu, 20 Jul 2017 17:27:36 +0530
> Subject: [PATCH] avfiltergraph : Auto insert hwupload_cuda when needed
>
> ---
> libavfilter/avfiltergraph.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index 4304c06..c1e900e 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -433,7 +433,7 @@ static int can_merge_formats(AVFilterFormats *a_arg,
> static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
> {
> int i, j, ret;
> - int scaler_count = 0, resampler_count = 0;
> + int scaler_count = 0, resampler_count = 0, hwupload_cuda_count = 0;
> int count_queried = 0; /* successful calls to query_formats() */
> int count_merged = 0; /* successful merge of formats lists */
> int count_already_merged = 0; /* lists already merged */
> @@ -460,10 +460,49 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
> for (j = 0; j < filter->nb_inputs; j++) {
> AVFilterLink *link = filter->inputs[j];
> int convert_needed = 0;
> + int cuda_upload_needed = 0;
>
> if (!link)
> continue;
>
> + if (link->type == AVMEDIA_TYPE_VIDEO) {
> + if (link->out_formats && link->out_formats->nb_formats == 1) {
> +
> + if (link->out_formats->formats[0] == AV_PIX_FMT_CUDA) {
> + cuda_upload_needed = 1;
This is too early. You are inserting this code before the format
negotiation actually takes place, and therefore bypassing it and
duplicating some of its logic, with missing features.
If that kind of code is needed (I am not sure what Philip's comment
implies exactly), it must go later in this loop:
if (convert_needed) {
...
switch (link->type) {
case AVMEDIA_TYPE_VIDEO:
/* *** */
if (!(filter = avfilter_get_by_name("scale"))) {
It must go there, where we know already that a conversion is needed and
that we are dealing with a video filter. Also, the code to create and
insert the filter is already written, and you just have to change its
name as needed:
const char *autoconv_name = "scale";
if (this is an hw format)
autoconv_name = "hwsomething";
Another possibility, that I like somewhat better, would be to implement
a filter "autoconvert" that would work like scale for normal formats and
like hwsomething for hardware formats.
(And of course, when I say "work like scale", I do not mean copy-paste
the code from scale, I mean call it.)
> +
> + for (int k = 0; k < link->in_formats->nb_formats; k++) {
> + if (link->in_formats->formats[k] == AV_PIX_FMT_CUDA)
> + cuda_upload_needed = 0;
> + }
> + }
> + }
> +
> + if (cuda_upload_needed)
> + {
> + AVFilterContext *upload;
> + AVFilter *filter;
> + char inst_name[40];
> +
> + if (!(filter = avfilter_get_by_name("hwupload_cuda"))) {
> + av_log(log_ctx, AV_LOG_ERROR, "'hwupload_cuda' filter "
> + "not present, cannot combine video formats.\n");
> + return AVERROR(EINVAL);
> + }
> +
> + snprintf(inst_name, sizeof(inst_name), "hwupload_cuda_%d",
> + hwupload_cuda_count++);
> +
> + if ((ret = avfilter_graph_create_filter(&upload, filter,
> + inst_name, NULL, NULL,
> + graph)) < 0)
> + return ret;
> +
> + if ((ret = avfilter_insert_filter(link, upload, 0, 0)) < 0)
> + return ret;
> + }
> + }
> +
> if (link->in_formats != link->out_formats
> && link->in_formats && link->out_formats)
> if (!can_merge_formats(link->in_formats, link->out_formats,
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20170726/58107940/attachment.sig>
More information about the ffmpeg-devel
mailing list