From patchwork Mon Nov 26 18:09:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: msanders X-Patchwork-Id: 11175 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 78E0E44D3D3 for ; Mon, 26 Nov 2018 20:09:14 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id ED93E68A705; Mon, 26 Nov 2018 20:09:14 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6C05E68A6E7 for ; Mon, 26 Nov 2018 20:09:09 +0200 (EET) Date: Mon, 26 Nov 2018 18:09:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=default; t=1543255746; bh=Gpp6xAh4YkS0WaipQgDKryN0Yd1yrQ7Pq/VyldGT7JI=; h=Date:To:From:Reply-To:Subject:Feedback-ID:From; b=XTJCKCG3RETTx+qSoGOh6tF1Ogbrp9+K5Gsyq892m/PoJLgiFRvTTFBm/4Uz8CS84 Y34dud4W+BjCysvyNIBBp931M6iE9fuwWWo1MoOcW1TmVJvKj0zApewDCv7yuL2dnh iRkdLKxn3h6arXC0hm+xTA41V8KWQE89j6iHfQIo= To: "ffmpeg-devel@ffmpeg.org" From: msanders Message-ID: Feedback-ID: hxVIcPzxvPRBewlNhpteUTv_4-N7gEzUoa5RGYAcfYt7NnoUnD-6ZZ-GI3i3cXkBY60X3toqu87_pcSsszad1Q==:Ext:ProtonMail MIME-Version: 1.0 X-Spam-Status: No, score=-1.1 required=7.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,HTML_MESSAGE autolearn=ham autolearn_force=no version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.protonmail.ch X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH] libavfilter: scale_cuda filter adds dynamic command values X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Hi, This patch adds command support for dynamic change the size in the “scale_cuda” resize filter. In fact, it’s the first GPU filter accepting realtime commands. Using similar changes it’s possible to port it to other hwaccelerators. The only limitation is that the values cannot exceed the initial values. It is therefore necessary to set up the graph with the higher values you may need. One example: { -filter_complex "scale_cuda=720:576,hwdownload,format=nv12,zmq" } And then you can use the or ZMQ messages to change the width and/or height. Warning: This patch requires, to have sense, to apply too this other patch that fixes the hwdownload filter. https://patchwork.ffmpeg.org/patch/11165/ From 46c58c1da02ba40c1fab0ec93febc995db90caca Mon Sep 17 00:00:00 2001 From: M. Sanders Date: Mon, 26 Nov 2018 17:52:52 +0000 Subject: [PATCH 2/2] libavfilter: scale_cuda dynamic command values --- libavfilter/vf_scale_cuda.c | 72 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index 53b7aa9..ac8f8cc 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -78,6 +78,8 @@ typedef struct CUDAScaleContext { char *w_expr; ///< width expression string char *h_expr; ///< height expression string + int target_width; + int target_height; CUcontext cu_ctx; CUevent cu_event; @@ -314,9 +316,22 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink) outlink->w = w; outlink->h = h; - ret = init_processing_chain(ctx, inlink->w, inlink->h, w, h); - if (ret < 0) - return ret; + if (!s->frames_ctx) { + ret = init_processing_chain(ctx, inlink->w, inlink->h, w, h); + if (ret < 0) + return ret; + } else { + // We are reconfiguring, so reuse the current hw_context + av_log(s, AV_LOG_DEBUG, "Reusing the current hw_context.\n"); + if (s->planes_out && outlink->w > s->planes_out[0].width) { + outlink->w = s->planes_out[0].width; + av_log(s, AV_LOG_ERROR, "Impossible to resize above the Context width.\n"); + } + if (s->planes_out && outlink->h > s->planes_out[0].height) { + outlink->h = s->planes_out[0].height; + av_log(s, AV_LOG_ERROR, "Impossible to resize above the Context height.\n"); + } + } av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n", inlink->w, inlink->h, outlink->w, outlink->h); @@ -329,6 +344,9 @@ static av_cold int cudascale_config_props(AVFilterLink *outlink) outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; } + s->target_width = outlink->w; + s->target_height = outlink->h; + return 0; fail: @@ -375,11 +393,11 @@ static int scalecuda_resize(AVFilterContext *ctx, 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+in->linesize[0]*in->height, in->width/2, in->height/2, in->linesize[0]/2, - out->data[0]+out->linesize[0]*out->height, out->width/2, out->height/2, out->linesize[0]/2, + out->data[0]+out->linesize[0]*s->planes_out[0].height, out->width/2, out->height/2, out->linesize[0]/2, 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+ ALIGN_UP((in->linesize[0]*in->height*5)/4, s->tex_alignment), in->width/2, in->height/2, in->linesize[0]/2, - out->data[0]+(out->linesize[0]*out->height*5)/4, out->width/2, out->height/2, out->linesize[0]/2, + out->data[0]+(out->linesize[0]*s->planes_out[0].height*5)/4, out->width/2, out->height/2, out->linesize[0]/2, 1); break; case AV_PIX_FMT_YUV444P: @@ -389,11 +407,11 @@ static int scalecuda_resize(AVFilterContext *ctx, 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+in->linesize[0]*in->height, in->width, in->height, in->linesize[0], - out->data[0]+out->linesize[0]*out->height, out->width, out->height, out->linesize[0], + out->data[0]+out->linesize[0]*s->planes_out[0].height, out->width, out->height, out->linesize[0], 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+in->linesize[0]*in->height*2, in->width, in->height, in->linesize[0], - out->data[0]+out->linesize[0]*out->height*2, out->width, out->height, out->linesize[0], + out->data[0]+out->linesize[0]*s->planes_out[0].height*2, out->width, out->height, out->linesize[0], 1); break; case AV_PIX_FMT_NV12: @@ -401,9 +419,10 @@ static int scalecuda_resize(AVFilterContext *ctx, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], 1); + call_resize_kernel(s, s->cu_func_uchar2, s->cu_tex_uchar2, 2, in->data[1], in->width/2, in->height/2, in->linesize[1], - out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width/2, out->height/2, out->linesize[1]/2, + out->data[0] + out->linesize[0] * ((s->planes_out[0].height + 31) & ~0x1f), out->width/2, out->height/2, out->linesize[1]/2, 1); break; case AV_PIX_FMT_P010LE: @@ -413,7 +432,7 @@ static int scalecuda_resize(AVFilterContext *ctx, 2); call_resize_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2, in->data[1], in->width / 2, in->height / 2, in->linesize[1]/2, - out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, + out->data[0] + out->linesize[0] * ((s->planes_out[0].height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, 2); break; case AV_PIX_FMT_P016LE: @@ -423,7 +442,7 @@ static int scalecuda_resize(AVFilterContext *ctx, 2); call_resize_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2, in->data[1], in->width / 2, in->height / 2, in->linesize[1] / 2, - out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, + out->data[0] + out->linesize[0] * ((s->planes_out[0].height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, 2); break; default: @@ -439,6 +458,11 @@ static int cudascale_scale(AVFilterContext *ctx, AVFrame *out, AVFrame *in) AVFrame *src = in; int ret; + out->width = s->target_width; + out->height = s->target_height; + s->frame->width = out->width; + s->frame->height = out->height; + ret = scalecuda_resize(ctx, s->frame, src); if (ret < 0) return ret; @@ -499,6 +523,33 @@ fail: return ret; } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + CUDAScaleContext *s = ctx->priv; + int ret; + + if ( !strcmp(cmd, "width") || !strcmp(cmd, "w") + || !strcmp(cmd, "height") || !strcmp(cmd, "h")) { + + int old_w = s->target_width; + int old_h = s->target_height; + AVFilterLink *outlink = ctx->outputs[0]; + + av_opt_set(s, cmd, args, 0); + if ((ret = cudascale_config_props(outlink)) < 0) { + s->target_width = old_w; + s->target_height = old_h; + } else { + av_log(ctx, AV_LOG_VERBOSE, "Reconfiguration w:%d h:%d -> w:%d h:%d\n", + ctx->inputs[0]->w, ctx->inputs[0]->h, ctx->outputs[0]->w, ctx->outputs[0]->h); + } + } else + ret = AVERROR(ENOSYS); + + return ret; +} + #define OFFSET(x) offsetof(CUDAScaleContext, x) #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM) static const AVOption options[] = { @@ -545,6 +596,7 @@ AVFilter ff_vf_scale_cuda = { .inputs = cudascale_inputs, .outputs = cudascale_outputs, + .process_command = process_command, .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, };