From patchwork Sat Mar 23 16:18:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 12403 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 339F6449213 for ; Sat, 23 Mar 2019 18:19:01 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1E91068A9A1; Sat, 23 Mar 2019 18:19:01 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8C0D368829F for ; Sat, 23 Mar 2019 18:18:54 +0200 (EET) Received: by mail-wr1-f41.google.com with SMTP id t5so5509668wri.7 for ; Sat, 23 Mar 2019 09:18:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=8sZF7HK04cv0ygwItMjlffVve+BB2RVjHU+y7F+cPC4=; b=RzI5PELwBL0bem6oFRLSpCe1NQ1Hka3Sg8mNlaVgEYzFzaaipMsVztcnqgMPbYK+BZ wxqkZ31Ct0cd6CcKlLa9AmRaHI+h2am3leDm9rVFKftZoyeHsaRdARvQJJBWPrInQenF AFx/w21XuwvNcp0fCRo88CFZONpKhrHJkW5fLZxVn8Hm/fqd9l8Kt0J6mv7Ug1TCSsRc JcLKWiXnpqP2lE5l7oi1JX7B6wHDK8avoEBcf4sGh1ADwR6YWq9WVtxTI/AU9PUIm2/f P9eRAXuNb1SOa8vPvvAR9+girBFvz6ck+0phUtXYulKcymVaCpRwUZNkcghdmF303L3D FLBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=8sZF7HK04cv0ygwItMjlffVve+BB2RVjHU+y7F+cPC4=; b=piDu7Rrvy/abrcdiT0rr3wXXUjGHat8axQMQGgUcgWn6PLnKaidhG3DEiG/mJfm5gr LFvuz5Sq3xWY57PVrYzI1mqtTbHwKvBKCir09DhaphydX2oXRzt7fFpARK3BGAQX15TK WjyL9YZ9p/NcR/RabdlKge2WALy+1NdQWoKc9q3oXEPhZHlq9D4RVW6W3oHVSTuAsZEQ KAlYnrxUQfFlY3KOhY6nDc9heWwjg4xL/2iJReW9y887X6VzZ46k3q+oO/wlHufxssg5 yDsN0AejLzQmzZsAFb8xgxk46/oD0x4kuu/plydIYJzbdis7Q6aW1v3EGCRqB94AMWfJ Vh4A== X-Gm-Message-State: APjAAAV93vKuVQdD2VSWoTwvcvQIRVhseQHwBJOMDiluQkxrfz5MrMeT 9/S6GjwzXCgLEcMwrqZRbD0rOYErrEw= X-Google-Smtp-Source: APXvYqzJo9BWQEmbtIIEOmLGFtWM5l+x5Ne/fe6UVIoEaxd+oJYPruKgDMivoQBeZy2fbWjaslqTFw== X-Received: by 2002:a5d:4c88:: with SMTP id z8mr3225892wrs.291.1553357933743; Sat, 23 Mar 2019 09:18:53 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id i18sm6564532wrm.7.2019.03.23.09.18.52 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 23 Mar 2019 09:18:53 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sat, 23 Mar 2019 16:18:48 +0000 Message-Id: <20190323161849.7019-1-sw@jkqxz.net> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 1/2] vf_crop: Add support for cropping hardware frames 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" Set the cropping fields in the AVFrame. --- libavfilter/vf_crop.c | 74 +++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 23 deletions(-) There is the slightly unfortunate effect the filter links don't carry the cropping information, so we don't know how big the cropped output is in following links until we actually get a frame. For example, to get the middle ninth of a stream: ./ffmpeg_g -y -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i in.mp4 -an -vf "crop=iw/3:ih/3:iw/3:ih/3,scale_vaapi=iw/3:ih/3" -c:v h264_vaapi out.mp4 Without the extra arguments to scale it will take the cropped part correctly but then scale it to the original size. diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 84be4c7d0d..7f6b0f03d3 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -98,9 +98,17 @@ static int query_formats(AVFilterContext *ctx) for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & (AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM)) && - !((desc->log2_chroma_w || desc->log2_chroma_h) && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) && - (ret = ff_add_format(&formats, fmt)) < 0) + if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) + continue; + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + // Not usable if there is any subsampling but the format is + // not planar (e.g. YUYV422). + if ((desc->log2_chroma_w || desc->log2_chroma_h) && + !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) + continue; + } + ret = ff_add_format(&formats, fmt); + if (ret < 0) return ret; } @@ -157,8 +165,14 @@ static int config_input(AVFilterLink *link) s->var_values[VAR_POS] = NAN; av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc); - s->hsub = pix_desc->log2_chroma_w; - s->vsub = pix_desc->log2_chroma_h; + + if (pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + s->hsub = 1; + s->vsub = 1; + } else { + s->hsub = pix_desc->log2_chroma_w; + s->vsub = pix_desc->log2_chroma_h; + } if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), var_names, s->var_values, @@ -237,9 +251,15 @@ fail_expr: static int config_output(AVFilterLink *link) { CropContext *s = link->src->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - link->w = s->w; - link->h = s->h; + if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + // Hardware frames adjust the cropping regions rather than + // changing the frame size. + } else { + link->w = s->w; + link->h = s->h; + } link->sample_aspect_ratio = s->out_sar; return 0; @@ -252,9 +272,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); int i; - frame->width = s->w; - frame->height = s->h; - s->var_values[VAR_N] = link->frame_count_out; s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ? NAN : frame->pts * av_q2d(link->time_base); @@ -285,22 +302,33 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) (int)s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS], s->x, s->y, s->x+s->w, s->y+s->h); - frame->data[0] += s->y * frame->linesize[0]; - frame->data[0] += s->x * s->max_step[0]; - - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & FF_PSEUDOPAL)) { - for (i = 1; i < 3; i ++) { - if (frame->data[i]) { - frame->data[i] += (s->y >> s->vsub) * frame->linesize[i]; - frame->data[i] += (s->x * s->max_step[i]) >> s->hsub; + if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + frame->crop_top += s->y; + frame->crop_left += s->x; + frame->crop_bottom = frame->height - frame->crop_top - frame->crop_bottom - s->h; + frame->crop_right = frame->width - frame->crop_left - frame->crop_right - s->w; + + } else { + frame->width = s->w; + frame->height = s->h; + + frame->data[0] += s->y * frame->linesize[0]; + frame->data[0] += s->x * s->max_step[0]; + + if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & FF_PSEUDOPAL)) { + for (i = 1; i < 3; i ++) { + if (frame->data[i]) { + frame->data[i] += (s->y >> s->vsub) * frame->linesize[i]; + frame->data[i] += (s->x * s->max_step[i]) >> s->hsub; + } } } - } - /* alpha plane */ - if (frame->data[3]) { - frame->data[3] += s->y * frame->linesize[3]; - frame->data[3] += s->x * s->max_step[3]; + /* alpha plane */ + if (frame->data[3]) { + frame->data[3] += s->y * frame->linesize[3]; + frame->data[3] += s->x * s->max_step[3]; + } } return ff_filter_frame(link->dst->outputs[0], frame);