From patchwork Tue Jan 30 12:48:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45902 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2130696pzb; Tue, 30 Jan 2024 04:51:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IHpG3OHG2EAFp4I16dgBkUARzcnazksZlwLsVfXuT/4HMca/efYW0awxUA9MW1yVJzxTvtz X-Received: by 2002:a05:6402:3593:b0:55e:ab6b:5575 with SMTP id y19-20020a056402359300b0055eab6b5575mr8129981edc.1.1706619069213; Tue, 30 Jan 2024 04:51:09 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id x5-20020a05640226c500b0055f16576808si1478509edd.439.2024.01.30.04.51.08; Tue, 30 Jan 2024 04:51:09 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b=cpqP8rpi; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 740B368D352; Tue, 30 Jan 2024 14:51:01 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-TYZ-obe.outbound.protection.outlook.com (mail-tyzapc01olkn2061.outbound.protection.outlook.com [40.92.107.61]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4A6B168D346 for ; Tue, 30 Jan 2024 14:50:53 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oXu25N01+akYIeO78HD/I8kpidyqrD2bsio0YfNe82mJ0N4gAw0OCatvSeaF0jldKGYcdqZDKwgDBuokBHNsU3Bbir96wBWo/JrijZ+li+Kg5WW1ICi3qcDaS2airHTnFNoapJUUKTHRvSmKDzXCQeoc+8BbyF/b8idFqAqHzXxJNwJdL4Z2uO1+OZf4O+aAxuk8pIbrOAKlLEcA7tS4EoN4RJmB6f5nEMOi1JGp4a8zF7WBC5HzRAnUFV7jOGZuCNiRiUP8QubX9/T4CWhphUKAS0u6nlavreLJw4F2olLhLCM1SYddYMpj1JKrxE0qgWRZCVUyECSOfWVxXo+dzg== 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=eUy7p2aRxoT45pgfoP5JM45kFGXNEc/L+LnQWVLs+fw=; b=mZ2AXxHKlaIIKzjthFmg6Ui5pk4GG4vpMMUnENYBRw0wmU4vzMg1QBKVq2CRnM5AKcsOoATTjpR8ZdyZer+YUqpYKuKL/6s0JZrFEc5Hd7hFAukgElczleBSQtmbO3Sr5rzngsfhiT0shmjFw0+hYpbXI4T3jnCHSgXxAXFBiXMPS4ORsF7ImLeEcMB2nYDhBLib60RhC7lHSfxD+wI23zcIHmd6ZIQ9OX8aBiweTkiRLzvlqBTJw1QNLTRBxcN1ix9IrtzddQsZ1Uw74r5snDKkaExmojsWFOpeCP8M4VN+PV4SHCpTFrk0Juram5SqUD6x6zGQkKEQ2V6vPRfZ3Q== 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=eUy7p2aRxoT45pgfoP5JM45kFGXNEc/L+LnQWVLs+fw=; b=cpqP8rpiDlWM2oRusJRfzvtbnjJrR6kYZkqfO8CBBmMT5hvGGmpU4hYD6/8i5S62Gns3QuYQ8VJjjqslNrQNcG4+yhAHa7aDfaPQtflAadu7ygDmPhvxftfYjVfDv5ot9/bjTLrXtXBvmYwektNhOoc2iUgcLIoC7Hwui8mNECwH3a5hYncMQYQtm6Xm8y9w8Wkj5l8Tmp56Be1rus9RtFB4Jilabpmw3yAkOTLN4rtOic8POhXRZIpd55nSxb9/y4a1j9bcveC7bSnYk7MWtd1KO0T+ZmKb5l9YcWWzkzbneh7pcdCOzmZjSXZQIddBrQL84BnEFhKY6HG276W1kA== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by TYZPR06MB7274.apcprd06.prod.outlook.com (2603:1096:405:ab::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Tue, 30 Jan 2024 12:50:45 +0000 Received: from TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7]) by TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7%7]) with mapi id 15.20.7228.029; Tue, 30 Jan 2024 12:50:45 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 20:48:58 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240130124903.16892-1-nuomi2021@gmail.com> References: <20240130124903.16892-1-nuomi2021@gmail.com> X-TMN: [+jRihCQbnTylagGzqPPHpYNJA0lDwY9P] X-ClientProxiedBy: SI2PR02CA0035.apcprd02.prod.outlook.com (2603:1096:4:195::22) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240130124903.16892-2-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|TYZPR06MB7274:EE_ X-MS-Office365-Filtering-Correlation-Id: 88f3a105-59c8-42bc-5106-08dc219212fa X-MS-Exchange-SLBlob-MailProps: WaIXnCbdHrMX0ub4IzufZP48szTFHkH0Rp78Htu2j4bzlb60ArULl7mN+kY+ftl5FhtjFEJ+o3qUkNj91kFeKEdloPa+7vtnxHssAD1Vxtd6WDOXO3mqRmGSowKo0h0MZONYDgBWrZlluHSl/DE82mB6Xc61wxO6UcVjPVpCpYiW6zWOjHL5XOVdrhJgABxtmgMMxKxfuOQnys9W+80KAs4Y6nySqy1QRUqKZpmtRwARLJsj9e+WzlwiQVh0MSWVhGnrzXFJa2Y1+zXsP9OLK4+FUdxKgR25sycT6TXZV1Ds16w7tIY1AVnQ/mUafeS7IVlpAk+Z3/YL46xeXkjUfXMkHbxc9mNwhflZ/sijQSuLAdiAie27SaEHi5YDx+VM2m1MbHVLuhuiN9GBxJpnQyi7tRV6q2rx7Crq7S6zxWNHVssb/tLqMWNusItW8FrX1LOJNc+Eq3hd74q7gnwxKhfFRe8y6vY2JEWTI5kcHOfd2al98Z0wnzwO0+93yvfOSC74rksmNOUkOih3OP21tikqnqfcWFxUb0q/JRjUs4t1FrHunCIHAzA1rTL1sJ95L6LKT8Re2jLtuvR1asV7OK0TA6M/NxChWcSQebmLBsFdLizh4PaU/TWvpp8wv/7V94iST8e6IC0e4qCRDkqmsToZ0Ja+i2hwo5TxdYf5ZsqB3LYh3eWB6aa/agnm9jMj3rE1M2VPsJ//K8xfxI3ul1/WIVDkXz7xgZpQGov8vQNVxEoQPD0iPLurf01Rp3jQ64MKNBmqbFk= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +MpI8Rj1EA4Vhye4cMy9zZER3i2IRI+A3onkl9kvKqIKCz/+ueCy6tR4GIo5+JVcXnnhXfWmkaI+2QVM/wUbn8VKO0bAsqE29MdhxTZdRKAI4dwKE05xuyHbATQP1zZJAyiGN7nrFscsEFED0WleocmfMVjUgiBxK6e9okv6RiXxHnQHwvhcdskG+InaHnBsjXMgb2Kwan92+8A+410wIMqQER68nfrF33w/kLs1/NY99plCanUEFvmsUSSUiwTVgmNM2lyZYJu7wgptQ9lTtyIzqvUEhEy8eMbW6mjaY51NOhDAP7Dej3GEKYP8b1K3ApNONwSSLgIDBACNeQ0r+YHLL/X2gJyBHxgL0yWpvToAePlZJM0WCavtfWdxA/IPnivY0ZWt7D2HZccmmtVpYhisM41RjsEhZ0zj1VF/NRVxIl8itVXfBRDWhuOlg7V8gl2dB0nmZq5amd86wAvOvmAXl+qZrEEQGpXHkYXyk2QJjxV16Zpbi/oMFOME7FnhZIn/ww9PUeycdAgb6C1EmsOEnQmsxQhb9fjGSjfHnt1cTuqWMyCSsThRHa1PRjnogSL2rIXZ2DnrsvJeMZXN1LCMfPylhl3t80GtJxfHBI2n5ZdYYuHYJJ4XULeZWwDh X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?kOaHI3k/wVtnID/UE9KR01MuxVN4?= =?utf-8?q?CN8Ju/2M++AROdvJVNZaf4z7vnRT3cfc4+AKcv+ruMO9+5+HjL1dfF2BALf689Iwx?= =?utf-8?q?eajl4Q81gH3Wa3UyGcCAP0g853WJOzsqfCwksDxTKeywCcXb6PnReP7b2Dq4TKclX?= =?utf-8?q?vzSHWBHPExuTDE589CZ3hNDxYerk0mWtgU0sgZ6i34p2Wi7+31J8vfHlfCYeKIIKf?= =?utf-8?q?1pCTy+fvv13nzjkk+zDgmcVOMsT0M5bO7U5i3k6ssszJ4sxACf1/izDhEJqvQ5QlY?= =?utf-8?q?AeVuriTXoxmLj0+kOoEotzgmh5uLTYiFRgozuLmetI63I/vuQrETrQ2NV6VY1A5AV?= =?utf-8?q?Sp4rpJLF53sSwFJJshB4TUhER3Fc18wLy1f/UUjEcye9UTj4Cu7cPWatK6Qv8lo+5?= =?utf-8?q?nnxrX29ysb5AWN5He5VfeSC1xmplAF0YkxfFKJkwNpin6YlAaoIiH48vqJidrr1LY?= =?utf-8?q?pdstU7W22dbu7bTKV7+iLYDNkz98lbr6kF0igh7OCjx99oW3BASR0VsNw+vckhumA?= =?utf-8?q?Lq1yRCgVSvrnhxKnkV7aLnXYi5vSLLLWxMHms+Mc3Db8qL5xlMADsnq143ozZMeqe?= =?utf-8?q?BsSy8AihpQ3tlY8sgHaGcFcTSJZCVodTG2zNNvAeKhVm/w1ooj58jowXRPXyi0kYN?= =?utf-8?q?7oaIsDQuTClOcf50N6gP+nDljbe83HNrQ/qHKWPbfYYzfiD4cKi7yBm2g1kMcTYX+?= =?utf-8?q?qPARbJmi8ZmQf4+HculHRQBeynopeG0NUO+x+7MZLLZs3OSTw9pmp3LnaOyhlDYxE?= =?utf-8?q?xZA6+1IzjBwy3E5jDh6J0yBIjsgt2cSnoJWWuCfZbeUip3Nm3Gd8r3KR5vURwXrG5?= =?utf-8?q?s7AHuwRjULAIr/m5nZ+Y6Z5XGjuBPbV3ehTTS2JqzbhRSfs68jx8sQhX8+uGMR0cb?= =?utf-8?q?67c2dZEbO9yNYoh/UK5IVQo1W/xlAt6ES3Xq67vGZRHKlzHfsxS41tjd1YDtRH0zG?= =?utf-8?q?vB+8IFBBjYYLxufDcDyTxQlbrHVkC4caZJTsiBclX/y8gCPROrUreaBM+rzmZQdA1?= =?utf-8?q?BJRU+WceVeDhkI7HfUUxv/s5h/+QaIcv5w5DzlLczDNQ0Sq9HNcjm5XiFxG3wBCJT?= =?utf-8?q?htXw91lQAMX+U/+OYot8NlcyGSRpfthxJPkn0vS9ZmR/ifgadrlCbuCT2ultv/bf1?= =?utf-8?q?eyJsIXiGFHJLdYDnIhfgM/pETEI9LrjJNTf+iBydkcnf+Q8EbhG6vHxWTfCtdBlfv?= =?utf-8?q?Mcq8njDSLcrClNWjm?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 88f3a105-59c8-42bc-5106-08dc219212fa X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2024 12:50:45.0141 (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: TYZPR06MB7274 Subject: [FFmpeg-devel] [PATCH v5 1/6] avformat/mp4: add muxer support for H266/VVC X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nuo Mi , Thomas Siedel Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: Ff6a8uFFYOdA From: Thomas Siedel Add muxer for vvcc byte stream format. Add AV_CODEC_ID_VVC to ff_mp4_obj_type. Add AV_CODEC_ID_VVC to ISO Media codec (VvcConfigurationBox vvi1, vvc1 defined in ISO/IEC 14496-15:2021). Add VvcConfigurationBox vvcC which extends FullBox type in ISO/IEC 14496-15:2021. Tested with: ffmpeg -i NovosobornayaSquare_1920x1080.mp4 -c:v libvvenc test.mp4 && ffmpeg -i test.mp4 -f null - ffmpeg -i NovosobornayaSquare_1920x1080.mp4 -c:v copy test.mp4 && ffmpeg -i test.mp4 -f md5 - Signed-off-by: Thomas Siedel Co-Authored-By: Nuo Mi --- libavformat/Makefile | 6 +- libavformat/isom.c | 1 + libavformat/isom_tags.c | 3 + libavformat/mov.c | 6 + libavformat/movenc.c | 40 +- libavformat/vvc.c | 971 ++++++++++++++++++++++++++++++++++++++++ libavformat/vvc.h | 99 ++++ 7 files changed, 1122 insertions(+), 4 deletions(-) create mode 100644 libavformat/vvc.c create mode 100644 libavformat/vvc.h diff --git a/libavformat/Makefile b/libavformat/Makefile index dcc99eeac4..05b9b8a115 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -343,7 +343,7 @@ OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ oggparsevorbis.o vorbiscomment.o \ qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - av1.o avc.o hevc.o \ + av1.o avc.o hevc.o vvc.o\ flacenc_header.o avlanguage.o \ vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o @@ -365,7 +365,7 @@ OBJS-$(CONFIG_MODS_DEMUXER) += mods.o OBJS-$(CONFIG_MOFLEX_DEMUXER) += moflex.o OBJS-$(CONFIG_MOV_DEMUXER) += mov.o mov_chan.o mov_esds.o \ qtpalette.o replaygain.o dovi_isom.o -OBJS-$(CONFIG_MOV_MUXER) += movenc.o av1.o avc.o hevc.o vpcc.o \ +OBJS-$(CONFIG_MOV_MUXER) += movenc.o av1.o avc.o hevc.o vvc.o vpcc.o \ movenchint.o mov_chan.o rtp.o \ movenccenc.o movenc_ttml.o rawutils.o \ dovi_isom.o evc.o @@ -520,7 +520,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_vp8.o \ rtpenc_vp9.o \ rtpenc_xiph.o \ - avc.o hevc.o + avc.o hevc.o vvc.o OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o rtspdec.o httpauth.o \ urldecode.o OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o httpauth.o \ diff --git a/libavformat/isom.c b/libavformat/isom.c index 6d019881e5..9fbccd4437 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -36,6 +36,7 @@ const AVCodecTag ff_mp4_obj_type[] = { { AV_CODEC_ID_MPEG4 , 0x20 }, { AV_CODEC_ID_H264 , 0x21 }, { AV_CODEC_ID_HEVC , 0x23 }, + { AV_CODEC_ID_VVC , 0x33 }, { AV_CODEC_ID_AAC , 0x40 }, { AV_CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */ { AV_CODEC_ID_MPEG2VIDEO , 0x61 }, /* MPEG-2 Main */ diff --git a/libavformat/isom_tags.c b/libavformat/isom_tags.c index a575b7c160..058f0f2a59 100644 --- a/libavformat/isom_tags.c +++ b/libavformat/isom_tags.c @@ -118,6 +118,9 @@ const AVCodecTag ff_codec_movvideo_tags[] = { { AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') }, + { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') }, + { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') }, + { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, /* HEVC/H.265 which indicates parameter sets may be in ES */ { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */ { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', 'e') }, /* HEVC-based Dolby Vision derived from hev1 */ diff --git a/libavformat/mov.c b/libavformat/mov.c index 4cffd6c7db..cf931d4594 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2123,6 +2123,11 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) if ((uint64_t)atom.size > (1<<30)) return AVERROR_INVALIDDATA; + if (atom.type == MKTAG('v','v','c','C')) { + avio_skip(pb, 4); + atom.size -= 4; + } + if (atom.size >= 10) { // Broken files created by legacy versions of libavformat will // wrap a whole fiel atom inside of a glbl atom. @@ -8129,6 +8134,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('s','g','p','d'), mov_read_sgpd }, { MKTAG('s','b','g','p'), mov_read_sbgp }, { MKTAG('h','v','c','C'), mov_read_glbl }, +{ MKTAG('v','v','c','C'), mov_read_glbl }, { MKTAG('u','u','i','d'), mov_read_uuid }, { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 }, { MKTAG('f','r','e','e'), mov_read_free }, diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 8a27afbc57..b724bd5ebc 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -68,6 +68,7 @@ #include "ttmlenc.h" #include "version.h" #include "vpcc.h" +#include "vvc.h" static const AVOption options[] = { { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM }, @@ -1473,6 +1474,23 @@ static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track) return update_size(pb, pos); } +static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track) +{ + int64_t pos = avio_tell(pb); + + avio_wb32(pb, 0); + ffio_wfourcc(pb, "vvcC"); + + avio_w8 (pb, 0); /* version */ + avio_wb24(pb, 0); /* flags */ + + if (track->tag == MKTAG('v','v','c','1')) + ff_isom_write_vvcc(pb, track->vos_data, track->vos_len, 1); + else + ff_isom_write_vvcc(pb, track->vos_data, track->vos_len, 0); + return update_size(pb, pos); +} + /* also used by all avid codecs (dv, imx, meridien) and their variants */ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track) { @@ -2382,6 +2400,8 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex avid = 1; } else if (track->par->codec_id == AV_CODEC_ID_HEVC) mov_write_hvcc_tag(pb, track); + else if (track->par->codec_id == AV_CODEC_ID_VVC) + mov_write_vvcc_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) { mov_write_avcc_tag(pb, track); if (track->mode == MODE_IPOD) @@ -6170,6 +6190,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if ((par->codec_id == AV_CODEC_ID_DNXHD || par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_HEVC || + par->codec_id == AV_CODEC_ID_VVC || par->codec_id == AV_CODEC_ID_VP9 || par->codec_id == AV_CODEC_ID_EVC || par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->vos_len && @@ -6235,6 +6256,18 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL); } } + } else if (par->codec_id == AV_CODEC_ID_VVC && trk->vos_len > 6 && + (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) { + /* extradata is Annex B, assume the bitstream is too and convert it */ + if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) { + ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data, + &size, 0, NULL); + if (ret < 0) + return ret; + avio_write(pb, reformatted_data, size); + } else { + size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL); + } } else if (par->codec_id == AV_CODEC_ID_AV1) { if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) { ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data, @@ -6281,6 +6314,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) { int nal_size_length = (par->extradata[21] & 0x3) + 1; 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 { ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size); } @@ -7363,7 +7398,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_H264 || track->par->codec_id == AV_CODEC_ID_HEVC || + track->par->codec_id == AV_CODEC_ID_VVC), s->flags & AVFMT_FLAG_BITEXACT); if (ret) return ret; @@ -7832,6 +7868,8 @@ static const AVCodecTag codec_mp4_tags[] = { { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') }, + { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') }, + { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') }, { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') }, { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') }, { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') }, diff --git a/libavformat/vvc.c b/libavformat/vvc.c new file mode 100644 index 0000000000..14a4c0a2f3 --- /dev/null +++ b/libavformat/vvc.c @@ -0,0 +1,971 @@ +/* + * H.266/VVC helper functions for muxers + * + * Copyright (C) 2022, Thomas Siedel + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/get_bits.h" +#include "libavcodec/golomb.h" +#include "libavcodec/vvc.h" +#include "libavutil/intreadwrite.h" +#include "avc.h" +#include "avio.h" +#include "avio_internal.h" +#include "vvc.h" + +typedef struct VVCCNALUnitArray { + uint8_t array_completeness; + uint8_t NAL_unit_type; + uint16_t num_nalus; + uint16_t *nal_unit_length; + uint8_t **nal_unit; +} VVCCNALUnitArray; + +typedef struct VVCPTLRecord { + uint8_t num_bytes_constraint_info; + uint8_t general_profile_idc; + uint8_t general_tier_flag; + uint8_t general_level_idc; + uint8_t ptl_frame_only_constraint_flag; + uint8_t ptl_multilayer_enabled_flag; + uint8_t general_constraint_info[9]; + uint8_t ptl_sublayer_level_present_flag[VVC_MAX_SUBLAYERS - 1]; + uint8_t sublayer_level_idc[VVC_MAX_SUBLAYERS - 1]; + uint8_t ptl_num_sub_profiles; + uint32_t general_sub_profile_idc[VVC_MAX_SUB_PROFILES]; +} VVCPTLRecord; + +typedef struct VVCDecoderConfigurationRecord { + uint8_t lengthSizeMinusOne; + uint8_t ptl_present_flag; + uint16_t ols_idx; + uint8_t num_sublayers; + uint8_t constant_frame_rate; + uint8_t chroma_format_idc; + uint8_t bit_depth_minus8; + VVCPTLRecord ptl; + uint16_t max_picture_width; + uint16_t max_picture_height; + uint16_t avg_frame_rate; + uint8_t num_of_arrays; + VVCCNALUnitArray *array; +} VVCDecoderConfigurationRecord; + +typedef struct VVCCProfileTierLevel { + uint8_t profile_idc; + uint8_t tier_flag; + uint8_t general_level_idc; + uint8_t ptl_frame_only_constraint_flag; + uint8_t ptl_multilayer_enabled_flag; +// general_constraint_info + uint8_t gci_present_flag; + uint8_t gci_general_constraints[9]; + uint8_t gci_num_reserved_bits; +// end general_constraint_info + uint8_t ptl_sublayer_level_present_flag[VVC_MAX_SUBLAYERS - 1]; + uint8_t sublayer_level_idc[VVC_MAX_SUBLAYERS - 1]; + uint8_t ptl_num_sub_profiles; + uint32_t general_sub_profile_idc[VVC_MAX_SUB_PROFILES]; +} VVCCProfileTierLevel; + +static void vvcc_update_ptl(VVCDecoderConfigurationRecord *vvcc, + VVCCProfileTierLevel *ptl) +{ + /* + * The level indication general_level_idc must indicate a level of + * capability equal to or greater than the highest level indicated for the + * highest tier in all the parameter sets. + */ + if (vvcc->ptl.general_tier_flag < ptl->tier_flag) + vvcc->ptl.general_level_idc = ptl->general_level_idc; + else + vvcc->ptl.general_level_idc = + FFMAX(vvcc->ptl.general_level_idc, ptl->general_level_idc); + + /* + * The tier indication general_tier_flag must indicate a tier equal to or + * greater than the highest tier indicated in all the parameter sets. + */ + vvcc->ptl.general_tier_flag = + FFMAX(vvcc->ptl.general_tier_flag, ptl->tier_flag); + + /* + * The profile indication general_profile_idc must indicate a profile to + * which the stream associated with this configuration record conforms. + * + * If the sequence parameter sets are marked with different profiles, then + * the stream may need examination to determine which profile, if any, the + * entire stream conforms to. If the entire stream is not examined, or the + * examination reveals that there is no profile to which the entire stream + * conforms, then the entire stream must be split into two or more + * sub-streams with separate configuration records in which these rules can + * be met. + * + * Note: set the profile to the highest value for the sake of simplicity. + */ + vvcc->ptl.general_profile_idc = + FFMAX(vvcc->ptl.general_profile_idc, ptl->profile_idc); + + /* + * Each bit in flags may only be set if all + * the parameter sets set that bit. + */ + vvcc->ptl.ptl_frame_only_constraint_flag &= + ptl->ptl_frame_only_constraint_flag; + vvcc->ptl.ptl_multilayer_enabled_flag &= ptl->ptl_multilayer_enabled_flag; + + /* + * Constraints Info + */ + if (ptl->gci_present_flag) { + vvcc->ptl.num_bytes_constraint_info = 9; + memcpy(&vvcc->ptl.general_constraint_info[0], + &ptl->gci_general_constraints[0], sizeof(uint8_t) * 9); + + } else { + vvcc->ptl.num_bytes_constraint_info = 1; + memset(&vvcc->ptl.general_constraint_info[0], 0, sizeof(uint8_t) * 9); + } + + /* + * Each bit in flags may only be set if one of + * the parameter sets set that bit. + */ + memset(vvcc->ptl.ptl_sublayer_level_present_flag, 0, + sizeof(uint8_t) * vvcc->num_sublayers - 1); + memset(vvcc->ptl.sublayer_level_idc, 0, + sizeof(uint8_t) * vvcc->num_sublayers - 1); + + for (int i = vvcc->num_sublayers - 2; i >= 0; i--) { + vvcc->ptl.ptl_sublayer_level_present_flag[i] |= + ptl->ptl_sublayer_level_present_flag[i]; + if (vvcc->ptl.ptl_sublayer_level_present_flag[i]) { + vvcc->ptl.sublayer_level_idc[i] = + FFMAX(vvcc->ptl.sublayer_level_idc[i], + ptl->sublayer_level_idc[i]); + } else { + if (i == vvcc->num_sublayers - 1) { + vvcc->ptl.sublayer_level_idc[i] = vvcc->ptl.general_level_idc; + } else { + vvcc->ptl.sublayer_level_idc[i] = + vvcc->ptl.sublayer_level_idc[i + 1]; + } + } + } + + vvcc->ptl.ptl_num_sub_profiles = + FFMAX(vvcc->ptl.ptl_num_sub_profiles, ptl->ptl_num_sub_profiles); + if (vvcc->ptl.ptl_num_sub_profiles) { + for (int i = 0; i < vvcc->ptl.ptl_num_sub_profiles; i++) { + vvcc->ptl.general_sub_profile_idc[i] = + ptl->general_sub_profile_idc[i]; + } + } +} + +static void vvcc_parse_ptl(GetBitContext *gb, + VVCDecoderConfigurationRecord *vvcc, + unsigned int profileTierPresentFlag, + unsigned int max_sub_layers_minus1) +{ + VVCCProfileTierLevel general_ptl; + int j; + + if (profileTierPresentFlag) { + general_ptl.profile_idc = get_bits(gb, 7); + general_ptl.tier_flag = get_bits1(gb); + } + general_ptl.general_level_idc = get_bits(gb, 8); + + general_ptl.ptl_frame_only_constraint_flag = get_bits1(gb); + general_ptl.ptl_multilayer_enabled_flag = get_bits1(gb); + if (profileTierPresentFlag) { // parse constraint info + general_ptl.gci_present_flag = get_bits1(gb); + if (general_ptl.gci_present_flag) { + for (j = 0; j < 8; j++) + general_ptl.gci_general_constraints[j] = get_bits(gb, 8); + general_ptl.gci_general_constraints[8] = get_bits(gb, 7); + + general_ptl.gci_num_reserved_bits = get_bits(gb, 8); + skip_bits(gb, general_ptl.gci_num_reserved_bits); + } + while (gb->index % 8 != 0) + skip_bits1(gb); + } + + for (int i = max_sub_layers_minus1 - 1; i >= 0; i--) + general_ptl.ptl_sublayer_level_present_flag[i] = get_bits1(gb); + + while (gb->index % 8 != 0) + skip_bits1(gb); + + for (int i = max_sub_layers_minus1 - 1; i >= 0; i--) { + if (general_ptl.ptl_sublayer_level_present_flag[i]) + general_ptl.sublayer_level_idc[i] = get_bits(gb, 8); + } + + if (profileTierPresentFlag) { + general_ptl.ptl_num_sub_profiles = get_bits(gb, 8); + if (general_ptl.ptl_num_sub_profiles) { + for (int i = 0; i < general_ptl.ptl_num_sub_profiles; i++) + general_ptl.general_sub_profile_idc[i] = get_bits_long(gb, 32); + } + } + + vvcc_update_ptl(vvcc, &general_ptl); +} + +static int vvcc_parse_vps(GetBitContext *gb, + VVCDecoderConfigurationRecord *vvcc) +{ + unsigned int vps_max_layers_minus1; + unsigned int vps_max_sublayers_minus1; + unsigned int vps_default_ptl_dpb_hrd_max_tid_flag; + unsigned int vps_all_independent_layers_flag; + unsigned int vps_each_layer_is_an_ols_flag; + unsigned int vps_ols_mode_idc; + + unsigned int vps_pt_present_flag[VVC_MAX_PTLS]; + unsigned int vps_ptl_max_tid[VVC_MAX_PTLS]; + unsigned int vps_num_ptls_minus1 = 0; + + /* + * vps_video_parameter_set_id u(4) + */ + skip_bits(gb, 4); + + vps_max_layers_minus1 = get_bits(gb, 6); + vps_max_sublayers_minus1 = get_bits(gb, 3); + + /* + * numTemporalLayers greater than 1 indicates that the stream to which this + * configuration record applies is temporally scalable and the contained + * number of temporal layers (also referred to as temporal sub-layer or + * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 + * indicates that the stream is not temporally scalable. Value 0 indicates + * that it is unknown whether the stream is temporally scalable. + */ + vvcc->num_sublayers = FFMAX(vvcc->num_sublayers, + vps_max_sublayers_minus1 + 1); + + if (vps_max_layers_minus1 > 0 && vps_max_sublayers_minus1 > 0) + vps_default_ptl_dpb_hrd_max_tid_flag = get_bits1(gb); + if (vps_max_layers_minus1 > 0) + vps_all_independent_layers_flag = get_bits1(gb); + else + vps_all_independent_layers_flag = 1; + + for (int i = 0; i <= vps_max_layers_minus1; i++) { + skip_bits(gb, 6); //vps_layer_id[i] + if (i > 0 && !vps_all_independent_layers_flag) { + if (get_bits1(gb)) { // vps_independent_layer_flag[i] + unsigned int vps_max_tid_ref_present_flag = get_bits1(gb); + for (int j = 0; j < i; j++) { + if (vps_max_tid_ref_present_flag && get_bits1(gb)) // vps_direct_ref_layer_flag[i][j] + skip_bits(gb, 3); // vps_max_tid_il_ref_pics_plus1 + } + } + } + } + + if (vps_max_layers_minus1 > 0) { + if (vps_all_independent_layers_flag) + vps_each_layer_is_an_ols_flag = get_bits1(gb); + else + vps_each_layer_is_an_ols_flag = 0; + if (!vps_each_layer_is_an_ols_flag) { + if (!vps_all_independent_layers_flag) + vps_ols_mode_idc = get_bits(gb, 2); + else + vps_ols_mode_idc = 2; + if (vps_ols_mode_idc == 2) { + unsigned int vps_num_output_layer_sets_minus2 = get_bits(gb, 8); + for (int i = 1; i <= vps_num_output_layer_sets_minus2 + 1; i++) { + for (int j = 0; j <= vps_max_layers_minus1; j++) { + skip_bits1(gb); // vps_ols_output_layer_flag[i][j] + } + } + } + } + vps_num_ptls_minus1 = get_bits(gb, 8); + } else { + vps_each_layer_is_an_ols_flag = 0; + } + + for (int i = 0; i <= vps_num_ptls_minus1; i++) { + if (i > 0) + vps_pt_present_flag[i] = get_bits1(gb); + else + vps_pt_present_flag[i] = 1; + + if (!vps_default_ptl_dpb_hrd_max_tid_flag) + vps_ptl_max_tid[i] = get_bits(gb, 3); + else + vps_ptl_max_tid[i] = vps_max_sublayers_minus1; + } + + while (gb->index % 8 != 0) + skip_bits1(gb); + + for (int i = 0; i <= vps_num_ptls_minus1; i++) + vvcc_parse_ptl(gb, vvcc, vps_pt_present_flag[i], vps_ptl_max_tid[i]); + + /* nothing useful for vvcc past this point */ + return 0; +} + +static int vvcc_parse_sps(GetBitContext *gb, + VVCDecoderConfigurationRecord *vvcc) +{ + unsigned int sps_max_sublayers_minus1, sps_log2_ctu_size_minus5; + unsigned int sps_subpic_same_size_flag, sps_pic_height_max_in_luma_samples, + sps_pic_width_max_in_luma_samples; + unsigned int sps_independent_subpics_flag; + + skip_bits(gb, 8); // sps_seq_parameter_set_id && sps_video_parameter_set_id + sps_max_sublayers_minus1 = get_bits(gb, 3); + + /* + * numTemporalLayers greater than 1 indicates that the stream to which this + * configuration record applies is temporally scalable and the contained + * number of temporal layers (also referred to as temporal sub-layer or + * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 + * indicates that the stream is not temporally scalable. Value 0 indicates + * that it is unknown whether the stream is temporally scalable. + */ + vvcc->num_sublayers = FFMAX(vvcc->num_sublayers, + sps_max_sublayers_minus1 + 1); + + vvcc->chroma_format_idc = get_bits(gb, 2); + sps_log2_ctu_size_minus5 = get_bits(gb, 2); + + if (get_bits1(gb)) // sps_ptl_dpb_hrd_params_present_flag + vvcc_parse_ptl(gb, vvcc, 1, sps_max_sublayers_minus1); + + skip_bits1(gb); // sps_gdr_enabled_flag + if (get_bits(gb, 1)) // sps_ref_pic_resampling_enabled_flag + skip_bits1(gb); // sps_res_change_in_clvs_allowed_flag + + sps_pic_width_max_in_luma_samples = get_ue_golomb_long(gb); + vvcc->max_picture_width = + FFMAX(vvcc->max_picture_width, sps_pic_width_max_in_luma_samples); + sps_pic_height_max_in_luma_samples = get_ue_golomb_long(gb); + vvcc->max_picture_height = + FFMAX(vvcc->max_picture_height, sps_pic_height_max_in_luma_samples); + + if (get_bits1(gb)) { + get_ue_golomb_long(gb); // sps_conf_win_left_offset + get_ue_golomb_long(gb); // sps_conf_win_right_offset + get_ue_golomb_long(gb); // sps_conf_win_top_offset + get_ue_golomb_long(gb); // sps_conf_win_bottom_offset + } + + if (get_bits1(gb)) { // sps_subpic_info_present_flag + const unsigned int sps_num_subpics_minus1 = get_ue_golomb_long(gb); + const int ctb_log2_size_y = sps_log2_ctu_size_minus5 + 5; + const int ctb_size_y = 1 << ctb_log2_size_y; + const int tmp_width_val = AV_CEIL_RSHIFT(sps_pic_width_max_in_luma_samples, ctb_log2_size_y); + const int tmp_height_val = AV_CEIL_RSHIFT(sps_pic_height_max_in_luma_samples, ctb_log2_size_y); + const int wlen = av_ceil_log2(tmp_width_val); + const int hlen = av_ceil_log2(tmp_height_val); + if (sps_num_subpics_minus1 > 0) { // sps_num_subpics_minus1 + sps_independent_subpics_flag = get_bits1(gb); + sps_subpic_same_size_flag = get_bits1(gb); + } + for (int i = 0; sps_num_subpics_minus1 > 0 && i <= sps_num_subpics_minus1; i++) { + if (!sps_subpic_same_size_flag || i == 0) { + if (i > 0 && sps_pic_width_max_in_luma_samples > ctb_size_y) + skip_bits(gb, wlen); + if (i > 0 && sps_pic_height_max_in_luma_samples > ctb_size_y) + skip_bits(gb, hlen); + if (i < sps_num_subpics_minus1 && sps_pic_width_max_in_luma_samples > ctb_size_y) + skip_bits(gb, wlen); + if (i < sps_num_subpics_minus1 && sps_pic_height_max_in_luma_samples > ctb_size_y) + skip_bits(gb, hlen); + } + if (!sps_independent_subpics_flag) { + skip_bits(gb, 2); // sps_subpic_treated_as_pic_flag && sps_loop_filter_across_subpic_enabled_flag + } + } + get_ue_golomb_long(gb); // sps_subpic_id_len_minus1 + if (get_bits1(gb)) { // sps_subpic_id_mapping_explicitly_signalled_flag + if (get_bits1(gb)) // sps_subpic_id_mapping_present_flag + for (int i = 0; i <= sps_num_subpics_minus1; i++) { + skip_bits1(gb); // sps_subpic_id[i] + } + } + } + vvcc->bit_depth_minus8 = get_ue_golomb_long(gb); + + /* nothing useful for vvcc past this point */ + return 0; +} + +static int vvcc_parse_pps(GetBitContext *gb, + VVCDecoderConfigurationRecord *vvcc) +{ + + // Nothing of importance to parse in PPS + /* nothing useful for vvcc past this point */ + return 0; +} + +static void nal_unit_parse_header(GetBitContext *gb, uint8_t *nal_type) +{ + /* + * forbidden_zero_bit u(1) + * nuh_reserved_zero_bit u(1) + * nuh_layer_id u(6) + */ + skip_bits(gb, 8); + *nal_type = get_bits(gb, 5); + + /* + * nuh_temporal_id_plus1 u(3) + */ + skip_bits(gb, 3); +} + +static int vvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, + uint8_t nal_type, int ps_array_completeness, + VVCDecoderConfigurationRecord *vvcc) +{ + int ret; + uint8_t index; + uint16_t num_nalus; + VVCCNALUnitArray *array; + + for (index = 0; index < vvcc->num_of_arrays; index++) + if (vvcc->array[index].NAL_unit_type == nal_type) + break; + + if (index >= vvcc->num_of_arrays) { + uint8_t i; + + ret = + av_reallocp_array(&vvcc->array, index + 1, + sizeof(VVCCNALUnitArray)); + if (ret < 0) + return ret; + + for (i = vvcc->num_of_arrays; i <= index; i++) + memset(&vvcc->array[i], 0, sizeof(VVCCNALUnitArray)); + vvcc->num_of_arrays = index + 1; + } + + array = &vvcc->array[index]; + num_nalus = array->num_nalus; + + ret = av_reallocp_array(&array->nal_unit, num_nalus + 1, sizeof(uint8_t *)); + if (ret < 0) + return ret; + + ret = + av_reallocp_array(&array->nal_unit_length, num_nalus + 1, + sizeof(uint16_t)); + if (ret < 0) + return ret; + + array->nal_unit[num_nalus] = nal_buf; + array->nal_unit_length[num_nalus] = nal_size; + array->NAL_unit_type = nal_type; + array->num_nalus++; + + /* + * When the sample entry name is 'vvc1', the following applies: + * • The value of array_completeness shall be equal to 1 for arrays of SPS, + * and PPS NAL units. + * • If a VVC bitstream includes DCI NAL unit(s), the value of + * array_completeness shall be equal to 1 for the array of DCI units. + * Otherwise, NAL_unit_type shall not indicate DCI NAL units. + * • If a VVC bitstream includes VPS NAL unit(s), the value of + * array_completeness shall be equal to 1 for the array of VPS NAL units. + * Otherwise, NAL_unit_type shall not indicate VPS NAL units. + * When the value of array_completeness is equal to 1 for an array of a + * particular NAL_unit_type value, NAL units of that NAL_unit_type value + * cannot be updated without causing a different sample entry to be used. + * When the sample entry name is 'vvi1', the value of array_completeness + * of at least one of the following arrays shall be equal to 0: + • The array of DCI NAL units, if present. + • The array of VPS NAL units, if present. + • The array of SPS NAL units + • The array of PPS NAL units. + */ + if (nal_type == VVC_VPS_NUT || nal_type == VVC_SPS_NUT || + nal_type == VVC_PPS_NUT || nal_type == VVC_DCI_NUT ) + array->array_completeness = ps_array_completeness; + + return 0; +} + +static int vvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, + int ps_array_completeness, + VVCDecoderConfigurationRecord *vvcc) +{ + int ret = 0; + GetBitContext gbc; + uint8_t nal_type; + uint8_t *rbsp_buf; + uint32_t rbsp_size; + + rbsp_buf = ff_nal_unit_extract_rbsp(nal_buf, nal_size, &rbsp_size, 2); + if (!rbsp_buf) { + ret = AVERROR(ENOMEM); + goto end; + } + + ret = init_get_bits8(&gbc, rbsp_buf, rbsp_size); + if (ret < 0) + goto end; + + nal_unit_parse_header(&gbc, &nal_type); + + /* + * Note: only 'declarative' SEI messages are allowed in + * vvcc. Perhaps the SEI playload type should be checked + * and non-declarative SEI messages discarded? + */ + switch (nal_type) { + case VVC_OPI_NUT: + case VVC_VPS_NUT: + case VVC_SPS_NUT: + case VVC_PPS_NUT: + case VVC_PREFIX_SEI_NUT: + case VVC_SUFFIX_SEI_NUT: + ret = vvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, + ps_array_completeness, vvcc); + if (ret < 0) + goto end; + else if (nal_type == VVC_VPS_NUT) + ret = vvcc_parse_vps(&gbc, vvcc); + else if (nal_type == VVC_SPS_NUT) + ret = vvcc_parse_sps(&gbc, vvcc); + else if (nal_type == VVC_PPS_NUT) + ret = vvcc_parse_pps(&gbc, vvcc); + else if (nal_type == VVC_OPI_NUT) { + // not yet supported + } + if (ret < 0) + goto end; + break; + default: + ret = AVERROR_INVALIDDATA; + goto end; + } + + end: + av_free(rbsp_buf); + return ret; +} + +static void vvcc_init(VVCDecoderConfigurationRecord *vvcc) +{ + memset(vvcc, 0, sizeof(VVCDecoderConfigurationRecord)); + vvcc->lengthSizeMinusOne = 3; // 4 bytes + + vvcc->ptl.num_bytes_constraint_info = 1; + + vvcc->ptl_present_flag = 1; +} + +static void vvcc_close(VVCDecoderConfigurationRecord *vvcc) +{ + uint8_t i; + + for (i = 0; i < vvcc->num_of_arrays; i++) { + vvcc->array[i].num_nalus = 0; + av_freep(&vvcc->array[i].nal_unit); + av_freep(&vvcc->array[i].nal_unit_length); + } + + vvcc->num_of_arrays = 0; + av_freep(&vvcc->array); +} + +static int vvcc_write(AVIOContext *pb, VVCDecoderConfigurationRecord *vvcc) +{ + uint8_t i; + uint16_t j, vps_count = 0, sps_count = 0, pps_count = 0; + unsigned char *buf = NULL; + /* + * It's unclear how to properly compute these fields, so + * let's always set them to values meaning 'unspecified'. + */ + vvcc->avg_frame_rate = 0; + vvcc->constant_frame_rate = 1; + + av_log(NULL, AV_LOG_TRACE, + "lengthSizeMinusOne: %" PRIu8 "\n", + vvcc->lengthSizeMinusOne); + av_log(NULL, AV_LOG_TRACE, + "ptl_present_flag: %" PRIu8 "\n", + vvcc->ptl_present_flag); + av_log(NULL, AV_LOG_TRACE, + "ols_idx: %" PRIu16 "\n", vvcc->ols_idx); + av_log(NULL, AV_LOG_TRACE, + "num_sublayers: %" PRIu8 "\n", + vvcc->num_sublayers); + av_log(NULL, AV_LOG_TRACE, + "constant_frame_rate: %" PRIu8 "\n", + vvcc->constant_frame_rate); + av_log(NULL, AV_LOG_TRACE, + "chroma_format_idc: %" PRIu8 "\n", + vvcc->chroma_format_idc); + + av_log(NULL, AV_LOG_TRACE, + "bit_depth_minus8: %" PRIu8 "\n", + vvcc->bit_depth_minus8); + av_log(NULL, AV_LOG_TRACE, + "num_bytes_constraint_info: %" PRIu8 "\n", + vvcc->ptl.num_bytes_constraint_info); + av_log(NULL, AV_LOG_TRACE, + "general_profile_idc: %" PRIu8 "\n", + vvcc->ptl.general_profile_idc); + av_log(NULL, AV_LOG_TRACE, + "general_tier_flag: %" PRIu8 "\n", + vvcc->ptl.general_tier_flag); + av_log(NULL, AV_LOG_TRACE, + "general_level_idc: %" PRIu8 "\n", + vvcc->ptl.general_level_idc); + av_log(NULL, AV_LOG_TRACE, + "ptl_frame_only_constraint_flag: %" PRIu8 "\n", + vvcc->ptl.ptl_frame_only_constraint_flag); + av_log(NULL, AV_LOG_TRACE, + "ptl_multilayer_enabled_flag: %" PRIu8 "\n", + vvcc->ptl.ptl_multilayer_enabled_flag); + for (i = 0; i < vvcc->ptl.num_bytes_constraint_info; i++) { + av_log(NULL, AV_LOG_TRACE, + "general_constraint_info[%d]: %" PRIu8 "\n", i, + vvcc->ptl.general_constraint_info[i]); + } + + for (i = 0; i < vvcc->num_sublayers - 1; i++) { + av_log(NULL, AV_LOG_TRACE, + "ptl_sublayer_level_present_flag[%" PRIu8 "]: %" PRIu8 "\n", i, + vvcc->ptl.ptl_sublayer_level_present_flag[i]); + av_log(NULL, AV_LOG_TRACE, + "sublayer_level_idc[%" PRIu8 "]: %" PRIu8 "\n", i, + vvcc->ptl.sublayer_level_idc[i]); + } + + av_log(NULL, AV_LOG_TRACE, + "num_sub_profiles: %" PRIu8 "\n", + vvcc->ptl.ptl_num_sub_profiles); + + for (i = 0; i < vvcc->ptl.ptl_num_sub_profiles; i++) { + av_log(NULL, AV_LOG_TRACE, + "general_sub_profile_idc[%" PRIu8 "]: %" PRIx32 "\n", i, + vvcc->ptl.general_sub_profile_idc[i]); + } + + av_log(NULL, AV_LOG_TRACE, + "max_picture_width: %" PRIu16 "\n", + vvcc->max_picture_width); + av_log(NULL, AV_LOG_TRACE, + "max_picture_height: %" PRIu16 "\n", + vvcc->max_picture_height); + av_log(NULL, AV_LOG_TRACE, + "avg_frame_rate: %" PRIu16 "\n", + vvcc->avg_frame_rate); + + av_log(NULL, AV_LOG_TRACE, + "num_of_arrays: %" PRIu8 "\n", + vvcc->num_of_arrays); + for (i = 0; i < vvcc->num_of_arrays; i++) { + av_log(NULL, AV_LOG_TRACE, + "array_completeness[%" PRIu8 "]: %" PRIu8 "\n", i, + vvcc->array[i].array_completeness); + av_log(NULL, AV_LOG_TRACE, + "NAL_unit_type[%" PRIu8 "]: %" PRIu8 "\n", i, + vvcc->array[i].NAL_unit_type); + av_log(NULL, AV_LOG_TRACE, + "num_nalus[%" PRIu8 "]: %" PRIu16 "\n", i, + vvcc->array[i].num_nalus); + for (j = 0; j < vvcc->array[i].num_nalus; j++) + av_log(NULL, AV_LOG_TRACE, + "nal_unit_length[%" PRIu8 "][%" PRIu16 "]: %" + PRIu16 "\n", i, j, vvcc->array[i].nal_unit_length[j]); + } + + /* + * We need at least one of each: VPS and SPS. + */ + for (i = 0; i < vvcc->num_of_arrays; i++) + switch (vvcc->array[i].NAL_unit_type) { + case VVC_VPS_NUT: + vps_count += vvcc->array[i].num_nalus; + break; + case VVC_SPS_NUT: + sps_count += vvcc->array[i].num_nalus; + break; + case VVC_PPS_NUT: + pps_count += vvcc->array[i].num_nalus; + break; + default: + break; + } + + if (vps_count > VVC_MAX_VPS_COUNT) + return AVERROR_INVALIDDATA; + if (!sps_count || sps_count > VVC_MAX_SPS_COUNT) + return AVERROR_INVALIDDATA; + if (!pps_count || pps_count > VVC_MAX_PPS_COUNT) + return AVERROR_INVALIDDATA; + + /* bit(5) reserved = ‘11111’b; + unsigned int (2) LengthSizeMinusOne + unsigned int (1) ptl_present_flag */ + avio_w8(pb, vvcc->lengthSizeMinusOne << 1 | vvcc->ptl_present_flag | 0xf8); + + if (vvcc->ptl_present_flag) { + /* + * unsigned int(9) ols_idx; + * unsigned int(3) num_sublayers; + * unsigned int(2) constant_frame_rate; + * unsigned int(2) chroma_format_idc; */ + avio_wb16(pb, + vvcc->ols_idx << 7 | vvcc->num_sublayers << 4 | vvcc-> + constant_frame_rate << 2 | vvcc->chroma_format_idc); + + /* unsigned int(3) bit_depth_minus8; + bit(5) reserved = ‘11111’b; */ + avio_w8(pb, vvcc->bit_depth_minus8 << 5 | 0x1f); + + //VVCPTLRecord + + /* bit(2) reserved = ‘00’b; + unsigned int (6) num_bytes_constraint_info */ + avio_w8(pb, vvcc->ptl.num_bytes_constraint_info & 0x3f); + + /* unsigned int (7) general_profile_idc + unsigned int (1) general_tier_flag */ + avio_w8(pb, + vvcc->ptl.general_profile_idc << 1 | vvcc->ptl.general_tier_flag); + + /* unsigned int (8) general_level_idc */ + avio_w8(pb, vvcc->ptl.general_level_idc); + + /* + * unsigned int (1) ptl_frame_only_constraint_flag + * unsigned int (1) ptl_multilayer_enabled_flag + * unsigned int (8*num_bytes_constraint_info -2) general_constraint_info */ + buf = + (unsigned char *) malloc(sizeof(unsigned char) * + vvcc->ptl.num_bytes_constraint_info); + *buf = vvcc->ptl.ptl_frame_only_constraint_flag << vvcc->ptl. + num_bytes_constraint_info * 8 - 1 | vvcc->ptl. + ptl_multilayer_enabled_flag << vvcc->ptl.num_bytes_constraint_info * + 8 - 2 | *vvcc->ptl.general_constraint_info >> 2; + avio_write(pb, buf, vvcc->ptl.num_bytes_constraint_info); + free(buf); + + if (vvcc->num_sublayers > 1) { + uint8_t ptl_sublayer_level_present_flags = 0; + for (int i = vvcc->num_sublayers - 2; i >= 0; i--) { + ptl_sublayer_level_present_flags = + (ptl_sublayer_level_present_flags << 1 | vvcc->ptl. + ptl_sublayer_level_present_flag[i]); + } + avio_w8(pb, ptl_sublayer_level_present_flags); + } + + for (int i = vvcc->num_sublayers - 2; i >= 0; i--) { + if (vvcc->ptl.ptl_sublayer_level_present_flag[i]) + avio_w8(pb, vvcc->ptl.sublayer_level_idc[i]); + } + + /* unsigned int(8) num_sub_profiles; */ + avio_w8(pb, vvcc->ptl.ptl_num_sub_profiles); + + for (int j = 0; j < vvcc->ptl.ptl_num_sub_profiles; j++) { + /* unsigned int(32) general_sub_profile_idc[j]; */ + avio_wb32(pb, vvcc->ptl.general_sub_profile_idc[j]); + } + + //End of VvcPTLRecord + + /* + * unsigned int(16) max_picture_width;*/ + avio_wb16(pb, vvcc->max_picture_width); + + /* + * unsigned int(16) max_picture_height;*/ + avio_wb16(pb, vvcc->max_picture_height); + + /* + * unsigned int(16) avg_frame_rate; */ + avio_wb16(pb, vvcc->avg_frame_rate); + } + + /* unsigned int(8) num_of_arrays; */ + avio_w8(pb, vvcc->num_of_arrays); + + for (i = 0; i < vvcc->num_of_arrays; i++) { + /* + * bit(1) array_completeness; + * unsigned int(2) reserved = 0; + * unsigned int(5) NAL_unit_type; + */ + avio_w8(pb, vvcc->array[i].array_completeness << 7 | + vvcc->array[i].NAL_unit_type & 0x1f); + /* unsigned int(16) num_nalus; */ + if (vvcc->array[i].NAL_unit_type != VVC_DCI_NUT && + vvcc->array[i].NAL_unit_type != VVC_OPI_NUT) + avio_wb16(pb, vvcc->array[i].num_nalus); + for (j = 0; j < vvcc->array[i].num_nalus; j++) { + /* unsigned int(16) nal_unit_length; */ + avio_wb16(pb, vvcc->array[i].nal_unit_length[j]); + + /* bit(8*nal_unit_length) nal_unit; */ + avio_write(pb, vvcc->array[i].nal_unit[j], + vvcc->array[i].nal_unit_length[j]); + } + } + + return 0; +} + +int ff_vvc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, + int size, int filter_ps, int *ps_count) +{ + int num_ps = 0, ret = 0; + uint8_t *buf, *end, *start = NULL; + + if (!filter_ps) { + ret = ff_avc_parse_nal_units(pb, buf_in, size); + goto end; + } + + ret = ff_avc_parse_nal_units_buf(buf_in, &start, &size); + if (ret < 0) + goto end; + + ret = 0; + buf = start; + end = start + size; + + while (end - buf > 4) { + uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4); + uint8_t type = (buf[5] >> 3); + + buf += 4; + + switch (type) { + case VVC_VPS_NUT: + case VVC_SPS_NUT: + case VVC_PPS_NUT: + num_ps++; + break; + default: + ret += 4 + len; + avio_wb32(pb, len); + avio_write(pb, buf, len); + break; + } + + buf += len; + } + + end: + av_free(start); + if (ps_count) + *ps_count = num_ps; + return ret; +} + +int ff_vvc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, + int *size, int filter_ps, int *ps_count) +{ + AVIOContext *pb; + int ret; + + ret = avio_open_dyn_buf(&pb); + if (ret < 0) + return ret; + + ret = ff_vvc_annexb2mp4(pb, buf_in, *size, filter_ps, ps_count); + if (ret < 0) { + ffio_free_dyn_buf(&pb); + return ret; + } + + *size = avio_close_dyn_buf(pb, buf_out); + + return 0; +} + +int ff_isom_write_vvcc(AVIOContext *pb, const uint8_t *data, + int size, int ps_array_completeness) +{ + VVCDecoderConfigurationRecord vvcc; + uint8_t *buf, *end, *start; + int ret; + + if (size < 6) { + /* We can't write a valid vvcc from the provided data */ + return AVERROR_INVALIDDATA; + } else if ((*data & 0xf8) == 0xf8) { + /* Data is already vvcc-formatted */ + avio_write(pb, data, size); + return 0; + } else if (!(AV_RB24(data) == 1 || AV_RB32(data) == 1)) { + /* Not a valid Annex B start code prefix */ + return AVERROR_INVALIDDATA; + } + + ret = ff_avc_parse_nal_units_buf(data, &start, &size); + if (ret < 0) + return ret; + + vvcc_init(&vvcc); + + buf = start; + end = start + size; + + while (end - buf > 4) { + uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4); + uint8_t type = (buf[5] >> 3); + + buf += 4; + + switch (type) { + case VVC_OPI_NUT: + case VVC_VPS_NUT: + case VVC_SPS_NUT: + case VVC_PPS_NUT: + case VVC_PREFIX_SEI_NUT: + case VVC_SUFFIX_SEI_NUT: + ret = vvcc_add_nal_unit(buf, len, ps_array_completeness, &vvcc); + if (ret < 0) + goto end; + break; + default: + break; + } + + buf += len; + } + + ret = vvcc_write(pb, &vvcc); + + end: + vvcc_close(&vvcc); + av_free(start); + return ret; +} diff --git a/libavformat/vvc.h b/libavformat/vvc.h new file mode 100644 index 0000000000..11c700540f --- /dev/null +++ b/libavformat/vvc.h @@ -0,0 +1,99 @@ +/* + * H.266 / VVC helper functions for muxers + * + * 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 + */ + +/** + * @file + * internal header for H.266/VVC (de)muxer utilities + */ + +#ifndef AVFORMAT_VVC_H +#define AVFORMAT_VVC_H + +#include +#include "avio.h" + +/** + * Writes Annex B formatted H.266/VVC NAL units to the provided AVIOContext. + * + * The NAL units are converted to an MP4-compatible format (start code prefixes + * are replaced by 4-byte size fields, as per ISO/IEC 14496-15). + * + * If filter_ps is non-zero, any VVC parameter sets found in the input will be + * discarded, and *ps_count will be set to the number of discarded PS NAL units. + * + * @param pb address of the AVIOContext where the data shall be written + * @param buf_in address of the buffer holding the input data + * @param size size (in bytes) of the input buffer + * @param filter_ps whether to write parameter set NAL units to the output (0) + * or to discard them (non-zero) + * @param ps_count address of the variable where the number of discarded + * parameter set NAL units shall be written, may be NULL + * @return the amount (in bytes) of data written in case of success, a negative + * value corresponding to an AVERROR code in case of failure + */ +int ff_vvc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, + int size, int filter_ps, int *ps_count); + +/** + * Writes Annex B formatted H.266/VVC NAL units to a data buffer. + * + * The NAL units are converted to an MP4-compatible format (start code prefixes + * are replaced by 4-byte size fields, as per ISO/IEC 14496-15). + * + * If filter_ps is non-zero, any VVC parameter sets found in the input will be + * discarded, and *ps_count will be set to the number of discarded PS NAL units. + * + * On success, *size holds the size (in bytes) of the output data buffer. + * + * @param buf_in address of the buffer holding the input data + * @param size address of the variable holding the size (in bytes) of the input + * buffer (on input) and of the output buffer (on success) + * @param buf_out on success, address of the variable holding the address of + * the output buffer + * @param filter_ps whether to write parameter set NAL units to the output (0) + * or to discard them (non-zero) + * @param ps_count address of the variable where the number of discarded + * parameter set NAL units shall be written, may be NULL + * @return 0 in case of success, a negative value corresponding to an AVERROR + * code in case of failure + * @note *buf_out will be treated as uninitialized on input and won't be freed. + */ +int ff_vvc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, + int *size, int filter_ps, int *ps_count); + +/** + * Writes H.266/VVC extradata (parameter sets, declarative SEI NAL units) to + * the provided AVIOContext. + * + * If the extradata is Annex B format, it gets converted to vvcC format before + * writing. + * + * @param pb address of the AVIOContext where the vvcC shall be written + * @param data address of the buffer holding the data needed to write the vvcC + * @param size size (in bytes) of the data buffer + * @param ps_array_completeness whether all parameter sets are in the vvcC (1) + * or there may be additional parameter sets in the bitstream (0) + * @return >=0 in case of success, a negative value corresponding to an AVERROR + * code in case of failure + */ +int ff_isom_write_vvcc(AVIOContext *pb, const uint8_t *data, + int size, int ps_array_completeness); + +#endif /* AVFORMAT_VVC_H */ From patchwork Tue Jan 30 12:48:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45901 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2130621pzb; Tue, 30 Jan 2024 04:51:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IGt0WUybKRufJaxS20AbexPaUVK7WJ36QvsP+3Dd4lKlq4dqhVEOBsTBiNFss2PZWf76sDw X-Received: by 2002:a05:6402:281:b0:55f:3975:209c with SMTP id l1-20020a056402028100b0055f3975209cmr1137504edv.18.1706619059791; Tue, 30 Jan 2024 04:50:59 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f25-20020a056402161900b0055f15762772si1489961edv.32.2024.01.30.04.50.59; Tue, 30 Jan 2024 04:50:59 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b=cKbFcL7d; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 71F0C68D349; Tue, 30 Jan 2024 14:50:57 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-TYZ-obe.outbound.protection.outlook.com (mail-tyzapc01olkn2015.outbound.protection.outlook.com [40.92.107.15]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4874268D2F2 for ; Tue, 30 Jan 2024 14:50:50 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Ab/JQqdsldhR4sDMsy8ktL6uHbc5cdi21xR4YOW15JWu6tnk3t1w7LlFDPG+aOhmjxGqcis1ayJhupj07pcpSxn8x7SUZOdoybIKqK1ukiYsRIT+ZQhW2p8AswleJMmJSXi2a3lQIlI0za3E6DtzC0SVXwuujwVLWAqA6ZYdSXx80RzXTc5E7+0Nhh/NJnJ1+yl5T8DUhfoYL03j6uqJIE+oZHrXA+ikozzvOlbPJtnlovETX+EwXfK0XWBAsbD8Xkbs0IY/DXSkRg/A/qPFwn93WdaWG9agHu495OHH3GCvUdXhuOxQCktIONMgnmDr9Xg4BqkyWO1HwaRHzK5OZA== 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=l4LjObjmA5n/06oN7f6DOnVd8fANF0gDN1CEocYblpU=; b=frg3JL84QJkLSSB09WUUEtHuMBDN6jzJBFVjIr5lPb7vjlHTclVi9Q3yfLP25y0kxqZQEpKa2OmtHTEix2zNHssHC2xiUbGloBf0rvwdHScAm0y35YKvgmKRnWvlRgJwBWgT3QtqQiT0jbjkYN/+xGStGwnZZ3xsVlhA2dVaEQ9HmsPrFUpJq5Ddvoj0BzsSf0xpeb6PKductNenTm9n9guaPTnaU5NknNaUDJUJlrP9aPMFl3RDYl4ioM0zFTq7wCCUPDZ2ngCeHKXmMZv1Pa4MeaQ/T3/SCea6KtXqwS2XiiPzt9Tq5nZ2qnLtYxjwbtua/LhVzXe42mcLlMiy6g== 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=l4LjObjmA5n/06oN7f6DOnVd8fANF0gDN1CEocYblpU=; b=cKbFcL7dWNck86YQQv5kI4+nXqtibw6YtE+ud0nWbHX+6J9b2osAIWen7WmelJqKv9ebVl9+IssTYs8O2855lHd5rfOv5EAnsBv1w4VPJpWMOi8RZPOWfclbkm3fNTPaZJp3nlpEombSjP29KWpWCDrTEttoETJTuHRLwJG1rTqPeIhLV7uVlhUl5uewJclO4LKBKApcsi+x3IE8HrM4Z1PiFR2E3jRqGFZba+hUjxtp/I/NdeUJUCJerfaCJSk6i8+/oG/1hSwrkXwJqM3/sLmzKj4WtYaTLvbb3XX7vMD7U5+tzTEsl+iJ5zfxKfNHnoihb00yUZOlGBHWttlQHw== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by TYZPR06MB7274.apcprd06.prod.outlook.com (2603:1096:405:ab::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Tue, 30 Jan 2024 12:50:45 +0000 Received: from TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7]) by TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7%7]) with mapi id 15.20.7228.029; Tue, 30 Jan 2024 12:50:45 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 20:48:59 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240130124903.16892-1-nuomi2021@gmail.com> References: <20240130124903.16892-1-nuomi2021@gmail.com> X-TMN: [6ucquX9K4c3rflKf9ime3x9Ez4XbIXxz] X-ClientProxiedBy: SI2PR02CA0035.apcprd02.prod.outlook.com (2603:1096:4:195::22) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240130124903.16892-3-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|TYZPR06MB7274:EE_ X-MS-Office365-Filtering-Correlation-Id: f7730a59-6498-4fad-0ce6-08dc21921399 X-MS-Exchange-SLBlob-MailProps: Vs63Iqe4sQmENacaprcsf8K7uW5aY0aB8oW0MSUSc0xswzBDk5H9buDKTSzH208phJd6f+L+rY5KjNYNMDrHdAQZ6zCUkheYqA68cazLRZZbYj9sJZt6HAzwiPc85u8/OPkCA4LYd//3dITJF63KHTgvWdklZqidfywbE8LtKnayStrYmU6Fo/sj3ZlGWbiwIxTR6wroTYk2RCN0XaL5fwNHg34nRL7nRVmZvn21OK1SbcTzBN4ZgZYgadqkeplHu+DhnDuyYOBuW7L68YvdAqopj0+YR5iCU5dM1pyS0nDGaLkEDiuvdkTlulrtN5M8xVVbcgcBTGhzisdu+uQWfqMRqD4IJYQ5l+hSh9Xd4ZWvEGyUQ3tL/3g53dHDfEK0iqzorWfMkSc0sOVLAJ0h3o5vwCtVuD35iWv/VJGD5z5h6JdB0Hbr/lMttgNtB/rcNt8nFVwT96Le8WJDN4K1NzkwOQjhh/F5gd1h2zmHZjkzDaWI+L9T+v1x+wtApJRpejCoOSIzraU39dJMXNXu3KSEfI0DmSOpQQw4kvyT15Cr72Aia8T07Dm7Pc0tF2xVaE4lvshVy6otSV30urB5iunMdt4LqqVSWpDgG6KJlSbDeBTJtV2KdJLU3rPBxnLBF9R0bwNBQWrJf2VO2/L36vZQDbnUPMtqSBDqDgoc1K8p6+m8zTSJpt6Fd/5KriWG3zddw2ONymMwSVTkcE2jl4432OIVZACIZRXyuXUvAHI= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LdrCBOeO1Jy/mRThXc7G1m+YiPWSLIZzjxSpbzvRorVBLKD1tNb6y2ymWNQ65xjO8OkteYrhMSZSHZ61efzJkdCr2xAuhjfY+HSLkXNwnE2uX0NvYzBPYHfF/dc5enT33kYbMdRoU3btcRjOWAyXvofP6kAQyWlBFtvUTRbkaEuXpMSmWDSLMzqogRAczte/6QHrquYZaNjAomOKHIC3iqcqX3EeZu/paRGxpnzv7VZ8ffMTS15PzBb9gtAH9XaBmFZYA2UraR+J0AMfRVYsuBAYbrZiYZvEnP6k2VI4rfwMD4lAehn4j7P+lkybBJ8+KYXXr+kvJEqfr/WwEGhhGYMmKoxsWoJ2XF/CMpWnOdZh/7rstXvZrUSopGYm1++wYFD/G/zARRJ1UGXkRFV2TXp6rPbHwTIYdesCaqevxdfHjASkoBLc5JNwFFzsyG71c8dOLvQZfwwSK5G+vtmkiQbKNkRN4k9CQtrJEzHK+O4MNTtL443boh8U2gwXmZOqBPvnmxxFr9pip3kWpP2SbEK9+Yteje8sFfqPByhTGAYLu71M4sOngYTYMb5Dif66MRIB31A2+jdc4jwSAkhblkvcbBjalmy84uI0ERj91e7/uth7Wa2L8uIgOugkEtb0 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 0kdoUNxPXW9sRe38u2Pxr7DyLErcfRDBEj5vZgSaUDNhpf+gYqTA4a6mfX/OCc8mb3JvjJfI92aoLV8Wdeh1qmyTrAYlrOS8pRTx/HVIKmjZsNIs7g+x9e7pQNDJc5BFUhp+QcrCtHOtsRauqWs8ff+JZwCAMZf4M0SzQiiUORz6lcZwpe2Wf8k0S0HRJVokaR7yFH88UCr6fj/yWXjuuu19oojZARRgoSvGV+yE0qwvSm/j58HDHV0MVfUi+O7iymjEIaWxz/Nocm7CNGGCW65A32I4j/weskLYc6FF0XeEG7TocvqO0Ax8hZK3El1XMVbNdMnwBMgZrdkV7cCnpFL9rcNBkvvrzXA9oX9mZKjXcEwAh3JmmxVyruVbHNT75HWvrnLJqHTJxwtAGnBMHwUiCBJj9Cta91em16Qi3Dq++mHlJ26yJvQkrfMnCo+42nHTVmWwlVdOxMrtWu2RlRN+x+l+0vQrnF08MVF/Ms5WchYR1E6c8iPRaEiVfSD5JJhNASBkb4Jfwt5EgR99miLevOGJxtops2uKJGKQQBtwEmvvHGKheKa4JXCDuZ+kuIsNz+GtP8O1pU0cEg/E2pmzc6jqGnFB5Z5/c20SDJjli1uIXE0sWpO2gQwFQdYlS7g84iR5aUnpIpOt398IAQanKTT+5XdFnMZcjVbcXgSijVO1F5pSp/GdAR9w3A/lDfsRzSIgtCxmmu78Sj9VQzZnbh6EqfhrQVOrvWIEQTgXjSARartmy6N5Xq8H2kQfvFzNlSLuerRffWS8yCVq3DPRro/g0OZUD/pw0htUwHN9iEBDttI783naYqVbZJG8WvNABUuzftz5wF86gzr03ms/ucWDIqwAWOx1HHWNW/MyTHc3/SorWLRvCvo9anNERc1gPMKqLbFok0XR+dX3nB3XH1qmBNfSAwCBUtu7IXYSpHIpWuJO+Bp9lioKPqLUp4Sriae7I1pI5ODtgbi8NRytbIKiXtPYJOpcGfCizsq+4g5x8eGW+6KVXQMigfW9iPNSUPGzKCq3E1ej4Pkx9jAGqPbcL8j694DCUw8RqemhSAzU2yJWiVEQUqBgUTVWhUFt4CvKEFCfXEcC5iOMH9VtwrUdgYjUNiWQH0sjN+3SNOOpCQ2EHOn9jiJL0ytNBEwgBY5SauAKHkxByCFCEg1ZWmP7Nj5FEu9kFDZ3uRdSGug8TvDUADWUj03IPZprvm0mUSXZfoKXa7V7UCgXizn1AXUK2fF1JwCHO//LMnwXWA1/DkZbwCgZX5cF23vl X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: f7730a59-6498-4fad-0ce6-08dc21921399 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2024 12:50:45.8984 (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: TYZPR06MB7274 Subject: [FFmpeg-devel] [PATCH v5 2/6] avformat/mpegtsenc: refact mpegts_check_bitstream to loop up table X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: qBrsK9yeh0DY --- libavformat/mpegtsenc.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 84edd418f0..4e5c264d2a 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -2257,23 +2257,26 @@ static void mpegts_deinit(AVFormatContext *s) static int mpegts_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt) { - int ret = 1; + const struct Entry { + enum AVCodecID id; + const char *bsf_name; + uint8_t mask; + uint8_t value; + } list[] = { + { AV_CODEC_ID_H264, "h264_mp4toannexb", 0xff, 0x01 /* configurationVersion in AVCDecoderConfigurationRecord */}, + { AV_CODEC_ID_HEVC, "hevc_mp4toannexb", 0xff, 0x01 /* configurationVersion in HEVCDecoderConfigurationRecord */}, + }; - if (st->codecpar->codec_id == AV_CODEC_ID_H264) { - if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && - (AV_RB24(pkt->data) != 0x000001 || - (st->codecpar->extradata_size > 0 && - st->codecpar->extradata[0] == 1))) - ret = ff_stream_add_bitstream_filter(st, "h264_mp4toannexb", NULL); - } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { - if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && - (AV_RB24(pkt->data) != 0x000001 || - (st->codecpar->extradata_size > 0 && - st->codecpar->extradata[0] == 1))) - ret = ff_stream_add_bitstream_filter(st, "hevc_mp4toannexb", NULL); + for (int i = 0; i < FF_ARRAY_ELEMS(list); i++) { + const struct Entry *e = list + i; + if (e->id == st->codecpar->codec_id && + pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && + (AV_RB24(pkt->data) != 0x000001 || + (st->codecpar->extradata_size > 0 && + (st->codecpar->extradata[0] & e->mask == e->value)))) + return ff_stream_add_bitstream_filter(st, e->bsf_name, NULL); } - - return ret; + return 1; } #define OFFSET(x) offsetof(MpegTSWrite, x) From patchwork Tue Jan 30 12:49:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45903 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2130791pzb; Tue, 30 Jan 2024 04:51:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IFSOSOQiN4+NFVoXUy/3loztUtm9GGOUyhhWupqE/UktGbOxygNYe9EOf3ghxuChOWW9sTq X-Received: by 2002:a50:ee11:0:b0:55e:ec08:acdd with SMTP id g17-20020a50ee11000000b0055eec08acddmr4418177eds.4.1706619080991; Tue, 30 Jan 2024 04:51:20 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 13-20020a0564021f4d00b0055f4253b128si566815edz.593.2024.01.30.04.51.19; Tue, 30 Jan 2024 04:51:20 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b=rHv1EpXf; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 915EC68D358; Tue, 30 Jan 2024 14:51:03 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-TYZ-obe.outbound.protection.outlook.com (mail-tyzapc01olkn2015.outbound.protection.outlook.com [40.92.107.15]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C6FE568D347 for ; Tue, 30 Jan 2024 14:50:55 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JFpAyVsszxVOSmo34owmerehd46hd/StwvMV+t75uoekbxKpITLWZ9BekLBdscWemDbubxR4jaL1BiB8EMSfG0n5bH4lUzJhiIibpzpf1SQrpp8tZWjEWUyRySvM8UlGTSuDVJ71sKfMEY8inXZw+xU07gsghknxEt2Vlm2kRgxqAAOZxRGn6nRlNpb9U9u7xzUyiT6L1bRHsqSIA8kPDs2WiVDuFQO5/13WLMvRtOOicbWFblDWQ8fjNeb+7HVz27FoiM8FrNKvIhgW295nZfDFne2R66nDXFar9pB/MxHG7GvLbksJ2z7yBPg+j+hjutpVUDtAQ7sMJyOVj51A9A== 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=Pb4T+6T3Yq7IDyYduLenPAAxpfjP1HBP+230kDS5V5w=; b=BCGU5dUWAUzR+HoxrcleINnwX237/DZ61c5Z2tkSAiuCdYnL23daaC/DExOB6SuczF8SbpheRS1/6/Nff3ARmusdm43uNauD2KhNWJCjfAEvN5fMcEGcGN4L91KD3YguRn0MB+fUWRPADUF8rOTEWeRX9Al1LNBmQF02pIVB3NkRS8fXSQM4VZNkVdDiP7/h2wXv9FoG1IUg27s4IVXLK0nOie4dNwH++b2agHGE1L+nREcYsbAnA8oP0Gjej7t994AkM0ynD0JtSjsQSntOt6sAyDpBT5FxbHpO168GrlPbMcyuuFpdgeelGm4AQDSQFOT8nC6D2qfUIshOLj6Mqw== 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=Pb4T+6T3Yq7IDyYduLenPAAxpfjP1HBP+230kDS5V5w=; b=rHv1EpXf5WXhK0xHibNd9O/jAS46CMtlJgHQ3100jfAj6ck6KPnxl/THRpi1yWN9JeSQPb6YCUy4VPafsyHrhFB60YzaIREnULt9/HbMOybntcR4KYCyBb/A03KBWYyGjOR2qTqqRFwgJrHza7/TBIpd24cjk++/dws7oOl0wA8ghE+Jiay1fbWWICCL8ClUnSYp1LfzsNVxQiiE34uGfC2eA+LKr6sx6Vd1+q0oQvXZlKzWFQUKV4ua0zf0dVqexLjzHEbjG3cbQWToHK8RUrtI47dX6MxwJqY5WotmKa5r53sLpE9bT0RGPhv3SgXiSZGBhZTEhqzOng/n7Im27Q== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by TYZPR06MB7274.apcprd06.prod.outlook.com (2603:1096:405:ab::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Tue, 30 Jan 2024 12:50:46 +0000 Received: from TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7]) by TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7%7]) with mapi id 15.20.7228.029; Tue, 30 Jan 2024 12:50:46 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 20:49:00 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240130124903.16892-1-nuomi2021@gmail.com> References: <20240130124903.16892-1-nuomi2021@gmail.com> X-TMN: [KDeF/uVXwwBJ+sbZMliXGvcokxPlzTjE] X-ClientProxiedBy: SI2PR02CA0035.apcprd02.prod.outlook.com (2603:1096:4:195::22) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240130124903.16892-4-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|TYZPR06MB7274:EE_ X-MS-Office365-Filtering-Correlation-Id: 5f077196-0c09-4863-29b1-08dc2192141c X-MS-Exchange-SLBlob-MailProps: Vs63Iqe4sQmENacaprcsf8K7uW5aY0aB1ulir33xJ1OSYflJceSf65ORPvpbFzmv4bfTrjXtyEUnkZIGPCNz9M6dkalqdfgD7IKCYwXRi2XAiZbfr6Ks+iveD0Vn0FVIIvQt2z+mTit/+vYQIz+Eq37abFYZVle1nPV54BAbS5p270Y1/YoPN900KOKAkhFcDFIToyBKxnYTpbBrIFbXd2ra423FTUyESatrs5hj/X/UzNyrVXmL7Ur9te0q2tmrkRe6DZO0yUO2/mZnaT83goMYWPmJczyOOIwa2ZXcCtCgMfi6QBsNRf501vMdXWgKGfblKmUGHY7bkw6/Lr3UhTctPjbcwY/fqk1G7F3FlMCcRUujBT2hXHZ8/UftZ+KUgszbpZpXw2T5YnjH8Y+9xXc7toOUlmt1ZqCMcy1dkwS/aAjDoAB1RgP9XPh4CiDSFqjbCCzv1ZJnFwyUdxTflvaWABANRgqXulqHWySs6PCnkVgVhGDx/UAFHKRdh6xYtMx38So2jHFn9IZb2F4WtFZoB2Wy8hx6zWg+hnZl6RImaxCOOAzmdxnhiTOyvAEcLVDy3CfYfQC6b3/b1hIh18FDx8axrhoULTyDg8wEM4qa9Ni88yuxo0Tr5RSyoPAvEgrCSe/CYWh8HyyG45TlMemcjA9muabxcR5hPdRRa3+cJCMwdAOZPGQ7K1d/3TYY+PnN18g7n+clHGpEFGQQC/8kwZBveMg4+v/I7ps5dMU= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 5qRmsY1CCIs6+JmVJY9q6k1OobMu/9B/O5adKVwM/fez4LmbThq9fJuAZjFakMP3tMzbN8eCoFe/JFcY2QFQuZ8ew27MftnEKWr4jKiKwSQST2b8O9bPattnOcKNPH2WNqLNgKjC3veL5ZnrhfTXWLAs/oCH008Tv3FFJaVvcTr4CvIZdFMBrr/rzrGLIGyZTmEghrLSl4f1eLZ/heS3SS3NUc7WQ/60CvcGpNBRLEz+mwURTAWAHSQbqr4OfKIHehL5M7KMYixpHIGLnhGKmY6qPatpC0TmGUcT41kcQlXvyLkpjif7BQvKsNg6xqpgZV8QyYHjjMS2QqX6uMuhzwUaFgvIcQad/4bzClcgUTWXBRv1HtVEpMo6Nse3Sb2qmcmPsSwUbr7so4YCa9g1Yq6v2w2qytNieWhFsqufKt8kDsnqfIovFN5rGKJy9vmfLFkjss506wUmBSHvguaDai2jsTfA4iUrG6A3zG4hkJwEEtfPQj3lItAiEue/S46dBtNn6Pih0a1WzmPWu2KdmDP73HgqK+zf6N3DqeMbzyfGCujT7YPCianQP0t8Y29ehVln+dAxSoDRMpX2QWN6ByA8inswlSfBqRKaEcWGIRB74iXaPvMjlfK+sxEUaA8T X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 9bP1Tu4GqFYgUYsPFblq0ABP+SycWQUAYke0NLizB9NN02XlPSwwlobhq7vqOZC8/OhtHkn7L3OV58XzyiRzSmqmnxFpnHGuchdwzLanVtwyeZxBhpkHtS31zCa+64fnG2vhPsluYDW+BplUiqdiLvUfje5/NCShzySI+7REsW5eZx/xa2j8QEqbmmClG8QVK/U+vTd0mh53bjPcyiWWpAQFpK2lDRLxumGd14n0mLafMTig6L7rsuyjGMEbfM7Alml4c01K+psPYhJjvoHEN91QK9P8CV7PgkUhVvK82FLzs6ONnZG5mC5Sjmj38BVwlZQiu/RV9UypCdnQdZqHSMfZxgnS5EwLVHowQOGa4n/GpdjGOidLUfU0xSO/zzr260DMCdjtYPoZZTEwCre+SpnzEoYVGaNZEtyWbyfRshOcP+JNSXFHGiBiVmCndgfloYiFUUnU+mL2WU/7mx8dZd2pcm3GRu2da7K46HPXvDpYeIE2Xjgnw/lqs2u0g+82Ve1rxs/t8yZnEW0oLYRGLUFRZT9InutOd+dnDNWn8O4ixsgs2AV1bNPwKu/dG1aQ3t0da257AH0k3FCbweOrPF2qpp2DYwUSmD5JWNHjJ62SGuojEPcVB9MZq0YzcbTCyFEP2gG4JYe1LRUhZ0BvoR2bweNXTGCTnxXA8rUDKI9o9EAH53bC+EnS2ScnHNAt86EYGDVU+8NTucPkczo+AyQTAJBK34y4utV5fLQJOcITwx9vzVqH7KM8Z1snWH9/LeRzj6UNFNusZ3fKGpxFDoo/V9TMrjoVmQZpjoLNGYwbte6WtuFtUG9yKyjDrG/64vq+Lc1n1P391RWlyEA3/vUEXT0cXMnfiVRA/tQJH53nP7mZ91K155erjVOkVBhTbMwwY1rqBQoKXAtQcrijJ4tb0JFG3GOA4fXBrVSiwcCgnDk2O5cYQ1YxINz3kLVCnhjoRBwvDFaaSE23oSfaL3WLJkSPZaAAHmlTXLG9h0NWXeQFj37itecwmRT4QZ6yvlKcvIpjq8Gjx5PFm7lneiXsYNGGYsKEVFpQ5KDjWDZyOQeMOUe+U4SfQtj4auCRf7QlQ+FHSySfQc8PsHNU5F47nfLx4DyjD3QbqRsufmZf/1JzmP1KD0HU8hoXOnzhuqPl927B+qDuSXTi+KgKaceV9f8eFUtIk4W36TiBZ7jCcqdCMrQygzbQJucp35vhwf3yeOM/5NAxB2A4lowzogABXrygAlOnvmTzzK//kqi5IMVgDlu1gu2f2L7rBwpm X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5f077196-0c09-4863-29b1-08dc2192141c X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2024 12:50:46.7608 (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: TYZPR06MB7274 Subject: [FFmpeg-devel] [PATCH v5 3/6] avformat/mpegtsenc: refact, move h264, hevc startcode checking to check_h26x_startcode X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: vWvfW/xojZvH --- libavformat/mpegtsenc.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 4e5c264d2a..5e089f2866 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1759,16 +1759,16 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ts_st->prev_payload_key = key; } -int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt) +static int check_h26x_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt, const char *codec) { if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001 && AV_RB24(pkt->data) != 0x000001) { if (!st->nb_frames) { - av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, " - "no startcode found, use the video bitstream filter 'h264_mp4toannexb' to fix it " - "('-bsf:v h264_mp4toannexb' option with ffmpeg)\n"); + av_log(s, AV_LOG_ERROR, "%s bitstream malformed, " + "no startcode found, use the video bitstream filter '%s_mp4toannexb' to fix it " + "('-bsf:v %s_mp4toannexb' option with ffmpeg)\n", codec, codec, codec); return AVERROR_INVALIDDATA; } - av_log(s, AV_LOG_WARNING, "H.264 bitstream error, startcode missing, size %d", pkt->size); + av_log(s, AV_LOG_WARNING, "%s bitstream error, startcode missing, size %d", codec, pkt->size); if (pkt->size) av_log(s, AV_LOG_WARNING, " data %08"PRIX32, AV_RB32(pkt->data)); av_log(s, AV_LOG_WARNING, "\n"); @@ -1776,19 +1776,9 @@ int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPack return 0; } -static int check_hevc_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt) +int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt) { - if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001 && AV_RB24(pkt->data) != 0x000001) { - if (!st->nb_frames) { - av_log(s, AV_LOG_ERROR, "HEVC bitstream malformed, no startcode found\n"); - return AVERROR_PATCHWELCOME; - } - av_log(s, AV_LOG_WARNING, "HEVC bitstream error, startcode missing, size %d", pkt->size); - if (pkt->size) - av_log(s, AV_LOG_WARNING, " data %08"PRIX32, AV_RB32(pkt->data)); - av_log(s, AV_LOG_WARNING, "\n"); - } - return 0; + return check_h26x_startcode(s, st, pkt, "h264"); } /* Based on GStreamer's gst-plugins-base/ext/ogg/gstoggstream.c @@ -1985,7 +1975,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) const uint8_t *p = buf, *buf_end = p + size; uint32_t state = -1; int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; - int ret = check_hevc_startcode(s, st, pkt); + int ret = check_h26x_startcode(s, st, pkt, "hevc"); if (ret < 0) return ret; From patchwork Tue Jan 30 12:49:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45904 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2130847pzb; Tue, 30 Jan 2024 04:51:30 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCXozHNs+BNnglCE1kUlkp9MRoHfcpp1VnvRx+i6Kvr5akI/pSHNfT7VghGezutalBCfq4PyZp9cLcIN72cwoQfP8ULpaO8ciNBo0A== X-Google-Smtp-Source: AGHT+IFzcqmLRJarC2w1mbPbxhBqpS10U044M3UUzCzDvc5UDijg4QUXu9DSA0J+qKMu+7YgkynQ X-Received: by 2002:a05:6402:3457:b0:55e:fc89:5d40 with SMTP id l23-20020a056402345700b0055efc895d40mr3407826edc.0.1706619089954; Tue, 30 Jan 2024 04:51:29 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id p1-20020a05640210c100b0054bf6c62e5asi4525820edu.419.2024.01.30.04.51.29; Tue, 30 Jan 2024 04:51:29 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b=qcHctlgl; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CD95868D360; Tue, 30 Jan 2024 14:51:05 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-TYZ-obe.outbound.protection.outlook.com (mail-tyzapc01olkn2061.outbound.protection.outlook.com [40.92.107.61]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4A1F368D35A for ; Tue, 30 Jan 2024 14:50:59 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dCuA43FJQV2nbky6EEz8rs64Y61HoA5X+tkBQNkYHp/x2ovg74K+xtuvwYXpx/YQgthMhZLP8vw2QhiEA1GvzjkGq8k+wiW/FfyLg/UnYj1iW45rmfjCIfZYRrVfc7CJ/qxhBVFhV1d9eaipd9B3TxpMXw+I4sDNfm+mdVdGaPGNeQHoVYGrs4kmR0V+XixE1R9moJPWLCH6n8GJsJv/tyTTzyr7lLngwQLncE+BfLm7FproGYuhguOu1YGCxP8FHAHsSgIWW2dNGkBAMGYt8lwNwYXee73XUXH3I+Hie41zr/lx2EelW1etDJJc1FlI601RAeEACDhNhJBqzbaNzg== 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=AoVBPpzW4a7aDn9D7ldoZye+f8sPOq8JYqANxf7jBSU=; b=dss210u8IdWo9joIoVbhXvD3LfaFwq7wP1DSbZqWUwsD+XmROafnLAXKJ2rBwy+E431I90wDvLf1yznAfF+1K9XsJo12c7TFuAeEkFVV3SDdi3v9U/ibWDNGn9sS028nU9JVWyjSyg0FEhfpHufoj/o6adKv7HeYCdLLEMdeGUoTfDnpbsQXUcN3Ply+bXtnKxQofTn3G8guiBD7S3vZZFX9+CVRs6ej46vsgCgaDeBLGrxDAlpB2FeHT1W7YDw9h8KJmjvRRT9xNn0lChMXvL4DWGKihQ+FajCzqlo8Chd7XlskikpSBg1k+grjJuwAxwy+uN2fq+2IW0DmFUfMyg== 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=AoVBPpzW4a7aDn9D7ldoZye+f8sPOq8JYqANxf7jBSU=; b=qcHctlglEqdXFp56Nw8dPqiXzUlQzKDNiBNXj5qGhfLGlj31UUssk8WlTkpCL2S8Xi2jGAlRHU2hlwspDkXdZIAbsLYolkNLuoiTsCiN/WE56hcyegSZzi5FnL1dvswL+ByuRRhcbQGa25in24FhCfsPluEoVNPrQ2D+471N/zujuquRVylmlytSwWrvqVpWZfzrP7WkvnhDi0TzFNYFilF0sGu2PoGv2CPh17JGE9/y9pmwAzH2n7cetMP5/uBRh4yLWgrnUAoIvk+MdtZhlFl2o3492i0Qol3W3Fpc2swb1GBP37TaZBuLn1EyzTo6OfMzqBJM5dATNdpjf2itnA== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by TYZPR06MB7274.apcprd06.prod.outlook.com (2603:1096:405:ab::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Tue, 30 Jan 2024 12:50:47 +0000 Received: from TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7]) by TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7%7]) with mapi id 15.20.7228.029; Tue, 30 Jan 2024 12:50:47 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 20:49:01 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240130124903.16892-1-nuomi2021@gmail.com> References: <20240130124903.16892-1-nuomi2021@gmail.com> X-TMN: [11q2OP3lCWwbPo+mKE9kx71NJDAPpnPr] X-ClientProxiedBy: SI2PR02CA0035.apcprd02.prod.outlook.com (2603:1096:4:195::22) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240130124903.16892-5-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|TYZPR06MB7274:EE_ X-MS-Office365-Filtering-Correlation-Id: a3f098c8-c9c1-4ffb-71c1-08dc219214a0 X-MS-Exchange-SLBlob-MailProps: znQPCv1HvwUOfv/FaQKFvjfX5nGwqybwcEDA0DM+CYm84eDYkxYESvgY7P9A30WeHBUpVo+dKfmUvu1CVOUxTlULJ76y4CujRmQcB84JMT9ov4Oy26j0mF7+SMDPY8nrJ8yKOk5tJ78Zg5ovMR2CkXYXrAQoTbWr+/SLObfU9PMSKRjujJgo5aYK9af6SHt13kEDmZ9zZ6t0nIpH28cLwwABOH1NnAar5BdeioEd/wpYMwCQBYIQ97otbMzXPUAlZFT127f11S1pjU6z08uz6uoehLHoeQ37hAavqa7EDc+DuUz2TbSItENPWDE4U6jg6qpNtPvPeORGk3KOzOWw1CdnGmmX2aMaXlRcHlmZ5k1XKfNV0e9XNlJ4Yqc85nPppQ6V7nvLnltALwGJYIv8Z99o8HZsbM8MBHz/ommZk10cPe5qBsZxGrUdu4SubDzNzGSoYXcF5gEAdZRHAQXi56o/n4RcQJJNCRCiZHvFV/UciZiBarM1Y8UHqmXvZl9oI/msV4kD3z13Lf2Ucrx9D5bcYXBmCuuKZXKheWaeoDSBZApdCXPWoTt0Bo3XxqOivN8oonuTz6nk5brXlVCuAmt64UNrrpQXgKmF5jTu5xtcOMcTnrTFLhz2ECOMgPKF5ZvXZZA1YRqO9BsZxtGxBeZRVDBVYGI86ayEpXP2vzUCyLFuFn/Zj1vjDYbWEii19dnKIXmAbgETOSkmhdDctSOGtIa4DF962imFUdAzFlHVHLjQSKyHyW/g5DHkK8fPRnIItTEfNNE= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: E1nbDC25Hp/x2YAZkfljEEjGcMfxzjulxfh3jzL0NBDPEcjAGPOSC33pH+hSYVhfoYmJzsVNyxsuELTDIBTBw0eI4FtEMdBRij5IIrZouSzVV+n6x9cog6fHRXn8wkZFe3GMPLM4liK8y8CJ78+p/q//wi7sQi07KhLitmEJNMYXM35rgxnZ825XLQJm/uE2Gn2GkbF1PRn5Rn82Xv8VTsSThPiUv6MUwO0q5R9XUx7egoNLptEmbYp5XauDSqffvA8GHQPJPfnxLUTRYt0Gnq6WRQ/St6HDqhpjNjGE6ysa7E9AzmlqD8IDaxCgvU03FRvcJT6d1ooFDz3NqDfVVFU91sUZAbU6QGMsL50l9LSlSvvsL6aG4idZk616x05ej4RmeWAoFhVmMrSVv8vdMOC0zy5j228zEvp+KhqSgH9BtaI0QOx/4A/h1bWYiw6QrTGlnA/b9zhEh3ithtrWNMnoL6X3zUg0NEXIkrzsHIQJ3uvtKvu3zOwZZSmlKkW4H4IWQfjb5Yq8e4oeVp3TgnKC25Br/nGzqDtGC1qJ46mE3bILamMUE2AXrU0ou8oyCXnlPQ2I4tj+7pE0/fzWj06qRSvXsqJyGI0rkNialg/iOmAayqJRigha4HM2wyr+ X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: p6YrDELPllvj82hhI5M+n1wqpx4O89P1/ZfmGRdvylHShb7G+YPqEUL/UC1x6yTxupD0zHmzH4t8LnPmY6IDgYhRrIDVSaEY4Jm5VtiImhVkbIwKrV/Aj/UbBuTdhV/6jM1D2IC+esjspHcnZnT5vzmnm+/Jo57bj+InMoe9eV6hYpoFfg9coBkyTQ5FlEmp989O9FbY2P7OspHGxW4sbd5zIKIv6ZwToXL9337eX6nTJFOXZAT+1m07o/wfKl1n/aARaVfwdvg18pypLpDFjKb+yYbMoqg1vCKokmnZRbBCvrwO37AjwkU9F1cYmU2tY9qCLZO+Ca/GAmoPPfZrcDwr0AcL3/Pz7A9wh5jVKhWL3kCJPTdwvjqwQ9HI+fINuwajsEb8dhN+ldIvwaWs8EYcjL/B1fIVEi+gG3pJO1qySKmdJwDXlCvpB3atW+Me7TQCd9fUHQs8PQeyTDtJ6bG9ZdFIJhUsqtXdNNFyf213tWBssHAsybwEezXx+MgjSS9yuumgIdWN8ZV0Ak8WuF0iKf95CHJkW+iA+3oR0kH9e7ANHF1lOerW7M5E9S+i8aK+TFt8ym8j+msGxh/Ge1PsulC4huTBz7SwzTZYmlDuUCaeU0ibq/gYgRPM2sGC8D17vje8GC84a/VW/2r7s8Ws800Z8nUJEgfXDiGj+Mfdt1cl3PDoeb9uttPXaH8u6yDn/AkzwfHgt+u5JAupQ5C56zIk/o0aFV8xVl25tiIgXLni+YkdV6VKFUgu718J7XssmtThP7G2h16eFPFuzQV64hUcqmMU+X3DnGgPKXkF71dVUODualj4L29U7fUfPoWPaz3CPgRJP9ims6S2pQPHGcQ5bL+CaqVzyCbQ8Rv/ZIUsYiQ3U8e+kCOehaFMQl/x8ehTwF5KC6fKjUn1jbacph8BZOrvRZeozak6qI5yoMIt5EgYo5GhqsEpE0DXLb/X9nQiGHfhK9voVPnJvYJFYNRgcOQf09L2XcPx3H7njzT6FL7kx7MNXXuqtzQ0l36QQMEqeRyddzn49ApG+fxXaiYN404oBolrJMr2S/zhvZF5D+x1FioKzceNapQJkZm/xzukgmGTi+PmOd3a/a0+QiNhTmIhB0P4OwS3K1lTs5PmJOAw9YwjceuAeyUZ5L/yu0sYRZfhujcMl2hOd9UznZasahY24jtuFjN+3VLruCtYxHNShYkrLZT69/JBH++o8dMO9ucPwwbfD81iCKi3nZWSEmskNgy7k9afIh3OQ8qbxOb9viWrOCwvyqRN X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: a3f098c8-c9c1-4ffb-71c1-08dc219214a0 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2024 12:50:47.6466 (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: TYZPR06MB7274 Subject: [FFmpeg-devel] [PATCH v5 4/6] avformat/mpegtsenc: refact, remove h264, hevc magic numbers for nal_type X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: A7q9LhK5FyR/ --- libavformat/mpegtsenc.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 5e089f2866..3872be0f46 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -31,6 +31,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/defs.h" #include "libavcodec/h264.h" +#include "libavcodec/hevc.h" #include "libavcodec/startcode.h" #include "avformat.h" @@ -1833,6 +1834,8 @@ static int opus_get_packet_samples(AVFormatContext *s, AVPacket *pkt) return duration; } +#define H264_NAL_TYPE(state) (state & 0x1f) +#define HEVC_NAL_TYPE(state) ((state & 0x7e) >> 1) static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { AVStream *st = s->streams[pkt->stream_index]; @@ -1876,6 +1879,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (st->codecpar->codec_id == AV_CODEC_ID_H264) { const uint8_t *p = buf, *buf_end = p + size; const uint8_t *found_aud = NULL, *found_aud_end = NULL; + int nal_type; uint32_t state = -1; int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; int ret = ff_check_h264_startcode(s, st, pkt); @@ -1890,10 +1894,11 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) * are assumed to be available in 'extradata' if not found in-band. */ do { p = avpriv_find_start_code(p, buf_end, &state); - av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", state & 0x1f); - if ((state & 0x1f) == H264_NAL_SPS) + nal_type = H264_NAL_TYPE(state); + av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", nal_type); + if (nal_type == H264_NAL_SPS) extradd = 0; - if ((state & 0x1f) == H264_NAL_AUD) { + if (nal_type == H264_NAL_AUD) { found_aud = p - 4; // start of the 0x000001 start code. found_aud_end = p + 1; // first byte past the AUD. if (found_aud < buf) @@ -1902,10 +1907,10 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) found_aud_end = buf_end; } } while (p < buf_end - && (state & 0x1f) != H264_NAL_IDR_SLICE - && (state & 0x1f) != H264_NAL_SLICE + && nal_type != H264_NAL_IDR_SLICE + && nal_type != H264_NAL_SLICE && (extradd > 0 || !found_aud)); - if ((state & 0x1f) != H264_NAL_IDR_SLICE) + if (nal_type != H264_NAL_IDR_SLICE) extradd = 0; if (!found_aud) { @@ -1974,6 +1979,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { const uint8_t *p = buf, *buf_end = p + size; uint32_t state = -1; + int nal_type; int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; int ret = check_h26x_startcode(s, st, pkt, "hevc"); if (ret < 0) @@ -1984,22 +1990,22 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) do { p = avpriv_find_start_code(p, buf_end, &state); - av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", (state & 0x7e)>>1); - if ((state & 0x7e) == 2*32) + nal_type = HEVC_NAL_TYPE(state); + av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", nal_type); + if (nal_type == HEVC_NAL_VPS) extradd = 0; - } while (p < buf_end && (state & 0x7e) != 2*35 && - (state & 0x7e) >= 2*32); + } while (p < buf_end && nal_type != HEVC_NAL_AUD && nal_type >= HEVC_NAL_VPS); - if ((state & 0x7e) < 2*16 || (state & 0x7e) >= 2*24) + if (nal_type < HEVC_NAL_BLA_W_LP || nal_type >= HEVC_NAL_RSV_VCL24) extradd = 0; - if ((state & 0x7e) != 2*35) { // AUD NAL + if (nal_type != HEVC_NAL_AUD) { // AUD NAL data = av_malloc(pkt->size + 7 + extradd); if (!data) return AVERROR(ENOMEM); memcpy(data + 7, st->codecpar->extradata, extradd); memcpy(data + 7 + extradd, pkt->data, pkt->size); AV_WB32(data, 0x00000001); - data[4] = 2*35; + data[4] = (HEVC_NAL_AUD << 1); data[5] = 1; data[6] = 0x50; // any slice type (0x4) + rbsp stop one bit buf = data; From patchwork Tue Jan 30 12:49:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45905 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2130928pzb; Tue, 30 Jan 2024 04:51:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IFWKZCoT4QqLLB4Pavu2xBtOfwwG5Fu2psosPMFvT1PPLYGbNtx8ukeq25v6cgFFBRAIlh1 X-Received: by 2002:a05:6402:3594:b0:55d:30b2:983e with SMTP id y20-20020a056402359400b0055d30b2983emr6846526edc.4.1706619099803; Tue, 30 Jan 2024 04:51:39 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id cn2-20020a0564020ca200b0055f0cd6afcesi1713204edb.642.2024.01.30.04.51.39; Tue, 30 Jan 2024 04:51:39 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b="n7j4pFV/"; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1DAAB68D367; Tue, 30 Jan 2024 14:51:08 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-TYZ-obe.outbound.protection.outlook.com (mail-tyzapc01olkn2015.outbound.protection.outlook.com [40.92.107.15]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 583A568D359 for ; Tue, 30 Jan 2024 14:51:01 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NPeORpbk8lAcn1XMGI4ffgAKN6gN55IxAkUJpUBOQ6bNIKt5JApNEQVwZ+O4TRPL+PyFsOIaQwLp2ZrFfTOF2SihG+uXwJQPuJ6B/jFNqFbqDvQKe7Ox8b4Vwn4RRdTApQedNPXsulYQYFcN9OXVmVNx4rWjtZqt61Lbcwf3qbVnuyt5HqK0aIe0MYwvA+kiIJgJxG90nkrSCjX2PGIGMLl76aWoIQKY+LRSF7MRwzd2hZhw6XCPM24oc/iBo1JfwdRIZrEbEdCsJBTzJTmGxRU9qfjqvm4EvIG95V/nnOSpj1bFLBjqRUPiTuTSVDcpBPQxIRXIaHAmxkOpeBvVuA== 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=xOZZRHDYD/OEH+YscTPOdZP6Lj7h/4724CFU1yDDs7Y=; b=QXcI8IOIB3vzCumj+XpXMGapFJPPA/coxBrxBd296LTyOrKikpws0lWGrIZZdbI9wLRGgDWRUIf21v8Tge1KS74p6dGAQVYVHLdb2CC7A00xIV0wFgDzuVCc/ZrPbPSYhwTD7gkqRhREebX3EWiuyGrBSpkpA7FzJDkr30xlL6vsVI7f+JtQATn/D8XlkIb4aAlHHQxZQ4nVbic3EUGr20ZTToD8m5OmRFxq40+ROId2kDaqYoeJzFCpdF6KExhbv//uvJmgqlYQEh+VGwxepfcbIQ/TASCjQ4Bvb1fCfuAO88QwiuRKfee/X0W5DKErbFIxVM0bT/AkalwybyLU+g== 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=xOZZRHDYD/OEH+YscTPOdZP6Lj7h/4724CFU1yDDs7Y=; b=n7j4pFV/J4O5NvY163u+Gwe3Z/PkCnnQIl8y6ovjACyxnLxktt+Az0SHxPPzw7ryKyTV5a27jENDebEAbHDeT+1Y61dDtoCqbgVUFZYvyShV3006Mkz+k6O355g4/idWYs2rN2IL5O8XXv+4c7Mqp02AKMiIhsG5GHiUYDxL0Z7WU5v77uC6QCq6+IeM+RPk8H5pekSuoIFThuPySbnx+LkWdqMEMM8P/hji/cKpQpBslCOqWpSPhyIYE+WKWf688IC7qla+8ezkSpux6pWpI7sEPFsBq1T/KNFKLlUs8mMIH70uiKc5Ix6rkikBx9KTVCCgSNEbpyLS5Hw5jIdAlw== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by TYZPR06MB7274.apcprd06.prod.outlook.com (2603:1096:405:ab::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Tue, 30 Jan 2024 12:50:48 +0000 Received: from TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7]) by TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7%7]) with mapi id 15.20.7228.029; Tue, 30 Jan 2024 12:50:48 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 20:49:02 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240130124903.16892-1-nuomi2021@gmail.com> References: <20240130124903.16892-1-nuomi2021@gmail.com> X-TMN: [Hz0UiovTKQ8g0hPiuH0xDGgrUkniZLnv] X-ClientProxiedBy: SI2PR02CA0035.apcprd02.prod.outlook.com (2603:1096:4:195::22) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240130124903.16892-6-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|TYZPR06MB7274:EE_ X-MS-Office365-Filtering-Correlation-Id: 2f4f0c5f-051a-4cc3-e686-08dc21921526 X-MS-Exchange-SLBlob-MailProps: znQPCv1HvwUOfv/FaQKFvjfX5nGwqybwiJWaiom+51qabi7Og2uloEiWedtAfBOVoRaiDD+GUgtGbiNNvVS36+C8q52fr/NtNxFHupzxTcNFLdt4cSX7OoCUyKzkgFbRcc1b4znJX5dmJQblyQiDFyj8MLI8EE3TpitqHLwrsW9XHkn/xkQXNdF2NhvwTJjW0VsQoV1OKJGbZ/jXMhHXsra7c3qFOyLhsACEyssLJZPSZcqV1R/FnGUmcmiKMr0krdNnh6RGpJ+JjpN6H5I7MXkguT4oa8K/da8lX9xewIPlMApCEH/yVYOCIk6DCZaYGSaIAJr3YoRGp98cPeJyt3xyyqYAZAHCuJjlpE+q/8zM6i/335ArP/voXqn5m1piPAwh4I1i63za+vBjPPrQZD4HpDxhzyWoufxcnJK4BvosUkAgKurnHUeJNRiNqGFdoqdis9uy1J9gH7rj1TgGb8OxseK4CeAAW7VcMCdHvpzDqv1MSPKV0V+mcIGDBlkU7JL9LLEBYuxbW//Pf3L7BkX7bNMZlwm46XNMEjPbl50PCYRKYQIbf4ieK4L8NIvAcMa1NIbjxtjAOF3R0Wtd9carbPjg+qob4B3d0gHIcfwl+HUnPU/a9K0378Zq9Mnsr7x8KlSaF6K+f0P25O2Pq2V3rQX+RlOP3ZDASDR+TZf/QxOJL2DBnCqEB7fm6NxhfGunvs5IPznTP0I+Kuz9GyDuG+SStD3Hv+5L9Rib8CcizIeclkwTwxVMaNyBDn7R0UUzo6TeO5I= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Nqxi1aKB5IJBp0kuxVObjTvRc4ay5IOQMEKnhbEtLwP0OhhizRqtRKHre5ws2m2Ujg2zO3VqqcPsPby/qMkDt7cKhrvkCT/KU8UbTtXQ8tI9SccY+5U8Sae3kQQiC1IWUdrlfzuIjdyzW7UbxWxf8LE0MC7DF6CYPfDvXuLiAeBO1Cm0OPjyn/rO0Jfci7qr+JbgsMQEaZfuvmxTan509veKJvwQnTtqixWbF/QW5u1dMVdwrr78RrS75XsNBHlLMzlqMw4t+I3yCOje9smRbxNYaoSD/ytnWzJd4wubXX41p5cHOEpYLlcbIqxr0XsXsfcoHvYn9TnF3NQJshztrrMp4gUIVAGSwJqazkBHDeOsP6ypcNLpv1YE7qyZ0aRrgz19PUIdUAfuwWNVe6i1VG/PLQu0Sb9ltkS7DDppv3svlnztBGKxJYvEy04LTMh1HVnN7H97yR7dM5ywjUJf0rS8UMnM5gmuxntBvTKxIBxXBw/RMtDeSE1tO+YK4EWKuufc5A0urnMstfsb8N9BDG4+7OBFsrHTjhAqjW9EqJMoN/we7QPY9PKx6c1/ktaOPm4JVJ9b6WOZErGeng3E0Px3GEbkuiYgwt2QajuU7OfMXYuFDZW/2DQQrYj4kkBG X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: wHSTUIxH8kPkBuFVtbiQ1xgEhYLKwIVJv5CLlFf30RhlvK2ORcPuTGzAMQ0t5GXI2PL7ivshPBK4Q+ZkxtWSkGlVRF2DvjeJObNmcskccEu5tuK0UYHvTgNS7D5q1kH0pLnGp/q2S5a81D1aNl4DUcm563hpjlOcOqMxJiCrLWwqobMrsQcWRK3Dx3MFR6FkpJVvB90OapXKMrQQI37kau7W1IoSSzxIs2MG9M9yO/MkdGOKmGa/XVKaz1+Hws17O+AJQo9Rmt1WgLPRSlq3VBa6CG7Eb2gyvXWZ+NsoL5VIIkCtiF/h6oKVrxI9V5qu3Hfh4F0JjXDa+wLPZFb+ly3DgvSbdZNVOTaTgyLJO+xk4NFSrXPmpNrp1PzHQFm+grrbU438m6SlolxqGf62miAuVhKIi02Oalkr2fiPLs86YL+8GOO16RZT7KPtQLRL/hS0Pvl0e0j2bTEcgYuKhJYc1Dpil1deEq9VWz4AmDUmw/S9f14FxAzAo7CBHHEuuU1YQag6eGXPG3k0hOqBT/x0+AjBNCoTKzU9dmZGNkYNeZCbi2nYsSU5wa13u/NUFq7h4cjqZrymbDc3RFi1nX9EtmTGATcLRMAY8ubHf3Zh4HePA9KIb/Qtifb+vFVMn28qcgndznMXua3x8Pxu2338PTWRS7rRhqDm3HDfWTMvT5Hc8zszeiODDrrsCLoMbPowhWRgmSPcBVH1opO23bhVcAhoer1nmuqmVBT2bo65BhfMAXyPlZIeT4NUsX02bomjUXBtr5fdxWm0CTcY5bClCaLgR1x+9lg8mP8zEqlwLOS+urA/u2KodNBL6anGSvolzMLBONyM5H1PUUA+cPg3ByhkSbT2Rr32yPqDnG+6/OnJAa2CFOyt0PMCHSJDjUzBscGSkwGG8TgfzRJ+FeE/YB9QH9x/SSjKKTfQksHeBUS+2hCFAfO7oM6tVOFlprcb+tMuViTHxFDvl5eK7vjI+ROoirHpmugQD/OsLxuEyJs+7CBRsHxUrhyz8685atdzlbS87r6McKo1nlX/xNBSa1WF3LcCiMHkIf0e3y+OjAi5SRmbGJBwyYdsq5McUUPBjAliWq1tej+n5oSIQCy+jK8nCSYtbsJTbYDTcM86Nt3P+b8qcb3wkpHNopBnMWZ5x1thobm2Hp330yqg7Ggus4x8BgHsr7See5ll2ypriFUKB6d/Xly6gWh1KCkiGCcDzBeq0h58Owh4BCOECxdG8XdehGWohXW+AK948RxXw24E8un8GIRqHJuJJ3dN X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2f4f0c5f-051a-4cc3-e686-08dc21921526 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2024 12:50:48.5308 (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: TYZPR06MB7274 Subject: [FFmpeg-devel] [PATCH v5 5/6] avformat/mpegtsenc: refact out h26x_prefix_aud X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nuo Mi Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 9PtVflMjGrfp --- libavformat/mpegtsenc.c | 45 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 3872be0f46..7bc3feaef1 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1834,6 +1834,21 @@ static int opus_get_packet_samples(AVFormatContext *s, AVPacket *pkt) return duration; } +static uint8_t *h26x_prefix_aud(const uint8_t *aud, const int aud_size, + const uint8_t *extra_data, const int extra_size, AVPacket *pkt, int *size) +{ + const int sz = 4; //start code size + uint8_t *data = av_malloc(pkt->size + sz + aud_size + extra_size); + if (!data) + return NULL; + AV_WB32(data, 0x00000001); + memcpy(data + sz, aud, aud_size); + memcpy(data + sz + aud_size, extra_data, extra_size); + memcpy(data + sz + aud_size + extra_size, pkt->data, pkt->size); + *size = pkt->size + sz + aud_size + extra_size; + return data; +} + #define H264_NAL_TYPE(state) (state & 0x1f) #define HEVC_NAL_TYPE(state) ((state & 0x7e) >> 1) static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) @@ -1915,16 +1930,14 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (!found_aud) { /* Prefix 'buf' with the missing AUD, and extradata if needed. */ - data = av_malloc(pkt->size + 6 + extradd); + const uint8_t aud[] = { + H264_NAL_AUD, + 0xf0, // any slice type (0xe) + rbsp stop one bit + }; + buf = data = h26x_prefix_aud(aud, FF_ARRAY_ELEMS(aud), + st->codecpar->extradata, extradd, pkt, &size); if (!data) return AVERROR(ENOMEM); - memcpy(data + 6, st->codecpar->extradata, extradd); - memcpy(data + 6 + extradd, pkt->data, pkt->size); - AV_WB32(data, 0x00000001); - data[4] = H264_NAL_AUD; - data[5] = 0xf0; // any slice type (0xe) + rbsp stop one bit - buf = data; - size = pkt->size + 6 + extradd; } else if (extradd != 0) { /* Move the AUD up to the beginning of the frame, where the H.264 * spec requires it to appear. Emit the extradata after it. */ @@ -1999,17 +2012,15 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (nal_type < HEVC_NAL_BLA_W_LP || nal_type >= HEVC_NAL_RSV_VCL24) extradd = 0; if (nal_type != HEVC_NAL_AUD) { // AUD NAL - data = av_malloc(pkt->size + 7 + extradd); + const uint8_t aud[] = { + (HEVC_NAL_AUD << 1), + 0x01, + 0x50, // any slice type (0x4) + rbsp stop one bit + }; + buf = data = h26x_prefix_aud(aud, FF_ARRAY_ELEMS(aud), + st->codecpar->extradata, extradd, pkt, &size); if (!data) return AVERROR(ENOMEM); - memcpy(data + 7, st->codecpar->extradata, extradd); - memcpy(data + 7 + extradd, pkt->data, pkt->size); - AV_WB32(data, 0x00000001); - data[4] = (HEVC_NAL_AUD << 1); - data[5] = 1; - data[6] = 0x50; // any slice type (0x4) + rbsp stop one bit - buf = data; - size = pkt->size + 7 + extradd; } } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { if (pkt->size < 2) { From patchwork Tue Jan 30 12:49:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45906 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2130988pzb; Tue, 30 Jan 2024 04:51:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IGk/u4FQuDBCqJnGkEqq65+n4p6qAe2ZVd7w7gojAOC8596aTMUSVbAxv2dJC92U0zMw/1h X-Received: by 2002:a17:906:1401:b0:a31:410a:18e4 with SMTP id p1-20020a170906140100b00a31410a18e4mr6061914ejc.4.1706619109292; Tue, 30 Jan 2024 04:51:49 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id h10-20020a170906718a00b00a35df307711si1480952ejk.286.2024.01.30.04.51.48; Tue, 30 Jan 2024 04:51:49 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b=UXma1B1g; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 44C7168D36D; Tue, 30 Jan 2024 14:51:11 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-TYZ-obe.outbound.protection.outlook.com (mail-tyzapc01olkn2061.outbound.protection.outlook.com [40.92.107.61]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C517B68D35A for ; Tue, 30 Jan 2024 14:51:04 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OLrTpZcyCnHUgEXw0SmHvgqh2QEBJLawnAIw5ufAFgowMdD+Hy8n8+V0F108RVuEo/OR0sjyHNjeNg8NHoxsfGqEOlr/PqRzhg2y/eppH+Y8n+N6izFcwhMOMiSFKJekafC5ZugLLgzi9NJKUxSgvcwNghA+JGDOgBqLnmAJ1t+VdKttzeBxbpiBzjqkGMaDq9OgUiim2h07bwb/I/WSpxm5+5NNRQ80eWuD5zvFE9S/yETcQzUcXeNMFMoqnxBzEDX4lyTeHP7ewIVqhnThO5isD3pFUro+O2egAtrfYX10hde1HyYtkDtTV3bA8LzAeJvJbhnBQTOTWbsjT227QQ== 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=+iW/j7ePHKqqVVU+cWeKJzS85rD5LWJyrYIuA5gTN48=; b=mZZs858QPVQ8c8+ZV+jxtBiu6G/1KTkZfMNcXPYThnnVAMrOe39jkPRVEgacyvS1HQVRtKyWGeqK4qYAwn0HOPfT+/CJrP6u23CbjGZOBWpRtZhRoWbH3xzAdiW12UOBDk6G4lTWFsIRA47udxnfONj2hg1k62GmLmWF9gIV84s2NF1dAwp5uVxuIsPYaU3vbQE0Ey4ffkK5RixAYjOAVgCHLsXHeG+lM3FRJ1U52Q0+oZY3E3wumHjXa3ytVBl4Eowmfl+g6uQ0SgVAMVlPyLv7KdTHlSUq7DbQRVfUE9CPBHmzzb4A6von+kjhWLgP/q17sIPihCtHhdiSHAA97g== 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=+iW/j7ePHKqqVVU+cWeKJzS85rD5LWJyrYIuA5gTN48=; b=UXma1B1gxwzyTwbJWEcfSeb8gRSFyXJgrVnbSxEnglj15XtxR7Y1XXDp6Lc5WlY1LVdJKzVlpiRvmWz3Mq1gLoXKEDpw79Qt2m8wAPHLbxq+7OsZCB8ii5vXD49bbYj1qMvDV4HDcEP3aod2EmphNKbGY1wh2JFxcGQjVatzR6RQt+NCvH3im0NFnHW/9v+G/4sNOmy0d1KJPDqXV1GiKl/ObdVNGeeFzUwS5AkSQB59b4zAZGC/A4quPltMyVga7qZbDqDByTYGLx0zobjPx5iZ/SYlC56I5ABVx5SvuqucU39dzczEaqqgXzZo1EhXd+AMu4pFFRr6UrEKhx/Hwg== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by TYZPR06MB7274.apcprd06.prod.outlook.com (2603:1096:405:ab::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Tue, 30 Jan 2024 12:50:49 +0000 Received: from TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7]) by TYSPR06MB6433.apcprd06.prod.outlook.com ([fe80::e139:fd7a:1b66:a3f7%7]) with mapi id 15.20.7228.029; Tue, 30 Jan 2024 12:50:49 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 20:49:03 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240130124903.16892-1-nuomi2021@gmail.com> References: <20240130124903.16892-1-nuomi2021@gmail.com> X-TMN: [RxK6mDYJNGg6YJt9MkQc6BQIPk7RPvXd] X-ClientProxiedBy: SI2PR02CA0035.apcprd02.prod.outlook.com (2603:1096:4:195::22) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240130124903.16892-7-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|TYZPR06MB7274:EE_ X-MS-Office365-Filtering-Correlation-Id: 6ad5ef55-a27e-4604-eb11-08dc219215c2 X-MS-Exchange-SLBlob-MailProps: WaIXnCbdHrMX0ub4IzufZP48szTFHkH0TiszLay4W89NJTOY/CgJ1rNFyBt8imoFbCiCaqpDtH+6gzIy9+lLQNMswxy8I2jxFxHANy+7Ue4DahYoRMzvhRO0TwLjFwLX+qgd2UDRW6lA+YDv1kEbvsX3z6a0kjYPsV7BtGz2ORFSwo5i+/Wr0F0EJf4Ws2Lu87B7sY3QzUuhDiCAYUm+EbOB57GNmtI9y2ArHGmCLrCWl5/Fq7yWK95OC0dbam3ivpCVWt0JS8si3nNoK8GmMGUUX9L7JSyVfsmouKfgbhIhSRopFjEEl1FcNeRajCMOkfLWucUCWHef1Q8vXoCIIWsBz/qYYgWP8IlgtyYZjbf7570XwqO23sbglxb82JCzEFv1NLC2i1UkXnUGY7B2G9/HGBnP7V/GE0phis69LQ0IFlk7VZrKUXJVnKBptE6hBurJ+WVgkbwNF1j0UNimuBj63ZBXoFmntTG/dJ16P5+u7SqcelOdglLh4ljmGDnKF3qWaZ7goqw+HFJe0vCW0C4gvkmMWF6DSaiGbU1vmLblhQQ5ekGXXDVIIKSxqAnEq75hy42SLUEL1yZ0BDG2bBp4ix8ONkRGdf+waOU7GZ/iRJTJWIYzwPVikHiIWKD7/63DRFpbrH1vOW8CcwaZDdbgEcBygW786ZQAHXXNmpqosMQMp1jPIB4dOC3e0zQ5nRqKh9DGtG5wvU+5lLthEAO6BbG+upocl8H6jehSnd7ZV4qB5OR4kdUgkKA18KMHjl+lorClUdA= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: YDQDtHE+qDjRh01Bolwe1apYcnSbXid+pgTT8/uRWRTdfug/1fGy390Ed5N5qPXUSEtcHAx/geS/CEqgui/mxciIiKxop4LLzGF5nDncOw/jbcky3UAgH5sSaQ4J/kT62sHAQUhJc4B0Aho66fCc+7yVqD68w6KLyZJCaujhbZlYkVOICc8VkrG2PM6SkefP/O9J8hsCkdX254f4BoDeC3o85Z+DTUOCjYnxXb6K+xgisrMTIINQdl2SuQ8J9SNJF4bxkUFXQIPNk0hAVuTqMlRvl3iplUpW6ZV0Q/PSOehh8QbdIgHqS6tVp0W/TM+iFOw+VB1Xr8bvL/aGmxEqMjhhARFDT8dZdgefIjuP0RW61Xo3h2zNoOTBbLe3m4OhMHx/MwUtF4orakVdnDqY+Yudw8zfNIV5cDi/W9uRNv+EJjbfzI2sAntJ/w1b0UEoh1Nmnd67batviylUEdg8SEPUyJhIGmE7zdJslzsbUp3NSil/KTMhTWzILtpGWH9cH1FJGI4GUwyTKCqC4Z2t5klBzWT4r9ztYG94b9nHO2QYnOO0OJuTwcbv6i4+MTlRb65qZ9aWowDdoknlAVCeSpxbY1r7HaDoXx4Lq9JNe/4xumJUUXrlufBG9VLpaxP2 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: nQZSHDLH7HhBz2dDvtyNG2wHeBvM6/Vf5HTD8l0kyXESoOtPVZgHkts3WfO5zQSdd5GT4rdhk/dCZBlydH65uoi44co69b0AdZLqKIrdX6Lb4JAlx6lDSQ5sxKBkhkVNaWmIA26fq35Kn6KQ+i9Nwuy8na3NigrxNveucJa2MEJSLNgfpXMbMCtaQcUCTbQnr/WbsMxWYQVs8Tas7Upbddn4fu6RlQhRrcckU6/wLaZPcsnLwmC41NL8EMGSU7ZCRBTctNeD7s150TSXNGBWl0eXP8NuZNozTFPtChXpbGcze2mMEegalfmtoQ7z6wC2g+OwJiWHh/o9C/yxM1W99pUFpIRzpsB2SEfDedC8qjUpw5HyVoocVbKYcxaDUBSDkS7UrHAvJs1VX1sjf6veKQYjwzU0WpqamGNjT5LlSsI4n0FLKuLHf3XhxebmfIA+wb3/OsF4ACpvzVsZMTO6YKuR5w9p13ArgVoJuszVxfxEcqGwPx6vjCIdX4hKm+LmjxjpV6enrvI/kCdkty1P6qtwS7q1wddiYY7wQyTCEBxikfT+pQsQt7Jz9uRALfLJJup0n9OOSrGycaaK/Ubrspx49YwvxtLfgtC05EObNUQpa0EvKC7nSUlP+qj3V7PJrqrWJXRkR0BVa2My+4OU0avHbEEDHVz7RPRhosNMQbA3Vz/aZvUrFodq4C4ljUtnLq3ts/aFvh4lbIBDfEmeqtBP/Hno+fJjgzqTEKsvHC+qio04StaeUdFYoqkxApGUN5GZtl4TYJbMAb0dtiWV+iwFGdfEBS6smjfrRMmL8DxxdRlsBIrh8Xypt781+KlmLO/kp7v6vEN6Vb9eU+Z+B1ty7waPVGrXTdI6sfzBx+8EcK1uz16DyKBPE/0Fm/RexsggaaxRBIsYMeo9qfTGHGmWbN5zwB0x0S4WnHbOEt3uzgo1P9OrW1tUwqlHeOseDxQgMAb71VDSqiu6ehPcglX2Lp5EoUI4EHXDrMSMDMJvV46m9SgfBYcP//+o5LI/nk6ArCfZVelPSLImRkPlgNikjbixfMTF/NkqdNTIDbpjJf/kavAmC9aZgpmv2ycVSQmgpawZVsT3h0zNkC4WLdMcerVjiIywoFhHWA8eIkVMrmAOSToHG6UvD+YzM0qg/IhL3ztcny5stG//W1R/rabKflWD6e9HmRlOuj7qKS0j7ivZVyUHvk9plfh80JqcYeAWa9HJJK0bAd1ckpl9YVY8PA3WegnYxWrjC1WWhAbivnul0UPOF/JCo/BLtIxU X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6ad5ef55-a27e-4604-eb11-08dc219215c2 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2024 12:50:49.5392 (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: TYZPR06MB7274 Subject: [FFmpeg-devel] [PATCH v5 6/6] avformat/mpegts: add ts stream types for H266/VVC X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nuo Mi , Thomas Siedel Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: LSImJtxNXZbZ From: Thomas Siedel Add transport stream stream type 0x33 for vvc. Add STREAM_TYPE_VIDEO_VVC to MPEG-1/2 and MPEG-2 transport stream. Add basic transport stream support for TS mux/demux. Tested with: ffmpeg -i NovosobornayaSquare_1920x1080.mp4 -c:v libvvenc test.ts && ffmpeg -i test.ts -f null - ffmpeg -i NovosobornayaSquare_1920x1080.mp4 -c:v copy test.ts && ffmpeg -i test.ts -f md5 - Signed-off-by: Thomas Siedel Co-Authored-By: Nuo Mi --- configure | 2 +- libavformat/mpeg.c | 3 +++ libavformat/mpeg.h | 1 + libavformat/mpegts.c | 2 ++ libavformat/mpegts.h | 1 + libavformat/mpegtsenc.c | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 21663000f8..68f675a4bc 100755 --- a/configure +++ b/configure @@ -3552,7 +3552,7 @@ mp3_demuxer_select="mpegaudio_parser" mp3_muxer_select="mpegaudioheader" mp4_muxer_select="mov_muxer" mpegts_demuxer_select="iso_media" -mpegts_muxer_select="ac3_parser adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf" +mpegts_muxer_select="ac3_parser adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf vvc_mp4toannexb_bsf" mpegtsraw_demuxer_select="mpegts_demuxer" mxf_muxer_select="pcm_rechunk_bsf rangecoder" mxf_d10_muxer_select="mxf_muxer" diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 781c3162d6..a0f2c6da05 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -546,6 +546,9 @@ redo: } else if (es_type == STREAM_TYPE_VIDEO_HEVC) { codec_id = AV_CODEC_ID_HEVC; type = AVMEDIA_TYPE_VIDEO; + } else if (es_type == STREAM_TYPE_VIDEO_VVC) { + codec_id = AV_CODEC_ID_VVC; + type = AVMEDIA_TYPE_VIDEO; } else if (es_type == STREAM_TYPE_AUDIO_AC3) { codec_id = AV_CODEC_ID_AC3; type = AVMEDIA_TYPE_AUDIO; diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h index b635295776..20592eb184 100644 --- a/libavformat/mpeg.h +++ b/libavformat/mpeg.h @@ -56,6 +56,7 @@ #define STREAM_TYPE_VIDEO_MPEG4 0x10 #define STREAM_TYPE_VIDEO_H264 0x1b #define STREAM_TYPE_VIDEO_HEVC 0x24 +#define STREAM_TYPE_VIDEO_VVC 0x33 #define STREAM_TYPE_VIDEO_CAVS 0x42 #define STREAM_TYPE_AUDIO_AC3 0x81 diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index c7fd1f5d1f..bef00c88e7 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -812,6 +812,7 @@ static const StreamType ISO_types[] = { { 0x20, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, { 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 }, { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, + { 0x33, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VVC }, { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, { 0xd2, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS2 }, @@ -867,6 +868,7 @@ static const StreamType REGD_types[] = { { MKTAG('D', 'T', 'S', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, { MKTAG('E', 'A', 'C', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, { MKTAG('H', 'E', 'V', 'C'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, + { MKTAG('V', 'V', 'C', ' '), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VVC }, { MKTAG('K', 'L', 'V', 'A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV }, { MKTAG('V', 'A', 'N', 'C'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_2038 }, { MKTAG('I', 'D', '3', ' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 }, diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index a48f14e768..14ae312c50 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -128,6 +128,7 @@ #define STREAM_TYPE_METADATA 0x15 #define STREAM_TYPE_VIDEO_H264 0x1b #define STREAM_TYPE_VIDEO_HEVC 0x24 +#define STREAM_TYPE_VIDEO_VVC 0x33 #define STREAM_TYPE_VIDEO_CAVS 0x42 #define STREAM_TYPE_VIDEO_AVS2 0xd2 #define STREAM_TYPE_VIDEO_AVS3 0xd4 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 7bc3feaef1..db3f5b64e6 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -32,6 +32,7 @@ #include "libavcodec/defs.h" #include "libavcodec/h264.h" #include "libavcodec/hevc.h" +#include "libavcodec/vvc.h" #include "libavcodec/startcode.h" #include "avformat.h" @@ -369,6 +370,9 @@ static int get_dvb_stream_type(AVFormatContext *s, AVStream *st) case AV_CODEC_ID_HEVC: stream_type = STREAM_TYPE_VIDEO_HEVC; break; + case AV_CODEC_ID_VVC: + stream_type = STREAM_TYPE_VIDEO_VVC; + break; case AV_CODEC_ID_CAVS: stream_type = STREAM_TYPE_VIDEO_CAVS; break; @@ -1851,6 +1855,7 @@ static uint8_t *h26x_prefix_aud(const uint8_t *aud, const int aud_size, #define H264_NAL_TYPE(state) (state & 0x1f) #define HEVC_NAL_TYPE(state) ((state & 0x7e) >> 1) +#define VVC_NAL_TYPE(state) ((state >> 11) & 0x1f) static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { AVStream *st = s->streams[pkt->stream_index]; @@ -2022,6 +2027,39 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (!data) return AVERROR(ENOMEM); } + } else if (st->codecpar->codec_id == AV_CODEC_ID_VVC) { + const uint8_t *p = buf, *buf_end = p + size; + uint32_t state = -1; + uint32_t nal_type = -1; + int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; + int ret = check_h26x_startcode(s, st, pkt, "vvc"); + if (ret < 0) + return ret; + + if (extradd && AV_RB24(st->codecpar->extradata) > 1) + extradd = 0; + + do { + p = avpriv_find_start_code(p, buf_end, &state); + // state contains byte behind start code, p points 2 bytes behind start code + nal_type = VVC_NAL_TYPE(state); + av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", nal_type ); + if (nal_type == VVC_VPS_NUT) + extradd = 0; + } while (p < buf_end && nal_type != VVC_AUD_NUT && nal_type >= VVC_OPI_NUT); + + if (nal_type >= VVC_OPI_NUT) + extradd = 0; + if (nal_type != VVC_AUD_NUT) { // AUD NAL + const uint8_t aud[] = { + 0, // forbidden_zero_bit, nuh_reserved_zero_bit, nuh_layer_id + (VVC_AUD_NUT << 3) | 1, // nal_unit_type, nuh_temporal_id_plus1(1) + (pkt->flags & AV_PKT_FLAG_KEY) << 7 | 0x28, // aud_irap_or_gdr_flag, aud_pic_type(2), rbsp_stop_one_bit + }; + buf = data = h26x_prefix_aud(aud, FF_ARRAY_ELEMS(aud), st->codecpar->extradata, extradd, pkt, &size); + if (!data) + return AVERROR(ENOMEM); + } } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) { if (pkt->size < 2) { av_log(s, AV_LOG_ERROR, "Opus packet too short\n"); @@ -2272,6 +2310,7 @@ static int mpegts_check_bitstream(AVFormatContext *s, AVStream *st, } list[] = { { AV_CODEC_ID_H264, "h264_mp4toannexb", 0xff, 0x01 /* configurationVersion in AVCDecoderConfigurationRecord */}, { AV_CODEC_ID_HEVC, "hevc_mp4toannexb", 0xff, 0x01 /* configurationVersion in HEVCDecoderConfigurationRecord */}, + { AV_CODEC_ID_VVC, "vvc_mp4toannexb", 0xf8, 0xf8 /* reserved '11111'b in VVCDecoderConfigurationRecord */}, }; for (int i = 0; i < FF_ARRAY_ELEMS(list); i++) {