From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <ffmpeg-devel-bounces@ffmpeg.org>
Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100])
	by master.gitmailbox.com (Postfix) with ESMTPS id BC48C474FF
	for <ffmpegdev@gitmailbox.com>; Fri, 21 Mar 2025 02:55:29 +0000 (UTC)
Received: from [127.0.1.1] (localhost [127.0.0.1])
	by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 03786687BB9;
	Fri, 21 Mar 2025 04:55:26 +0200 (EET)
Received: from EUR05-AM6-obe.outbound.protection.outlook.com
 (mail-am6eur05olkn2103.outbound.protection.outlook.com [40.92.91.103])
 by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 209C5687AC6
 for <ffmpeg-devel@ffmpeg.org>; Fri, 21 Mar 2025 04:55:19 +0200 (EET)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=jNJALFk5c/FXn2Af6WBOttuqPM7CdnAp7j1ABlk/vK/EWZGV++KDiWqoQagrYQ5AgPLJ/jfN7RJb7X7jUBcVHGoogleAoptyADiZK/0gUQ/O6LiublSlsUPBJD6PtIxdAIFrt4DK5xZRU7eAqlS8QDBvmU4Soz7VylMJZomWTC2JOFCivaOBK0iHbY17p1IMPL9KD614ABdQbPS2E98ogb5/U3CFSdl1Px6fnvWGnqWvgWt21Ew/keBLI/owOtCcWa0Sb5aaLF3CcdEvejSzhAkOUdqzCykwCw3Fmz/y/e9p2sRN4WyY9i4eWow6IFpG+a5AWE3xHbVn3Nx8dWMOLg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector10001;
 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=B3gxNzKg0vuxbgzvF6TTHfYVFtwdwVa20pFCrpRBW+0=;
 b=HlcsGmhvOxXetzcyWtH/fXKifI4tzCS6UWOx4uvyc7qEf5s6IZwXJsv3ELP76p3eIkUW5pAVS0sYQNRJCTlgFSwK3S0YUNEKNwTbGblHWXU+C+yWngKYqXjlEVyjRfbRpOItrb3cYLJI7/vZp05ad8Usd3j8d+jt4hWDyJo9w6snpfGgf+oEide8/kFEtuC0uKjRRLpzK1lP3eH43xRxMM/x2Ls5je+2x6tVh9b98yYyW4wCV2zEG6TPNahF8If/CxV8ENDLeNtfNP3Su89el5zjUt3URvIpNemTMLuQFM6XQBhYrhF6v8dDafuQH11KRmeyuFXVlf8nwXAtrwzIlg==
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=B3gxNzKg0vuxbgzvF6TTHfYVFtwdwVa20pFCrpRBW+0=;
 b=M3DTmP1VkhvE6FrsdE5ETo5ldk6W1G8AXPrCFqhogg/67B5XWEjHFpRtRxzFg3gtPF1JoGcPhtJ+qi5vJZM5px+4g0Dv3O4MOhJRMsaGvGIxTiiuKGYfdQgeXklpCez9ndydTmM+gzVDE0pccWgKsIKGGfikewzAFhDiIFs0so8XILEsFIo84d4C7jdvOa1+W+TemVDhUhDdiOrPZOsBdWUHYBUylgd2JAG7c4MFjQ7hwBdU5ud30zLWWdk/O+FIHEaOY+GZ0Rby5S7WbuJwRClZtzU6bJd2Y8VK7uXkR/N2/JXz+Hm9i3ffEHVhxA3c9XodSCGOn6XX65nGC1XmVw==
Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14)
 by AS8P250MB0188.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:37b::5) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8534.34; Fri, 21 Mar
 2025 02:55:17 +0000
Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM
 ([fe80::384d:40d4:ecb7:1c9]) by AS8P250MB0744.EURP250.PROD.OUTLOOK.COM
 ([fe80::384d:40d4:ecb7:1c9%5]) with mapi id 15.20.8534.034; Fri, 21 Mar 2025
 02:55:17 +0000
Message-ID: <AS8P250MB07449D27E40B6BF89F801F058FDB2@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM>
Date: Fri, 21 Mar 2025 03:55:16 +0100
User-Agent: Mozilla Thunderbird
To: ffmpeg-devel@ffmpeg.org
References: <20250320170148.522-1-jamrial@gmail.com>
 <20250320170148.522-2-jamrial@gmail.com>
Content-Language: en-US
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
In-Reply-To: <20250320170148.522-2-jamrial@gmail.com>
X-ClientProxiedBy: ZR2P278CA0008.CHEP278.PROD.OUTLOOK.COM
 (2603:10a6:910:50::11) To AS8P250MB0744.EURP250.PROD.OUTLOOK.COM
 (2603:10a6:20b:541::14)
X-Microsoft-Original-Message-ID: <e312af62-604b-4eab-bd04-1e1f5996df96@outlook.com>
MIME-Version: 1.0
X-MS-Exchange-MessageSentRepresentingType: 1
X-MS-PublicTrafficType: Email
X-MS-TrafficTypeDiagnostic: AS8P250MB0744:EE_|AS8P250MB0188:EE_
X-MS-Office365-Filtering-Correlation-Id: d031f946-7893-4c27-11cf-08dd6823cfc5
X-Microsoft-Antispam: BCL:0;
 ARA:14566002|19110799003|6090799003|15080799006|5072599009|8060799006|7092599003|461199028|440099028|3412199025|12091999003|41001999003|56899033;
X-Microsoft-Antispam-Message-Info: =?utf-8?B?ZVhheXJhS3hVRjhKcG5kamJSQmpQdFYxaVZFb09RVE4vWWxRNTVkZmh6eVh6?=
 =?utf-8?B?YlQrVFRPM1VjU0hXamM5UytpbmJrZzdIU01yYmlhK05HVUkwRkNDWUsrWHJP?=
 =?utf-8?B?TzVtU2JRZkJLUDcvU1lHcVoyeWlITmVTcE1YVm15ZE9nVUQ4QjkwMXRxL3Vo?=
 =?utf-8?B?R1NvOU5YeGk0VTd1QTQyOVFUTTFTTHZnYU5RZE43ZmtUWGxBcjVPMHRiTlJO?=
 =?utf-8?B?YUlCTW1CbFc0RjlHYXNuTmNzSG9Ca0tQNkN1MFJKbGZac3Zxb2lGZnFGV0tw?=
 =?utf-8?B?S25YZUNNSVI2QnVtME5EWEFnODJscFRRRkIrMUxOeksyUXRQSWdraVFid1ZB?=
 =?utf-8?B?bk1hU1pOTUNiMmQ4U0lpOGNTa1dSOVpKbGRpU1RFVjlZd1hCZjZ0YUpQdGJX?=
 =?utf-8?B?c1E3TFpZajFweW94NHoxaTZ6ZkNwWUUxRW4xTldMZ2N2UFZnSGNYdHQ4bWhC?=
 =?utf-8?B?RE9pMittMVlBd2gzVGlKc1FIQ1pQako2Z2pDSmpBVUtNWjdtaS84bGFMZjJp?=
 =?utf-8?B?TnBFSWp1MkxIM0dmRmV3OStYdGVEMFkzT1BESmQrYVVXckFuV3BOcjlEOWJw?=
 =?utf-8?B?THp3OFBuYUxjakNiNHlQM1k4R1hPOXQ5Z242RlNkSnNKUTlndEhoNGNrVkR1?=
 =?utf-8?B?TEN2S2FCUUZtSVp4elBobnBHWk84TkwwanBIZ2RIeHhUQmpoQmJzOFo1N3N1?=
 =?utf-8?B?VWpQMVpndGdEYndaSVJQd3Uyc2lTdEo2dkdMNGNlZFQ3ZjJJYlhqRStuT1lp?=
 =?utf-8?B?UkJ3ZFdHOFZvTTdvWVR1RDgrM2l6TjNJSHM5VHZpUmdlL1BGOThRQVRNQkp0?=
 =?utf-8?B?OEE0U3ZyUDd0Yy96UENGUjFpT1p3Tk92YmxGL0t0bnRlY2tOVzNKRVYxZmts?=
 =?utf-8?B?OHpmNUZZU1dVWXR4dFRzMzMvRlhWUVdVZytUVDNFbE1sRkUxNFZqMTZnb1h6?=
 =?utf-8?B?RUg2VWNjMFFBeTNPb3UwaDZIdmdYbk1DeDRoaUtPbkpSUk9WL3hwMDJVNFlI?=
 =?utf-8?B?b3RvaVBFa2k1S2lqYmZ3elo4bktvc0gwTVhTMzd4ZnV0VVVieStDRzlqOUcw?=
 =?utf-8?B?bnZ0UEVzYlZUemkxSXp3VWJ0ZXQ4cmJzYzhpejRHWmFMbDdhNngyOTFtS09r?=
 =?utf-8?B?MFJtdHhHcE9yOEdSTTlqRlVwNmEraDJoTTRBbmp6T1AybHE2VnFKQlhBdHdW?=
 =?utf-8?B?MkZpZU8vNEF0b1ZnbldsbWdYQXRsTElWdTZQU09zb01TUU9kWmllbTZMVUsv?=
 =?utf-8?B?SWdQa055Y0RNYXNSemQ2NTMxNnFFVDZhVjlQN2FHZFdyUlVpSDdZZkVOWUZR?=
 =?utf-8?B?OTg1Y1lJc0FpTjNNNmZ3Q0VrWkVFcEZyb0VhM1VIL2lIeU9wWk1WYmEweTRq?=
 =?utf-8?B?dER2Sy9sVE5RM3ZjRzdQSnJEVWN1U2xWUFpuME0zSkVVMmw3ZkFEZUhsWnE5?=
 =?utf-8?B?eXRqTVNoVGlzeWpLRllMM3hPVStNaTRsVDZsQ3pjMkVEbjJRNC9xc1BoR0dK?=
 =?utf-8?B?OUwwN0EzOTJ6NWQvdDgzSWpwUll1eUppRDNmZUpLcEg0cjliRnNrYmpGV215?=
 =?utf-8?B?STZiR1ZWbXpKdS9PL1dWZXc5bTcrTHZPNVIzSnBoSlpKdmdQWkxJdStZZHEz?=
 =?utf-8?B?ajVVbW9uSWRtUFF1bjA1cStpem85SVE9PQ==?=
X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1
X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?ZXJzVFN6U2huQWRSRCtaclRyNlIwMzJjYlBlakNzUW1YUHEyaTFWczRRUEZl?=
 =?utf-8?B?bTZHMG5xVkpKWXprZmw5MmpwL2o0RFdXRlVuUlZVdlNhaHd6VkZlN1J5N1lu?=
 =?utf-8?B?ME9tWjdYQUlNWHJmNEtsVnczQk9mRVZRQ0o2UUliMW4zR1Z0UGxac3I0NUFY?=
 =?utf-8?B?TWRJbUJYcFZhRk8zcmc0WjU2Q1R1OWNSZzhzVDBqTjE2ajlvaFEybXpjdktM?=
 =?utf-8?B?ZlBWQTF5T2JYYURuMVZEdk00Q2w5UXFnenZvOTlpYzlHc1B3NHpEVmw5cGt0?=
 =?utf-8?B?SUhoZFkySkNOcTFTV3ZucDhxUG53UExVdmgwNUk0alRIeG5WdkV2WG5ZSEdR?=
 =?utf-8?B?ZVh2MXRPd2RjZVE2c0V5NkRXdzNaOFNJbGU2cjBSS29ja3RrN3hTUlFyVFZZ?=
 =?utf-8?B?YVZ0c1B3aEVscEtXelNqdWlQS2xzQlMwajhlUWVReWpLSkxsYjVEN0wrdGg2?=
 =?utf-8?B?ZXMyeWJMN25qRVBuSzg4TDZtUDY1eDJWMkZuMkQvMktMQVhFSWtsVkl0VU9x?=
 =?utf-8?B?MFRybm0yZ01QN1ZSOFJ0b3NrTDZGZTJIaWtad3A3K2RiTFZNcVpYMnBkMUNa?=
 =?utf-8?B?R0tRZ1BRYmEzQy9jc0xJeTBjWENQZVRTSDZPUXhwbFM5SzhBNnhjNERaMTFX?=
 =?utf-8?B?N2FSS0VSM0pwNDUvRkVwc3lPQXkwWWgreWtqejF1d2lnSWpxMXZaQXBaUXZs?=
 =?utf-8?B?bDRkVFlOU3BlOFVKMmUzVE13RndwQk1MMGVycGFQaVhRWDFIOGM3SWcwTFBE?=
 =?utf-8?B?dll4N1J5c08vM0F4T2IxVWpBNjJ6MWF3SDhNbkNrdU9kRmIvajNFM0NWcnpZ?=
 =?utf-8?B?KzJSNUxpL1M3aWFyOXhXUEljd0Rvc25jcU4xbzdqdmx3UzBNNCs3RWdNcDZ3?=
 =?utf-8?B?Zkw1UjRDblRKOThiOTVkSkJNVDVDUnc5SzNHaVMvaTdZR2dTK1c1NnZ4S1FT?=
 =?utf-8?B?VCtVL3RxZmdDRktoZU1FVHZQZnZmeXByZDFOaUw0eGdWelRYUTh0TllOY204?=
 =?utf-8?B?V0NRZkoyV2hpaVFqbjFVak1SSS91MlNLL1NGREhXc25kTVcvSnhoVWtnbkVn?=
 =?utf-8?B?RzVMaGdVMnA4RllWc1cvUkw1YmF6VGVxR25tYVJocVdxSnJHNXd6L2trZzd5?=
 =?utf-8?B?ZkV3dEpkazFJMm1nQ1BzU0dUcVEvczNoODBpOGx2NHlDcnF6dVhIL0FCaHp4?=
 =?utf-8?B?MGpnaGluQnRpMFpQNU9XczFsSWRhTjZnYlVMKy9LRkFZYm5uOWh1cjB2L0h3?=
 =?utf-8?B?b05LN0l4bjE3c20rRFVZNWlFZllHRVR3aEZ0bWpkTkFERTlyT2pwWklyYTds?=
 =?utf-8?B?Yk1xbXlqWnRPd2JYczJyQzRjMHFweHQwR3RWdGJ3L2gvc0tteGsvaGl0QVZV?=
 =?utf-8?B?WHhET1lONE9ZaVJWUy9wVDY2ODZ0Y29Va01RK2FRaDdRZEw3bkx3WHRxVk1r?=
 =?utf-8?B?Q1NhL0tBbUsvbVBGU2swbThUWndsS3V5ajRjc2VuZ09waG1XdjE3Y2ZkVCtB?=
 =?utf-8?B?ZWRMWnoxMHF2blByS3V5emUxQWI4RXFCeEJteVRSNmFkL09SSkoyNDhxbEtX?=
 =?utf-8?B?amFvTkJLQmcybmRRck55N25WdzFXbm15Y2VZcEFWemVVM3FMdU83R1l4QnNM?=
 =?utf-8?B?UDY3SkN1WEt3ZVYzYU1FMTd3V1ZaYlEzbTJ5Rzl0Z1RoR3d0clhwZjZjS21U?=
 =?utf-8?B?eFZvNzZGN0pxaXZZalV3elMrQ3NGTUhhN2RLd3pXZzVTOUFCei9pU1FBPT0=?=
X-OriginatorOrg: outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: d031f946-7893-4c27-11cf-08dd6823cfc5
X-MS-Exchange-CrossTenant-AuthSource: AS8P250MB0744.EURP250.PROD.OUTLOOK.COM
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Mar 2025 02:55:17.8144 (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: AS8P250MB0188
Subject: Re: [FFmpeg-devel] [PATCH 2/2] avformat/movenccenc: add support for
 CENC AV1 encryption
X-BeenThere: ffmpeg-devel@ffmpeg.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org>
List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe>
List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel>
List-Post: <mailto:ffmpeg-devel@ffmpeg.org>
List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help>
List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe>
Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: ffmpeg-devel-bounces@ffmpeg.org
Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org>
Archived-At: <https://master.gitmailbox.com/ffmpegdev/AS8P250MB07449D27E40B6BF89F801F058FDB2@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM/>
List-Archive: <https://master.gitmailbox.com/ffmpegdev/>
List-Post: <mailto:ffmpegdev@gitmailbox.com>

James Almer:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  configure                |   2 +-
>  libavformat/Makefile     |   1 +
>  libavformat/cbs.c        |   1 +
>  libavformat/cbs_av1.c    |   1 +
>  libavformat/movenc.c     |  13 ++-
>  libavformat/movenccenc.c | 223 ++++++++++++++++++++++++++++++++++++++-
>  libavformat/movenccenc.h |  20 +++-
>  7 files changed, 255 insertions(+), 6 deletions(-)
>  create mode 100644 libavformat/cbs.c
>  create mode 100644 libavformat/cbs_av1.c
> 
> diff --git a/configure b/configure
> index 14f7bcde0e..0f6b6c20fb 100755
> --- a/configure
> +++ b/configure
> @@ -3689,7 +3689,7 @@ mlp_demuxer_select="mlp_parser"
>  mmf_muxer_select="riffenc"
>  mov_demuxer_select="iso_media riffdec"
>  mov_demuxer_suggest="iamfdec zlib"
> -mov_muxer_select="iso_media iso_writer riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf ac3_parser"
> +mov_muxer_select="iso_media iso_writer riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf ac3_parser cbs_av1"
>  mov_muxer_suggest="iamfenc"
>  mp3_demuxer_select="mpegaudio_parser"
>  mp3_muxer_select="mpegaudioheader"
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 7730e7c4e6..1e57ae7d8a 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -740,6 +740,7 @@ SHLIBOBJS-$(CONFIG_JNI)                  += ffjni.o
>  SHLIBOBJS-$(CONFIG_JPEGXL_ANIM_DEMUXER)  += jpegxl_parse.o
>  SHLIBOBJS-$(CONFIG_MATROSKA_DEMUXER)     += mpeg4audio_sample_rates.o
>  SHLIBOBJS-$(CONFIG_MOV_DEMUXER)          += ac3_channel_layout_tab.o
> +SHLIBOBJS-$(CONFIG_MOV_MUXER)            += cbs.o cbs_av1.o
>  SHLIBOBJS-$(CONFIG_MP3_MUXER)            += mpegaudiotabs.o
>  SHLIBOBJS-$(CONFIG_MXF_MUXER)            += golomb_tab.o \
>                                              rangecoder_dec.o
> diff --git a/libavformat/cbs.c b/libavformat/cbs.c
> new file mode 100644
> index 0000000000..8f1235da8d
> --- /dev/null
> +++ b/libavformat/cbs.c
> @@ -0,0 +1 @@
> +#include "libavcodec/cbs.c"
> diff --git a/libavformat/cbs_av1.c b/libavformat/cbs_av1.c
> new file mode 100644
> index 0000000000..32b9e72c57
> --- /dev/null
> +++ b/libavformat/cbs_av1.c
> @@ -0,0 +1 @@
> +#include "libavcodec/cbs_av1.c"
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index af013e1fc6..c60c46012f 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -6767,7 +6767,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
>          } else {
>              size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
>          }
> -    } else if (par->codec_id == AV_CODEC_ID_AV1) {
> +    } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
>          if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
>              ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
>                                           &size, &offset);
> @@ -6815,6 +6815,13 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
>                  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
>              } else if(par->codec_id == AV_CODEC_ID_VVC) {
>                  ret = AVERROR_PATCHWELCOME;
> +            } else if(par->codec_id == AV_CODEC_ID_AV1) {
> +                av_assert0(size == pkt->size);
> +				ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
> +                if (ret > 0) {
> +                    size = ret;
> +                    ret = 0;
> +                }
>              } else {
>                  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
>              }
> @@ -8135,8 +8142,8 @@ static int mov_init(AVFormatContext *s)
>          if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
>              ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
>                  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
> -                 track->par->codec_id == AV_CODEC_ID_VVC),
> -                s->flags & AVFMT_FLAG_BITEXACT);
> +                 track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
> +                 track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
>              if (ret)
>                  return ret;
>          }
> diff --git a/libavformat/movenccenc.c b/libavformat/movenccenc.c
> index f54d3bcbca..af801eb3a0 100644
> --- a/libavformat/movenccenc.c
> +++ b/libavformat/movenccenc.c
> @@ -19,6 +19,9 @@
>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>   */
>  #include "movenccenc.h"
> +#include "libavcodec/av1_parse.h"
> +#include "libavcodec/bytestream.h"
> +#include "libavcodec/cbs_av1.h"
>  #include "libavutil/intreadwrite.h"
>  #include "libavutil/mem.h"
>  #include "avio_internal.h"
> @@ -280,6 +283,203 @@ int ff_mov_cenc_avc_write_nal_units(AVFormatContext *s, MOVMuxCencContext* ctx,
>      return 0;
>  }
>  
> +static int write_tiles(AVFormatContext *s, MOVMuxCencContext *ctx, AVIOContext *pb, AV1_OBU_Type type,
> +                       const AV1RawFrameHeader *frame_header, const uint8_t *fh_data, size_t fh_data_size,
> +                       const AV1RawTileGroup *tile_group)
> +{
> +    GetByteContext gb;
> +    size_t tgh_data_size = tile_group->data_size;
> +    int cur_tile_num = frame_header->tile_cols * frame_header->tile_rows;
> +    int total = 0;
> +
> +    // Get the Frame Header size
> +    if (type == AV1_OBU_FRAME)
> +        fh_data_size -= tgh_data_size;
> +    // Get the Tile Group Header size
> +    tgh_data_size -= tile_group->tile_data.data_size;
> +
> +    if (ctx->tile_num < cur_tile_num) {
> +        int ret = av_reallocp_array(&ctx->tile_group_sizes, cur_tile_num,
> +                                    sizeof(*ctx->tile_group_sizes));
> +        if (ret < 0) {
> +            ctx->tile_num = 0;
> +            return ret;
> +        }
> +    }
> +    ctx->tile_num = cur_tile_num;
> +
> +    total = fh_data_size + tgh_data_size;
> +    ctx->clear_bytes += total;
> +
> +    bytestream2_init(&gb, tile_group->tile_data.data, tile_group->tile_data.data_size);
> +
> +    // Build a table with block sizes for encrypted bytes and clear bytes
> +    for (unsigned tile_num = tile_group->tg_start; tile_num <= tile_group->tg_end; tile_num++) {
> +        uint32_t encrypted_bytes, tile_size_bytes, tile_size = 0;
> +
> +        if (tile_num == tile_group->tg_end) {
> +            tile_size = bytestream2_get_bytes_left(&gb);
> +            encrypted_bytes = tile_size & ~0xFU;
> +            ctx->clear_bytes += tile_size & 0xFU;
> +
> +            ctx->tile_group_sizes[tile_num].encrypted_bytes   = encrypted_bytes;
> +            ctx->tile_group_sizes[tile_num].aux_clear_bytes   = encrypted_bytes ? ctx->clear_bytes : 0;
> +            ctx->tile_group_sizes[tile_num].write_clear_bytes = tile_size & 0xFU;
> +
> +            if (encrypted_bytes)
> +                ctx->clear_bytes = 0;
> +            total += tile_size;
> +
> +            break;
> +        }
> +
> +        tile_size_bytes = frame_header->tile_size_bytes_minus1 + 1;
> +        if (bytestream2_get_bytes_left(&gb) < tile_size_bytes)
> +            return AVERROR_INVALIDDATA;
> +
> +        for (int i = 0; i < tile_size_bytes; i++)
> +            tile_size |= bytestream2_get_byteu(&gb) << 8 * i;
> +        if (bytestream2_get_bytes_left(&gb) <= tile_size)
> +            return AVERROR_INVALIDDATA;
> +        tile_size++;
> +
> +        // The spec requires encrypted bytes to be in blocks multiple of 16
> +        encrypted_bytes   =  tile_size & ~0xFU;
> +        ctx->clear_bytes += (tile_size &  0xFU) + tile_size_bytes;
> +
> +        ctx->tile_group_sizes[tile_num].encrypted_bytes   = encrypted_bytes;
> +        ctx->tile_group_sizes[tile_num].aux_clear_bytes   = encrypted_bytes ? ctx->clear_bytes : 0;
> +        ctx->tile_group_sizes[tile_num].write_clear_bytes = (tile_size & 0xFU) + tile_size_bytes;
> +
> +        if (encrypted_bytes)
> +            ctx->clear_bytes = 0;
> +
> +        total += tile_size + tile_size_bytes;
> +        bytestream2_skipu(&gb, tile_size);
> +    }
> +
> +    bytestream2_init(&gb, tile_group->tile_data.data, tile_group->tile_data.data_size);
> +
> +    avio_write(pb, fh_data, fh_data_size);
> +    avio_write(pb, tile_group->data, tgh_data_size);
> +
> +    for (unsigned tile_num = tile_group->tg_start; tile_num <= tile_group->tg_end; tile_num++) {
> +        const struct MOVMuxCencAV1TGInfo *sizes = &ctx->tile_group_sizes[tile_num];
> +
> +        avio_write(pb, gb.buffer, sizes->write_clear_bytes);
> +        bytestream2_skipu(&gb, sizes->write_clear_bytes);
> +        mov_cenc_write_encrypted(ctx, pb, gb.buffer, sizes->encrypted_bytes);
> +        bytestream2_skipu(&gb, sizes->encrypted_bytes);
> +        if (sizes->encrypted_bytes) {
> +            unsigned clear_bytes = sizes->aux_clear_bytes;
> +            if (clear_bytes > UINT16_MAX) {
> +                auxiliary_info_add_subsample(ctx, UINT16_MAX, 0);
> +                clear_bytes -= UINT16_MAX;
> +            }
> +            auxiliary_info_add_subsample(ctx, clear_bytes, sizes->encrypted_bytes);
> +        }
> +    }
> +
> +    return total;
> +}
> +
> +int ff_mov_cenc_av1_write_obus(AVFormatContext *s, MOVMuxCencContext* ctx,
> +                               AVIOContext *pb, const AVPacket *pkt)
> +{
> +    CodedBitstreamFragment *td = &ctx->temporal_unit;
> +    const CodedBitstreamAV1Context *av1 = ctx->cbc->priv_data;
> +    const AV1RawFrameHeader *frame_header = NULL;
> +    const uint8_t *fh_data = NULL;
> +    size_t fh_data_size;
> +    int out_size = 0, ret;
> +
> +    ret = mov_cenc_start_packet(ctx);
> +    if (ret) {
> +        return ret;
> +    }
> +
> +    ret = ff_cbs_read_packet(ctx->cbc, td, pkt);
> +    if (ret < 0) {
> +        av_log(s, AV_LOG_ERROR, "CENC-AV1: Failed to parse temporal unit.\n");
> +        return ret;
> +    }
> +
> +    if (!av1->sequence_header) {
> +        av_log(s, AV_LOG_ERROR, "CENC-AV1: No sequence header available\n");
> +        ret = AVERROR_INVALIDDATA;
> +        goto end;
> +    }
> +
> +    for (int i = 0; i < td->nb_units; i++) {
> +        const CodedBitstreamUnit *unit = &td->units[i];
> +        const AV1RawOBU *obu = unit->content;
> +
> +        switch (unit->type) {
> +        case AV1_OBU_FRAME_HEADER:
> +            if (!obu->obu.frame_header.show_existing_frame) {
> +                frame_header = &obu->obu.frame_header;
> +                fh_data      = unit->data;
> +                fh_data_size = unit->data_size;
> +                break;
> +            }
> +        // fall-through
> +        case AV1_OBU_SEQUENCE_HEADER:
> +        case AV1_OBU_METADATA:
> +            avio_write(pb, unit->data, unit->data_size);
> +            ctx->clear_bytes += unit->data_size;
> +            out_size += unit->data_size;
> +            break;
> +        case AV1_OBU_FRAME:
> +            frame_header = &obu->obu.frame.header;
> +            fh_data      = unit->data;
> +            fh_data_size = unit->data_size;
> +        // fall-through
> +        case AV1_OBU_TILE_GROUP:
> +            {
> +                const AV1RawTileGroup *tile_group;
> +
> +                if (!frame_header){
> +                    ret = AVERROR_INVALIDDATA;
> +                    goto end;
> +                }
> +
> +                if (unit->type == AV1_OBU_FRAME)
> +                    tile_group = &obu->obu.frame.tile_group;
> +                else
> +                    tile_group = &obu->obu.tile_group;
> +
> +                ret = write_tiles(s, ctx, pb, unit->type,
> +                                  frame_header, fh_data, fh_data_size, tile_group);
> +                if (ret < 0) {
> +                    av_log(s, AV_LOG_ERROR, "CENC-AV1: Failed to write tiles\n");
> +                    goto end;
> +                }
> +                av_assert0(ret == unit->data_size);
> +                out_size += unit->data_size;
> +                frame_header = NULL;
> +            }
> +            break;
> +        default:
> +            break;
> +        }
> +    }
> +
> +    if (ctx->clear_bytes)
> +        auxiliary_info_add_subsample(ctx, ctx->clear_bytes, 0);
> +    ctx->clear_bytes = 0;
> +
> +    ret = mov_cenc_end_packet(ctx);
> +    if (ret) {
> +        ret = AVERROR_INVALIDDATA;
> +        goto end;
> +    }
> +
> +    ret = out_size;
> +end:
> +    ff_cbs_fragment_reset(td);
> +    return ret;
> +}
> +
>  /* TODO: reuse this function from movenc.c */
>  static int64_t update_size(AVIOContext *pb, int64_t pos)
>  {
> @@ -388,8 +588,16 @@ int ff_mov_cenc_write_sinf_tag(MOVTrack* track, AVIOContext *pb, uint8_t* kid)
>      return update_size(pb, pos);
>  }
>  
> +static const CodedBitstreamUnitType decompose_unit_types[] = {
> +    AV1_OBU_TEMPORAL_DELIMITER,
> +    AV1_OBU_SEQUENCE_HEADER,
> +    AV1_OBU_FRAME_HEADER,
> +    AV1_OBU_TILE_GROUP,
> +    AV1_OBU_FRAME,
> +};
> +
>  int ff_mov_cenc_init(MOVMuxCencContext* ctx, uint8_t* encryption_key,
> -                     int use_subsamples, int bitexact)
> +                     int use_subsamples, enum AVCodecID codec_id, int bitexact)
>  {
>      int ret;
>  
> @@ -409,6 +617,15 @@ int ff_mov_cenc_init(MOVMuxCencContext* ctx, uint8_t* encryption_key,
>  
>      ctx->use_subsamples = use_subsamples;
>  
> +    if (codec_id == AV_CODEC_ID_AV1) {
> +        ret = ff_cbs_init(&ctx->cbc, codec_id, NULL);
> +        if (ret < 0)
> +            return ret;
> +
> +        ctx->cbc->decompose_unit_types    = decompose_unit_types;
> +        ctx->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types);
> +    }
> +
>      return 0;
>  }
>  
> @@ -417,4 +634,8 @@ void ff_mov_cenc_free(MOVMuxCencContext* ctx)
>      av_aes_ctr_free(ctx->aes_ctr);
>      av_freep(&ctx->auxiliary_info);
>      av_freep(&ctx->auxiliary_info_sizes);
> +
> +    av_freep(&ctx->tile_group_sizes);
> +    ff_cbs_fragment_free(&ctx->temporal_unit);
> +    ff_cbs_close(&ctx->cbc);
>  }
> diff --git a/libavformat/movenccenc.h b/libavformat/movenccenc.h
> index 7da5268090..722914dc1c 100644
> --- a/libavformat/movenccenc.h
> +++ b/libavformat/movenccenc.h
> @@ -23,6 +23,7 @@
>  #define AVFORMAT_MOVENCCENC_H
>  
>  #include "libavutil/aes_ctr.h"
> +#include "libavcodec/cbs.h"
>  #include "avformat.h"
>  #include "avio.h"
>  
> @@ -30,6 +31,12 @@
>  
>  struct MOVTrack;
>  
> +struct MOVMuxCencAV1TGInfo {
> +    uint32_t encrypted_bytes;
> +    uint32_t write_clear_bytes;
> +    uint32_t aux_clear_bytes;
> +};
> +
>  typedef struct {
>      struct AVAESCTR* aes_ctr;
>      uint8_t* auxiliary_info;
> @@ -43,6 +50,14 @@ typedef struct {
>      size_t auxiliary_info_subsample_start;
>      uint8_t* auxiliary_info_sizes;
>      size_t  auxiliary_info_sizes_alloc_size;
> +
> +    /* AV1 */
> +    struct MOVMuxCencAV1TGInfo *tile_group_sizes;
> +    uint32_t clear_bytes;
> +    int tile_num;
> +    /* CBS */
> +    CodedBitstreamContext *cbc;
> +    CodedBitstreamFragment temporal_unit;
>  } MOVMuxCencContext;
>  
>  /**
> @@ -50,7 +65,8 @@ typedef struct {
>   * @param key encryption key, must have a length of AES_CTR_KEY_SIZE
>   * @param use_subsamples when enabled parts of a packet can be encrypted, otherwise the whole packet is encrypted
>   */
> -int ff_mov_cenc_init(MOVMuxCencContext* ctx, uint8_t* encryption_key, int use_subsamples, int bitexact);
> +int ff_mov_cenc_init(MOVMuxCencContext* ctx, uint8_t* encryption_key, int use_subsamples,
> +                     enum AVCodecID codec_id, int bitexact);
>  
>  /**
>   * Free a CENC context
> @@ -73,6 +89,8 @@ int ff_mov_cenc_avc_parse_nal_units(MOVMuxCencContext* ctx, AVIOContext *pb, con
>  int ff_mov_cenc_avc_write_nal_units(AVFormatContext *s, MOVMuxCencContext* ctx, int nal_length_size,
>      AVIOContext *pb, const uint8_t *buf_in, int size);
>  
> +int ff_mov_cenc_av1_write_obus(AVFormatContext *s, MOVMuxCencContext* ctx,
> +                               AVIOContext *pb, const AVPacket *pkt);
>  /**
>   * Write the cenc atoms that should reside inside stbl
>   */

Duplicating .o files is meant for small stuff, not for gigantic things
like cbs_av1.o (whose .text is 86519B here).

- Andreas

_______________________________________________
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".