From patchwork Fri Jul 8 22:53:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36712 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323278pzb; Fri, 8 Jul 2022 15:55:02 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tBUx9B7THuGO+5URIUnj/CelMCjCJtdCnqx8z4SHOZNQbdXp2FT0wvtGXDYQ8AZCFvT1DL X-Received: by 2002:a05:6402:5245:b0:43a:a024:82cc with SMTP id t5-20020a056402524500b0043aa02482ccmr7867170edd.56.1657320902517; Fri, 08 Jul 2022 15:55:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320902; cv=none; d=google.com; s=arc-20160816; b=FrEYnvMOvlHS4//Rc5OkRBWziDUhEWdoPuk4BIIKVyQUAMHIukzc7hsVP1rhixcInt XESG4L1ORor4OTdSbxYTfvMvIxh7OcQbmYyBeqGbx3Zor3NtHfo5RxdH1VenzRxTl49H 5Ws3RyHqRjdlnmEEnauQGvzUvKWHFJN9q2nt99UHCYrzTh3cY70kfMqCBq9DyVsAV0Er 3AnhAx8a5boD//l/xtKo/tMMDvY5Ys+ID/6oEWLIVFwygcX9CCJOOxiQuhGgiFgGLfY2 enxatIB/3cS2J8Q+cdFUOvh50aqCHTz2ctpJbc/KEH/g3axdEy6OBU9foT7kKniPSH3t ECvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=us/YI6p0XFNsKZEQJuNr80xDRn/zsOKrZnFy8J/g6dU=; b=le047Kkz/ZTWWTJdKCAEDA2lCq4mrnYltMfC0qCWbify7qe502hUgrI6aKS4SNDmJK aaSjVY6jn8oJnJal3s7/e+1bL4eYaOf7dVthXL/nMgaj5ksA9nkIQXes6TSs6jZqd+NH twWqrlKZJmCngQtah6+x3TMSkLG7wqJnW1Q5QLohbzZPF8z3Nxycsb4mBooTWKnbXCfi VeipXOljJCu5lAsbLS9ZymGBkNvfF3dVoKVe3l2JcUAyxLDHuE8tuVJquKaEagMuQ4ki fgVGksSdsPDz4ZnihEVJV3/zVZyzLEk8Mj/IYjuLH8M97JM7Nyu0I/GKXK9nt2e1eGNC rHRQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b="iEw/nOrr"; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a5-20020a1709066d4500b00718d1cddac7si25249107ejt.2.2022.07.08.15.55.02; Fri, 08 Jul 2022 15:55:02 -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=@rothenpieler.org header.s=mail header.b="iEw/nOrr"; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E345368B889; Sat, 9 Jul 2022 01:54:32 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8DCAE68B871 for ; Sat, 9 Jul 2022 01:54:22 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id EE9FB317320; Sat, 9 Jul 2022 00:54:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=Bmzam+iYvlG6j5Tx8e/IsLnfBQ4CIaYRrPyPDHletVE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=iEw/nOrrR38ygWNDHkkMONn/2r5KnuNfy3YDOSkeL8bJlKtXKFHVN5xN9aSDVIEve cuEPTpzt5snwdHgegsmZk3kLuprSa60B1cmRgzmF3U/R0SOBxCBBkKIWcevDynel2S CKMhvomhaVFEIvsG3td0Mo1ke46w/KRk5jh/zjRvxjdRh6+0n2DBZR1jFRCPx5aEFs j2xZgXQqrla4rSbVicnySrtAC/pEfmX+kmO4QVIazSBdBFtGMx8QTszCVSKv0ZuT+O EIU2I65W5jENKkkq86H3ojS5FpxcOTntEm8dWeF8uhvfi8LnxycOdzQLJVxL8H75AG cefFB8NXAS5bA== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:53:57 +0200 Message-Id: <20220708225404.23748-2-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/8] fftools/ffmpeg: make debug_ts print raw filter output X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pom2hMlUXpCo --- fftools/ffmpeg.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index e7384f052a..a69364c0d4 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -765,7 +765,9 @@ static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost, AVFrame *frame) { double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision + int64_t orig_pts = AV_NOPTS_VALUE; AVCodecContext *enc = ost->enc_ctx; + AVRational filter_tb = (AVRational){ -1, -1 }; if (!frame || frame->pts == AV_NOPTS_VALUE || !enc || !ost->filter || !ost->filter->graph->graph) goto early_exit; @@ -774,9 +776,10 @@ static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost, AVFilterContext *filter = ost->filter->filter; int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; - AVRational filter_tb = av_buffersink_get_time_base(filter); AVRational tb = enc->time_base; int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16); + filter_tb = av_buffersink_get_time_base(filter); + orig_pts = frame->pts; tb.den <<= extra_bits; float_pts = @@ -794,9 +797,14 @@ static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost, early_exit: if (debug_ts) { + av_log(NULL, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n", + frame ? av_ts2str(orig_pts) : "NULL", + frame ? av_ts2timestr(orig_pts, &filter_tb) : "NULL", + filter_tb.num, filter_tb.den); + av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n", frame ? av_ts2str(frame->pts) : "NULL", - frame ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL", + (enc && frame) ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL", float_pts, enc ? enc->time_base.num : -1, enc ? enc->time_base.den : -1); From patchwork Fri Jul 8 22:53:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36709 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323124pzb; Fri, 8 Jul 2022 15:54:34 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sfyh1QYyWGjIniPQ7R+KvNUTr2UJh/O/bX++K+31bsA4LYlfN7EtQ7koahu8DMkJ9eG/XU X-Received: by 2002:a05:6402:239f:b0:43a:92a7:84e with SMTP id j31-20020a056402239f00b0043a92a7084emr8000606eda.293.1657320874747; Fri, 08 Jul 2022 15:54:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320874; cv=none; d=google.com; s=arc-20160816; b=iBfP5LkWn6jlBl67iuyh8/J8AcnTjgl8ntx4Bl1Wz52Zz0wAW/z95q0Dejai8G4LOT N7SbAo055aF6jBq1IWaQICGKnz+/vCA64nhBbxb88pClmsjxssKkOdCLcIfb2/aNyOf4 cbKdKCxGWpgZ0PcuTugVKhlcTIJYL12fnvEG1CEuQg0uLs48VoB2pilkqR7I2QP9aCQc A7mMlz8UkOwNOY132C41Ee0bpI7axGxwy6YyUjVlSo0D+yEGqjjLE0YBS+wvcDbf4Fuw RxEz4vZ2JVfuccZMAssfU3J/caZbNnCYoB10cpGjl5jawq4YAdBYFCyQe1LWxqmRXh7M Wbsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=K6szcJ4z/CJwzAjELsv0RWCQ2HprBdjXjbB3jvdFaL0=; b=WXC7ny4arQd6M+5x88jsNX/HvVFNHmBCWY38sIFrrPEzU+SGbJtCktgI1+lXs9RYHc 4CsJMXPk3OBG6j3ePZDCfrZX5Dmu0C8ZsfvX6ifpo+LvjFDpNasrzd5eMKZ3yOjSbZVk X6ofUmapLak9mMnPTzavD6VWTRlF7yIDCNTea2ijHIGW4tJLQkfVThB4yiVhHdoCbp+1 JExN4HLZum4I8jkbUhMnOI8rEj+/23En6yaoXxlF7PrsNQUQbKGG0IA1jnmW+C9xDc10 828lvwoDxgEcmWKEFrVr0WTzwF/TZtGMwnNdz/hpvoQB1J7UH/KD2cKLBJXibBQm4N9+ hpZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=llfgLf4h; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hb34-20020a170907162200b00726b4eb3517si32327284ejc.501.2022.07.08.15.54.33; Fri, 08 Jul 2022 15:54:34 -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=@rothenpieler.org header.s=mail header.b=llfgLf4h; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 887D368B978; Sat, 9 Jul 2022 01:54:29 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8986968B84C for ; Sat, 9 Jul 2022 01:54:22 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id 238A5316FAD; Sat, 9 Jul 2022 00:54:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=gcHFgghrJABVFrLkM8LdT5JZNUA+wwQnXwdD46jDp44=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=llfgLf4hlyPGI006vV6XKUL4wo6oye7XVdSFZmx7zMsJNl2g5bQDVmDBm/WLNcOw8 jl9ZvIoCfQN8i66/0kBSf5milUh1RlA2ZIj2cuRX0KYtwtMoV97foGQy9X1LqbgQfN I9Gu+BKgMWKtx2cyLvl5DGsh6IvB8nSNCvzrVuk6/QZ1Oec0xgKesxuGV7qJwIs68a L97776MZUcBVNxENcqnDuuycTUN4lDbg3rVAFXAYvsVw8dSn57RXKR3QpS0HBY5lVD Rnf4ibIsWwc7hgr2vpl8ZoInxXJwNcJL5tepu3Fckjgxm6yjiculJ+d3N8/ZhC1q2o qhpJZGB6PmNEw== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:53:58 +0200 Message-Id: <20220708225404.23748-3-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 2/8] avutil/hwcontext_d3d11va: fix mixed declaration and code X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: S++NyKWHkFeD --- libavutil/hwcontext_d3d11va.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index 904d14bbc8..e5afcb2a9d 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -397,6 +397,7 @@ static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, D3D11_TEXTURE2D_DESC desc; D3D11_MAPPED_SUBRESOURCE map; HRESULT hr; + int res; if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format) return AVERROR(EINVAL); @@ -405,7 +406,7 @@ static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, if (!s->staging_texture) { ID3D11Texture2D_GetDesc((ID3D11Texture2D *)texture, &desc); - int res = d3d11va_create_staging_texture(ctx, desc.Format); + res = d3d11va_create_staging_texture(ctx, desc.Format); if (res < 0) return res; } From patchwork Fri Jul 8 22:53:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36710 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323181pzb; Fri, 8 Jul 2022 15:54:45 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tewec5UoI5LLHpsSTwNoiiNQh+xPje8UyOPHL43QVsFsgt9lXKEL53S+MLE67sTKcCOi2Q X-Received: by 2002:a17:907:2704:b0:72a:596f:8b9f with SMTP id w4-20020a170907270400b0072a596f8b9fmr5721033ejk.761.1657320885031; Fri, 08 Jul 2022 15:54:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320885; cv=none; d=google.com; s=arc-20160816; b=BQzjIgm1w51jA4zABDELKhDoLL1xgSIDBqxp21Cu+jTlMP4lyPPEbFj+b4SmPdUp8P WiD+8wFnOmZ6lM60s16hUi/eBIOLE77Ji5QuVTnqRn0668CKyaGtgpjneiGBx4WTroFj 6CdxtkDna8KfZTjIOWT3qaJFnPUUYLLgNEA2p2JqEJnO0mo/45JIJNbeXUdF6L1hO/Ke QXplZRL9O4ePPSm72hTxWEBPBfvujhCKZom/MHKB+2VXMEGJm8GXqnsG2n4NVOYBHhJc FoJmpdGjrp0ti5Pbp5iXhz+YFJX9TQNRyZjXXmXmokrIlV8aphMesHbQQjkudq7kGCLp e/ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=HF6X7IULf9SNAoEbW4wF0+vD34GNSNpwJEzTVIq2fNc=; b=J2i+prOmQ4fmtjBEme7e4N9j9osY/Z/ui+/WCRcS+UfyCv0woDxYUm0IpO73JVucaC PyeaEI8iEnBP172LduQdsNCuQN5emJ5Jm5U6j4Sc+tR1N4JMVd8qULoaZp5bA+zwUZBZ QXrDb7SFG4ZGDo/j++xwoDuI5vi1MQbBLWT0OYwuvuO/G4qYpqCgldD3viGj2G5SVLY8 ziOtKyF8sLnDU8WxXx+qA+4KbsSMcPpTWwZPKzJQ7CayESXFN35HmywVQv2R17xrMzwr QEppOUNjcHcB495RNQf5YIuYp5gsO74ui3RXOzA5Nv0+gUXZ9gIvBdH6vlKMCic/EwR0 o3HA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=PKKCKZlg; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id qb12-20020a1709077e8c00b0070fc7c9d71dsi41257290ejc.989.2022.07.08.15.54.44; Fri, 08 Jul 2022 15:54:45 -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=@rothenpieler.org header.s=mail header.b=PKKCKZlg; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A87DD68B970; Sat, 9 Jul 2022 01:54:30 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 86F8F68B793 for ; Sat, 9 Jul 2022 01:54:22 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id 4632B316FAE; Sat, 9 Jul 2022 00:54:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=NjPytgcci73A/SdvACKFfVvC72pm+MpFO1LURbVJDME=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=PKKCKZlgN6A66IDbmGDaDuSksnGoXDhKx2CyXHshD6a7eokaHMCdM3tFCd0UQKw1C OygMEA8quOfODgatixtXv3h4enCje/RxLA0iYmczc05oGQhwZfKpFLoxtTzztJafth GxHGAkVHU26z+RDeSEqPdWgjmFW1EGMDww12VZzx2lgLm8q29rCAYHreCSHFe8X7wI aW4QBh1nApZFOMHUa/3hOP5JFg8EGevm3je20VZzJuRk249NmGyuSD4lNKncy5Hq4r 2elfnT93IkwlYifJVNG+tX7DoN1U3j44bNLsivGDTrBJ2kpwcZXbb2QMBlule9wPgQ zJviNkjxSUxjA== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:53:59 +0200 Message-Id: <20220708225404.23748-4-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 3/8] avutil/hwcontext_d3d11va: fix texture_infos writes on non-fixed-size pools X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: F3VNMJPNSrwp --- libavutil/hwcontext_d3d11va.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index e5afcb2a9d..6355bd1e29 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -166,6 +166,17 @@ static AVBufferRef *wrap_texture_buf(AVHWFramesContext *ctx, ID3D11Texture2D *te return NULL; } + if (s->nb_surfaces <= s->nb_surfaces_used) { + frames_hwctx->texture_infos = av_realloc_f(frames_hwctx->texture_infos, + s->nb_surfaces_used + 1, + sizeof(*frames_hwctx->texture_infos)); + if (!frames_hwctx->texture_infos) { + ID3D11Texture2D_Release(tex); + return NULL; + } + s->nb_surfaces = s->nb_surfaces_used + 1; + } + frames_hwctx->texture_infos[s->nb_surfaces_used].texture = tex; frames_hwctx->texture_infos[s->nb_surfaces_used].index = index; s->nb_surfaces_used++; @@ -284,7 +295,7 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx) } } - hwctx->texture_infos = av_calloc(ctx->initial_pool_size, sizeof(*hwctx->texture_infos)); + hwctx->texture_infos = av_realloc_f(NULL, ctx->initial_pool_size, sizeof(*hwctx->texture_infos)); if (!hwctx->texture_infos) return AVERROR(ENOMEM); s->nb_surfaces = ctx->initial_pool_size; From patchwork Fri Jul 8 22:54:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36711 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323223pzb; Fri, 8 Jul 2022 15:54:54 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tufpxhwMRbyzO4miH9maNK4xkTjmc7B7EXddvTA48lve7BxO0O3rQ6Vd6Z0AGBCId97JhJ X-Received: by 2002:a17:907:9693:b0:726:372c:2c02 with SMTP id hd19-20020a170907969300b00726372c2c02mr5964685ejc.483.1657320894135; Fri, 08 Jul 2022 15:54:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320894; cv=none; d=google.com; s=arc-20160816; b=Iyt86gpGTmisbijYgHksuxM74Ibi2quKA92I/6VbMWIOTvnWRXucS2SdXe+LnnRpms +bdDUJA5yPmMDB+g0HK61iXrc/Wn5g9jvn5uszAOlEsrTaJWjIPleq0rt25le4Sp2yEV Htiq/+hLD8CcfCFlaCB7l1nJYZFDS7WNgtlyjA7hrAEYH2zKmdLiixypFwtkPBTLVoE1 8K+LsH3Sw7uhohMVbE6p1msBR/JmUsd1Owhkep/+q+GhVLNoZGMQXde31Qc4xDluv11O gBBGsx6TMMcxw0Z3jsCRE1Oz/3bVQAyZreEQxDSPGZ6WnwnUGt39eKtNWBCDTF51vbOF xNLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=/cflSPVMHKVS9dv/JGwbagGDBHwZUdWS3L0Oji9niJU=; b=ZP/5/DO/mO+adb+AgV3/2nrscw3NQxelJaUpAhRQGctzCr7LGEq611rkjPr1vPGiyQ xJXnpeHDCP7+LxDMej1p8y4R5f9W6XeHSrHemlD7e75uEAe1eIvtHBHprCAAuvIYfko1 BoB50eNc6J5kqeglx7EX3M81kvUXHYmHkwGSCrVGHg6ZkCkp+8BV/EMsvPWiJYU5BaKC hhZxLmObvLqLmP0q4lYTKn4kf0WMwZybTdRN8/HTehO19RqbjZZ5O8a/nx8UIskcHzOy xDaTapvMjIvaO3GY85Zxi0LiWyjtf16x1slgKTRn7F0Sg1tFxA+c1KEjpBrTqAhbaVyk FVsw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=YoT6U0ec; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id y14-20020a056402358e00b004359f471717si74378edc.0.2022.07.08.15.54.53; Fri, 08 Jul 2022 15:54:54 -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=@rothenpieler.org header.s=mail header.b=YoT6U0ec; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E22F968B860; Sat, 9 Jul 2022 01:54:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8BAD968B860 for ; Sat, 9 Jul 2022 01:54:22 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id 6777C316FAF; Sat, 9 Jul 2022 00:54:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=fuzoJZK64L8OKKm1yvH0ODp8OSWQ+CALp+mtRYxXTJg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=YoT6U0ecmv25LEBGRXbQ7zzuxKIWV+AbvCQAGFLTQZuVwvs92MzvOgdj/SUxatZl+ TbpjlkBlzrFTVDjIV6569OaNPMtDbtxl4BDWtSH8l1n5WODBZEpLv+vp+HuwtlTa+a EXM5OhHQiZvlQjAinHkRM+lfqSXkvypv/NxaAuNFMhVrgdH9mdF+7Y4Q2/7eiu9NhO Ilowb2KgbB1DrCiJNfnLAZEWLgS7LxM8AOxVXgB+LGD+nqcAfD+XdFetQujXs9A8eE gHhREjqvck1bn/SVjUE12Y9B3tQwXN/xGQK9x1o2mONXNsEF7hNAPp4T7mHiGfKOMh HZCk20TXwg+2Q== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:54:00 +0200 Message-Id: <20220708225404.23748-5-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 4/8] avutil/hwcontext_d3d11va: update hwctx flags from input texture X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: CxghhPIc7YTl At least QSV relies on those being set correctly when deriving a hwctx. --- libavutil/hwcontext_d3d11va.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index 6355bd1e29..d492489b79 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -287,6 +287,10 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx) av_log(ctx, AV_LOG_ERROR, "User-provided texture has mismatching parameters\n"); return AVERROR(EINVAL); } + + ctx->initial_pool_size = texDesc2.ArraySize; + hwctx->BindFlags = texDesc2.BindFlags; + hwctx->MiscFlags = texDesc2.MiscFlags; } else if (!(texDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && texDesc.ArraySize > 0) { hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture); if (FAILED(hr)) { From patchwork Fri Jul 8 22:54:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36714 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323452pzb; Fri, 8 Jul 2022 15:55:29 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uE0Kv4LAmS7lq9j6q0uNGp8oYP5urxKlbIEuY3uR2ZJ0D5bDqd83O6l879uTalVLvdOJqJ X-Received: by 2002:a05:6402:3490:b0:435:9802:96ac with SMTP id v16-20020a056402349000b00435980296acmr7824587edc.40.1657320929088; Fri, 08 Jul 2022 15:55:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320929; cv=none; d=google.com; s=arc-20160816; b=JBOxvCCPABAz0LePVC0TcIWjIroNY0C1UsV8TChwR88KJ1I8LmWed8tCwW+1B1RIWj bIOQckNKUYmcNbuMdM1BYi8i/lfOfeKlz3xtdKm8JZUQ/J5aC81QR4GNYhZ20cF04kx6 I9HUrH9ljMR1cOItPwoNBjCBMOQWgH/jQdcENgreiqTkdcvw4VppKZYnovvduJo43hR8 JJc5ifzfnAkNEAypZrOlMOit+Y4cTj9vGlEKS0jyaBnL3ndJuHrp7nSQIA+Hc8I8LjTC XYGQt9wIdVoGJ3I/XEQ1Px2sHUw7GozqNWZHgy9cs1TZXuT4QTHDbMoP4XcAnX+sNJwX mTxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=sJ4oiDLP1v75JaEuyb9yZiDMbAgsDCNfYphd/oH7/Rk=; b=LFgbK+FBJEPNtpoHetfQMQMfDxm5wxF1NOFCHD6d2IsXNyzIPwjRXC6GmsoXovTxfq HXp6gHOX8Esu8zTcjRrT/0y2fEBeVZergaL3Pd1XQQaWeI3BrHTkrhtjKJ256VnA83if JTC1PaWrzXvhwTjUnnzA6zzQkDmJp4Otpa8XZWihiuzYdhVDw8qo/+gB8bJAm7HziUTd /pPFIvz+ewnCpLuzmpuc03Tj+X6qIiQdKX9C4Vrzwcc7HB0lawLnu9P69nthMaCTcAk8 6ITEg937vP2tEArsStGHNGly0X3xhK/YIMy5v0wc0Lk9v/vrhxxbgSNwjqQPVXj82AQ5 XQwQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=MBBRO9T0; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id cs14-20020a170906dc8e00b0072ae568f4a0si16564700ejc.93.2022.07.08.15.55.28; Fri, 08 Jul 2022 15:55: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=@rothenpieler.org header.s=mail header.b=MBBRO9T0; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B9EFC68B9AC; Sat, 9 Jul 2022 01:54:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id ED0DE68B922 for ; Sat, 9 Jul 2022 01:54:27 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id 887EA316FB0; Sat, 9 Jul 2022 00:54:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=/ob1PJaGgIxUzifJGjG0aP/QJLOEzNMg/4RXgWDE9ks=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=MBBRO9T0LGHZ2R1Qb6qp3sZvR35/t5NMh2AlEafjascb0rN7nVHX4Bme8UToQULLx Tl0zrmDMvHEq0Exuu+Oznn/Q9bUClNuo885I7MGe50Waq4VEUwBAsfoysvWrQA0f8F fJeMPUDaDFETugyx+0xCQvph4q/QgpDX50+Z7bT7qqMlEZ9z5QljmgbSIlN22jEW8u qlRM9ZX207Rpu4pxEmY//ikQJPOI+HjepwsOCi/Ly5qup+QrEpHK3Fiu+u/6R/xhyP XUo4qWTljJPgJJ83tZ3eSlvYGdM0wJhxlwTj1nQZdp5HlE2bZY+450eBCjIC2tJ4ug 1N1T6phkSgJrQ== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:54:01 +0200 Message-Id: <20220708225404.23748-6-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 5/8] avutil/hwcontext_d3d11va: add BGRA/RGBA10 formats support X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: +HoAVwrp4adg Desktop duplication outputs those --- libavutil/hwcontext_d3d11va.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index d492489b79..27c0c80413 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -86,6 +86,8 @@ static const struct { } supported_formats[] = { { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 }, { DXGI_FORMAT_P010, AV_PIX_FMT_P010 }, + { DXGI_FORMAT_B8G8R8A8_UNORM, AV_PIX_FMT_BGRA }, + { DXGI_FORMAT_R10G10B10A2_UNORM, AV_PIX_FMT_X2BGR10 }, // Special opaque formats. The pix_fmt is merely a place holder, as the // opaque format cannot be accessed directly. { DXGI_FORMAT_420_OPAQUE, AV_PIX_FMT_YUV420P }, From patchwork Fri Jul 8 22:54:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36713 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323401pzb; Fri, 8 Jul 2022 15:55:20 -0700 (PDT) X-Google-Smtp-Source: AGRyM1slF7jkl0skV3FwYb278aAQxbjM/CadqJm2r1NQmYS7KgLuABZ0/oUx3m616EjyWOK/OTOj X-Received: by 2002:a05:6402:1102:b0:43a:9cf7:68a3 with SMTP id u2-20020a056402110200b0043a9cf768a3mr7883122edv.68.1657320920331; Fri, 08 Jul 2022 15:55:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320920; cv=none; d=google.com; s=arc-20160816; b=UCcPCvnk/gzNyhCcGdfqHl1RXyDnBBgVKmq4cL6eX7TGmV/WtcPi1EV8okAIqdKks4 WdWNgR2xI22vcun7QKI2PIxx9CjncjdzLZZvoGXGAU5Gh5jRiJ0B97YPQXdWiE5/Eh3T UqZfYIfAi9IUHTb2WFcy/ynd+ySOKpJNLLhWY9LxaJCdA6mm+T/fnq3D8vj1VpsRW7wx BUJmBuCHaPaYoQyr/iO+2Yj0V4iVdxzEal+dNlesXUGHEjvnZTVD3UtSZjEzMx0R9JDe 9OTWXoDd7La1pDmprm9Op8TrscJwkHNqSDyjD3RCOm1Tx2/WkC76Yu7Z+WkLXl5LpSM1 3Shw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=WUZdrhtTvKi+M7ngRsAs0BSX7G2VLe4GR2dlDUus5IM=; b=aZCepkpmpBQ9pw+f1n+t6P7wnOlv2T4KRsrIz7jUVSfOFzf847tcLCpf19rzCwtyoA D68uNiX3qlwYV4isYXEI+zzpnSm77odFqeDoLVCk5C3x3kN5KcJVQGb6pTGTEKcmvJu2 W2vTQuMpGPaCwRGSvzZdPVARJUqIsotaPFAQihC54q/XL/dmFQPTfBApzIBry6STH3xM LKIXBWJIoy4yPI9opaL3Fxzdmani5un8Inxa0ggl7k7SurzcvKlLscsGsIQBgmcANDbx qNhVzmbOODcuwSEc8PtdwI737kqlDK3kxBRl2WZmIfzpmiLdciErBk+Qa7BkuwKZsDF3 dqqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=c7gCGumR; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ga21-20020a1709070c1500b0072b303bc76asi2626183ejc.141.2022.07.08.15.55.19; Fri, 08 Jul 2022 15:55:20 -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=@rothenpieler.org header.s=mail header.b=c7gCGumR; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C1F0268B9A0; Sat, 9 Jul 2022 01:54:34 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id ECB2368B889 for ; Sat, 9 Jul 2022 01:54:27 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id B5F81316FB4; Sat, 9 Jul 2022 00:54:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=ceIHBhXpdVmA4mDBzER3vhKTUKPfQgk7qV7YjT1Xl80=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=c7gCGumRzjK1c16L/HE+r164WuG6MPwsQsHto8o7ATveOPje71+8hokagIRcaiW5t 3Yciu4jEoomqi+LDmRnS7Z3ApJQZNRhlsGvrWcIc2X2wICc1NSc1OW2yK98FAvGn0W T4knHFhgxlPoarmvkAez1q7Ga+m2PdnHGZAi4oKzDK+GotEeJNtGFZyj35/BX26DuO ABn6SycjNErSCSD6ZQ1bCOtnToqNoH8/kTb6fQbxBZhKlpeZ8/N3QlFvXZ0xvfBNcU bHubJun2tGkGI1NRAX6fqfd7JBjzmw35X48kdBgRy4e+dX+G89Jbvd3OtXCQ8kbpqY dqqndVj3fDZSQ== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:54:02 +0200 Message-Id: <20220708225404.23748-7-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 6/8] avdevice/lavfi: output wrapped AVFrames X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: un8zatFeVUwr This avoids an extra copy of potentially quite big video frames. Instead of copying the entire frames data into a rawvideo packet it packs the frame into a wrapped avframe packet and passes it through as-is. Unfortunately, wrapped avframes are set up to be video frames, so the audio frames continue to be copied. Additionally, this enabled passing through video frames that previously were impossible to process, like hardware frames or other special formats that couldn't be packed into a rawvideo packet. --- libavdevice/lavfi.c | 89 +++++++++-------------- libavdevice/version.h | 2 +- tests/ref/fate/filter-metadata-cropdetect | 3 +- 3 files changed, 38 insertions(+), 56 deletions(-) diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index db5d0b94de..1b282a70cb 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -54,32 +54,10 @@ typedef struct { int *sink_eof; int *stream_sink_map; int *sink_stream_subcc_map; - AVFrame *decoded_frame; int nb_sinks; AVPacket subcc_packet; } LavfiContext; -static int *create_all_formats(int n) -{ - int i, j, *fmts, count = 0; - - for (i = 0; i < n; i++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - count++; - } - - if (!(fmts = av_malloc_array(count + 1, sizeof(*fmts)))) - return NULL; - for (j = 0, i = 0; i < n; i++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - fmts[j++] = i; - } - fmts[j] = AV_PIX_FMT_NONE; - return fmts; -} - av_cold static int lavfi_read_close(AVFormatContext *avctx) { LavfiContext *lavfi = avctx->priv_data; @@ -90,7 +68,6 @@ av_cold static int lavfi_read_close(AVFormatContext *avctx) av_freep(&lavfi->sink_stream_subcc_map); av_freep(&lavfi->sinks); avfilter_graph_free(&lavfi->graph); - av_frame_free(&lavfi->decoded_frame); return 0; } @@ -125,15 +102,11 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) LavfiContext *lavfi = avctx->priv_data; AVFilterInOut *input_links = NULL, *output_links = NULL, *inout; const AVFilter *buffersink, *abuffersink; - int *pix_fmts = create_all_formats(AV_PIX_FMT_NB); enum AVMediaType type; int ret = 0, i, n; #define FAIL(ERR) { ret = ERR; goto end; } - if (!pix_fmts) - FAIL(AVERROR(ENOMEM)); - buffersink = avfilter_get_by_name("buffersink"); abuffersink = avfilter_get_by_name("abuffersink"); @@ -264,8 +237,6 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) ret = avfilter_graph_create_filter(&sink, buffersink, inout->name, NULL, NULL, lavfi->graph); - if (ret >= 0) - ret = av_opt_set_int_list(sink, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN); if (ret < 0) goto end; } else if (type == AVMEDIA_TYPE_AUDIO) { @@ -321,15 +292,12 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) avpriv_set_pts_info(st, 64, time_base.num, time_base.den); par->codec_type = av_buffersink_get_type(sink); if (par->codec_type == AVMEDIA_TYPE_VIDEO) { - int64_t probesize; - par->codec_id = AV_CODEC_ID_RAWVIDEO; + par->codec_id = AV_CODEC_ID_WRAPPED_AVFRAME; par->format = av_buffersink_get_format(sink); par->width = av_buffersink_get_w(sink); par->height = av_buffersink_get_h(sink); - probesize = par->width * par->height * 30 * - av_get_padded_bits_per_pixel(av_pix_fmt_desc_get(par->format)); - avctx->probesize = FFMAX(avctx->probesize, probesize); - st ->sample_aspect_ratio = + avctx->probesize = FFMAX(avctx->probesize, sizeof(AVFrame) * 30); + st ->sample_aspect_ratio = par->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink); } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { par->sample_rate = av_buffersink_get_sample_rate(sink); @@ -348,11 +316,7 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) if ((ret = create_subcc_streams(avctx)) < 0) goto end; - if (!(lavfi->decoded_frame = av_frame_alloc())) - FAIL(AVERROR(ENOMEM)); - end: - av_free(pix_fmts); avfilter_inout_free(&input_links); avfilter_inout_free(&output_links); return ret; @@ -378,15 +342,20 @@ static int create_subcc_packet(AVFormatContext *avctx, AVFrame *frame, return 0; } +static void lavfi_free_frame(void *opaque, uint8_t *data) +{ + AVFrame *frame = (AVFrame*)data; + av_frame_free(&frame); +} + static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) { LavfiContext *lavfi = avctx->priv_data; double min_pts = DBL_MAX; int stream_idx, min_pts_sink_idx = 0; - AVFrame *frame = lavfi->decoded_frame; + AVFrame *frame; AVDictionary *frame_metadata; int ret, i; - int size = 0; AVStream *st; if (lavfi->subcc_packet.size) { @@ -394,12 +363,15 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) return pkt->size; } + frame = av_frame_alloc(); + if (!frame) + return AVERROR(ENOMEM); + /* iterate through all the graph sinks. Select the sink with the * minimum PTS */ for (i = 0; i < lavfi->nb_sinks; i++) { AVRational tb = av_buffersink_get_time_base(lavfi->sinks[i]); double d; - int ret; if (lavfi->sink_eof[i]) continue; @@ -411,7 +383,7 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) lavfi->sink_eof[i] = 1; continue; } else if (ret < 0) - return ret; + goto fail; d = av_rescale_q_rnd(frame->pts, tb, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); ff_dlog(avctx, "sink_idx:%d time:%f\n", i, d); av_frame_unref(frame); @@ -421,8 +393,10 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) min_pts_sink_idx = i; } } - if (min_pts == DBL_MAX) - return AVERROR_EOF; + if (min_pts == DBL_MAX) { + ret = AVERROR_EOF; + goto fail; + } ff_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx); @@ -431,15 +405,19 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) st = avctx->streams[stream_idx]; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - size = av_image_get_buffer_size(frame->format, frame->width, frame->height, 1); - if ((ret = av_new_packet(pkt, size)) < 0) + pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame), + &lavfi_free_frame, NULL, 0); + if (!pkt->buf) { + ret = AVERROR(ENOMEM); goto fail; + } - av_image_copy_to_buffer(pkt->data, size, (const uint8_t **)frame->data, frame->linesize, - frame->format, frame->width, frame->height, 1); + pkt->data = pkt->buf->data; + pkt->size = pkt->buf->size; + pkt->flags |= AV_PKT_FLAG_TRUSTED; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - size = frame->nb_samples * av_get_bytes_per_sample(frame->format) * - frame->ch_layout.nb_channels; + int size = frame->nb_samples * av_get_bytes_per_sample(frame->format) * + frame->ch_layout.nb_channels; if ((ret = av_new_packet(pkt, size)) < 0) goto fail; memcpy(pkt->data, frame->data[0], size); @@ -468,10 +446,13 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) pkt->stream_index = stream_idx; pkt->pts = frame->pts; pkt->pos = frame->pkt_pos; - av_frame_unref(frame); - return size; + + if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) + av_frame_free(&frame); + + return pkt->size; fail: - av_frame_unref(frame); + av_frame_free(&frame); return ret; } diff --git a/libavdevice/version.h b/libavdevice/version.h index 09c1d778dc..5462173f17 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVDEVICE_VERSION_MINOR 6 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ diff --git a/tests/ref/fate/filter-metadata-cropdetect b/tests/ref/fate/filter-metadata-cropdetect index e7c03ead4e..104acdd77f 100644 --- a/tests/ref/fate/filter-metadata-cropdetect +++ b/tests/ref/fate/filter-metadata-cropdetect @@ -1,4 +1,5 @@ -pts=0 +pts=0| + pts=400 pts=800|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=719|tag:lavfi.cropdetect.y1=61|tag:lavfi.cropdetect.y2=424|tag:lavfi.cropdetect.w=720|tag:lavfi.cropdetect.h=352|tag:lavfi.cropdetect.x=0|tag:lavfi.cropdetect.y=68 pts=1200|tag:lavfi.cropdetect.x1=0|tag:lavfi.cropdetect.x2=719|tag:lavfi.cropdetect.y1=61|tag:lavfi.cropdetect.y2=424|tag:lavfi.cropdetect.w=720|tag:lavfi.cropdetect.h=352|tag:lavfi.cropdetect.x=0|tag:lavfi.cropdetect.y=68 From patchwork Fri Jul 8 22:54:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36715 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323503pzb; Fri, 8 Jul 2022 15:55:37 -0700 (PDT) X-Google-Smtp-Source: AGRyM1v4YPaji3tjtOrL8Hu5DRYqKkNgj4tzvGydDxUMrUYEQEwQkHjZcYhJJOLrK3NG1DyiC4Pj X-Received: by 2002:a17:907:6818:b0:72b:1347:3566 with SMTP id qz24-20020a170907681800b0072b13473566mr6027910ejc.277.1657320937776; Fri, 08 Jul 2022 15:55:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320937; cv=none; d=google.com; s=arc-20160816; b=PeEEbfHwI2cM9JP8XP3ES2Skllq/3uA7b/EW6F7FCDv1HLUfSUIXTbFi1U8rNCtP70 Dzpik63o8NXO29ZRU9F6+ylcnb+gDJOa/3x2tO8aa43gB+S4DWdS11h3b5PGRsIW/3qT 7jY/BEFSzfezInWHJQtyWraUCEkZ5HvpB0+zNkk2QucKCcfAnC9phA56SZOvLW7DGQU9 sfbLgJKQVxKDmAwaVHd1/DWVV5EuagXrvz1MYK5VXIZD02N/FdIpqOMSVbRdvpSKk6BP 8EjZ0l2pIFT7QEytasI8sy62z4gI1r/KTTOM/P2UMgFlA90v4jfhuMimRKOVf8FTAoXJ EzEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=XRuXlhMy+1bIyYclInDSBcQPVSjzRADy0y4qdOQBbAk=; b=OmWzu4AKIGHGDGZlVQ3DYYOX57iWlzNMyEt/BklWRCjD2BsATOYadPwLkOtTo6u+GT fBcq9PucakPwluQZnL89dqPZCtZLbyV2sFzf7ESPS9c3GAMppYP6/U3/3OnImuNTwqLn HGSHPL+cgcNlZ6ivqibuoYH7rnBJLotUdbYxUYV9+iJ0wgJfXjM6iXxUXkk4M7Bwq/ik Ga6OdPZuRgT83/l7oHvZtf/UnjmzsTw2TFojC+0nc2DVF73g/ECuFZw9/uvR2x/EmXTq 9o4k5g3GbA1S/Jpciqwra2Jb7PP+ajm2XxIQsM5yngEWQ0dc8PuY4K+W6ryhw6gBLIDo nEzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b=U51Z0+Av; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d17-20020a170906545100b00711fc1fb3cfsi28398113ejp.399.2022.07.08.15.55.37; Fri, 08 Jul 2022 15:55:37 -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=@rothenpieler.org header.s=mail header.b=U51Z0+Av; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A8E8F68B9B7; Sat, 9 Jul 2022 01:54:36 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id ED03A68B90D for ; Sat, 9 Jul 2022 01:54:27 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id D8EF9316FBA; Sat, 9 Jul 2022 00:54:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320861; bh=1nQPcAKKAqvzv0Vuf5xUolsyvwAiPr6eeSf6BqUx7aQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=U51Z0+AvL7XQsOvBfmjdFxyEk7tZwC2g1WYhfm8LPNUwY9GPOpev+b22BOL7RZDVQ sD+iSmGOdMpy7Roi6FJAQEozPvRzzcUV+NFZbDrlHTgKeZzGXkVnJMKZu66rBwupvI yahJmQEwPjvxNri6CKytLNMwHhVe2zlGK+3OJ2Zj3NvRyI5ftddXepJLZSpgntdvtK AT1AXGNMB+n5OwZgpe+NWQLLlTx9JboKlebTOjG8NtoCGtHp2P6MckzsEIgvGVpS14 ETxylU402GnV9TB066JR90akIdO6lzeObHpHdNq7an30fu/3Hm7Vl/6RFdU7uLsuAN wBBFNVXnl4GKw== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:54:03 +0200 Message-Id: <20220708225404.23748-8-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 7/8] avdevice/lavfi: pass forward video framerate X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: c5GkUZ7yub4W --- libavdevice/lavfi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index 1b282a70cb..246f7dff3b 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -287,6 +287,7 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) for (i = 0; i < lavfi->nb_sinks; i++) { AVFilterContext *sink = lavfi->sinks[lavfi->stream_sink_map[i]]; AVRational time_base = av_buffersink_get_time_base(sink); + AVRational frame_rate = av_buffersink_get_frame_rate(sink); AVStream *st = avctx->streams[i]; AVCodecParameters *const par = st->codecpar; avpriv_set_pts_info(st, 64, time_base.num, time_base.den); @@ -299,6 +300,10 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) avctx->probesize = FFMAX(avctx->probesize, sizeof(AVFrame) * 30); st ->sample_aspect_ratio = par->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink); + if (frame_rate.num > 0 && frame_rate.den > 0) { + st->avg_frame_rate = frame_rate; + st->r_frame_rate = frame_rate; + } } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { par->sample_rate = av_buffersink_get_sample_rate(sink); ret = av_buffersink_get_ch_layout(sink, &par->ch_layout); From patchwork Fri Jul 8 22:54:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Rothenpieler X-Patchwork-Id: 36716 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1916:b0:8b:804:ebe9 with SMTP id bv22csp323545pzb; Fri, 8 Jul 2022 15:55:47 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sssA4sVa+cyo2BASIKpDAcLYEIRNi3Yb0sLE8K+gGdvuCc67VV65LZgtbTlaRH1qR4z0cZ X-Received: by 2002:a17:907:60cb:b0:726:a69a:c7a with SMTP id hv11-20020a17090760cb00b00726a69a0c7amr6104473ejc.156.1657320946905; Fri, 08 Jul 2022 15:55:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657320946; cv=none; d=google.com; s=arc-20160816; b=HPStE8j0ggJPps4FHyzzTY3a1FU1sgp0MmVjVoKoAJbdMgJKlt6tW3vKTpUdY3TOsg sglSRpTALaQV1GNsiKQT7Pfd9bkN/xuy9O5G3fG0BIRTEG9IyUfeuuHLx4o3HEMv1N5e zita9tefedU+LXajBMLiiA1OJ8mkR5p3Ud+hyomCtw2ZZaaAYlMTf49JZLE8i1A77GHc pvnY7E1G0v26sAvZ1VhO4nr7Q3W+0Rkx5/WQQYA8nXwQpEbxi4i/mUlVZ9G+Ilmp+wbN XYB534QPNVV0RPA2EvR8sQ44BQzl4DEvouqxFWBeg6Hl/++q3oO3QtieY+75L0Xy92Oy qKqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=c71hwpqEaJgiV/E+1+RM7rv2e6v9uQfjjDe13RX3oJw=; b=0lKBIMS/bZ6GlWzdA7FToieRu/ZFgkJyoRUXeLOJ6JR9OjOSpK1FeEcc77ym2AFgql CojgEl00X5GiHjpm7QpEB+UYbzfJzKZyBmu0mSivOc6QUZMfY+UvJ0M8dcaBoH+idGSu uUY7fOpngeKHW/42h0AmAUVVjaEWYkdBYn56K4BQQvos2joRJ8CFkj78+ogCAz1yVhAl iMlBGWWveAcXbxRYaLImkYvWZlaBt5OkzZ5TdUkjIrS57WTYG/1lAITaR99GHbg9Uzg7 ijyPSbdjTnkzXbplF2c6KthQCMdyCrOTEyn+KytSw057etYIgvoduwZhuRGv5c0y6Hys odQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@rothenpieler.org header.s=mail header.b="LXPIgC2/"; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ga34-20020a1709070c2200b00726bdd2e93csi8288189ejc.350.2022.07.08.15.55.46; Fri, 08 Jul 2022 15:55:46 -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=@rothenpieler.org header.s=mail header.b="LXPIgC2/"; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=rothenpieler.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A1CDC68B9C5; Sat, 9 Jul 2022 01:54:37 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from btbn.de (btbn.de [136.243.74.85]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id ED19B68B930 for ; Sat, 9 Jul 2022 01:54:27 +0300 (EEST) Received: from [authenticated] by btbn.de (Postfix) with ESMTPSA id 0CF49316FBB; Sat, 9 Jul 2022 00:54:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rothenpieler.org; s=mail; t=1657320862; bh=K8do0cGhmQcJ2E6b4FqPbw/k57wJYj4hUdDQ9kYIAWo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=LXPIgC2/qK6bY+MGDvOe1jVJDfXT7juH5Vp6N+jJtja0p/f/b2SQrIh5xwn6KJf0/ uwcwXNvWmPsG/0rKLZKPReu3pmDts7cXfvLKhpXy0U8QULWzv76PeMvhNTJMugcPSs 6IJJJ3/aI9tLl/KWtmKEwfWwvp4Jf4+XGaN46Pj+RYJ3rPdhjMq5SiHkTETvy5U2wU MPO0JkeS5U0qgiyNEdq5oP9XtngCTPFGonDq6gd7G4swZQqCTSvrzMQRuRo4Ulq/2l NdMPiJrQehYB8dyXxzzF/v4wIGoDXHBbLgITfwP7CK9rFZNSY31a3Yg/kTFLEg5Vr1 cE3MfB/4Vda8A== From: Timo Rothenpieler To: ffmpeg-devel@ffmpeg.org Date: Sat, 9 Jul 2022 00:54:04 +0200 Message-Id: <20220708225404.23748-9-timo@rothenpieler.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220708225404.23748-1-timo@rothenpieler.org> References: <20220708225404.23748-1-timo@rothenpieler.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 8/8] avfilter: add vsrc_ddagrab X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Timo Rothenpieler Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: yUImZBHEBWQx --- Changelog | 1 + configure | 7 + doc/filters.texi | 68 ++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vsrc_ddagrab.c | 980 +++++++++++++++++++++++++++++ libavfilter/vsrc_ddagrab_shaders.h | 120 ++++ 8 files changed, 1179 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vsrc_ddagrab.c create mode 100644 libavfilter/vsrc_ddagrab_shaders.h diff --git a/Changelog b/Changelog index 1a7c84b7f8..9467e92dd1 100644 --- a/Changelog +++ b/Changelog @@ -24,6 +24,7 @@ version 5.1: - VDPAU AV1 hwaccel - PHM image format support - remap_opencl filter +- ddagrab (Desktop Duplication) video source filter version 5.0: diff --git a/configure b/configure index 7d5c4900bf..5a1794ebdc 100755 --- a/configure +++ b/configure @@ -2309,6 +2309,7 @@ SYSTEM_FUNCS=" SetDllDirectory setmode setrlimit + SetThreadDpiAwarenessContext Sleep strerror_r sysconf @@ -2352,6 +2353,7 @@ TOOLCHAIN_FEATURES=" " TYPES_LIST=" + IDXGIOutput5 kCMVideoCodecType_HEVC kCMVideoCodecType_HEVCWithAlpha kCMVideoCodecType_VP9 @@ -3154,6 +3156,8 @@ overlay_cuda_filter_deps="ffnvcodec" overlay_cuda_filter_deps_any="cuda_nvcc cuda_llvm" sharpen_npp_filter_deps="ffnvcodec libnpp" +ddagrab_filter_deps="d3d11va IDXGIOutput1" + amf_deps_any="libdl LoadLibrary" nvenc_deps="ffnvcodec" nvenc_deps_any="libdl LoadLibrary" @@ -6389,10 +6393,13 @@ check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss check_type "windows.h dxva.h" "DXVA_PicParams_AV1" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 check_type "windows.h dxva.h" "DXVA_PicParams_HEVC" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 check_type "windows.h dxva.h" "DXVA_PicParams_VP9" -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_CRT_BUILD_DESKTOP_APP=0 +check_type "windows.h dxgi1_2.h" "IDXGIOutput1" +check_type "windows.h dxgi1_5.h" "IDXGIOutput5" check_type "windows.h d3d11.h" "ID3D11VideoDecoder" check_type "windows.h d3d11.h" "ID3D11VideoContext" check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602 check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat +check_func_headers windows.h SetThreadDpiAwarenessContext -D_WIN32_WINNT=0x0A00 check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC" check_type "vdpau/vdpau.h" "VdpPictureInfoVP9" diff --git a/doc/filters.texi b/doc/filters.texi index 296b0693ae..bb651112f6 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -26390,6 +26390,74 @@ need for a nullsrc video source. @end itemize +@section ddagrab + +Captures the Windows Desktop via Desktop Duplication API. + +The filter exclusively returns D3D11 Hardware Frames, for on-gpu encoding +or processing. So an explicit @ref{hwdownload} is needed for any kind of +software processing. + +It accepts the following options: + +@table @option +@item output_idx +DXGI Output Index to capture. + +Usually corresponds to the index Windows has given the screen minus one, +so it's starting at 0. + +Defaults to output 0. + +@item draw_mouse +Whether to draw the mouse cursor. + +Defaults to true. + +Only affects hardware cursors. If a game or application renders its own cursor, +it'll always be captured. + +@item framerate +Framerate at which the desktop will be captured. + +Defaults to 30 FPS. + +@item video_size +Specify the size of the captured video. + +Defaults to the full size of the screen. + +Cropped from the bottom/right if smaller than screen size. + +@item offset_x +Horizontal offset of the captured video. + +@item offset_y +Vertical offset of the captured video. + +@end table + +@subsection Examples + +Capture primary screen and encode using nvenc: +@example +ffmpeg -f lavfi -i ddagrab -c:v h264_nvenc -cq 18 output.mp4 +@end example + +You can also skip the lavfi device and directly use the filter. +Also demonstrates downloading the frame and encoding with libx264. +Explicit output format specification is required in this case: +@example +ffmpeg -filter_complex ddagrab=output_idx=1:framerate=60,hwdownload,format=bgra -c:v libx264 -crf 18 output.mp4 +@end example + +If you want to capture only a subsection of the desktop, this can be achieved +by specifying a smaller size and its offsets into the screen: +@example +ddagrab=video_size=800x600:offset_x=100:offset_y=100 +@end example + + @section gradients Generate several gradients. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 139f7cb751..e161196d87 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -555,6 +555,7 @@ OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_COLORCHART_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_COLORSPECTRUM_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_COREIMAGESRC_FILTER) += vf_coreimage.o +OBJS-$(CONFIG_DDAGRAB_FILTER) += vsrc_ddagrab.o OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o OBJS-$(CONFIG_GRADIENTS_FILTER) += vsrc_gradients.o OBJS-$(CONFIG_HALDCLUTSRC_FILTER) += vsrc_testsrc.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 3018850b4b..bd3d2c2d47 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -523,6 +523,7 @@ extern const AVFilter ff_vsrc_color; extern const AVFilter ff_vsrc_colorchart; extern const AVFilter ff_vsrc_colorspectrum; extern const AVFilter ff_vsrc_coreimagesrc; +extern const AVFilter ff_vsrc_ddagrab; extern const AVFilter ff_vsrc_frei0r_src; extern const AVFilter ff_vsrc_gradients; extern const AVFilter ff_vsrc_haldclutsrc; diff --git a/libavfilter/version.h b/libavfilter/version.h index 37f03b44a6..2f4f4c6c21 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #include "version_major.h" -#define LIBAVFILTER_VERSION_MINOR 42 +#define LIBAVFILTER_VERSION_MINOR 43 #define LIBAVFILTER_VERSION_MICRO 100 diff --git a/libavfilter/vsrc_ddagrab.c b/libavfilter/vsrc_ddagrab.c new file mode 100644 index 0000000000..fdcb7515ec --- /dev/null +++ b/libavfilter/vsrc_ddagrab.c @@ -0,0 +1,980 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0A00 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0A00 +#endif +#define WIN32_LEAN_AND_MEAN + +#include + +#define COBJMACROS + +#include +#include +#include +#if HAVE_IDXGIOUTPUT5 +#include +#endif + +#include "libavutil/opt.h" +#include "libavutil/time.h" +#include "libavutil/avstring.h" +#include "libavutil/avassert.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_d3d11va.h" +#include "avfilter.h" +#include "internal.h" +#include "formats.h" +#include "video.h" + +#include "vsrc_ddagrab_shaders.h" + +// avutil/time.h takes and returns time in microseconds +#define TIMER_RES 1000000 +#define TIMER_RES64 INT64_C(1000000) + +typedef struct DdagrabContext { + const AVClass *class; + + AVBufferRef *device_ref; + AVHWDeviceContext *device_ctx; + AVD3D11VADeviceContext *device_hwctx; + + AVBufferRef *frames_ref; + AVHWFramesContext *frames_ctx; + AVD3D11VAFramesContext *frames_hwctx; + + DXGI_OUTPUT_DESC output_desc; + IDXGIOutputDuplication *dxgi_outdupl; + AVFrame *last_frame; + + int mouse_x, mouse_y; + ID3D11Texture2D *mouse_texture; + ID3D11ShaderResourceView* mouse_resource_view ; + + AVRational time_base; + int64_t time_frame; + int64_t time_timeout; + int64_t first_pts; + + DXGI_FORMAT raw_format; + int raw_width; + int raw_height; + + ID3D11Texture2D *probed_texture; + + ID3D11VertexShader *vertex_shader; + ID3D11InputLayout *input_layout; + ID3D11PixelShader *pixel_shader; + ID3D11Buffer *const_buffer; + ID3D11SamplerState *sampler_state; + ID3D11BlendState *blend_state; + + int output_idx; + int draw_mouse; + AVRational framerate; + int width; + int height; + int offset_x; + int offset_y; +} DdagrabContext; + +#define OFFSET(x) offsetof(DdagrabContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +static const AVOption ddagrab_options[] = { + { "output_idx", "dda output index to capture", OFFSET(output_idx), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, + { "draw_mouse", "draw the mouse pointer", OFFSET(draw_mouse), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, + { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "30" }, 0, INT_MAX, FLAGS }, + { "video_size", "set video frame size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, FLAGS }, + { "offset_x", "capture area x offset", OFFSET(offset_x), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS }, + { "offset_y", "capture area y offset", OFFSET(offset_y), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(ddagrab); + +static inline void release_resource(void *resource) +{ + IUnknown **resp = (IUnknown**)resource; + if (*resp) { + IUnknown_Release(*resp); + *resp = NULL; + } +} + +static av_cold void ddagrab_uninit(AVFilterContext *avctx) +{ + DdagrabContext *dda = avctx->priv; + + release_resource(&dda->blend_state); + release_resource(&dda->sampler_state); + release_resource(&dda->pixel_shader); + release_resource(&dda->input_layout); + release_resource(&dda->vertex_shader); + release_resource(&dda->const_buffer); + + release_resource(&dda->probed_texture); + + release_resource(&dda->dxgi_outdupl); + release_resource(&dda->mouse_resource_view); + release_resource(&dda->mouse_texture); + + av_frame_free(&dda->last_frame); + av_buffer_unref(&dda->frames_ref); + av_buffer_unref(&dda->device_ref); +} + +static av_cold int init_dxgi_dda(AVFilterContext *avctx) +{ + DdagrabContext *dda = avctx->priv; + IDXGIDevice *dxgi_device = NULL; + IDXGIAdapter *dxgi_adapter = NULL; + IDXGIOutput *dxgi_output = NULL; + IDXGIOutput1 *dxgi_output1 = NULL; +#if HAVE_IDXGIOUTPUT5 && HAVE_SETTHREADDPIAWARENESSCONTEXT + IDXGIOutput5 *dxgi_output5 = NULL; +#endif + HRESULT hr; + + hr = ID3D11Device_QueryInterface(dda->device_hwctx->device, &IID_IDXGIDevice, (void**)&dxgi_device); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed querying IDXGIDevice\n"); + return AVERROR_EXTERNAL; + } + + hr = IDXGIDevice_GetParent(dxgi_device, &IID_IDXGIAdapter, (void**)&dxgi_adapter); + IDXGIDevice_Release(dxgi_device); + dxgi_device = NULL; + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed getting parent IDXGIAdapter\n"); + return AVERROR_EXTERNAL; + } + + hr = IDXGIAdapter_EnumOutputs(dxgi_adapter, dda->output_idx, &dxgi_output); + IDXGIAdapter_Release(dxgi_adapter); + dxgi_adapter = NULL; + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed to enumerate DXGI output %d\n", dda->output_idx); + return AVERROR_EXTERNAL; + } + + hr = IDXGIOutput_GetDesc(dxgi_output, &dda->output_desc); + if (FAILED(hr)) { + IDXGIOutput_Release(dxgi_output); + av_log(avctx, AV_LOG_ERROR, "Failed getting output description\n"); + return AVERROR_EXTERNAL; + } + +#if HAVE_IDXGIOUTPUT5 && HAVE_SETTHREADDPIAWARENESSCONTEXT + hr = IDXGIOutput_QueryInterface(dxgi_output, &IID_IDXGIOutput5, (void**)&dxgi_output5); + if (SUCCEEDED(hr)) { + DPI_AWARENESS_CONTEXT prev_dpi_ctx; + DXGI_FORMAT formats[] = { + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM + }; + + IDXGIOutput_Release(dxgi_output); + dxgi_output = NULL; + + prev_dpi_ctx = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + if (!prev_dpi_ctx) + av_log(avctx, AV_LOG_WARNING, "Failed enabling DPI awareness for DDA\n"); + + hr = IDXGIOutput5_DuplicateOutput1(dxgi_output5, + (IUnknown*)dda->device_hwctx->device, + 0, + FF_ARRAY_ELEMS(formats), + formats, + &dda->dxgi_outdupl); + IDXGIOutput5_Release(dxgi_output5); + dxgi_output5 = NULL; + + if (prev_dpi_ctx) + SetThreadDpiAwarenessContext(prev_dpi_ctx); + } else { + av_log(avctx, AV_LOG_DEBUG, "Falling back to IDXGIOutput1\n"); +#else + { +#endif + hr = IDXGIOutput_QueryInterface(dxgi_output, &IID_IDXGIOutput1, (void**)&dxgi_output1); + IDXGIOutput_Release(dxgi_output); + dxgi_output = NULL; + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed querying IDXGIOutput1\n"); + return AVERROR_EXTERNAL; + } + + hr = IDXGIOutput1_DuplicateOutput(dxgi_output1, + (IUnknown*)dda->device_hwctx->device, + &dda->dxgi_outdupl); + IDXGIOutput1_Release(dxgi_output1); + dxgi_output1 = NULL; + } + + if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { + av_log(avctx, AV_LOG_ERROR, "Too many open duplication sessions\n"); + return AVERROR(EBUSY); + } else if (hr == DXGI_ERROR_UNSUPPORTED) { + av_log(avctx, AV_LOG_ERROR, "Selected output not supported\n"); + return AVERROR_EXTERNAL; + } else if (hr == E_INVALIDARG) { + av_log(avctx, AV_LOG_ERROR, "Invalid output duplication argument\n"); + return AVERROR(EINVAL); + } else if (hr == E_ACCESSDENIED) { + av_log(avctx, AV_LOG_ERROR, "Desktop duplication access denied\n"); + return AVERROR(EPERM); + } else if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed duplicating output\n"); + return AVERROR_EXTERNAL; + } + + dda->raw_width = dda->output_desc.DesktopCoordinates.right - dda->output_desc.DesktopCoordinates.left; + dda->raw_height = dda->output_desc.DesktopCoordinates.bottom - dda->output_desc.DesktopCoordinates.top; + av_log(avctx, AV_LOG_VERBOSE, "Opened dxgi output %d with dimensions %dx%d\n", + dda->output_idx, dda->raw_width, dda->raw_height); + + return 0; +} + +typedef struct ConstBufferData +{ + float width; + float height; + + uint64_t padding; +} ConstBufferData; + +static const D3D11_INPUT_ELEMENT_DESC vertex_shader_input_layout[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } +}; + +static av_cold int init_render_resources(AVFilterContext *avctx) +{ + DdagrabContext *dda = avctx->priv; + ID3D11Device *dev = dda->device_hwctx->device; + D3D11_SAMPLER_DESC sampler_desc = { 0 }; + D3D11_BLEND_DESC blend_desc = { 0 }; + D3D11_BUFFER_DESC buffer_desc = { 0 }; + D3D11_SUBRESOURCE_DATA buffer_data = { 0 }; + ConstBufferData const_data = { 0 }; + HRESULT hr; + + hr = ID3D11Device_CreateVertexShader(dev, + vertex_shader_bytes, + FF_ARRAY_ELEMS(vertex_shader_bytes), + NULL, + &dda->vertex_shader); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateVertexShader failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + hr = ID3D11Device_CreateInputLayout(dev, + vertex_shader_input_layout, + FF_ARRAY_ELEMS(vertex_shader_input_layout), + vertex_shader_bytes, + FF_ARRAY_ELEMS(vertex_shader_bytes), + &dda->input_layout); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateInputLayout failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + hr = ID3D11Device_CreatePixelShader(dev, + pixel_shader_bytes, + FF_ARRAY_ELEMS(pixel_shader_bytes), + NULL, + &dda->pixel_shader); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreatePixelShader failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + const_data = (ConstBufferData){ dda->width, dda->height }; + + buffer_data.pSysMem = &const_data; + buffer_desc.ByteWidth = sizeof(const_data); + buffer_desc.Usage = D3D11_USAGE_IMMUTABLE; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + hr = ID3D11Device_CreateBuffer(dev, + &buffer_desc, + &buffer_data, + &dda->const_buffer); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateBuffer const buffer failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + hr = ID3D11Device_CreateSamplerState(dev, + &sampler_desc, + &dda->sampler_state); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateSamplerState failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + blend_desc.AlphaToCoverageEnable = FALSE; + blend_desc.IndependentBlendEnable = FALSE; + blend_desc.RenderTarget[0].BlendEnable = TRUE; + blend_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blend_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blend_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blend_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blend_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + hr = ID3D11Device_CreateBlendState(dev, + &blend_desc, + &dda->blend_state); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateBlendState failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + return 0; +} + +static av_cold int ddagrab_init(AVFilterContext *avctx) +{ + DdagrabContext *dda = avctx->priv; + int ret = 0; + + if (avctx->hw_device_ctx) { + dda->device_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data; + + if (dda->device_ctx->type != AV_HWDEVICE_TYPE_D3D11VA) { + av_log(avctx, AV_LOG_ERROR, "Non-D3D11VA input hw_device_ctx\n"); + return AVERROR(EINVAL); + } + + dda->device_ref = av_buffer_ref(avctx->hw_device_ctx); + if (!dda->device_ref) + return AVERROR(ENOMEM); + + av_log(avctx, AV_LOG_VERBOSE, "Using provided hw_device_ctx\n"); + } else { + ret = av_hwdevice_ctx_create(&dda->device_ref, AV_HWDEVICE_TYPE_D3D11VA, NULL, NULL, 0); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to create D3D11VA device.\n"); + return ret; + } + + dda->device_ctx = (AVHWDeviceContext*)dda->device_ref->data; + + av_log(avctx, AV_LOG_VERBOSE, "Created internal hw_device_ctx\n"); + } + + dda->device_hwctx = (AVD3D11VADeviceContext*)dda->device_ctx->hwctx; + + ret = init_dxgi_dda(avctx); + if (ret < 0) + goto fail; + + if (dda->width <= 0) + dda->width = dda->raw_width; + if (dda->height <= 0) + dda->height = dda->raw_height; + + dda->width -= FFMAX(dda->width - dda->raw_width + dda->offset_x, 0); + dda->height -= FFMAX(dda->height - dda->raw_height + dda->offset_y, 0); + + dda->time_base = av_inv_q(dda->framerate); + dda->time_frame = av_gettime_relative() / av_q2d(dda->time_base); + dda->time_timeout = av_rescale_q(1, dda->time_base, (AVRational) { 1, 1000 }) / 2; + + dda->last_frame = av_frame_alloc(); + if (!dda->last_frame) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dda->mouse_x = -1; + dda->mouse_y = -1; + + if (dda->draw_mouse) { + ret = init_render_resources(avctx); + if (ret < 0) + goto fail; + } + + return 0; +fail: + ddagrab_uninit(avctx); + return ret; +} + +static int create_d3d11_pointer_tex(AVFilterContext *avctx, + uint8_t *buf, + DXGI_OUTDUPL_POINTER_SHAPE_INFO *shape_info, + ID3D11Texture2D **out_tex, + ID3D11ShaderResourceView **res_view) +{ + DdagrabContext *dda = avctx->priv; + D3D11_TEXTURE2D_DESC desc = { 0 }; + D3D11_SUBRESOURCE_DATA init_data = { 0 }; + D3D11_SHADER_RESOURCE_VIEW_DESC resource_desc = { 0 }; + HRESULT hr; + + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + desc.Width = shape_info->Width; + desc.Height = shape_info->Height; + + init_data.pSysMem = buf; + init_data.SysMemPitch = shape_info->Pitch; + + resource_desc.Format = desc.Format; + resource_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + resource_desc.Texture2D.MostDetailedMip = 0; + resource_desc.Texture2D.MipLevels = 1; + + hr = ID3D11Device_CreateTexture2D(dda->device_hwctx->device, + &desc, + &init_data, + out_tex); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "Failed creating pointer texture\n"); + return AVERROR_EXTERNAL; + } + + hr = ID3D11Device_CreateShaderResourceView(dda->device_hwctx->device, + (ID3D11Resource*)dda->mouse_texture, + &resource_desc, + res_view); + if (FAILED(hr)) { + release_resource(out_tex); + av_log(avctx, AV_LOG_ERROR, "CreateShaderResourceView for mouse failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + return 0; +} + +static uint8_t *convert_mono_buffer(uint8_t *input, int *_width, int *_height, int *_pitch) +{ + int width = *_width, height = *_height, pitch = *_pitch; + int real_height = height / 2; + uint8_t *output = av_malloc(real_height * width * 4); + int y, x; + + if (!output) + return NULL; + + // This simulates drawing the cursor on a full black surface + // i.e. ignore the AND mask, turn XOR mask into all 4 color channels + for (y = 0; y < real_height; y++) { + for (x = 0; x < width; x++) { + int v = input[(real_height + y) * pitch + (x / 8)]; + v = (v >> (7 - (x % 8))) & 1; + memset(&output[4 * ((y*width) + x)], v ? 0xFF : 0, 4); + } + } + + *_pitch = width * 4; + *_height = real_height; + + return output; +} + +static void fixup_color_mask(uint8_t *buf, int width, int height, int pitch) +{ + int x, y; + // There is no good way to replicate XOR'ig parts of the texture with the screen + // best effort is rendering the non-masked parts, and make the rest transparent + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int pos = (y*pitch) + (4*x) + 3; + buf[pos] = buf[pos] ? 0 : 0xFF; + } + } +} + +static int update_mouse_pointer(AVFilterContext *avctx, DXGI_OUTDUPL_FRAME_INFO *frame_info) +{ + DdagrabContext *dda = avctx->priv; + HRESULT hr; + int ret; + + if (frame_info->LastMouseUpdateTime.QuadPart == 0) + return 0; + + if (frame_info->PointerPosition.Visible) { + dda->mouse_x = frame_info->PointerPosition.Position.x; + dda->mouse_y = frame_info->PointerPosition.Position.y; + } else { + dda->mouse_x = dda->mouse_y = -1; + } + + if (frame_info->PointerShapeBufferSize) { + UINT size = frame_info->PointerShapeBufferSize; + DXGI_OUTDUPL_POINTER_SHAPE_INFO shape_info; + uint8_t *buf = av_malloc(size); + if (!buf) + return AVERROR(ENOMEM); + + hr = IDXGIOutputDuplication_GetFramePointerShape(dda->dxgi_outdupl, + size, + buf, + &size, + &shape_info); + if (FAILED(hr)) { + av_free(buf); + av_log(avctx, AV_LOG_ERROR, "Failed getting pointer shape: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + if (shape_info.Type == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME) { + uint8_t *new_buf = convert_mono_buffer(buf, &shape_info.Width, &shape_info.Height, &shape_info.Pitch); + av_free(buf); + if (!new_buf) + return AVERROR(ENOMEM); + buf = new_buf; + } else if (shape_info.Type == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR) { + fixup_color_mask(buf, shape_info.Width, shape_info.Height, shape_info.Pitch); + } else if (shape_info.Type != DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR) { + av_log(avctx, AV_LOG_WARNING, "Unsupported pointer shape type: %d\n", (int)shape_info.Type); + av_free(buf); + return 0; + } + + release_resource(&dda->mouse_resource_view); + release_resource(&dda->mouse_texture); + + ret = create_d3d11_pointer_tex(avctx, buf, &shape_info, &dda->mouse_texture, &dda->mouse_resource_view); + av_freep(&buf); + if (ret < 0) + return ret; + + av_log(avctx, AV_LOG_VERBOSE, "Updated pointer shape texture\n"); + } + + return 0; +} + +static int next_frame_internal(AVFilterContext *avctx, ID3D11Texture2D **desktop_texture) +{ + DXGI_OUTDUPL_FRAME_INFO frame_info; + DdagrabContext *dda = avctx->priv; + IDXGIResource *desktop_resource = NULL; + HRESULT hr; + int ret; + + hr = IDXGIOutputDuplication_AcquireNextFrame( + dda->dxgi_outdupl, + dda->time_timeout, + &frame_info, + &desktop_resource); + if (hr == DXGI_ERROR_WAIT_TIMEOUT) { + return AVERROR(EAGAIN); + } else if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "AcquireNextFrame failed: %lx\n", hr); + return AVERROR_EXTERNAL; + } + + if (dda->draw_mouse) { + ret = update_mouse_pointer(avctx, &frame_info); + if (ret < 0) + return ret; + } + + hr = IDXGIResource_QueryInterface(desktop_resource, &IID_ID3D11Texture2D, (void**)desktop_texture); + IDXGIResource_Release(desktop_resource); + desktop_resource = NULL; + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "DXGIResource QueryInterface failed\n"); + return AVERROR_EXTERNAL; + } + + return 0; +} + +static int probe_output_format(AVFilterContext *avctx) +{ + DdagrabContext *dda = avctx->priv; + D3D11_TEXTURE2D_DESC desc; + int ret; + + av_assert1(!dda->probed_texture); + + do { + ret = next_frame_internal(avctx, &dda->probed_texture); + } while(ret == AVERROR(EAGAIN)); + if (ret < 0) + return ret; + + ID3D11Texture2D_GetDesc(dda->probed_texture, &desc); + + dda->raw_format = desc.Format; + + return 0; +} + +static av_cold int init_hwframes_ctx(AVFilterContext *avctx) +{ + DdagrabContext *dda = avctx->priv; + int ret = 0; + + dda->frames_ref = av_hwframe_ctx_alloc(dda->device_ref); + if (!dda->frames_ref) + return AVERROR(ENOMEM); + dda->frames_ctx = (AVHWFramesContext*)dda->frames_ref->data; + dda->frames_hwctx = (AVD3D11VAFramesContext*)dda->frames_ctx->hwctx; + + dda->frames_ctx->format = AV_PIX_FMT_D3D11; + dda->frames_ctx->width = dda->width; + dda->frames_ctx->height = dda->height; + + switch (dda->raw_format) { + case DXGI_FORMAT_B8G8R8A8_UNORM: + av_log(avctx, AV_LOG_VERBOSE, "Probed 8 bit RGB frame format\n"); + dda->frames_ctx->sw_format = AV_PIX_FMT_BGRA; + break; + case DXGI_FORMAT_R10G10B10A2_UNORM: + av_log(avctx, AV_LOG_VERBOSE, "Probed 10 bit RGB frame format\n"); + dda->frames_ctx->sw_format = AV_PIX_FMT_X2BGR10; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unexpected texture output format!\n"); + return AVERROR_BUG; + } + + if (dda->draw_mouse) + dda->frames_hwctx->BindFlags |= D3D11_BIND_RENDER_TARGET; + + ret = av_hwframe_ctx_init(dda->frames_ref); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialise hardware frames context: %d.\n", ret); + goto fail; + } + + return 0; +fail: + av_buffer_unref(&dda->frames_ref); + return ret; +} + +static int ddagrab_config_props(AVFilterLink *outlink) +{ + AVFilterContext *avctx = outlink->src; + DdagrabContext *dda = avctx->priv; + int ret; + + outlink->w = dda->width; + outlink->h = dda->height; + outlink->time_base = (AVRational){1, TIMER_RES}; + outlink->frame_rate = dda->framerate; + + ret = probe_output_format(avctx); + if (ret < 0) + return ret; + + ret = init_hwframes_ctx(avctx); + if (ret < 0) + return ret; + + outlink->hw_frames_ctx = av_buffer_ref(dda->frames_ref); + if (!outlink->hw_frames_ctx) + return AVERROR(ENOMEM); + + return 0; +} + +static int draw_mouse_pointer(AVFilterContext *avctx, AVFrame *frame) +{ + DdagrabContext *dda = avctx->priv; + ID3D11DeviceContext *devctx = dda->device_hwctx->device_context; + ID3D11Texture2D *frame_tex = (ID3D11Texture2D*)frame->data[0]; + D3D11_RENDER_TARGET_VIEW_DESC target_desc = { 0 }; + ID3D11RenderTargetView* target_view = NULL; + ID3D11Buffer *mouse_vertex_buffer = NULL; + D3D11_TEXTURE2D_DESC tex_desc; + int num_vertices = 0; + int x, y; + HRESULT hr; + int ret = 0; + + if (!dda->mouse_texture || dda->mouse_x < 0 || dda->mouse_y < 0) + return 0; + + ID3D11Texture2D_GetDesc(dda->mouse_texture, &tex_desc); + + x = dda->mouse_x - dda->offset_x; + y = dda->mouse_y - dda->offset_y; + + if (x >= dda->width || y >= dda->height || + -x >= (int)tex_desc.Width || -y >= (int)tex_desc.Height) + return 0; + + target_desc.Format = dda->raw_format; + target_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + target_desc.Texture2D.MipSlice = 0; + + hr = ID3D11Device_CreateRenderTargetView(dda->device_hwctx->device, + (ID3D11Resource*)frame_tex, + &target_desc, + &target_view); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateRenderTargetView failed: %lx\n", hr); + ret = AVERROR_EXTERNAL; + goto end; + } + + ID3D11DeviceContext_ClearState(devctx); + + { + D3D11_VIEWPORT viewport = { 0 }; + viewport.Width = dda->width; + viewport.Height = dda->height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + ID3D11DeviceContext_RSSetViewports(devctx, 1, &viewport); + } + + { + FLOAT vertices[] = { + // x, y, z, u, v + x , y + tex_desc.Height, 0.0f, 0.0f, 1.0f, + x , y , 0.0f, 0.0f, 0.0f, + x + tex_desc.Width, y + tex_desc.Height, 0.0f, 1.0f, 1.0f, + x + tex_desc.Width, y , 0.0f, 1.0f, 0.0f, + }; + UINT stride = sizeof(FLOAT) * 5; + UINT offset = 0; + + D3D11_SUBRESOURCE_DATA init_data = { 0 }; + D3D11_BUFFER_DESC buf_desc = { 0 }; + + num_vertices = sizeof(vertices) / (sizeof(FLOAT) * 5); + + buf_desc.Usage = D3D11_USAGE_DEFAULT; + buf_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + buf_desc.ByteWidth = sizeof(vertices); + init_data.pSysMem = vertices; + + hr = ID3D11Device_CreateBuffer(dda->device_hwctx->device, + &buf_desc, + &init_data, + &mouse_vertex_buffer); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "CreateBuffer failed: %lx\n", hr); + ret = AVERROR_EXTERNAL; + goto end; + } + + ID3D11DeviceContext_IASetVertexBuffers(devctx, 0, 1, &mouse_vertex_buffer, &stride, &offset); + ID3D11DeviceContext_IASetInputLayout(devctx, dda->input_layout); + ID3D11DeviceContext_IASetPrimitiveTopology(devctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + } + + ID3D11DeviceContext_VSSetShader(devctx, dda->vertex_shader, NULL, 0); + ID3D11DeviceContext_VSSetConstantBuffers(devctx, 0, 1, &dda->const_buffer); + ID3D11DeviceContext_PSSetSamplers(devctx, 0, 1, &dda->sampler_state); + ID3D11DeviceContext_PSSetShaderResources(devctx, 0, 1, &dda->mouse_resource_view); + ID3D11DeviceContext_PSSetShader(devctx, dda->pixel_shader, NULL, 0); + + ID3D11DeviceContext_OMSetBlendState(devctx, dda->blend_state, NULL, 0xFFFFFFFF); + ID3D11DeviceContext_OMSetRenderTargets(devctx, 1, &target_view, NULL); + + ID3D11DeviceContext_Draw(devctx, num_vertices, 0); + +end: + release_resource(&mouse_vertex_buffer); + release_resource(&target_view); + + return ret; +} + +static int ddagrab_request_frame(AVFilterLink *outlink) +{ + AVFilterContext *avctx = outlink->src; + DdagrabContext *dda = avctx->priv; + + ID3D11Texture2D *cur_texture = NULL; + D3D11_TEXTURE2D_DESC desc = { 0 }; + D3D11_BOX box = { 0 }; + + int64_t time_frame = dda->time_frame; + int64_t now, delay; + AVFrame *frame = NULL; + HRESULT hr; + int ret; + + /* time_frame is in units of microseconds divided by the time_base. + * This means that adding a clean 1M to it is the equivalent of adding + * 1M*time_base microseconds to it, except it avoids all rounding error. + * The only time rounding error occurs is when multiplying to calculate + * the delay. So any rounding error there corrects itself over time. + */ + time_frame += TIMER_RES64; + for (;;) { + now = av_gettime_relative(); + delay = time_frame * av_q2d(dda->time_base) - now; + if (delay <= 0) { + if (delay < -TIMER_RES64 * av_q2d(dda->time_base)) { + time_frame += TIMER_RES64; + } + break; + } + av_usleep(delay); + } + + if (!dda->first_pts) + dda->first_pts = now; + now -= dda->first_pts; + + if (!dda->probed_texture) { + ret = next_frame_internal(avctx, &cur_texture); + } else { + cur_texture = dda->probed_texture; + dda->probed_texture = NULL; + ret = 0; + } + + if (ret == AVERROR(EAGAIN) && dda->last_frame->buf[0]) { + frame = av_frame_alloc(); + if (!frame) + return AVERROR(ENOMEM); + + ret = av_frame_ref(frame, dda->last_frame); + if (ret < 0) { + av_frame_free(&frame); + return ret; + } + + av_log(avctx, AV_LOG_DEBUG, "Duplicated output frame\n"); + + goto frame_done; + } else if (ret == AVERROR(EAGAIN)) { + av_log(avctx, AV_LOG_VERBOSE, "Initial DDA AcquireNextFrame timeout!\n"); + return AVERROR(EAGAIN); + } else if (ret < 0) { + return ret; + } + + // AcquireNextFrame sometimes has bursts of delay. + // This increases accuracy of the timestamp, but might upset consumers due to more jittery framerate? + now = av_gettime_relative() - dda->first_pts; + + ID3D11Texture2D_GetDesc(cur_texture, &desc); + if (desc.Format != dda->raw_format || + (int)desc.Width != dda->raw_width || + (int)desc.Height != dda->raw_height) { + av_log(avctx, AV_LOG_ERROR, "Output parameters changed!"); + ret = AVERROR_OUTPUT_CHANGED; + goto fail; + } + + frame = ff_get_video_buffer(outlink, dda->width, dda->height); + if (!frame) { + ret = AVERROR(ENOMEM); + goto fail; + } + + box.left = dda->offset_x; + box.top = dda->offset_y; + box.right = box.left + dda->width; + box.bottom = box.top + dda->height; + box.front = 0; + box.back = 1; + + ID3D11DeviceContext_CopySubresourceRegion( + dda->device_hwctx->device_context, + (ID3D11Resource*)frame->data[0], (UINT)(intptr_t)frame->data[1], + 0, 0, 0, + (ID3D11Resource*)cur_texture, 0, + &box); + + release_resource(&cur_texture); + + hr = IDXGIOutputDuplication_ReleaseFrame(dda->dxgi_outdupl); + if (FAILED(hr)) { + av_log(avctx, AV_LOG_ERROR, "DDA ReleaseFrame failed!\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + if (dda->draw_mouse) { + ret = draw_mouse_pointer(avctx, frame); + if (ret < 0) + goto fail; + } + + frame->sample_aspect_ratio = (AVRational){1, 1}; + + av_frame_unref(dda->last_frame); + ret = av_frame_ref(dda->last_frame, frame); + if (ret < 0) + return ret; + +frame_done: + frame->pts = now; + dda->time_frame = time_frame; + + return ff_filter_frame(outlink, frame); + +fail: + if (frame) + av_frame_free(&frame); + + if (cur_texture) + IDXGIOutputDuplication_ReleaseFrame(dda->dxgi_outdupl); + + release_resource(&cur_texture); + return ret; +} + +static const AVFilterPad ddagrab_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = ddagrab_request_frame, + .config_props = ddagrab_config_props, + }, +}; + +const AVFilter ff_vsrc_ddagrab = { + .name = "ddagrab", + .description = NULL_IF_CONFIG_SMALL("Grab Windows Desktop images using Desktop Duplication API"), + .priv_size = sizeof(DdagrabContext), + .priv_class = &ddagrab_class, + .init = ddagrab_init, + .uninit = ddagrab_uninit, + .inputs = NULL, + FILTER_OUTPUTS(ddagrab_outputs), + FILTER_SINGLE_PIXFMT(AV_PIX_FMT_D3D11), + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, +}; diff --git a/libavfilter/vsrc_ddagrab_shaders.h b/libavfilter/vsrc_ddagrab_shaders.h new file mode 100644 index 0000000000..0305f8de1c --- /dev/null +++ b/libavfilter/vsrc_ddagrab_shaders.h @@ -0,0 +1,120 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_VSRC_DDAGRAB_SHADERS_H +#define AVFILTER_VSRC_DDAGRAB_SHADERS_H + +#if 0 + +cbuffer PARAMS : register ( b0 ) +{ + float2 Dimensions; +}; + +struct VS_INPUT +{ + float3 Pos : POSITION; + float2 Tex : TEXCOORD; +}; + +struct VS_OUTPUT +{ + float4 Pos : SV_POSITION; + float2 Tex : TEXCOORD; +}; + +VS_OUTPUT VS(VS_INPUT input) +{ + VS_OUTPUT output; + float2 center = Dimensions / 2; + output.Pos = float4((input.Pos.xy - center) / center, input.Pos.z, 1.0f); + output.Pos.y *= -1; + output.Tex = input.Tex; + return output; +} + +Texture2D tx : register( t0 ); +SamplerState samLinear : register( s0 ); + +float4 PS(VS_OUTPUT input) : SV_Target +{ + return tx.Sample(samLinear, input.Tex); +} + +#endif + +static const uint8_t vertex_shader_bytes[] = +{ + 68, 88, 66, 67, 207, 194, 142, 193, 255, 85, 32, 72, 116, 77, 242, 140, 26, 229, 67, 69, 1, 0, 0, 0, + 40, 3, 0, 0, 4, 0, 0, 0, 48, 0, 0, 0, 56, 1, 0, 0, 124, 2, 0, 0, 208, 2, 0, 0, + 65, 111, 110, 57, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 254, 255, 204, 0, 0, 0, 52, 0, 0, 0, + 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 81, 0, 0, 5, 2, 0, 15, 160, + 0, 0, 0, 63, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, + 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 1, 0, 0, 2, 0, 0, 1, 128, + 2, 0, 0, 160, 4, 0, 0, 4, 0, 0, 6, 128, 1, 0, 208, 160, 0, 0, 0, 129, 0, 0, 208, 144, + 5, 0, 0, 3, 0, 0, 9, 128, 0, 0, 0, 128, 1, 0, 100, 160, 6, 0, 0, 2, 1, 0, 1, 128, + 0, 0, 0, 128, 6, 0, 0, 2, 1, 0, 2, 128, 0, 0, 255, 128, 5, 0, 0, 3, 0, 0, 3, 128, + 0, 0, 233, 128, 1, 0, 228, 128, 1, 0, 0, 2, 0, 0, 4, 128, 0, 0, 85, 129, 2, 0, 0, 3, + 0, 0, 3, 192, 0, 0, 232, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 12, 192, 0, 0, 170, 144, + 2, 0, 148, 160, 2, 0, 100, 160, 1, 0, 0, 2, 0, 0, 3, 224, 1, 0, 228, 144, 255, 255, 0, 0, + 83, 72, 68, 82, 60, 1, 0, 0, 64, 0, 1, 0, 79, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 3, 114, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, + 50, 16, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 50, 32, 16, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 56, 0, 0, 11, + 50, 0, 16, 0, 0, 0, 0, 0, 70, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 14, 194, 0, 16, 0, + 0, 0, 0, 0, 6, 132, 32, 128, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 6, 20, 16, 0, 0, 0, 0, 0, + 14, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, + 66, 32, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, + 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 50, 32, 16, 0, 1, 0, 0, 0, + 70, 16, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 73, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 7, 7, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, + 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 12, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171 +}; + +static const uint8_t pixel_shader_bytes[] = +{ + 68, 88, 66, 67, 0, 95, 83, 169, 90, 60, 208, 75, 219, 179, 108, 203, 8, 232, 255, 27, 1, 0, 0, 0, + 148, 1, 0, 0, 4, 0, 0, 0, 48, 0, 0, 0, 156, 0, 0, 0, 8, 1, 0, 0, 96, 1, 0, 0, + 65, 111, 110, 57, 100, 0, 0, 0, 100, 0, 0, 0, 0, 2, 255, 255, 60, 0, 0, 0, 40, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, + 0, 2, 255, 255, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 1, 0, 0, 2, + 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 100, 0, 0, 0, 64, 0, 0, 0, + 25, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171 +}; + +#endif