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 CCA2C4A07F for ; Tue, 19 Mar 2024 14:56:38 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BFC5268D391; Tue, 19 Mar 2024 16:56:34 +0200 (EET) Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-db3eur04olkn2019.outbound.protection.outlook.com [40.92.74.19]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 01AF868D2FB for ; Tue, 19 Mar 2024 16:56:28 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YMYWrQ4AGjd/m2dSv4c36udLwArM4DrbtdmpZ93JvfkyNBxKVVjaqjZttscpUUqmADnMCglXP1bwQ26fQhpuynCqp2UvXL/rDCEiI4VYiagPq+mEjGG0HUYrbp6zlwZowgqwP/4P+0BOtZCuCMG1YRAIeDHcZjBD9fH+hOBK0IzEaoU2kfG970WKO6tCRlFRuDI+wbkp1xypyzF0tChO0kf8TRdIsjZY32fnABUS/iDkC4vDYmv/iijHy1NcvPfDzhwVx7leQalh+dq4F4/FzgGOWCjGAXCC2q89xKjJvnEBwCEzXAawFSf+aZCAvb8FNQdkICNrFdAe1bWTm55X+g== 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=War6yLV3TEANdHak3VSmug95X6tjFnd3GnxqLCZEY78=; b=jEFWPgku2NNUWTa2iFaIebeQhSKx9JQrBsOGqdry70hQFnyHecxvywBkn0oBOsTiWEUU90F+nsg8wnztrpkHUUcsaL2Vtns8GoLxHQDPwpyOmk4PqVDawL6zVTl8hfFwCqoVJAZUCeedAe7fqMWZwkf5aMz+N6KeHKRjBRR6j3bfFzqLF2zHKoCIwTJ27flK/UaLLXeBs7Zop+0lBaaCjK5l34UN+Docr9rjWIMFvK8+UCBIRHu3zybs+9yvZnHtnrbp4LzxBYwVY3HpXXWu1RYPwSIv/9KvGNfGHPUPrI9B0hBvBPGyPpIxBpSZe0CTBeNl74sZV3mNeiuiIM7Fmw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=War6yLV3TEANdHak3VSmug95X6tjFnd3GnxqLCZEY78=; b=G0xyPTQClQmFqCLWpg3puqM8GwYIm9Qbk3Qx7rsa8WnWv/1XlT+Povxau+SQCLB8JjKPaWTvxAf0H78HhsXCBiZ6Nf3Nev8MMaxfUvtniPgvWvv0qy180/Q87bPxcH4v2AoS3vwqGfAEbC0nnqibgK1o59O/RGgfIxtybQppBGqE0VdQPRniNNiLh7inQvMJSAQnoUL0UoIk7j8GvY75eq0JYMiN5Dzz7waPYcME6bvr2zF7pHJ/I00Gslsl0XBroy/QxmFFux6mcR9AflKYTIsg/ry5nEtv5NZdlbuxd533QQUY0hQ/KQYBOFp0ski5ZEg5YR6VuwMAEhUsVesRbQ== Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) by PR3P250MB0004.EURP250.PROD.OUTLOOK.COM (2603:10a6:102:14f::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7386.29; Tue, 19 Mar 2024 14:56:26 +0000 Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::228d:8c6f:ed10:82eb]) by AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::228d:8c6f:ed10:82eb%7]) with mapi id 15.20.7362.035; Tue, 19 Mar 2024 14:56:26 +0000 Message-ID: Date: Tue, 19 Mar 2024 15:56:24 +0100 User-Agent: Mozilla Thunderbird To: ffmpeg-devel@ffmpeg.org References: <20240319140636.4323-1-jamrial@gmail.com> <20240319140636.4323-2-jamrial@gmail.com> Content-Language: en-US From: Andreas Rheinhardt In-Reply-To: <20240319140636.4323-2-jamrial@gmail.com> X-TMN: [UVEXV3t5/Oo7rE13fXO+FJnri6PZHgPskHAIs/VdJ6E=] X-ClientProxiedBy: ZR0P278CA0008.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:16::18) To AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) X-Microsoft-Original-Message-ID: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8P250MB0744:EE_|PR3P250MB0004:EE_ X-MS-Office365-Filtering-Correlation-Id: 96ff6042-61dc-4777-35dc-08dc4824c02e X-MS-Exchange-SLBlob-MailProps: Cq7lScuPrnr9wYTvfIwcniUcOEk7m2BTqMxwWN20h4lnZ9NJ/blGaGCb9u0b/iMVfRtQsOQPA9AqKHWGWGBjtFPHHfqeGcZPxkTQGJ20t8KV1J1+ctOaWdVaiRZl9RnlrmeqsQySUtLjPIi2drtMQnsApH60fRHf9VLk66VauLlWG37U82wmyt84Cbaisq8u7eEYsnUq9BEjj1wijyYSXFl9PbkK6vzDl5WBubp6Z3AXssJw+jTnLv8nIGnQWr1lGZ2GmfsOOTL5dSN9R64q6Ntq+2RFRnhf7lcSvsokXwcA0Bydfb4CLUgkedqmWSBQzS60H+ZAUDLn303X58S6wTAm90T0ExYbhOUyGMkcaTNOGoLxNMY65On/KHeUv+9rz+4WeGbhGjYZV82bex+9y5kZRMQhh1sNVQztZ8q6eFAofK1POi5KK5FcsfmOel+mkeMeCKL5iDL/8Wyoo5uH1vNIuuNAjlUD5lzb9+P3d+VCIXuQr+6LvpnwSMJcRgbH9UoKa7vpH2skbdEyyy6CQA/lKQ/a/PyRTc+GzOkYVmhGImHinPiila9E81mFzybfuSbAAEog7gDp6cKp10vFlx1W+IRw10/RF3jmjmnnw41GPos/AP9HqwP7Z3IPOQS+obqpyqq6CcQg5M4pPvEXs/rKbmz+1vWWNypB+753x5lLvzkdD3CnygFuQFoBIVy1YZU7DtKKHUwuSZsZC76rKofw8j4iiawOZKzR12JNHWlSQf8hW1yaXyMtqyAUjlI+aex5GCDRl30= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: WvwZ8o7CJoyZ/hEGLeVk1ZcRuD2CR059PO4Ya4B5SqUd/qAKYxuXtA/vMDliq9lXI1ssQdlRTfjmfHwX7Y01O8xN45TXu9hmL4PcGfv+82xH5NP2aLV5Kt3UrOYIrfDnqXu74w+fbkH87t5HZlC5OqVvZxRhwVllqF6G9YIQzgSbyn0Pqvdglh3EzCbi9FV2sT3jYQo8EWMzNpNfvnJN0Xl6XhJBcCDIQvBGUASYJS4Qniy5EC6aSRm24/JpQt9UROaF3L7GxhUsvMxLhYDayIdkF4U2HeCjqCch2E8uqXZ2s7ThNkVFEpjKShjTcBlD0OmMpVDxtGoSvWiK+1O3iyznTrydEvgaA4Wuv0J2/56mwpbtITDzHUyi+RrSYWu8ZHHYXOAV3jBrypLhUToygWzR1s9hSnQC2/hNtWzd0g+z1HFghw2iGQoGg0SaoVPyxGuxSyFsUYK51HTq0G2zpCDy6UDx71/TGtMOxr6XFOLv248j1ZsekujSW6dLrvH3XUSL7+pbRn3clx9UJALebxkpLWazCo0yq6kNGNB6CvSH/9Y9wIIZ78+gBsZgWOnD X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?WS8wVGs3d25ReW5zVDhTR2tscTFDZVZ0MzgydUN3c25Ybi8wRElraVQ2YU1H?= =?utf-8?B?dDlLTVczaG5pY2F4VC9DYkRncXF2RU9LNFpseVovOFFYVHp3Z3JoQkQ1MHI2?= =?utf-8?B?ak01UnM1ZXdjUFJZSGZkZnR1ZWJ4elhpUll4SWR2NldabjlQUW1SNUdFZ2JY?= =?utf-8?B?amMxa3VrMGdhZ2JPMGwyTy9EKzBnbGxDM2cwZ2tQOXZ3RG9MYWxmaXlZTFJI?= =?utf-8?B?dkh2dEdhUG55N3d3SWN6YWVLZERrS2NROEdCVytQc0ZleGdHTjlFcXpCREZj?= =?utf-8?B?aDNCMFlORVBFQlVLMXY3K2tDd2tuV3Z5a1pZNzUwT0V2UGFLS0laL2dzMEdD?= =?utf-8?B?dU1penVEQ3RjWlU5d0lNZTZYcUpHKzhNRmJyTlE0ZGt6b0lONkh2UWd6NnQ4?= =?utf-8?B?S3U1Qm16c3pFV3BHU2h3YVBzL1NIenZVNVV2ZjQ2YjRQSFcvZUVTdW91QXhH?= =?utf-8?B?L1pISTVJZ2pMcnlUTWRCMk15bUVtcXo4RWREbHRwQmtQTEdCVkhydTcxVElo?= =?utf-8?B?cFpYM1ZZZW1MYmF2bmxZN3g0Sm1uaC9YMW9XZTBaSit4dXdZK1JaRm1FVTlC?= =?utf-8?B?ejV2QzBTT2ZjRWNndVR4VUpSS0VzeHJ2TmhiSFQ3VXpYME9mK1BEUWpoQ3FX?= =?utf-8?B?UU5UYStYMm5TV29kTHBQUUc1RFdERE9ZQUlJdHdhTVJEQ2N3NUllYmtGTjZa?= =?utf-8?B?RCtDM1ZsTzI4U2pTS0xmWFJNaXpqOXpSQkJHcXRmL096VXhZcEU3T0ZSVGdi?= =?utf-8?B?UWYwaERmQ2hzUG1kR3lLTllDV3JPNmdXd2tpTjdwT3RLY3d1b0M2aWlYeW9X?= =?utf-8?B?cENoSEdJTUVjQVZTVklkVkxQdnZReUkyM1BOd3VrYXdCYkk1N0o5QmJZYUdx?= =?utf-8?B?SE93V05TaGtiOUZLWlIxMkpNM2lOVHRpcVRsODJTUnhYVFh3RTF2bmcydC9N?= =?utf-8?B?ZHBpWkYwanZXbjhzd0xvVEo5aitzTWx2MkNnTjhoZ1RPOVpCNW5HMEdKdklI?= =?utf-8?B?QVUwekpmQUh4aW5qTGo4VExaV2VrN1N3ZUtmbzdYckF2ZEV3eXRhU1g2cHBY?= =?utf-8?B?VldoY3FSUE55MkwvZ3pHeXNuM1NqZ1owL3ZtaXROcjBoaVd6ZzA5aFhqRW9M?= =?utf-8?B?S1A0blk1d0poWW5jQWtPUnBBUnZ1MmErSUdKTWxuTk1qTVIrc3lTM3Z0b1hz?= =?utf-8?B?Ly9IOUFHcVJ4TWtHYTV0NElFUDlicEZFSk83VWxoQ25NSVhMQjkra21qREV4?= =?utf-8?B?S0xVbGw2WmtUSk5ENVhmV2RvaGJPU1NDTkRQdXVZZ1VEL0pqMzA0OW9oN0dW?= =?utf-8?B?N1dwNlFpM0wvY2RwTktyZGVjOURFeXJzZ21uWlpEWmZ6dk5vS3lMdHdSdnVi?= =?utf-8?B?cnVQY0xHMEoyS0cxc0kzRC9hUkVreXJFYzNpZjlkTjVWK3ZHTVFBR1JOcnh6?= =?utf-8?B?V1pVcmc0VHJrT2ZITmFoMEdocnRwcjZRRmV1Yk1VUGFZL3haeHFrWnVUMWtu?= =?utf-8?B?bTBSRDFpTXpPWjB3V1pmeDJ5aDhHcXpFOFF3N3VEOVhJeElKMmRGTXV1eS9Y?= =?utf-8?B?WkVrb1IrMW5kTEhFdllyRkl6Tm04ZkplWjlDZHV2VndKVkdnUjZCcWdYZFA3?= =?utf-8?B?S0xsSHpHR2lTcjh5MkZ2L0R5UTNmaUpYRkhNamtuKytjUmhTQUlZQTd1UXRi?= =?utf-8?B?MmhKSFU3bEhwUnlHbzBZemVKVWx6T3hyTm1DY3JhSWF3WXZWSys1clVnPT0=?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 96ff6042-61dc-4777-35dc-08dc4824c02e X-MS-Exchange-CrossTenant-AuthSource: AS8P250MB0744.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Mar 2024 14:56:26.4457 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: PR3P250MB0004 Subject: Re: [FFmpeg-devel] [PATCH 2/3] avfilter: add an LCEVC decoding filter 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: James Almer: > Signed-off-by: James Almer > --- > configure | 4 + > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/vf_lcevc.c | 466 +++++++++++++++++++++++++++++++++++++++ > 4 files changed, 472 insertions(+) > create mode 100644 libavfilter/vf_lcevc.c > > diff --git a/configure b/configure > index e019d1b996..4022d13f76 100755 > --- a/configure > +++ b/configure > @@ -224,6 +224,7 @@ External library support: > --enable-libcdio enable audio CD grabbing with libcdio [no] > --enable-libcodec2 enable codec2 en/decoding using libcodec2 [no] > --enable-libdav1d enable AV1 decoding via libdav1d [no] > + --enable-liblcevc_dec enable AV1 decoding via liblcevc_dec [no] How is this filter supposed to decode AV1 if it does not even get AVPackets? It seems to be for decoding an EVC enhancment layer instead. > --enable-libdavs2 enable AVS2 decoding via libdavs2 [no] > --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394 > and libraw1394 [no] > @@ -1861,6 +1862,7 @@ EXTERNAL_LIBRARY_LIST=" > libcelt > libcodec2 > libdav1d > + liblcevc_dec > libdc1394 > libflite > libfontconfig > @@ -3789,6 +3791,7 @@ iccgen_filter_deps="lcms2" > interlace_filter_deps="gpl" > kerndeint_filter_deps="gpl" > ladspa_filter_deps="ladspa libdl" > +lcevc_filter_deps="liblcevc_dec" > lensfun_filter_deps="liblensfun version3" > libplacebo_filter_deps="libplacebo vulkan" > lv2_filter_deps="lv2" > @@ -6801,6 +6804,7 @@ enabled libjxl && require_pkg_config libjxl "libjxl >= 0.7.0" jxl/dec > enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc > enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 2.0.0" kvazaar.h kvz_api_get > enabled liblensfun && require_pkg_config liblensfun lensfun lensfun.h lf_db_create > +enabled liblcevc_dec && require_pkg_config liblcevc_dec "lcevc_dec >= 2.0.0" "LCEVC/lcevc_dec.h" LCEVC_CreateDecoder > > if enabled libmfx && enabled libvpl; then > die "ERROR: can not use libmfx and libvpl together" > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 994d9773ba..57f27a1221 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -359,6 +359,7 @@ OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o > OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o > OBJS-$(CONFIG_KIRSCH_FILTER) += vf_convolution.o > OBJS-$(CONFIG_LAGFUN_FILTER) += vf_lagfun.o > +OBJS-$(CONFIG_LCEVC_FILTER) += vf_lcevc.o > OBJS-$(CONFIG_LATENCY_FILTER) += f_latency.o > OBJS-$(CONFIG_LENSCORRECTION_FILTER) += vf_lenscorrection.o > OBJS-$(CONFIG_LENSFUN_FILTER) += vf_lensfun.o > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index 149bf50997..54d6ea1043 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -337,6 +337,7 @@ extern const AVFilter ff_vf_kerndeint; > extern const AVFilter ff_vf_kirsch; > extern const AVFilter ff_vf_lagfun; > extern const AVFilter ff_vf_latency; > +extern const AVFilter ff_vf_lcevc; > extern const AVFilter ff_vf_lenscorrection; > extern const AVFilter ff_vf_lensfun; > extern const AVFilter ff_vf_libplacebo; > diff --git a/libavfilter/vf_lcevc.c b/libavfilter/vf_lcevc.c > new file mode 100644 > index 0000000000..e18f0945f9 > --- /dev/null > +++ b/libavfilter/vf_lcevc.c > @@ -0,0 +1,466 @@ > +/* > + * This file is part of FFmpeg. > + * > + * Copyright (c) 2024 James Almer > + * > + * 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 > + > +#include > + > +#include "libavutil/internal.h" > +#include "libavutil/opt.h" > +#include "filters.h" > +#include "internal.h" > +#include "video.h" > + > +typedef struct LCEVCContext { > + LCEVC_DecoderHandle decoder; > + LCEVC_PictureHandle base; > + AVFrame *in; > + int w, h; > + int status; > +} LCEVCContext; > + > +static LCEVC_ColorFormat map_format(int format) > +{ > + switch (format) { > + case AV_PIX_FMT_YUV420P: > + return LCEVC_I420_8; > + case AV_PIX_FMT_YUV420P10LE: > + return LCEVC_I420_10_LE; > + case AV_PIX_FMT_YUV420P12LE: > + return LCEVC_I420_12_LE; > + case AV_PIX_FMT_NV12: > + return LCEVC_NV12_8; > + case AV_PIX_FMT_NV21: > + return LCEVC_NV21_8; > + case AV_PIX_FMT_GRAY8: > + return LCEVC_GRAY_8; > + case AV_PIX_FMT_GRAY10LE: > + return LCEVC_GRAY_10_LE; > + case AV_PIX_FMT_GRAY12LE: > + return LCEVC_GRAY_12_LE; > + case AV_PIX_FMT_RGB24: > + return LCEVC_RGB_8; > + case AV_PIX_FMT_BGR24: > + return LCEVC_BGR_8; > + case AV_PIX_FMT_RGBA: > + return LCEVC_RGBA_8; > + case AV_PIX_FMT_ARGB: > + return LCEVC_ARGB_8; > + case AV_PIX_FMT_ABGR: > + return LCEVC_ABGR_8; > + case AV_PIX_FMT_BGRA: > + return LCEVC_BGRA_8; > + } > + > + return LCEVC_ColorFormat_Unknown; > +} > + > +static inline LCEVC_ColorRange map_range(int range) > +{ > + switch (range) { > + case AVCOL_RANGE_MPEG: > + return LCEVC_ColorRange_Limited; > + case AVCOL_RANGE_JPEG: > + return LCEVC_ColorRange_Full; > + } > + > + return LCEVC_ColorRange_Unknown; > +} > + > +static inline enum AVColorRange map_av_range(int range) > +{ > + switch (range) { > + case LCEVC_ColorRange_Limited: > + return AVCOL_RANGE_MPEG; > + case LCEVC_ColorRange_Full: > + return AVCOL_RANGE_JPEG; > + } > + > + return AVCOL_RANGE_UNSPECIFIED; > +} > + > +static int alloc_base_frame(AVFilterLink *inlink, const AVFrame *in, > + LCEVC_PictureHandle *picture) > +{ > + AVFilterContext *ctx = inlink->dst; > + LCEVCContext *lcevc = ctx->priv; > + LCEVC_PictureDesc desc; > + LCEVC_PicturePlaneDesc planes[AV_VIDEO_MAX_PLANES] = { 0 }; > + LCEVC_ColorFormat fmt = map_format(in->format); > + int width = in->width - in->crop_left - in->crop_right; > + int height = in->height - in->crop_top - in->crop_bottom; > + LCEVC_ReturnCode res; > + > + res = LCEVC_DefaultPictureDesc(&desc, fmt, width, height); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_DefaultPictureDesc failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + for (int i = 0; i < AV_VIDEO_MAX_PLANES; i++) { > + planes[i].firstSample = in->data[i]; > + planes[i].rowByteStride = in->linesize[i]; > + } > + > + desc.cropTop = in->crop_top; > + desc.cropBottom = in->crop_bottom; > + desc.cropLeft = in->crop_left; > + desc.cropRight = in->crop_right; > + desc.sampleAspectRatioNum = in->sample_aspect_ratio.num; > + desc.sampleAspectRatioDen = in->sample_aspect_ratio.den; > + desc.colorRange = map_range(in->color_range); > + desc.colorPrimaries = (LCEVC_ColorPrimaries)in->color_primaries; > + desc.matrixCoefficients = (LCEVC_MatrixCoefficients)in->colorspace; > + desc.transferCharacteristics = (LCEVC_TransferCharacteristics)in->color_trc; > + av_log(ctx, AV_LOG_DEBUG, "in PTS %"PRId64", %dx%d, " > + "%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER", " > + "SAR %d:%d\n", > + in->pts, in->width, in->height, > + in->crop_top, in->crop_bottom, in->crop_left, in->crop_right, > + in->sample_aspect_ratio.num, in->sample_aspect_ratio.den); > + > + res = LCEVC_AllocPictureExternal(lcevc->decoder, &desc, NULL, planes, picture); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_AllocPictureExternal to allocate a buffer for a base frame\n"); > + return AVERROR_EXTERNAL; > + } > + > + return 0; > +} > + > +static int send_frame(AVFilterLink *inlink) > +{ > + AVFilterContext *ctx = inlink->dst; > + LCEVCContext *lcevc = ctx->priv; > + const AVFrameSideData *sd = av_frame_get_side_data(lcevc->in, AV_FRAME_DATA_LCEVC); > + LCEVC_ReturnCode res; > + > + // lcevc->base will be set only if a previous LCEVC_SendDecoderBase() call failed with LCEVC_Again, > + // in which case we'll try sending the picture again after having fetched at least one enhanced frame. > + if (!lcevc->base.hdl) { > + int ret = alloc_base_frame(inlink, lcevc->in, &lcevc->base); > + if (ret < 0) > + return ret; > + } > + > + if (sd) { > + res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, lcevc->in->pts, 0, sd->data, sd->size); > + if (res == LCEVC_Again) > + return AVERROR(EAGAIN); > + else if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_SendDecoderEnhancementData failed\n"); > + return AVERROR_EXTERNAL; > + } > + } > + > + res = LCEVC_SendDecoderBase(lcevc->decoder, lcevc->in->pts, 0, lcevc->base, -1, lcevc->in); > + if (res == LCEVC_Success) { > + lcevc->in = NULL; > + memset(&lcevc->base, 0, sizeof(lcevc->base)); > + } else if (res == LCEVC_Again) > + return AVERROR(EAGAIN); > + else { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_SendDecoderBase failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + return 0; > +} > + > +static int alloc_enhanced_frame(AVFilterLink *inlink, const AVFrame *out, > + LCEVC_PictureHandle *picture) > +{ > + AVFilterContext *ctx = inlink->dst; > + LCEVCContext *lcevc = ctx->priv; > + LCEVC_PictureDesc desc; > + LCEVC_PicturePlaneDesc planes[AV_VIDEO_MAX_PLANES] = { 0 }; > + LCEVC_ColorFormat fmt = map_format(out->format); > + LCEVC_ReturnCode res; > + > + res = LCEVC_DefaultPictureDesc(&desc, fmt, out->width, out->height); > + if (res != LCEVC_Success) > + return AVERROR_EXTERNAL; > + > + for (int i = 0; i < AV_VIDEO_MAX_PLANES; i++) { > + planes[i].firstSample = out->data[i]; > + planes[i].rowByteStride = out->linesize[i]; > + } > + > + res = LCEVC_AllocPictureExternal(lcevc->decoder, &desc, NULL, planes, picture); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_AllocPictureExternal to allocate a buffer for an enhanced frame\n"); > + return AVERROR_EXTERNAL; > + } > + > + return 0; > +} > + > +static int generate_output(AVFilterLink *inlink, AVFrame *out) > +{ > + AVFilterContext *ctx = inlink->dst; > + AVFilterLink *outlink = ctx->outputs[0]; > + LCEVCContext *lcevc = ctx->priv; > + LCEVC_PictureDesc desc; > + LCEVC_DecodeInformation info; > + LCEVC_PictureHandle picture; > + LCEVC_ReturnCode res; > + > + res = LCEVC_ReceiveDecoderPicture(lcevc->decoder, &picture, &info); > + if (res == LCEVC_Again) { > + int64_t pts; > + if (ff_inlink_acknowledge_status(inlink, &lcevc->status, &pts)) { > + av_frame_free(&out); > + ff_outlink_set_status(outlink, lcevc->status, pts); > + return 0; > + } > + // this shouldn't be reachable, but instead of asserting, just error out > + return AVERROR_EXTERNAL; > + } else if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_ReceiveDecoderPicture failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + av_frame_copy_props(out, (AVFrame *)info.baseUserData); > + av_frame_remove_side_data(out, AV_FRAME_DATA_LCEVC); > + > + av_frame_free((AVFrame **)&info.baseUserData); > + > + res = LCEVC_GetPictureDesc(lcevc->decoder, picture, &desc); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_GetPictureDesc failed\n"); > + return AVERROR_EXTERNAL; > + } > + res = LCEVC_FreePicture(lcevc->decoder, picture); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_FreePicture enhanced failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + out->crop_top = desc.cropTop; > + out->crop_bottom = desc.cropBottom; > + out->crop_left = desc.cropLeft; > + out->crop_right = desc.cropRight; > + out->sample_aspect_ratio.num = outlink->sample_aspect_ratio.num = desc.sampleAspectRatioNum; > + out->sample_aspect_ratio.den = outlink->sample_aspect_ratio.den = desc.sampleAspectRatioDen; > + out->color_range = map_range(desc.colorRange); > + out->color_primaries = (enum AVColorPrimaries)desc.colorPrimaries; > + out->colorspace = (enum AVColorSpace)desc.matrixCoefficients; > + out->color_trc = (enum AVColorTransferCharacteristic)desc.transferCharacteristics; > + out->width = outlink->w = desc.width + out->crop_left + out->crop_right; > + out->height = outlink->h = desc.height + out->crop_top + out->crop_bottom; > + > + av_log(ctx, AV_LOG_DEBUG, "out PTS %"PRId64", %dx%d, " > + "%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER", " > + "SAR %d:%d, " > + "hasEnhancement %d, enhanced %d\n", > + out->pts, out->width, out->height, > + out->crop_top, out->crop_bottom, out->crop_left, out->crop_right, > + out->sample_aspect_ratio.num, out->sample_aspect_ratio.den, > + info.hasEnhancement, info.enhanced); > + > + return ff_filter_frame(outlink, out); > +} > + > +static int receive_frame(AVFilterLink *inlink, AVFrame *out) > +{ > + AVFilterContext *ctx = inlink->dst; > + LCEVCContext *lcevc = ctx->priv; > + LCEVC_PictureHandle picture; > + LCEVC_ReturnCode res; > + int ret; > + > + ret = alloc_enhanced_frame(inlink, out, &picture); > + if (ret < 0) > + return ret; > + > + res = LCEVC_SendDecoderPicture(lcevc->decoder, picture); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_SendDecoderPicture failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + return generate_output(inlink, out); > +} > + > +static int config_props(AVFilterLink *outlink) > +{ > + AVFilterContext *ctx = outlink->src; > + AVFilterLink *inlink = ctx->inputs[0]; > + LCEVCContext *lcevc = ctx->priv; > + > + outlink->w = lcevc->w = inlink->w * 2 / FFMAX(inlink->sample_aspect_ratio.den, 1); > + outlink->h = lcevc->h = inlink->h * 2 / FFMAX(inlink->sample_aspect_ratio.den, 1); > + outlink->sample_aspect_ratio = (AVRational) { 0, 1 }; > + > + return 0; > +} > + > +static void flush_bases(AVFilterContext *ctx) > +{ > + LCEVCContext *lcevc = ctx->priv; > + LCEVC_PictureHandle picture; > + > + while (LCEVC_ReceiveDecoderBase(lcevc->decoder, &picture) == LCEVC_Success) > + LCEVC_FreePicture(lcevc->decoder, picture); > +} > + > +static int activate(AVFilterContext *ctx) > +{ > + LCEVCContext *lcevc = ctx->priv; > + AVFilterLink *inlink = ctx->inputs[0]; > + AVFilterLink *outlink = ctx->outputs[0]; > + AVFrame *out; > + int ret; > + > + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); > + > + if (!lcevc->in) { > + ret = ff_inlink_consume_frame(inlink, &lcevc->in); > + if (ret < 0) > + return ret; > + if (!ret) { > + int64_t pts; > + if (ff_inlink_acknowledge_status(inlink, &lcevc->status, &pts)) { > + if (!lcevc->status) > + ff_outlink_set_status(outlink, lcevc->status, pts); > + } > + if (!lcevc->status) > + FF_FILTER_FORWARD_WANTED(outlink, inlink); > + } > + } > + > + if (lcevc->in) { > + if (lcevc->in->width != inlink->w || > + lcevc->in->height != inlink->h || > + lcevc->in->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den || > + lcevc->in->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num) { > + inlink->dst->inputs[0]->w = lcevc->in->width; > + inlink->dst->inputs[0]->h = lcevc->in->height; > + inlink->dst->inputs[0]->sample_aspect_ratio.den = lcevc->in->sample_aspect_ratio.den; > + inlink->dst->inputs[0]->sample_aspect_ratio.num = lcevc->in->sample_aspect_ratio.num; > + > + config_props(outlink); > + } > + > + ret = send_frame(inlink); > + // Buffer as many base frames as the decoder allows > + if (!ret) { > + FF_FILTER_FORWARD_WANTED(outlink, inlink); > + return FFERROR_NOT_READY; > + } else if (ret < 0 && ret != AVERROR(EAGAIN)) > + return ret; > + } > + > + out = ff_get_video_buffer(outlink, lcevc->w, lcevc->h); > + if (!out) > + return AVERROR(ENOMEM); > + > + ret = receive_frame(inlink, out); > + if (ret < 0) { > + av_frame_free(&out); > + return ret; > + } > + > + flush_bases(ctx); > + > + return ret; > +} > + > +static void log_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, > + LCEVC_PictureHandle pic, const LCEVC_DecodeInformation *info, > + const uint8_t *data, uint32_t size, void *logctx) > +{ > + if (event != LCEVC_Log) // shouldn't happen > + return; > + > + if (strlen(data) != size) // sanitize input > + return; > + > + av_log(logctx, AV_LOG_INFO, "LCEVC Log: %s\n", data); > +} > + > +static av_cold int init(AVFilterContext *ctx) > +{ > + LCEVCContext *lcevc = ctx->priv; > + LCEVC_AccelContextHandle dummy = { 0 }; > + const int32_t event = LCEVC_Log; > + LCEVC_ReturnCode res; > + > + res = LCEVC_CreateDecoder(&lcevc->decoder, dummy); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_CreateDecoder failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + res = LCEVC_ConfigureDecoderIntArray(lcevc->decoder, "events", 1, &event); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_ConfigureDecoderIntArray failed to set \"events\"\n"); > + return AVERROR_EXTERNAL; > + } > + res = LCEVC_SetDecoderEventCallback(lcevc->decoder, log_callback, ctx); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_SetDecoderEventCallback failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + res = LCEVC_InitializeDecoder(lcevc->decoder); > + if (res != LCEVC_Success) { > + av_log(ctx, AV_LOG_ERROR, "LCEVC_InitializeDecoder failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + return 0; > +} > + > +static av_cold void uninit(AVFilterContext *ctx) > +{ > + LCEVCContext *lcevc = ctx->priv; > + > + LCEVC_DestroyDecoder(lcevc->decoder); > +} > + > +static const AVFilterPad lcevc_outputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .config_props = config_props, > + }, > +}; > + > +static const enum AVPixelFormat pix_fmts[] = { > + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUV420P12LE, > + AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, > + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10LE, AV_PIX_FMT_GRAY12LE, > + AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, > + AV_PIX_FMT_RGBA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, > + AV_PIX_FMT_NONE > +}; > + > +const AVFilter ff_vf_lcevc = { > + .name = "lcevc", > + .description = NULL_IF_CONFIG_SMALL("LCEVC"), > + .activate = activate, > + FILTER_INPUTS(ff_video_default_filterpad), > + FILTER_OUTPUTS(lcevc_outputs), > + FILTER_PIXFMTS_ARRAY(pix_fmts), > + .priv_size = sizeof(LCEVCContext), > + .init = init, > + .uninit = uninit, > +}; _______________________________________________ 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".