From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 2FD2742FA1 for ; Sun, 12 Feb 2023 08:49:07 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 58EAB68BD90; Sun, 12 Feb 2023 10:49:05 +0200 (EET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 19CF0680CEB for ; Sun, 12 Feb 2023 10:48:56 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676191742; x=1707727742; h=from:to:subject:date:message-id:references:in-reply-to: content-id:content-transfer-encoding:mime-version; bh=prn/N2AOBagk4tN6RGsuKNN9LsqYvKYgaxHgpgQGo/E=; b=PjsR945eRFIIu+1EjE7CoF8bNafSrf9Aw0eY0004MgbGtSv3LsIiQHN0 fWJZLra9yXkyKYHTvFGtRsgvPdtMwArfvnhX7EifOfCy0HVlceEnoctxj gsXMik5Q1lXrW2UgfxH4FsO78s1e6MoaFe1zH39wCdoPKr75X/d6WMLlV meoYlusgzwN7MRwkr8Una9z4pUP+Kar/TVe6JgJsjWwNkrUwS3oM0aAUp 7+5WIS3uwW7SB6ZTw0xgzT3j1n3mOXExKVG6kXhmsVJLAIEERkns6B2Md xASkLzwDvWZzYcOJ7aiANY8itqe0vwQ2Wz/5PYFI32pJ1s2Lceq/PGt/r Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10618"; a="330711861" X-IronPort-AV: E=Sophos;i="5.97,291,1669104000"; d="scan'208";a="330711861" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Feb 2023 00:48:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10618"; a="698862554" X-IronPort-AV: E=Sophos;i="5.97,291,1669104000"; d="scan'208";a="698862554" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by orsmga008.jf.intel.com with ESMTP; 12 Feb 2023 00:48:54 -0800 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Sun, 12 Feb 2023 00:48:53 -0800 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16 via Frontend Transport; Sun, 12 Feb 2023 00:48:53 -0800 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (104.47.58.100) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.16; Sun, 12 Feb 2023 00:48:53 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CVYOiKwLbPw1QnVghMEAKipmlMV4+vCMKG7m4evoJL/rKKavZ9HUKHHl7GvaFogVwQMC1cWrnOFC5tcMfDT4RNbM3L6Q7hy+0qMmxe6TDJtZgFHBcvHSZwhCIO7xEOAdc6qjySuknkuMM5WbkQcTUYOukto+WcKjLC5zxnFNGbGQvRknFImYch1loHB9HT0xMWtR3hiClq1t+2LkQSrxFfflfdVLeqFxAO8vheP7fOoIx8fti2Yj5XESYGpRO6sA4b8mibW1l0q9ViHIAZEBU+rYb5QoSs0ilkm9xIHV2I44MlmKU6/RPfksdhd1HoJzgtUfqclRx7/v1heyw571vQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=prn/N2AOBagk4tN6RGsuKNN9LsqYvKYgaxHgpgQGo/E=; b=BMfIT3i3zUnbMu77MiQvEiumW+W2LHQxBamC+RtvBD3sd6krr4dEM9fnH88Fb/Aij+BpQufx8E1uWzYbx0R/r83Xd8BigEtEl0R1rJxOn/fAHp2ODYGetUmKZeQfPAfgYAalVbilg/dKHAwn+nZY0pNsEhj+uWQiRMJs2Sdh8qmAFHd/OyD8nPwmUm75BH54h6Urbz03uMNUQ56SGAw6sW452AtWp+tDMJNi9J/uHY8vo/wsUo1yTpYCTPXIcDlF6Xyx305dmfU7lseEEWQfSXqWn1RTRFPoNN6ES3LTGf4ACqBq6oVQDrCjL7yeMkx35Q0mkQ3nT4i72tQZBpWqCQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from BN9PR11MB5515.namprd11.prod.outlook.com (2603:10b6:408:104::8) by PH0PR11MB5807.namprd11.prod.outlook.com (2603:10b6:510:140::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6086.21; Sun, 12 Feb 2023 08:48:50 +0000 Received: from BN9PR11MB5515.namprd11.prod.outlook.com ([fe80::36ba:13c8:6a29:c7af]) by BN9PR11MB5515.namprd11.prod.outlook.com ([fe80::36ba:13c8:6a29:c7af%9]) with mapi id 15.20.6086.022; Sun, 12 Feb 2023 08:48:50 +0000 From: "Xiang, Haihao" To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [FFmpeg-devel][PATCH 1/2] lavfi/vf_stack_vaapi: factor out the common code for stack setting Thread-Index: AQHZOqiWnJ2qu0fGd0K54jtoQR3nOq7LCFMA Date: Sun, 12 Feb 2023 08:48:50 +0000 Message-ID: <32e92861e0a118be98b772cbe1f06650e4c5dd47.camel@intel.com> References: <20230207035907.975340-1-haihao.xiang@intel.com> In-Reply-To: <20230207035907.975340-1-haihao.xiang@intel.com> Accept-Language: en-AS, zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Evolution 3.36.5-0ubuntu1 authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: BN9PR11MB5515:EE_|PH0PR11MB5807:EE_ x-ms-office365-filtering-correlation-id: 8b9e7141-2a07-4df5-aa1d-08db0cd5f68e x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: fR5LKLySIjoZ4SiVy060TAr1m1LgY4WHBpKnwMBMuJEb7DPLqd5v1IJ9mv39TFDGTLDIK+eycnuUpmdGMcL1GnnnIQd47BqKcgYS+s6rzXmh67NRjdIZlbmK8CUziA/agyW5cQO7I9JZSNrNBQWz7M6kDnKRyu/Hza+0A4UL/gZOxuQ7yUSoFLhazh+vFw1/Pynnv6PIoRBLaGle18soYsQAsyZdfqhbfEmevWFwOfb63OgNLTv4X4s+soy/Vs28yQA1M1OIzJCwF53I+RbT3jRBemsmcA541+Dwv1OM+v/kORrD7+BUkyv/kC3/JegF44Vjn/Ilyo3lW+NyNBpDqrWcJFxAffIDVbi53GwH/pr/LexKLFWiEo5gCcGv6zgpbZ9bzxOGBCOJE+QJOOB0s6zpMbUfzB0PQeiUv9Pqz1/AlwvThO2rWGC+A+Jw66jqKytD84kYMo2Td/5HHXfnDDit0Ezua5uSsW7zyclA0324cBcBqUbGCFnbaQIaMw5IrgIZp2TfikYYrz7D0Pimgc/R3Grg65ERj0RXUc7n0Z2kjtz+5Pj9Zb+d6euTV48Ga9OCY94cZGPBc9MRctScMcStR/mPKbdtbaDa1x6qN/3lYfIOBsIzJxJdBO/WvCJ9kVqt4iWDtu0JCFBj3ax819hhQ3YtQflsjidwQCxrciO9iD2JEl+8LZq27XD4DBmMwie7EDpaTi9eFo0jcUtZOFPTb6Lx4H8/IC3RTjAuGho= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BN9PR11MB5515.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230025)(396003)(346002)(39860400002)(366004)(136003)(376002)(451199018)(2906002)(6486002)(478600001)(36756003)(71200400001)(316002)(122000001)(38070700005)(86362001)(8936002)(38100700002)(82960400001)(5660300002)(2616005)(83380400001)(6506007)(26005)(6512007)(186003)(91956017)(76116006)(41300700001)(66446008)(66946007)(8676002)(66556008)(66476007)(64756008)(30864003)(6916009)(2004002)(579004)(559001); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?utf-8?B?YzRCWmhjN0RvTkQ0ckxic1ZhdW95bGhveGxSRlR0bldMUkNRREFBQWxJYnFF?= =?utf-8?B?czhBNFJnTG9jQzRYMERyemRaMERmRGVGeXBQQWVEanZNMUN4QndQbjhtOEhU?= =?utf-8?B?VWR0Ri84OC9WamlVVndicGJtZG5mQkUrYVhtUlNEOWJzQ2FGZmR0OWZTdE5n?= =?utf-8?B?QkJoKzZNcmN6b1A4YldDQ0VnTkxCekZ3ZWdwczlXODAzYXhZTVFtR3dkK29n?= =?utf-8?B?Zkw3K2Y5R2JrVHMxdW40NFRBOE4xb2tJNm5uSmNWRkRCSElWY1g5UDdXRXdQ?= =?utf-8?B?eXp5Tm9zRWVyejhuMUhKc2lJZWVUQmVLdHZrVkFzdHozcjJNZTBmaWhPcXYw?= =?utf-8?B?SHY5c1p6SDdBU2k0T2duTXJPeE5acldVbkxjeXRxcHZlSnZwd3BZWlAza1I1?= =?utf-8?B?VmpqNlExYUlNUmpoaDZmaHRVNm1EMXBNN3E5RXc4MDRqbUpxM3NCSUh4WG9O?= =?utf-8?B?cGNMME9lSGNkVldNbXhwRFg2cmtlWldaUU9McWFDcW83WlQ4aEpBb0hUdGcw?= =?utf-8?B?WmYvQVMzME1BRlRheUVKekFIWUdWcHN2YW9iRVArZTRmWHdoOWwrRGlEN0Jl?= =?utf-8?B?dHo5Z01qSWFMMm04UmxPV2xHWmZucXZKenQvSkhRa25INHRtNEZsN2xGTEFG?= =?utf-8?B?S21scVFiamIwUlE2amtZOERrSis0dVN6ZTY1M0s1ajVsbDVMaWdiby9ncXR3?= =?utf-8?B?cHJ0VlFaRlNIa0ZXV0xjejV0OXpVU1QyRDg3TENTODhyRzVROG9KSnpFamFK?= =?utf-8?B?MEdMWTViTUVtaEdtdmFaV3FOeVMyK0QvRER2Vm1hbGJDQVZCKzlaOUpyZ3lO?= =?utf-8?B?SmFONUtXQVUrV1VQRXJIMHl3OXZMd1VHSmw2dFRDWnZ4K3h1TWp2UG1TWEYr?= =?utf-8?B?dG9saHMwaHZMb2d4ZHNKOGJjd1V2bFk3MFIzcE1KbG4yaFc0Vkl3NWdLdWY2?= =?utf-8?B?MHJyckdwcGdOSGtMUnhkNGs2ZUlIN2J3ak9jclYvTXFYUmtwNG54bmlMeEhP?= =?utf-8?B?N1NaWDBkT0hKNFltbVRDUytORzdiL2ozY20vZy9DOUwwM2ZYdG1vZU02VVV2?= =?utf-8?B?M3VscFZyT296RVhBTGYrRzllenV1T2N1eHUwZk54c2tqakJGOHFBVXo2Rysw?= =?utf-8?B?enBRREJ2TzVKQTRrTlNxenM4Q2VkRmFyV01qNjdZZDhsM081VUZkT3BQdUgw?= =?utf-8?B?U1UyTldpUnlSb3g3RFFabklpbXY3bWlTL0ZWTklQMXA1YnY1b3BPTlYxZHlQ?= =?utf-8?B?eEplMkpWbERNNnBueWhScUtubElJUmNRY2pnYURqSlhRSUJFOENWa04rQ2dS?= =?utf-8?B?Y1hyWll3TWgzdU04ZjRLV0dCZm5vZE12OUxERFp2U0ZLbWRWWHc3MHB2WEZy?= =?utf-8?B?Zi9zTElFVkRyaTBwSFVZM09xS2xpWU9hSVg4TmVqRzAvS1VpTWJQUHRVY0s1?= =?utf-8?B?K1h5VndDKzAxWDFXSW9YbjNtcjZRa29namhiYWxXbmErOFBjK2d2eU1PMEhN?= =?utf-8?B?c01pVW5TVmVKdUtMY294TjhqM1h3QmViMy9sZGdFY1pQNVcraExVSUtkOW5Y?= =?utf-8?B?MHY0Z2VmeHdUK2tLdHA2Q00xaE1IekRneWp3SFJCM1BDVzlHbDkzTjgrY2pF?= =?utf-8?B?Tmc3T3ZWUjgxTVpIRnFMSVUxdWNoZVJ0NlpsZHRHVlpaazZZUDZYbnBNU3c2?= =?utf-8?B?WWZSZXk3V1hldzJPaGV0Qmpva0NpekNvSy9VT0padjBtK3NvQ3FLWDVYM3pW?= =?utf-8?B?YUp3d0o3bGFWTmRFbjRoR0tDM1NETnU2eVR3UjNxbDRZdFZ0NWxvYmNtK1Jx?= =?utf-8?B?eUVzMlBOSzhhSXFTQkczekN3U3hEUXIvZW82RjFiMkM1bFQyT3dlSWpNY1BI?= =?utf-8?B?dVJHMFk0clhtZXpZd043L2ZhVnR6a2dKNjh4R1NLdjJUMGNROGp0TlZlL2U2?= =?utf-8?B?cUlHNk5TS2JmK3BSN2xxOFA2bVVtVUNUdTNwMVFkcXJvK1dJd2diRXhUZFUv?= =?utf-8?B?U2Z4SDBMd250dGRSNmxlUk1PcHVTY3N3R2NTL3gwRGVIUi9CUnFDKzdZQ0xO?= =?utf-8?B?cm1yMDFVbVRFUm4zQUZVT1ZYNmV2ZjNFaWc0NXFBN09jWVc2blN6V1FLdHdC?= =?utf-8?B?Y2g0TkhJejc4R3hxZ2daM0lheThQbkczUUFmNHBzNDk5alN2RWJEdVVucmJv?= =?utf-8?B?NXc9PQ==?= Content-ID: MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN9PR11MB5515.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8b9e7141-2a07-4df5-aa1d-08db0cd5f68e X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Feb 2023 08:48:50.6700 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: BpmW9yN2PWdF6XJmnSKo7ceVTzYJIxCT9cM85KgAdxBw302OpI+B8YuAYKpnZP/6e64eX0xpe0gAt1/+YmMmYg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5807 X-OriginatorOrg: intel.com Subject: Re: [FFmpeg-devel] [PATCH 1/2] lavfi/vf_stack_vaapi: factor out the common code for stack setting 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: On Di, 2023-02-07 at 11:59 +0800, Xiang, Haihao wrote: > From: Haihao Xiang > > The common code will be used in QSV based stack filters. > > Signed-off-by: Haihao Xiang > --- > libavfilter/stack_internal.c | 355 +++++++++++++++++++++++++++++++ > libavfilter/stack_internal.h | 60 ++++++ > libavfilter/vf_stack_vaapi.c | 395 ++++------------------------------- > 3 files changed, 452 insertions(+), 358 deletions(-) > create mode 100644 libavfilter/stack_internal.c > create mode 100644 libavfilter/stack_internal.h > > diff --git a/libavfilter/stack_internal.c b/libavfilter/stack_internal.c > new file mode 100644 > index 0000000000..57661e1c97 > --- /dev/null > +++ b/libavfilter/stack_internal.c > @@ -0,0 +1,355 @@ > +/* > + * 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 > + */ > + > +#define OFFSET(x) offsetof(StackHWContext, x) > +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM) > + > +#define SET_OUTPUT_REGION(region, rx, ry, rw, rh) do { \ > + region->x = rx; \ > + region->y = ry; \ > + region->width = rw; \ > + region->height = rh; \ > + } while (0) > + > +static int init_framesync(AVFilterContext *avctx) > +{ > + StackBaseContext *sctx = avctx->priv; > + int ret; > + > + ret = ff_framesync_init(&sctx->fs, avctx, avctx->nb_inputs); > + if (ret < 0) > + return ret; > + > + sctx->fs.on_event = process_frame; > + sctx->fs.opaque = sctx; > + > + for (int i = 0; i < sctx->nb_inputs; i++) { > + FFFrameSyncIn *in = &sctx->fs.in[i]; > + > + in->before = EXT_STOP; > + in->after = sctx->shortest ? EXT_STOP : EXT_INFINITY; > + in->sync = 1; > + in->time_base = avctx->inputs[i]->time_base; > + } > + > + return ff_framesync_configure(&sctx->fs); > +} > + > +static int config_comm_output(AVFilterLink *outlink) > +{ > + AVFilterContext *avctx = outlink->src; > + StackBaseContext *sctx = avctx->priv; > + AVFilterLink *inlink0 = avctx->inputs[0]; > + int width, height, ret; > + > + if (sctx->mode == STACK_H) { > + height = sctx->tile_height; > + width = 0; > + > + if (!height) > + height = inlink0->h; > + > + for (int i = 0; i < sctx->nb_inputs; i++) { > + AVFilterLink *inlink = avctx->inputs[i]; > + StackItemRegion *region = &sctx->regions[i]; > + > + SET_OUTPUT_REGION(region, width, 0, av_rescale(height, inlink->w, > inlink->h), height); > + width += av_rescale(height, inlink->w, inlink->h); > + } > + } else if (sctx->mode == STACK_V) { > + height = 0; > + width = sctx->tile_width; > + > + if (!width) > + width = inlink0->w; > + > + for (int i = 0; i < sctx->nb_inputs; i++) { > + AVFilterLink *inlink = avctx->inputs[i]; > + StackItemRegion *region = &sctx->regions[i]; > + > + SET_OUTPUT_REGION(region, 0, height, width, av_rescale(width, > inlink->h, inlink->w)); > + height += av_rescale(width, inlink->h, inlink->w); > + } > + } else if (sctx->nb_grid_rows && sctx->nb_grid_columns) { > + int xpos = 0, ypos = 0; > + int ow, oh, k = 0; > + > + ow = sctx->tile_width; > + oh = sctx->tile_height; > + > + if (!ow || !oh) { > + ow = avctx->inputs[0]->w; > + oh = avctx->inputs[0]->h; > + } > + > + for (int i = 0; i < sctx->nb_grid_columns; i++) { > + ypos = 0; > + > + for (int j = 0; j < sctx->nb_grid_rows; j++) { > + StackItemRegion *region = &sctx->regions[k++]; > + > + SET_OUTPUT_REGION(region, xpos, ypos, ow, oh); > + ypos += oh; > + } > + > + xpos += ow; > + } > + > + width = ow * sctx->nb_grid_columns; > + height = oh * sctx->nb_grid_rows; > + } else { > + char *arg, *p = sctx->layout, *saveptr = NULL; > + char *arg2, *p2, *saveptr2 = NULL; > + char *arg3, *p3, *saveptr3 = NULL; > + int xpos, ypos, size; > + int ow, oh; > + > + width = avctx->inputs[0]->w; > + height = avctx->inputs[0]->h; > + > + for (int i = 0; i < sctx->nb_inputs; i++) { > + AVFilterLink *inlink = avctx->inputs[i]; > + StackItemRegion *region = &sctx->regions[i]; > + > + ow = inlink->w; > + oh = inlink->h; > + > + if (!(arg = av_strtok(p, "|", &saveptr))) > + return AVERROR(EINVAL); > + > + p = NULL; > + p2 = arg; > + xpos = ypos = 0; > + > + for (int j = 0; j < 3; j++) { > + if (!(arg2 = av_strtok(p2, "_", &saveptr2))) { > + if (j == 2) > + break; > + else > + return AVERROR(EINVAL); > + } > + > + p2 = NULL; > + p3 = arg2; > + > + if (j == 2) { > + if ((ret = av_parse_video_size(&ow, &oh, p3)) < 0) { > + av_log(avctx, AV_LOG_ERROR, "Invalid size '%s'\n", > p3); > + return ret; > + } > + > + break; > + } > + > + while ((arg3 = av_strtok(p3, "+", &saveptr3))) { > + p3 = NULL; > + if (sscanf(arg3, "w%d", &size) == 1) { > + if (size == i || size < 0 || size >= sctx->nb_inputs) > + return AVERROR(EINVAL); > + > + if (!j) > + xpos += sctx->regions[size].width; > + else > + ypos += sctx->regions[size].width; > + } else if (sscanf(arg3, "h%d", &size) == 1) { > + if (size == i || size < 0 || size >= sctx->nb_inputs) > + return AVERROR(EINVAL); > + > + if (!j) > + xpos += sctx->regions[size].height; > + else > + ypos += sctx->regions[size].height; > + } else if (sscanf(arg3, "%d", &size) == 1) { > + if (size < 0) > + return AVERROR(EINVAL); > + > + if (!j) > + xpos += size; > + else > + ypos += size; > + } else { > + return AVERROR(EINVAL); > + } > + } > + } > + > + SET_OUTPUT_REGION(region, xpos, ypos, ow, oh); > + width = FFMAX(width, xpos + ow); > + height = FFMAX(height, ypos + oh); > + } > + > + } > + > + outlink->w = width; > + outlink->h = height; > + outlink->frame_rate = inlink0->frame_rate; > + outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio; > + > + for (int i = 1; i < sctx->nb_inputs; i++) { > + AVFilterLink *inlink = avctx->inputs[i]; > + if (outlink->frame_rate.num != inlink->frame_rate.num || > + outlink->frame_rate.den != inlink->frame_rate.den) { > + av_log(avctx, AV_LOG_VERBOSE, > + "Video inputs have different frame rates, output will be > VFR\n"); > + outlink->frame_rate = av_make_q(1, 0); > + break; > + } > + } > + > + ret = init_framesync(avctx); > + if (ret < 0) > + return ret; > + > + outlink->time_base = sctx->fs.time_base; > + > + return 0; > +} > + > +static int stack_init(AVFilterContext *avctx) > +{ > + StackBaseContext *sctx = avctx->priv; > + int ret; > + > + if (!strcmp(avctx->filter->name, HSTACK_NAME)) > + sctx->mode = STACK_H; > + else if (!strcmp(avctx->filter->name, VSTACK_NAME)) > + sctx->mode = STACK_V; > + else { > + int is_grid; > + > + av_assert0(strcmp(avctx->filter->name, XSTACK_NAME) == 0); > + sctx->mode = STACK_X; > + is_grid = sctx->nb_grid_rows && sctx->nb_grid_columns; > + > + if (sctx->layout && is_grid) { > + av_log(avctx, AV_LOG_ERROR, "Both layout and grid were specified. > Only one is allowed.\n"); > + return AVERROR(EINVAL); > + } > + > + if (!sctx->layout && !is_grid) { > + if (sctx->nb_inputs == 2) { > + sctx->nb_grid_rows = 1; > + sctx->nb_grid_columns = 2; > + is_grid = 1; > + } else { > + av_log(avctx, AV_LOG_ERROR, "No layout or grid > specified.\n"); > + return AVERROR(EINVAL); > + } > + } > + > + if (is_grid) > + sctx->nb_inputs = sctx->nb_grid_rows * sctx->nb_grid_columns; > + > + if (strcmp(sctx->fillcolor_str, "none") && > + av_parse_color(sctx->fillcolor, sctx->fillcolor_str, -1, avctx) > >= 0) { > + sctx->fillcolor_enable = 1; > + } else { > + sctx->fillcolor_enable = 0; > + } > + } > + > + for (int i = 0; i < sctx->nb_inputs; i++) { > + AVFilterPad pad = { 0 }; > + > + pad.type = AVMEDIA_TYPE_VIDEO; > + pad.name = av_asprintf("input%d", i); > + > + if (!pad.name) > + return AVERROR(ENOMEM); > + > + if ((ret = ff_append_inpad_free_name(avctx, &pad)) < 0) > + return ret; > + } > + > + sctx->regions = av_calloc(sctx->nb_inputs, sizeof(*sctx->regions)); > + if (!sctx->regions) > + return AVERROR(ENOMEM); > + > + return 0; > +} > + > +static av_cold void stack_uninit(AVFilterContext *avctx) > +{ > + StackBaseContext *sctx = avctx->priv; > + > + av_freep(&sctx->regions); > + ff_framesync_uninit(&sctx->fs); > +} > + > +static int stack_activate(AVFilterContext *avctx) > +{ > + StackBaseContext *sctx = avctx->priv; > + return ff_framesync_activate(&sctx->fs); > +} > + > +static const AVFilterPad stack_outputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .config_props = config_output, > + }, > +}; > + > +#define STACK_COMMON_OPTS \ > + { "inputs", "Set number of inputs", OFFSET(base.nb_inputs), > AV_OPT_TYPE_INT, { .i64 = 2 }, 2, UINT16_MAX, .flags = FLAGS }, \ > + { "shortest", "Force termination when the shortest input terminates", > OFFSET(base.shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, > + > +#define DEFINE_HSTACK_OPTIONS(api) \ > + static const AVOption hstack_##api##_options[] = { \ > + STACK_COMMON_OPTS \ > + { "height", "Set output height (0 to use the height of input 0)", > OFFSET(base.tile_height), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, FLAGS > }, \ > + { NULL } \ > + } > + > +#define DEFINE_VSTACK_OPTIONS(api) \ > + static const AVOption vstack_##api##_options[] = { \ > + STACK_COMMON_OPTS \ > + { "width", "Set output width (0 to use the width of input 0)", > OFFSET(base.tile_width), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, FLAGS > }, \ > + { NULL } \ > + } > + > +#define DEFINE_XSTACK_OPTIONS(api) \ > + static const AVOption xstack_##api##_options[] = { \ > + STACK_COMMON_OPTS \ > + { "layout", "Set custom layout", OFFSET(base.layout), > AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, .flags = FLAGS }, \ > + { "grid", "set fixed size grid layout", > OFFSET(base.nb_grid_columns), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, > .flags = FLAGS }, \ > + { "grid_tile_size", "set tile size in grid layout", > OFFSET(base.tile_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, .flags = > FLAGS }, \ > + { "fill", "Set the color for unused pixels", > OFFSET(base.fillcolor_str), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = > FLAGS }, \ > + { NULL } \ > + } > + > +#define DEFINE_STACK_FILTER(category, api, capi) \ > + static const AVClass category##_##api##_class = { \ > + .class_name = #category "_" #api, \ > + .item_name = av_default_item_name, \ > + .option = category##_##api##_options, \ > + .version = LIBAVUTIL_VERSION_INT, \ > + }; \ > + const AVFilter ff_vf_##category##_##api = { \ > + .name = #category "_" #api, \ > + .description = NULL_IF_CONFIG_SMALL(#capi " " #category), \ > + .priv_size = sizeof(StackHWContext), \ > + .priv_class = &category##_##api##_class, \ > + .init = api##_stack_init, \ > + .uninit = api##_stack_uninit, \ > + .activate = stack_activate, \ > + FILTER_QUERY_FUNC(api##_stack_query_formats), \ > + FILTER_OUTPUTS(stack_outputs), \ > + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, \ > + .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, \ > + } > diff --git a/libavfilter/stack_internal.h b/libavfilter/stack_internal.h > new file mode 100644 > index 0000000000..2847fc620b > --- /dev/null > +++ b/libavfilter/stack_internal.h > @@ -0,0 +1,60 @@ > +/* > + * 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_STACK_INTERNAL_H > +#define AVFILTER_STACK_INTERNAL_H > + > +enum { > + STACK_H = 0, > + STACK_V = 1, > + STACK_X = 2 > +}; > + > +typedef struct StackItemRegion { > + int x; > + int y; > + int width; > + int height; > +} StackItemRegion; > + > +typedef struct StackBaseContext { > + HWContext hwctx; /**< must be the first field */ > + > + FFFrameSync fs; > + int mode; > + uint8_t fillcolor[4]; > + int fillcolor_enable; > + StackItemRegion *regions; > + > + /* Options */ > + int nb_inputs; > + int shortest; > + int tile_width; > + int tile_height; > + int nb_grid_columns; > + int nb_grid_rows; > + char *layout; > + char *fillcolor_str; > +} StackBaseContext; > + > +static int config_comm_output(AVFilterLink *outlink); > +static int stack_init(AVFilterContext *avctx); > +static av_cold void stack_uninit(AVFilterContext *avctx); > +static int stack_activate(AVFilterContext *avctx); > + > +#endif /* AVFILTER_STACK_INTERNAL_H */ > \ No newline at end of file > diff --git a/libavfilter/vf_stack_vaapi.c b/libavfilter/vf_stack_vaapi.c > index 403fbb19eb..26dbe3f7aa 100644 > --- a/libavfilter/vf_stack_vaapi.c > +++ b/libavfilter/vf_stack_vaapi.c > @@ -42,33 +42,17 @@ > #include "framesync.h" > #include "vaapi_vpp.h" > > -#define OFFSET(x) offsetof(StackVAAPIContext, x) > -#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM) > - > -enum { > - STACK_VAAPI_H = 0, > - STACK_VAAPI_V = 1, > - STACK_VAAPI_X = 2 > -}; > +#define HSTACK_NAME "hstack_vaapi" > +#define VSTACK_NAME "vstack_vaapi" > +#define XSTACK_NAME "xstack_vaapi" > +#define HWContext VAAPIVPPContext > +#define StackHWContext StackVAAPIContext > +#include "stack_internal.h" > > typedef struct StackVAAPIContext { > - VAAPIVPPContext vppctx; /**< must be the first field */ > + StackBaseContext base; > > - FFFrameSync fs; > - int mode; > VARectangle *rects; > - uint8_t fillcolor[4]; > - int fillcolor_enable; > - > - /* Options */ > - int nb_inputs; > - int shortest; > - int tile_width; > - int tile_height; > - int nb_grid_columns; > - int nb_grid_rows; > - char *layout; > - char *fillcolor_str; > } StackVAAPIContext; > > static int process_frame(FFFrameSync *fs) > @@ -122,14 +106,14 @@ static int process_frame(FFFrameSync *fs) > params[i].surface = (VASurfaceID)(uintptr_t)iframe->data[3]; > params[i].output_region = &sctx->rects[i]; > > - if (sctx->fillcolor_enable) > - params[i].output_background_color = (sctx->fillcolor[3] << 24 | > - sctx->fillcolor[0] << 16 | > - sctx->fillcolor[1] << 8 | > - sctx->fillcolor[2]); > + if (sctx->base.fillcolor_enable) > + params[i].output_background_color = (sctx->base.fillcolor[3] << > 24 | > + sctx->base.fillcolor[0] << > 16 | > + sctx->base.fillcolor[1] << 8 > | > + sctx->base.fillcolor[2]); > } > > - oframe->pts = av_rescale_q(sctx->fs.pts, sctx->fs.time_base, outlink- > >time_base); > + oframe->pts = av_rescale_q(sctx->base.fs.pts, sctx->base.fs.time_base, > outlink->time_base); > oframe->sample_aspect_ratio = outlink->sample_aspect_ratio; > > ret = ff_vaapi_vpp_render_pictures(avctx, params, avctx->nb_inputs, > oframe); > @@ -147,37 +131,6 @@ fail: > return ret; > } > > -static int init_framesync(AVFilterContext *avctx) > -{ > - StackVAAPIContext *sctx = avctx->priv; > - int ret; > - > - ret = ff_framesync_init(&sctx->fs, avctx, avctx->nb_inputs); > - if (ret < 0) > - return ret; > - > - sctx->fs.on_event = process_frame; > - sctx->fs.opaque = sctx; > - > - for (int i = 0; i < sctx->nb_inputs; i++) { > - FFFrameSyncIn *in = &sctx->fs.in[i]; > - > - in->before = EXT_STOP; > - in->after = sctx->shortest ? EXT_STOP : EXT_INFINITY; > - in->sync = 1; > - in->time_base = avctx->inputs[i]->time_base; > - } > - > - return ff_framesync_configure(&sctx->fs); > -} > - > -#define SET_INPUT_REGION(rect, rx, ry, rw, rh) do { \ > - rect->x = rx; \ > - rect->y = ry; \ > - rect->width = rw; \ > - rect->height = rh; \ > - } while (0) > - > static int config_output(AVFilterLink *outlink) > { > AVFilterContext *avctx = outlink->src; > @@ -185,7 +138,7 @@ static int config_output(AVFilterLink *outlink) > VAAPIVPPContext *vppctx = avctx->priv; > AVFilterLink *inlink0 = avctx->inputs[0]; > AVHWFramesContext *hwfc0 = NULL; > - int width, height, ret; > + int ret; > > if (inlink0->format != AV_PIX_FMT_VAAPI || !inlink0->hw_frames_ctx || > !inlink0->hw_frames_ctx->data) { > av_log(avctx, AV_LOG_ERROR, "Software pixel format is not > supported.\n"); > @@ -194,7 +147,7 @@ static int config_output(AVFilterLink *outlink) > > hwfc0 = (AVHWFramesContext *)inlink0->hw_frames_ctx->data; > > - for (int i = 1; i < sctx->nb_inputs; i++) { > + for (int i = 1; i < sctx->base.nb_inputs; i++) { > AVFilterLink *inlink = avctx->inputs[i]; > AVHWFramesContext *hwfc = NULL; > > @@ -219,168 +172,19 @@ static int config_output(AVFilterLink *outlink) > ff_vaapi_vpp_config_input(inlink0); > vppctx->output_format = hwfc0->sw_format; > > - if (sctx->mode == STACK_VAAPI_H) { > - height = sctx->tile_height; > - width = 0; > - > - if (!height) > - height = inlink0->h; > - > - for (int i = 0; i < sctx->nb_inputs; i++) { > - AVFilterLink *inlink = avctx->inputs[i]; > - VARectangle *rect = &sctx->rects[i]; > - > - SET_INPUT_REGION(rect, width, 0, av_rescale(height, inlink->w, > inlink->h), height); > - width += av_rescale(height, inlink->w, inlink->h); > - } > - } else if (sctx->mode == STACK_VAAPI_V) { > - height = 0; > - width = sctx->tile_width; > - > - if (!width) > - width = inlink0->w; > - > - for (int i = 0; i < sctx->nb_inputs; i++) { > - AVFilterLink *inlink = avctx->inputs[i]; > - VARectangle *rect = &sctx->rects[i]; > - > - SET_INPUT_REGION(rect, 0, height, width, av_rescale(width, > inlink->h, inlink->w)); > - height += av_rescale(width, inlink->h, inlink->w); > - } > - } else if (sctx->nb_grid_rows && sctx->nb_grid_columns) { > - int xpos = 0, ypos = 0; > - int ow, oh, k = 0; > - > - ow = sctx->tile_width; > - oh = sctx->tile_height; > - > - if (!ow || !oh) { > - ow = avctx->inputs[0]->w; > - oh = avctx->inputs[0]->h; > - } > - > - for (int i = 0; i < sctx->nb_grid_columns; i++) { > - ypos = 0; > - > - for (int j = 0; j < sctx->nb_grid_rows; j++) { > - VARectangle *rect = &sctx->rects[k++]; > - > - SET_INPUT_REGION(rect, xpos, ypos, ow, oh); > - ypos += oh; > - } > - > - xpos += ow; > - } > - > - width = ow * sctx->nb_grid_columns; > - height = oh * sctx->nb_grid_rows; > - } else { > - char *arg, *p = sctx->layout, *saveptr = NULL; > - char *arg2, *p2, *saveptr2 = NULL; > - char *arg3, *p3, *saveptr3 = NULL; > - int xpos, ypos, size; > - int ow, oh; > - > - width = avctx->inputs[0]->w; > - height = avctx->inputs[0]->h; > - > - for (int i = 0; i < sctx->nb_inputs; i++) { > - AVFilterLink *inlink = avctx->inputs[i]; > - VARectangle *rect = &sctx->rects[i]; > - > - ow = inlink->w; > - oh = inlink->h; > - > - if (!(arg = av_strtok(p, "|", &saveptr))) > - return AVERROR(EINVAL); > - > - p = NULL; > - p2 = arg; > - xpos = ypos = 0; > - > - for (int j = 0; j < 3; j++) { > - if (!(arg2 = av_strtok(p2, "_", &saveptr2))) { > - if (j == 2) > - break; > - else > - return AVERROR(EINVAL); > - } > - > - p2 = NULL; > - p3 = arg2; > - > - if (j == 2) { > - if ((ret = av_parse_video_size(&ow, &oh, p3)) < 0) { > - av_log(avctx, AV_LOG_ERROR, "Invalid size '%s'\n", > p3); > - return ret; > - } > - > - break; > - } > - > - while ((arg3 = av_strtok(p3, "+", &saveptr3))) { > - p3 = NULL; > - if (sscanf(arg3, "w%d", &size) == 1) { > - if (size == i || size < 0 || size >= sctx->nb_inputs) > - return AVERROR(EINVAL); > - > - if (!j) > - xpos += sctx->rects[size].width; > - else > - ypos += sctx->rects[size].width; > - } else if (sscanf(arg3, "h%d", &size) == 1) { > - if (size == i || size < 0 || size >= sctx->nb_inputs) > - return AVERROR(EINVAL); > - > - if (!j) > - xpos += sctx->rects[size].height; > - else > - ypos += sctx->rects[size].height; > - } else if (sscanf(arg3, "%d", &size) == 1) { > - if (size < 0) > - return AVERROR(EINVAL); > - > - if (!j) > - xpos += size; > - else > - ypos += size; > - } else { > - return AVERROR(EINVAL); > - } > - } > - } > - > - SET_INPUT_REGION(rect, xpos, ypos, ow, oh); > - width = FFMAX(width, xpos + ow); > - height = FFMAX(height, ypos + oh); > - } > - > - } > - > - outlink->w = width; > - outlink->h = height; > - outlink->frame_rate = inlink0->frame_rate; > - outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio; > - > - for (int i = 1; i < sctx->nb_inputs; i++) { > - AVFilterLink *inlink = avctx->inputs[i]; > - if (outlink->frame_rate.num != inlink->frame_rate.num || > - outlink->frame_rate.den != inlink->frame_rate.den) { > - av_log(avctx, AV_LOG_VERBOSE, > - "Video inputs have different frame rates, output will be > VFR\n"); > - outlink->frame_rate = av_make_q(1, 0); > - break; > - } > - } > - > - ret = init_framesync(avctx); > + ret = config_comm_output(outlink); > if (ret < 0) > return ret; > > - outlink->time_base = sctx->fs.time_base; > + for (int i = 0; i < sctx->base.nb_inputs; i++) { > + sctx->rects[i].x = sctx->base.regions[i].x; > + sctx->rects[i].y = sctx->base.regions[i].y; > + sctx->rects[i].width = sctx->base.regions[i].width; > + sctx->rects[i].height = sctx->base.regions[i].height; > + } > > - vppctx->output_width = width; > - vppctx->output_height = height; > + vppctx->output_width = outlink->w; > + vppctx->output_height = outlink->h; > > return ff_vaapi_vpp_config_output(outlink); > } > @@ -391,59 +195,12 @@ static int vaapi_stack_init(AVFilterContext *avctx) > VAAPIVPPContext *vppctx = avctx->priv; > int ret; > > - if (!strcmp(avctx->filter->name, "hstack_vaapi")) > - sctx->mode = STACK_VAAPI_H; > - else if (!strcmp(avctx->filter->name, "vstack_vaapi")) > - sctx->mode = STACK_VAAPI_V; > - else { > - int is_grid; > - > - av_assert0(strcmp(avctx->filter->name, "xstack_vaapi") == 0); > - sctx->mode = STACK_VAAPI_X; > - is_grid = sctx->nb_grid_rows && sctx->nb_grid_columns; > - > - if (sctx->layout && is_grid) { > - av_log(avctx, AV_LOG_ERROR, "Both layout and grid were specified. > Only one is allowed.\n"); > - return AVERROR(EINVAL); > - } > - > - if (!sctx->layout && !is_grid) { > - if (sctx->nb_inputs == 2) { > - sctx->nb_grid_rows = 1; > - sctx->nb_grid_columns = 2; > - is_grid = 1; > - } else { > - av_log(avctx, AV_LOG_ERROR, "No layout or grid > specified.\n"); > - return AVERROR(EINVAL); > - } > - } > - > - if (is_grid) > - sctx->nb_inputs = sctx->nb_grid_rows * sctx->nb_grid_columns; > - > - if (strcmp(sctx->fillcolor_str, "none") && > - av_parse_color(sctx->fillcolor, sctx->fillcolor_str, -1, avctx) > >= 0) { > - sctx->fillcolor_enable = 1; > - } else { > - sctx->fillcolor_enable = 0; > - } > - } > - > - for (int i = 0; i < sctx->nb_inputs; i++) { > - AVFilterPad pad = { 0 }; > - > - pad.type = AVMEDIA_TYPE_VIDEO; > - pad.name = av_asprintf("input%d", i); > - > - if (!pad.name) > - return AVERROR(ENOMEM); > - > - if ((ret = ff_append_inpad_free_name(avctx, &pad)) < 0) > - return ret; > - } > + ret = stack_init(avctx); > + if (ret) > + return ret; > > /* stack region */ > - sctx->rects = av_calloc(sctx->nb_inputs, sizeof(*sctx->rects)); > + sctx->rects = av_calloc(sctx->base.nb_inputs, sizeof(*sctx->rects)); > if (!sctx->rects) > return AVERROR(ENOMEM); > > @@ -457,14 +214,9 @@ static av_cold void vaapi_stack_uninit(AVFilterContext > *avctx) > { > StackVAAPIContext *sctx = avctx->priv; > > - ff_framesync_uninit(&sctx->fs); > - av_freep(&sctx->rects); > -} > + stack_uninit(avctx); > > -static int vaapi_stack_activate(AVFilterContext *avctx) > -{ > - StackVAAPIContext *sctx = avctx->priv; > - return ff_framesync_activate(&sctx->fs); > + av_freep(&sctx->rects); > } > > static int vaapi_stack_query_formats(AVFilterContext *avctx) > @@ -477,98 +229,25 @@ static int vaapi_stack_query_formats(AVFilterContext > *avctx) > return ff_set_common_formats_from_list(avctx, pixel_formats); > } > > -static const AVFilterPad vaapi_stack_outputs[] = { > - { > - .name = "default", > - .type = AVMEDIA_TYPE_VIDEO, > - .config_props = config_output, > - }, > -}; > - > -#define STACK_COMMON_OPTS \ > - { "inputs", "Set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, { > .i64 = 2 }, 2, UINT16_MAX, .flags = FLAGS }, \ > - { "shortest", "Force termination when the shortest input terminates", > OFFSET(shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, > +#include "stack_internal.c" > > #if CONFIG_HSTACK_VAAPI_FILTER > > -static const AVOption hstack_vaapi_options[] = { > - STACK_COMMON_OPTS > - > - { "height", "Set output height (0 to use the height of input 0)", > OFFSET(tile_height), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, FLAGS }, > - { NULL } > -}; > - > -AVFILTER_DEFINE_CLASS(hstack_vaapi); > - > -const AVFilter ff_vf_hstack_vaapi = { > - .name = "hstack_vaapi", > - .description = NULL_IF_CONFIG_SMALL("VA-API hstack."), > - .priv_size = sizeof(StackVAAPIContext), > - .priv_class = &hstack_vaapi_class, > - .init = vaapi_stack_init, > - .uninit = vaapi_stack_uninit, > - .activate = vaapi_stack_activate, > - FILTER_QUERY_FUNC(vaapi_stack_query_formats), > - FILTER_OUTPUTS(vaapi_stack_outputs), > - .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, > - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, > -}; > +DEFINE_HSTACK_OPTIONS(vaapi); > +DEFINE_STACK_FILTER(hstack, vaapi, "VA-API"); > > #endif > > #if CONFIG_VSTACK_VAAPI_FILTER > > -static const AVOption vstack_vaapi_options[] = { > - STACK_COMMON_OPTS > - > - { "width", "Set output width (0 to use the width of input 0)", > OFFSET(tile_width), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, FLAGS }, > - { NULL } > -}; > - > -AVFILTER_DEFINE_CLASS(vstack_vaapi); > - > -const AVFilter ff_vf_vstack_vaapi = { > - .name = "vstack_vaapi", > - .description = NULL_IF_CONFIG_SMALL("VA-API vstack."), > - .priv_size = sizeof(StackVAAPIContext), > - .priv_class = &vstack_vaapi_class, > - .init = vaapi_stack_init, > - .uninit = vaapi_stack_uninit, > - .activate = vaapi_stack_activate, > - FILTER_QUERY_FUNC(vaapi_stack_query_formats), > - FILTER_OUTPUTS(vaapi_stack_outputs), > - .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, > - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, > -}; > +DEFINE_VSTACK_OPTIONS(vaapi); > +DEFINE_STACK_FILTER(vstack, vaapi, "VA-API"); > > #endif > > #if CONFIG_XSTACK_VAAPI_FILTER > > -static const AVOption xstack_vaapi_options[] = { > - STACK_COMMON_OPTS > - > - { "layout", "Set custom layout", OFFSET(layout), AV_OPT_TYPE_STRING, > {.str = NULL}, 0, 0, .flags = FLAGS }, > - { "grid", "set fixed size grid layout", OFFSET(nb_grid_columns), > AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, .flags = FLAGS }, > - { "grid_tile_size", "set tile size in grid layout", OFFSET(tile_width), > AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, .flags = FLAGS }, > - { "fill", "Set the color for unused pixels", OFFSET(fillcolor_str), > AV_OPT_TYPE_STRING, {.str = "none"}, .flags = FLAGS }, > - { NULL } > -}; > - > -AVFILTER_DEFINE_CLASS(xstack_vaapi); > - > -const AVFilter ff_vf_xstack_vaapi = { > - .name = "xstack_vaapi", > - .description = NULL_IF_CONFIG_SMALL("VA-API xstack."), > - .priv_size = sizeof(StackVAAPIContext), > - .priv_class = &xstack_vaapi_class, > - .init = vaapi_stack_init, > - .uninit = vaapi_stack_uninit, > - .activate = vaapi_stack_activate, > - FILTER_OUTPUTS(vaapi_stack_outputs), > - FILTER_QUERY_FUNC(vaapi_stack_query_formats), > - .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, > - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, > -}; > +DEFINE_XSTACK_OPTIONS(vaapi); > +DEFINE_STACK_FILTER(xstack, vaapi, "VA-API"); > > #endif Will apply the patchset. -Haihao _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".