From patchwork Mon Jun 12 22:40:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 3955 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.22.4 with SMTP id 4csp78451vsw; Mon, 12 Jun 2017 15:44:29 -0700 (PDT) X-Received: by 10.28.220.212 with SMTP id t203mr696038wmg.6.1497307469467; Mon, 12 Jun 2017 15:44:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497307469; cv=none; d=google.com; s=arc-20160816; b=VCAQ+m8tfBVZv7pDcjkQND5+NU3VfSc7pFwsPmOHCJh8YPvdlwNjeospfzYbofUVRT eN8tq4ozq0O5+tXWKO4I+Np4wS9/8HWukEyJUZrdMIO6J7m4e7hZKyQxil7tB1WWyQzR roH5GzIMN7f33MqlgcJO7uBLhxzkms5kWllYIoSB/OvYbnT1d3uvvdmyG0WX2J3HnMZu 6kWpfmXaBYWfA7HIgESwtnU0BQfyy/1SIuf3BH89igyH/M7K8aglPAeg25xL/y7WaVOu OKFZXdrXPCdZjP3aBsjD1Li8mCcZR2fcK5a/F4o7hBk4jdpDX3NCHf/H7Q0AKBKuxeod ahmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=EIz0V6ZEotfKv5n6buKxAhUOjEqOAcnCjh/jzIcbAC8=; b=I2NxcCQ4uFlDVrvq75zW9HjyGIAz3WnXarCiIAwMstvs3ilwwWRKdQSXLk2a2PHmm4 0r1AZPvIwcitEAARJGZsY3KTGKcBKMqNL1CozNcKmyG5PqVbpLGMdu2dpuDoFdPz3jPw tOHjfoerm+tE5IgmVO83MVw/u0jFx/TTJ3CbyHcjfQmqpCk4nHaJMWtWcCFiOO8cGozS WAGnzGT1IvfF/vanp3gfXtNCNn96/DAYEq5SByLH1So1nelxQ+aoOV7zL83yBGdHDo3Q V8OSTAa33Nd3ClkYMxF83PBweb6BbJWz83Eo+wikgqhvWDzsgNG8kxkkmGmN27jr/UWT XqcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d30si11192799wrd.163.2017.06.12.15.44.29; Mon, 12 Jun 2017 15:44:29 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CD29F68091A; Tue, 13 Jun 2017 01:41:20 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f172.google.com (mail-wr0-f172.google.com [209.85.128.172]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7EBE668A09C for ; Tue, 13 Jun 2017 01:41:17 +0300 (EEST) Received: by mail-wr0-f172.google.com with SMTP id g76so113432308wrd.1 for ; Mon, 12 Jun 2017 15:41:19 -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:in-reply-to:references; bh=MC5Z7+7fHqUONEjUqFe4tf6pS5aar5n4qPeKqtg0Oao=; b=hxVqrnyi5QjKVWjFzfvMk5HTYVGM8eVp7H2iMJDoq00GMC1rtlimzVgz0Y142E/YGo dFgnCa4VR0xGhoeuNObQ+th8ocLd7aNj7n0skLq6QgJnF3mwWtJQv4Pot3IsEsoa/BEF o0/6ZBV8opcT9eaeFKSDDURAYjprD7qc3JXjwp9OBHVUwRpOKg21mZRTEc11/20n7fcF V6EsW5D/wuUMn+pVQpirAtH9w7/83QTKwNJ0wo+w33f+WDkxKAIuoPMaL5SLEajVqqsA Cnp3AU8QxcCs/Ucp1QhyJ9jXqY+629+U9zmSYUqNQqTWO4XV77DFBn8ZMYkQuAhCM6Rc rERQ== 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:in-reply-to :references; bh=MC5Z7+7fHqUONEjUqFe4tf6pS5aar5n4qPeKqtg0Oao=; b=VhTl8RVNd8Zh1xVKm8HwgpgwfyIsJPrxLzjwKGa3JTCGp2yaO3R+VlMMvUe8jk0SAC flYeakS4ihBOp8Fb+ZAhhXbxhfe8F0/S3sMpwfEzMYx4nd5Ee2X81dGyTfgVjiYj42CN OiovA1Fxzd6BVq6YLwvEKnv1lzvOJG72aEAOWlFrDnX+woWRPJStACFHP0spCXOovcTw wlgqGwF3IPCWWAVZMBewvxaV2cCjNqV7HtisRflEOi32VbUl1MT/epUuzBaTXkPoxWCk CGS/maAFEVUBwrPoawsmm5xkBnOuE3Ri8jztoyUr9k4IkVIhF79xpz9SF6iiDJ5faP5D j2Xg== X-Gm-Message-State: AKS2vOwH+awprwXYDJ3Jusf0N2H5Pu1lb6OrHm8JQuXZ5sxK8/0ncDUV rs8jyXcpeIFq6gh2HB0= X-Received: by 10.223.141.173 with SMTP id o42mr655141wrb.110.1497307278982; Mon, 12 Jun 2017 15:41:18 -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 m191sm13098233wmg.30.2017.06.12.15.41.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 15:41:18 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 12 Jun 2017 23:40:40 +0100 Message-Id: <20170612224041.6750-24-sw@jkqxz.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170612224041.6750-1-sw@jkqxz.net> References: <20170612224041.6750-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 23/24] vf_hwmap: Add reverse mapping for 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This is something of a hack. It allocates a new hwframe context for the target format, then maps it back to the source link and overwrites the input link hw_frames_ctx so that the previous filter will receive the frames we want from ff_get_video_buffer(). It may fail if the previous filter imposes any additional constraints on the frames it wants to use as output. (cherry picked from commit 81a4cb8e58636d4efd200c2b4fec786a7e948d8b) --- libavfilter/vf_hwmap.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c index c0fb42a1bc..c40ed4baf7 100644 --- a/libavfilter/vf_hwmap.c +++ b/libavfilter/vf_hwmap.c @@ -34,7 +34,7 @@ typedef struct HWMapContext { int mode; char *derive_device_type; - int map_backwards; + int reverse; } HWMapContext; static int hwmap_query_formats(AVFilterContext *avctx) @@ -96,7 +96,8 @@ static int hwmap_config_output(AVFilterLink *outlink) } if (inlink->format == hwfc->format && - (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) && + !ctx->reverse) { // Map between two hardware formats (including the case of // undoing an existing mapping). @@ -117,6 +118,56 @@ static int hwmap_config_output(AVFilterLink *outlink) goto fail; } + } else if (inlink->format == hwfc->format && + (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) && + ctx->reverse) { + // Map between two hardware formats, but do it in reverse. + // Make a new hwframe context for the target type, and then + // overwrite the input hwframe context with a derived context + // mapped from that back to the source type. + AVBufferRef *source; + AVHWFramesContext *frames; + + ctx->hwframes_ref = av_hwframe_ctx_alloc(device); + if (!ctx->hwframes_ref) { + err = AVERROR(ENOMEM); + goto fail; + } + frames = (AVHWFramesContext*)ctx->hwframes_ref->data; + + frames->format = outlink->format; + frames->sw_format = hwfc->sw_format; + frames->width = hwfc->width; + frames->height = hwfc->height; + frames->initial_pool_size = 64; + + err = av_hwframe_ctx_init(ctx->hwframes_ref); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialise " + "target frames context: %d.\n", err); + goto fail; + } + + err = av_hwframe_ctx_create_derived(&source, + inlink->format, + hwfc->device_ref, + ctx->hwframes_ref, + ctx->mode); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to create " + "derived source frames context: %d.\n", err); + goto fail; + } + + // Here is the naughty bit. This overwriting changes what + // ff_get_video_buffer() in the previous filter returns - + // it will now give a frame allocated here mapped back to + // the format it expects. If there were any additional + // constraints on the output frames there then this may + // break nastily. + av_buffer_unref(&inlink->hw_frames_ctx); + inlink->hw_frames_ctx = source; + } else if ((outlink->format == hwfc->format && inlink->format == hwfc->sw_format) || inlink->format == hwfc->format) { @@ -148,13 +199,13 @@ static int hwmap_config_output(AVFilterLink *outlink) if (!device) { av_log(avctx, AV_LOG_ERROR, "A device reference is " - "required to create new frames with backwards " + "required to create new frames with reverse " "mapping.\n"); err = AVERROR(EINVAL); goto fail; } - ctx->map_backwards = 1; + ctx->reverse = 1; ctx->hwframes_ref = av_hwframe_ctx_alloc(device); if (!ctx->hwframes_ref) { @@ -171,7 +222,7 @@ static int hwmap_config_output(AVFilterLink *outlink) err = av_hwframe_ctx_init(ctx->hwframes_ref); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to create frame " - "context for backward mapping: %d.\n", err); + "context for reverse mapping: %d.\n", err); goto fail; } @@ -203,7 +254,7 @@ static AVFrame *hwmap_get_buffer(AVFilterLink *inlink, int w, int h) AVFilterLink *outlink = avctx->outputs[0]; HWMapContext *ctx = avctx->priv; - if (ctx->map_backwards) { + if (ctx->reverse && !inlink->hw_frames_ctx) { AVFrame *src, *dst; int err; @@ -261,7 +312,7 @@ static int hwmap_filter_frame(AVFilterLink *link, AVFrame *input) goto fail; } - if (ctx->map_backwards && !input->hw_frames_ctx) { + if (ctx->reverse && !input->hw_frames_ctx) { // If we mapped backwards from hardware to software, we need // to attach the hardware frame context to the input frame to // make the mapping visible to av_hwframe_map(). @@ -327,6 +378,9 @@ static const AVOption hwmap_options[] = { { "derive_device", "Derive a new device of this type", OFFSET(derive_device_type), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, + { "reverse", "Map in reverse (create and allocate in the sink)", + OFFSET(reverse), AV_OPT_TYPE_INT, + { .i64 = 0 }, 0, 1, FLAGS }, { NULL } };