From patchwork Sat Jan 27 04:15:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45852 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp370505pzb; Fri, 26 Jan 2024 20:15:43 -0800 (PST) X-Google-Smtp-Source: AGHT+IHU/MB0sQ+dAN2bKBIyxyZsTy1rYqmm7ttfuOXxdIS0Rn+ndOlsAmdlo0Zj62VVce7CLllD X-Received: by 2002:a17:906:3ca:b0:a31:7cf7:9f3a with SMTP id c10-20020a17090603ca00b00a317cf79f3amr700620eja.43.1706328943072; Fri, 26 Jan 2024 20:15:43 -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 z8-20020a170906074800b00a311f5a256csi1267305ejb.494.2024.01.26.20.15.42; Fri, 26 Jan 2024 20:15:43 -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="WRf/Hr7z"; 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 4B73368D150; Sat, 27 Jan 2024 06:15:33 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-PSA-obe.outbound.protection.outlook.com (mail-psaapc01olkn2067.outbound.protection.outlook.com [40.92.52.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8F01568D145 for ; Sat, 27 Jan 2024 06:15:26 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=P79yVpgqMKUcQaXdjiM/vm55n4lzgzo3v/z6jRaDQDzYzWnxTux6tT5Yp3eOdGbjoADh42nQ/OAi7jpRFA+NW9MaEHCRIbjXR2lxZqa5FXs5ygYR3gh9D8KIqlEQrnM3Uj4c+pRJfC5udjK9VpKXxDhDtoFpksm3WSLViQoCJeLBxRCWDEGD2mkhD8hL4MU35ZrMxrzA/HFRf4cO9jUOtxVfMVCVQgbwqPBOhN3rgiHMkTFyBeoG70BtMev7b+In05plbcwFTVNfUwOpb9lWGYjrSsXMm0Dn59a2pAh3mBd8lDwxTGNJ+/Ts1rXxIKzF3biok+fH9euYYmjt80c4gA== 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=I6g3BWulvfiniml3byMHcAmomM6O69lR3hi21ybRD94=; b=fb8MgD9ssAsHobo0e0Egt57ytcvmvYgkjeOyh+6I8O9DTyyEM5MoEjzBUQG9MMIZfJ3eZ4zRqyDO+TrU3xqE8Zd/kHG9aAXoHNe+iblUXNkXGv+DkrlL+Mfz6j/BjvAl6/pvaI2zCSFlFEoEzBhcjBFFF7kYW0f1EFLNUabOUa0FhcT0Jfz2U9Of3ihLpbfj/s1jALAd6U0o9qkJhjZv65mt/JrqjQ7Ck2fAGXtunBuJM2RpLj1TJVA0P8qK4U70WjAE+SHu3Y8fXWBTZ/2MXoSt9slhxSljdAiKpcyua2zbXH45/LtLT5ReyEBhp3a42dBRNLKXq2eb9eSubq3+FA== 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=I6g3BWulvfiniml3byMHcAmomM6O69lR3hi21ybRD94=; b=WRf/Hr7zCqQZSsjo7+ombW2jMO6PQZvYzZMbG6tchZor6pzxVkPxXkh4tpO6s4NFHDa9O/ReofEMNAnSvymn0Wdgz1sd4duUL7MuBXL+jp9euE+FUIQfAjWAcfKf8wTv/shiC+NztaA6awbGYIExJpiasHqtRxNejFAWVDJEZzGtHmXI3guA0bmHfpTABlINH6xAi99pFe/ngPfjrZWME09m+DRtnVWq3QejZocG53tPsyh7FgG6GyKfUknmiBmeA92FQwqw2bp7Ju1uHCF/9vHP1/9lbk/RZZCcfGW3Qvk7BA3WP/dWDzTPx6P6Tl8RBIUm7F9s0y+FGOWQ45DavA== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by PUZPR06MB6068.apcprd06.prod.outlook.com (2603:1096:301:112::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.28; Sat, 27 Jan 2024 04:15:17 +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.028; Sat, 27 Jan 2024 04:15:17 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Jan 2024 12:15:07 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240127041512.14079-1-nuomi2021@gmail.com> References: <20240127041512.14079-1-nuomi2021@gmail.com> X-TMN: [18VXBnxXN3lhHINecjk2Tgtn6LCxuGhW] X-ClientProxiedBy: TYCP286CA0165.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:383::11) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240127041512.14079-2-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|PUZPR06MB6068:EE_ X-MS-Office365-Filtering-Correlation-Id: 84fa244f-a5ea-4910-2ea1-08dc1eee9130 X-MS-Exchange-SLBlob-MailProps: laRBL560oLRPh4k2uMNyV8ZBlUJyoQkYzS2HHiNUZ4q5eRpa6UBbqxy3mz7memP0d79xu6nHvay+c3l1Qjn96X/kzCGeftacLP3vOEAdYz8QsndET93X4toZqCD1TaYIbieMtzGmGrFHbjGB0juxLO1vrVlYQ3Mtwl18bLAFMWHKlczJ8Cx/Aj+v7LqOUeShI6lA1wUvVaUikTnC1Y+8UGBYg8RfV3DDXLoOhqH8FX7rouuMrpmGdajzuWPWwjaEq+5I+MxsnIycYHBgA6mfSw/6tSRjyrSF9wk4q9sHDxvmDjx0WyXtozOg4cVOfCC7ZWJhq8Kw5LirqhGqP9LHJhdkXmjJiTuFNVq11bcg6eXynGFMaDAn3xrqgqDWj/thLdRPOwFlXG2m5ZCh63Vs6ka9L2V+g63+t0EUfeIeixED8I+8G8xGMTNq0X9oU48OPDPMB1PUwXXCYvVR5U2AoE5+q6kdiVaivGUJGYSmxNt8Olutn5LNY0GF5x201L2JLqTK/t9ixKjmFDQzJb8b/QUiGKj80dRgBjQw6+qH7i9+jXYxs0GDoanOHuOBdcql/QKuZODNkEtYyLyvNOUQvGL8LAzMa98flWA1jHiZOKS5f+t0zG9gXVUHZWvsRWumAhJu0l1WIwg4vAfA70/0X862vXa+LrIVYiMaIIDcQhbXW0aAxmGnRxqoNm0NLOOQbmqK/jsPmLqL5SOYfC/NyB03qsT+Drp/R6Q2lipHQoRpfIbVHW+6KYOgzAPKK1bXn0B7cLrQ4Nd66L3NC2cnx9WnyPx84AK1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: xFCXArSQGlkPXv8t17xh2MkKOKbFHgTBC5Ml/UDvWr9EJTDZNMQKN30J7r6sJlCr148OTkFnKtjdZ5DIbDftAKfUXNGRUvuzAGs1qlIUoQIRWN9ZXtY49mTGiojrw044ZiDI+1uwpAms+8NPWJbZ98fB2T0RIXmsQ4H3CEEHT8Uc9Nke+di2OV/Bdtqy6sKWXOaepfhDTW+K9KmZ0/KysM2/xSOYgPkByXLfvP7GTCVOxkLAppuXiFhs6IX4D9Q2kCyWjUGynlx/imYtqNqW6yF8LTCKVtAP+sQ/sZjIadGhv0le4BrhMX82b+68vHphs5tkPrIIbX47WkOjiRvk5k0HB+IzF/+WCXMHxzGpOHJSXO9MImO8mGcr40vpmWHQ8WQhjcGK7BYCuqhZIxk9+PlMoINOWGPr8K6Rn5pr4ONK5OaFwA4Pn+S/zSW6Gmib/m+w7Sp07YvavPBWdKqnpaWrfre7+K8LnEA/IRD4GzHHGTsH5BVpG6p5+eZSfZUqwxY4siAu1vvdwOmoedLDHivAF9jGFqsBnLUnH2yUxmIUS4hSvM4Qjs3EipuXoerhMvrnRwtj5Ts4Mv0nagzSCHqxRXl/wGVcDKgfe7XR+S7amQD02Qpz/qgRSE3crQ9c X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?QJQM+YJfzXipYq6Xxs5KjVTlBv7Z?= =?utf-8?q?tHGS8aERKdY9UeofS0XSoG3PR80gWlZEZT3Loj6z833BMOHZCMy2w39BlMYMZaiud?= =?utf-8?q?YHmUCTpSwsMfkiUbPmxoiDaKV7ld3/vwam3cLSZauTVqravxQFePh6RHREgfRFEqw?= =?utf-8?q?zT4KfV8C6jtlQEER5n1nwq/v1yrcFd/qyD66nDpZqhbZ+2cmFwe/JUnw08uTeCnHB?= =?utf-8?q?cbeHA+M2JKBKQlotGjU4ARhyfAuBnuY4NtMimhTmKXWqGvHhmjob3Zxz9GhhKlIlb?= =?utf-8?q?A85udlqiO2+mMuZ+dhLw6btSVQhT1D34Hq2vqFlX/9JF3U69l0ToFrhnP5v22Bffo?= =?utf-8?q?yQtWWNRmTrHiEYnMhYJIq2J4MwCfcA8L5tnshEt0I5kwmLw580rSPdiS0FuBNfbDk?= =?utf-8?q?C++NJYontUBPUJRLz8041ywkMlHyy3fgo4lLth9rJPNAb860Cgc56uqGooL2lYJo2?= =?utf-8?q?YTl6I2rN21Ysg1uMbJnsrIvky1UIQ7UXy5SgYlt84HmLiJcuIZD2rTRoxTsC5dZGa?= =?utf-8?q?NSN8xGGp5CX6Zvj2kHE6bMrw9s8pE70VF/mOxuARXQciULhNtvddz67nCoT/2/p5k?= =?utf-8?q?wu6CX+R/jdlDIuued9d33L8j+PxphHlx/Bq3ju/UL8xuY+K3n9BvE7SuCM8noDzYq?= =?utf-8?q?z2xsHllMkeYo6iK9FIdbHL7jw2TeKV3jIcTrDt9go3qVn7Ds2stZcyFmp0HHwulS1?= =?utf-8?q?uRjEVj7KMP7KkoKE9hZXDW6YUw0SfKVCgq2gew9umIv2zw5uaJTuh1mAHBxDI888O?= =?utf-8?q?HIcRRQaAJmxdKD9SlyYsGN9rlqxE5yd8xf4UAIRXHLEH0Q8yOMJj3Xf66GnvOVrDN?= =?utf-8?q?FrNRbDfYCD/mx3qeoPLcnYgJhAMomvx9HS3rA/o7VmM1rYcscw9Cawt1Q737Q18dF?= =?utf-8?q?gTNtPv64OawEDgm2Ti7WuppV5YvS5QbRB90N0IpHV0Fbqq5B4FN5iG/aA50DcOgKU?= =?utf-8?q?jdO1kWFeQiiqW1RHXuD3k1Q9PLBj3wmxEECYiQhP2rjS3ePec357JXG1C9A/V3Dp5?= =?utf-8?q?rpqsGXKNiW/cvDfuo+6jyOFxqcynBYlYNAskyFyfGk1YLBH43ebw5kK8PkS4TjyDR?= =?utf-8?q?9xHsSBJuHfCF0EPtTtuMvTlkUCtFt4Xig3y4lZx3sk2T9PvakzejqnkinDTO77/zY?= =?utf-8?q?p/ckqttVDCJmKSzFqyFM38QqJdxObu2Ya6bKpofejQoQlqhrG6YGlvuN9am5QiUAK?= =?utf-8?q?i3SSa4PLLBWzr9Wb1?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 84fa244f-a5ea-4910-2ea1-08dc1eee9130 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2024 04:15:16.9586 (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: PUZPR06MB6068 Subject: [FFmpeg-devel] [PATCH v3 1/6] avformat: 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: 9FZf2lZfa93o 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 | 41 +- libavformat/vvc.c | 971 ++++++++++++++++++++++++++++++++++++++++ libavformat/vvc.h | 99 ++++ 7 files changed, 1123 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..705811e950 100644 --- a/libavformat/isom_tags.c +++ b/libavformat/isom_tags.c @@ -123,6 +123,9 @@ const AVCodecTag ff_codec_movvideo_tags[] = { { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', 'e') }, /* HEVC-based Dolby Vision derived from hev1 */ /* dvh1 is handled within mov.c */ + { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') }, /* VVC/H.266 which indicates parameter sets may be in ES */ + { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') }, /* VVC/H.266 which indicates parameter shall not be in ES */ + { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */ { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '2') }, { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') }, 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..40be71f3e0 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,9 @@ 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 && 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 { ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size); } @@ -7363,7 +7399,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 +7869,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 Sat Jan 27 04:15:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45853 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp370543pzb; Fri, 26 Jan 2024 20:15:52 -0800 (PST) X-Google-Smtp-Source: AGHT+IGfAX/+19XZ/8uFse8fV6G15uY2DwnkUHINDEIFewEe1ueKPF2o18XFKvKcCRcb9Y4drZj1 X-Received: by 2002:a17:906:8888:b0:a35:2758:2278 with SMTP id ak8-20020a170906888800b00a3527582278mr363520ejc.10.1706328952054; Fri, 26 Jan 2024 20:15:52 -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 j5-20020a170906830500b00a353eb581e9si221599ejx.70.2024.01.26.20.15.51; Fri, 26 Jan 2024 20:15:52 -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=qPHC0mPX; 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 E46E968D15D; Sat, 27 Jan 2024 06:15:35 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-PSA-obe.outbound.protection.outlook.com (mail-psaapc01olkn2042.outbound.protection.outlook.com [40.92.52.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7FFC568D154 for ; Sat, 27 Jan 2024 06:15:28 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BGGTJ95jOhG471lcAv5IZwXplXb+zQnnUUUMCEBK1oOV+7jp92qOL962GBIEvrNseKN8yTST1gPEE69G3bEl7XuvHwSC9xLv938YDp/fMKaqyo9K25LcVpQ5iTqpwdAKl/q5bGTV9BHVBYrvq3pMmwyPhT8ku6p9PlgCiypChWFdJ/C+Qh2Or0QJe6bj8Zc77J8QBJ2HAJdSF1MQxtjSRhlprQN3AIGF14vXOzpgAhl2okh2763E4qPBh6Nli8V1kuoyxvgSfheLGEZlzuBDxNJxTTk3x4dw2cbLqWEy7OcgUSNG88LAmh0rPxKoqpcxApDZvPEZMJQrOL9usUr/gw== 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=Mxv2+KuPneFh+G2G3cpQYne8Lqf27tR2FBX9LWSan0w=; b=j8cAv/vx/nXjexbad5o+iUFZs97CqoKO9Tgt/aDaI+SyQIcg3AXaZzGeXUYA2b0B81StPAtFIXTdChu03GS0vwRGaN51QkB1v94RVreXHORamQURjJdE1ykkkaS0UNJsSWJ+qci0YMl2+LUXyoY908wDd/j02x3L13JMbyjf+6vALQ2C1YkwZ27D7EmeKLp4K7d2SZlPADI//tKXW9CBkz+4Tmv1T39T54YALSMY1UJr0Ytd8120YFHSEdcZfWkTJ8urUF/xgQG4wuAGLM5DJCDlN4XieVGzLkfsQjCbCA+W50TlxyuJadBY2ui+M0Oja8z2qTGuiy3Kl9VZAtnvaw== 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=Mxv2+KuPneFh+G2G3cpQYne8Lqf27tR2FBX9LWSan0w=; b=qPHC0mPX9HQNVJZqW4ywF2VGedoKlrp8NeirANfxUsTT0DIH8Rg7mVeJd1tkNHH66zFrBjh+jFXC4RP75X8WmWoe591AXrbziNhEuxdsmvolcqGrwOa+eGysbN/1ihfMmwmLbHxA7OwqyeDOUGcOjRYL0VTgvMtNvhR4y8t+jwOzBHW2hZdt2rUzhyCzDDQ/tfT29YA2HS4EvOgdi8Dx/UzNdfOokjiwyiTf3sfP0SOqd48oMx2t+F91MGSHqRZADtciMGOjehWbEOKejKEH2y1l9RNZQlAFoWVtZcQczBxmBlxCO6QcxyXo/4hRjAVfgitFz8O0J5E4JvpE6UDTrw== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by PUZPR06MB6068.apcprd06.prod.outlook.com (2603:1096:301:112::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.28; Sat, 27 Jan 2024 04:15:17 +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.028; Sat, 27 Jan 2024 04:15:17 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Jan 2024 12:15:08 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240127041512.14079-1-nuomi2021@gmail.com> References: <20240127041512.14079-1-nuomi2021@gmail.com> X-TMN: [SYuf6cTbmtIBQEUQZaWJx+eikUqEDmb6] X-ClientProxiedBy: TYCP286CA0165.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:383::11) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240127041512.14079-3-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|PUZPR06MB6068:EE_ X-MS-Office365-Filtering-Correlation-Id: 6770f2ca-3f97-4c23-a769-08dc1eee91a4 X-MS-Exchange-SLBlob-MailProps: Vs63Iqe4sQlWSIg1UbM9To69ipPieoVEYZ2W6zxBBcjEOAHxgeolSDd6zpTYmcLiwR6AbGgkxRuhclWTzb9qQpIfsDHdT0XdIXHiROAeIcFwsWlRRQebjOCz8FQUD+b9GsNmm9nBbGwohM6SYba148wyZ4gvN3gV+lsd4M+TuWy1CyQj0uRAL+tCz/F+Tvie3w4kwtst8AVCkOnegO5zPCh8K7xyl/jVcKigTlE7+D8RL3b1/bOAUFuq/i8zndYGmUyMHYkXBTYvKIPvE0cCKMjQTW+AQeBbrB0EuE3kdGhJUMtp+Y5m/kM7GrUm8PWNP3m/WpnTGmhXYHSt8o3mFsb+Vtj9tuWxj8h16ooTai0A026qECsArHwTwCiMP9WJBQS1C2pZnPVhXxK4gqid4LQEGyqMsgYnquA5lyC3uZwISMytHT+Y32HbPaVWRk5z/632F+QgBNlInVn8dqu3A/G76uqSp2Drd9CL8+kgQynxkhSDy9wENSK220Bj6aE5fbODjSba0xbe3lL5Qa8lKz1FBXt8VLiinous3i9j5ylPk4Rt/Illa9d634kr6BdASGbTF42NCojghJ9x1/Amp7D3jDcppZ9tFyCy0RUJ1A5bhPZxKW6B4JpFwl0EY+7S5eZsOFmJRg5bU1ueozAMF6j/PuTEg2gSyjzq+rUHykiC1P4xM33W78RuL3/EvSZ5yo6pk8rsWlSE2QqtSOtsq/kScOgM2Jlk2Z7G9IzomkU= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ssMWA/jYYQN5z5m92SHUyLr16ZU2OvT4V0Ht+fHfzcOv9d+QGnBhVLviW3MJXpAKBfSJ5azshKNM9JMCDybf+aLkEILXe57ikE+Hca5pVFJDgb+NrFAmhHlVjCAMYAyXGAIuU+wBpeTD3kqlT7j74dyhPcCaVOK49Q4uQP/EqdXv2blDp6AlTfPRGZtx+F1LKyuSRDsih15dzbgfMAt1vdnqu8k50lpUw59BpPjlqfTCsxilNBrjcH0VPM+XuA4b1TJGLraSHNkcl6rSxN3riBJqXNXb/6p3kUtbo6+0kiCtBzVU2AFKedzNlAVMNzvZIKPcCgnfE6A2CMDdb1i6lKF0yVIqDeyn5I9LwDp+Xv1ATLahILe+QxxTwnfj065Y12QWYFolMRlgV5OZeD3Yl2rEHMCNHUcjtiAFuylS7+66B9uCps7gVu6znbJ23H4ZhQJOAhxG5UvaWyAU1Dd41H6EUN1J0CWA5jW8IuoQ7lsDjubTapMZhJ6ESS24lFT8/UOiXxWvcj68GhD1XfH4ZpU3l8DPyj48pfLalmjo1IsqYUASUkKWFEkxnSKDX32MPftObSAIUWnrlNiJvI89I4KU0Ab3DSZEaNjJghJ9Eu0= X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: TLSFNpornC1N0VXwhKIyJ/SLPUSxVB8u1z36jYFPmw1wXkCn1+EqW8U2TXuTpdBRZZqYh/oVx2DHqhgsECg9Lqz0/7/iPqH4m3fmpd3jJsJ9zWuKpkAOyhrX4WdisAHc5FyVWump4t8MTIG0kz3oz1xBlDopmZPd5/a709c7sVsScoCkKnKFR6EJmgd2qb6rWYo3dEJfuaQLg51dTrXqwfbjAntEQ3ENf2L0U+HjYkvsnxHP1Q961ZNg/BM+nNGlJMl+GFOM4XFrLSB4piOHe/SWIeOTjJ5cgyXwyVghXnX7F1tALPibfBD3B79mRCwj9vw/LH3yMratD5GcUWTHfYR7h3jxxja4ODMb5ZR+gw7arnpkzHMLK7CMxeR2WMISGFDr44fWPdiCkzqGgCARv8OwfAITtzbfBKi4u+a6cCi+q+pv00wLXQyb3lPXH+0CJ8JCYmzqukGdQSyH2iopUi/C0ohWoMk62QEXF+Y0wV0A7OaOlnJzRWBMOEnhjdISeFSaYRLGCvZM6QDeZV7BZ9oW5RSS/+wuTuh7mRKQI6V8+Ixn20M7GLJOlthCPtrdBtUiUl/Gk16LHtZmQyOtBgFXYSh2vTdIwHvbUzfxI7JhMVwSeZkygjAlWgAYc/d6FsFiLnItD0d6kJ4bVkag8fJQet+5/CFtk/JVzad0PnaHlprQAajIZ7PZ5Nz3TIybrISyb+SwPwN4M2euPpCXXL1ySpaoTiJRL8Pc+AbUJ20Qtb04vW/8QL6ka1RjxJDlU9N944NJkNwljng3BPwE6LLskwZA34OPqr+QWAo/01bi8nbZLkUsFLsDTqZ2zqWIg1nqnVjbJrc3iF73jTTheQufgJESb5ZQwzaylNE45kuh/aoe4orqcLlASbwnRy78ILZ+V46zWpVE1mOyOoy3LTeigqZljBPohWPNvjORxo0BzWG1Yb9aXQA1N5j9GVFDr05YRyt54CL0PxoaQi7a8kXID0upsBBh5UoJlzWxbsQSBkxdJxBX9uyFaQ+zhiSYArChJ+3Co+WJzJXYNGgPNwBlE/XxHPjj8EnK73vS9VXmHJHW9MTfy0HQFJg7kVb+x+BK5eCsOL2T4JpXLDyTwjWfJRs3qgG+64pmnE2/2D1p7wCrXAkrY/dSWrEloU+eOQV0E7L5sHtAokN6GbMOhw1QNIXVAIiSHjl3Bo6hUkCGtLNNbwhY1aqtQH7wXbqHymGktLlF8yN6ygAvfSKile6LTOS03vrfjrm8k7ET01muW49hPGQkde6RC70CkzAZ X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6770f2ca-3f97-4c23-a769-08dc1eee91a4 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2024 04:15:17.6849 (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: PUZPR06MB6068 Subject: [FFmpeg-devel] [PATCH v3 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: jVbeLHV1Ggjr --- libavformat/mpegtsenc.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 84edd418f0..418fa08ad5 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; + struct Entry { + enum AVCodecID id; + const char *bsf_name; + uint8_t m; + uint8_t v; + } list[] = { + { AV_CODEC_ID_H264, "h264_mp4toannexb", 0xff, 0x01 }, + { AV_CODEC_ID_HEVC, "hevc_mp4toannexb", 0xff, 0x01 }, + }; - 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++) { + 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->m == e->v)))) + return ff_stream_add_bitstream_filter(st, e->bsf_name, NULL); } - - return ret; + return 1; } #define OFFSET(x) offsetof(MpegTSWrite, x) From patchwork Sat Jan 27 04:15:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45854 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp370584pzb; Fri, 26 Jan 2024 20:16:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IEB+OXOxhk6py9Z9nl/q/P3YFt/5i6JFCtmTcSix9dzL98W+Hw/m0arCHvIE+ZLKZQDgKmM X-Received: by 2002:aa7:d895:0:b0:55e:adc9:f0e2 with SMTP id u21-20020aa7d895000000b0055eadc9f0e2mr819984edq.21.1706328960674; Fri, 26 Jan 2024 20:16:00 -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 t32-20020a056402242000b0055d2698adb9si1341416eda.10.2024.01.26.20.16.00; Fri, 26 Jan 2024 20:16:00 -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="B34nk/bT"; 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 7757A68D16E; Sat, 27 Jan 2024 06:15:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-PSA-obe.outbound.protection.outlook.com (mail-psaapc01olkn2067.outbound.protection.outlook.com [40.92.52.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4A10768D154 for ; Sat, 27 Jan 2024 06:15:32 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hXqlAc/vk+6uYZYxZz1ceRT2JzeJ2PuFWmwi5SuXuDe1xOluzxwEPNsJUOLN5i50A0duKSvG6RSCmDwjg1Isjpvg7Mog2iRvi7x8KXrx9OZZDBf2d7Hm8GHPHhWZEA6FX93noKFmUpC3vjl5vkOpDEue1K/LfY/6n6WH6ZaT0QpaCz4nRVTCA8ebgGKGJjJ5nlCovmz6btlwVEcdxwvyCTimJ5WfHkNMVOErEXrU8GPDwG7g9Ra+TgKgJ5v91rwSpe1l1r8amxrD1JXkEn3DVr+ccuSj+znjDe59/Q262DXT0JV06rOh4+wbkehAwUyHrAxViu2CZ3AMzmqRUHei/A== 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=MSIeVrdiTLUsE/5eTHqp2OxBsIT4xFmKlaAhCf29AF4=; b=dSdDK+z0zVmUeseOOtY0+KyqsDsSsBjJRL1xFoDnuDyRNaUVqv57ZV4Vj5d5JL5CgwlkUHdiVrPzL9B2V4Vt4rwj4e9kKeerTbN4reS6dBfDmQvrOjxAl3K+LisZILxUtJY5wAocB0NcuO3a7Pl3bZ2DBBtIkrlWo5N2eMsFXRXM0kqQxu/WzQHcjWWO3RYsvaMqzVvD3Kc2BjKQii0ShPZs8v8qonyqLpBYJs8/jNt5ADllcmu9odOzHXDZdLwOIx0XEUbhR/09cgPtU4wM74QyEebQXxMGiJF4xc6Irn8ei8bQkL0YwYRk94goVkTmYG8E7NJqB8fGlHnSUPM+5g== 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=MSIeVrdiTLUsE/5eTHqp2OxBsIT4xFmKlaAhCf29AF4=; b=B34nk/bTqjEjwv7VhRXRn/dicPw1vHfxXmPzlLOKyaY9kA9Hf0WBFwf5pPqa8F+7IWiK/soefEE3Y9Rvodpu+PH/zeHYwACoS4DwoPURyTv8t8klFJcAagGHku+kZzUwXydtS764u8Xq4Lc6qUXU2JzidAeL/l9Xqk4rPSdWyyOuatuFUCDOWbxCBbIFLC8mjIQ8/s9iikECfZfmWjUZh6lndUo/zo9y3MO7l8BmXnXyKTNmEhlCT4mFzv24r6jXR8MhfCKQsYRgpfSn/CLAuqquJLEf6+fxuM5BWqohZTG1RS85HBZqYwIcaAunYEUbe7fr6fbyQ/ovmMGW4C9MfA== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by PUZPR06MB6068.apcprd06.prod.outlook.com (2603:1096:301:112::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.28; Sat, 27 Jan 2024 04:15:18 +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.028; Sat, 27 Jan 2024 04:15:18 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Jan 2024 12:15:09 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240127041512.14079-1-nuomi2021@gmail.com> References: <20240127041512.14079-1-nuomi2021@gmail.com> X-TMN: [TOic7ORAclUsxaWqwVgZuwZX5afvOeOW] X-ClientProxiedBy: TYCP286CA0165.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:383::11) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240127041512.14079-4-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|PUZPR06MB6068:EE_ X-MS-Office365-Filtering-Correlation-Id: 7c956c77-1d93-4ac5-c504-08dc1eee9217 X-MS-Exchange-SLBlob-MailProps: Vs63Iqe4sQlWSIg1UbM9To69ipPieoVE3KXQ/PdRssvoBM7+ckW7ww0wRkmUDEUmVOChHF32QQk4eNFFIW5tnk8ddVuZGEdDhI0Op3Nmj/wlj7YosH/HVG4aBp3a6Mold7xZm/+onql1pFIReuCIl8JI81NAHZXWIv94ZCh8ns+qcz/9pWesjXondnZaDipSjf/Ur6fhyYxH5GzpEKsSfA/BQPWM9+Te6yQ3earkBMm1p9S+44ulyfgHiVsgwuQZU8Dw8rce6wkCzYyqInYXGPVFlN5AllU5iB3Zh5fz/HPP5hKH71F+cu5xDNNRqUP90IJjO4tlrUPBaWe+OKWkTBS4fPjUGD5Qbw5w7qK60i0C2i8YJdAdukAIxRh98QJkN5X7tot3aa3RArAGjLsY3RJXqyGHecOCrHMy7maY/8zbIBS12nYIPs0LAoeHEw41Ja+kWrnIWsJkFfnjYXW8/3yNS+OAidIsQxEs4n9qX2IAT76T5cU4JONGaTjzo7bK4CTvVRwbXEa5cXkN8SIx2DSWrEzML5zym5x0E7a70tnzSFLvllF8bc1KLHZZvVeAxIEcAiI5l2tZ51imxCgNLwfTw/rY6/9jN40ly1/CL5QPCdn8sYsF/569LZVP5knrNhBllUkdTQhyjBvug63SjZOwpCEkcly+vs+cu3o0/rDgirGuU0GIRuELsrG7AmvTo0dbltQSY4UdEFky3rvVvM28y3oaMmTYANx42/dZkNA= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: /vxByEa1+owFfr49HW9vtNJabpwABRsig7lqxvwiQp2zEOSk3xvK0Us/jyat2v7xAlOyODgtILLaTpaE3KGnNLC79e30mI7lwJ9Mwq2r9ZKvlEf3NOC9fqtI50/2zk+yAtGNv+g+6iSs6+4IA8mhDVS5BMAnwzUQqK2BtVgiCweEN7kuQ6F/bbZbM8SHoqCAkDHY1Ifv+PaP3FLXiiNn2jeY6bnacC3SkzadDQxDePf1iZvChF+NhXGL6xaBHVUYFG8EdDQ4vpAc8h6WU8JN0Aks8u5cBAOc21Bot1IUp8X4HcREiEvrjZXtjqZv85X3fGxAnk52CefMmG9gpSWiiYd3fwgv0FqhRM1NXzCnw+mvSNxSB8iBoUVYSRvLS0OEvhbv77iMYDHxD3f0YwxnaG14bb/vXfLhgq3FyfAPDvWv50moQJQfbSuSj5POo1hZBny0fbjqtgLEnOHH69X/SJrlvBRRt5v/XXYp4bU+ci8bfWJOKW4kYdrRBjoVa0yVxMxF+4MIKLOOLEHh7c8yW02yVNnN1rWwI06UJOBwOnhIiY2n+qMJi8PqJ0ev/YkoV4Y09guUBAc7wlZ8aeO4Y99RY+GnTVXwCR30+KZlSGt930UzhN2/up3f/njoqTvz X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: I9SEUDwNo3weyYz8CHuHJ4FYgRcfWyO+3B9FhVmYceQAqprycKszrPLJug/PC/Tb/1Ti1MGpF5rRu7pS8kUMoitBtSO4NvZxpO2jE7nYyFcd0e1sG3GMzBvUpOZSnkF2ylu0hKyNy4w4BryhDQ3e0i/yqCx4WyxFG8afQoRCmEY9RutCfLOQ9b5ZIpfJBpjslBkygspsuztTDzWbaQOO7ElBn44rnm4HUHaFI45/oQLhLhUg2+pb7b7NH9qfnfs4b+DINpS6wN73EAAAMfCgh93B93/rDR1ZJI8m0tojwzYI3fOlg4zuZNl0g0vp986LjsSoWz6DmIvlvFDlzzBIeuSkLgJ8rJbv5ewVaRUB8GSm/VeelGTFA8pXGg9TzKsoFuI+FQHvr1EHt+7ezRQb9y2YRPzUUz2CA/mBcabdWI2Rcdv+ktBdZXk7Xid/eBXG3po7gqgMpFKb2Xh/MJ3LTLrvXYSWJf3rM5KcbC0pybgTR/shaqFrm6kSAANr9RUXATpaSPnCIqPfvByQPCkTmYS1pwNIa10rwyuJnKs4w5v/GymB8iF39zrjd5PwMLtZZKtNpGT9PlNnRn59edJ4zcbkBNM7PZY/FA7IYaV86TxdMAnM3LH0nxojGzhJHOekhDIoEdwWGHDQznYJYMos99B+1NmCsL0E/wTRUv9R4NUcESyY9fMGPpbXsOa7/yeGIYZb6WW/epIXhuamiq0Ac9YdWZHg7gAlVc3V4TQmBgcJChsQhUPPCoBz+K+25lM0jyqRR5ATUoSMCFYfjg9fsExvbOhePFF/V6MK0tgfczNxFOzieWJmF3vLsk0FLNAzL5b6Y9mBp16Y8h43stHDT0uNYoIzOiIy8GeyD+ZAbqQzoCzblNPHyDjvbC3ESVsLq5esdIvCYurLGVUFQ7Mm3z+/LcodRW7Dy77QqUByxZa4q4/ZSHj5IkvpGi8zNLEUIx5qmQ7EhTJpTuUFZMtcTH93Yi8iG1JtIKGr9U9k7q8NhHhhtRpC4aLZiCirhr7Y0vn3gufF5ucQ1xuNCA3N3VnUlPub2xdw9umPrw8vjkQD6zAFluKV61cTP610Rrn8//q/t53piX4ygK3d+nkFTj7Xnrm5SEbQkM9j7Vxr0AKW66cXCX5PDrTqBmHxT+ZlNWP51MPVtRxcK7lUhksIGeqtw98Dt1hMk64DBLDmWvMInK6xUHBYXcPRPZy1pGxVWo035TDjOUOISKtw6krd3DNQPOb3veYhdl1lndFKVAhMHrz8i9OZN0E0PPjb7MAB X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7c956c77-1d93-4ac5-c504-08dc1eee9217 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2024 04:15:18.3507 (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: PUZPR06MB6068 Subject: [FFmpeg-devel] [PATCH v3 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: S0COu1SsmNyR --- libavformat/mpegtsenc.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 418fa08ad5..01b8c8d87a 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 Sat Jan 27 04:15:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45855 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp370633pzb; Fri, 26 Jan 2024 20:16:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IG7NAM5qohvZrrbmu4vryJQfdXJeFOaneVQxoGP2H21LEm3LN3fAEPeHMzDuQNby2a9UFcw X-Received: by 2002:a05:6512:3b0e:b0:50e:7a91:7e93 with SMTP id f14-20020a0565123b0e00b0050e7a917e93mr489441lfv.44.1706328970331; Fri, 26 Jan 2024 20:16:10 -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 l26-20020a1709061c5a00b00a2f1bc99283si1280080ejg.625.2024.01.26.20.16.08; Fri, 26 Jan 2024 20:16:10 -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=T3IxCJk9; 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 AC7B768D178; Sat, 27 Jan 2024 06:15:40 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-PSA-obe.outbound.protection.outlook.com (mail-psaapc01olkn2042.outbound.protection.outlook.com [40.92.52.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 18F5B68D163 for ; Sat, 27 Jan 2024 06:15:34 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YbbcDwlPBerU+XYiElzsnPEILg2zZWd16Q44v315PNBHOr0zn3oY00DR3dT7gXb4m52tKqtQA1qeschoLbG2n7FPGHAdymrLz8VyU+SJajmxR4ah1BSqHup/DirPSPxJbK7i/7G3L/M4yQc+7dqa6njCVbDXn8GpMCIe+EFhDcVdKfvUFPhONDiV30b1zhIf9MylnzKKx4c57KDgEqzUcWlqfCtvWcf2C0Imzj287ZrGWJoZiH4PXaNy2mAq4RvAMCJ21YwJ7ffOsfGSSCg+MM5mwvS4ABnkJEso5QqY4h7kv5XVIMMFhugKXkDtXrYRopF7HFXqZMIXluhtO0id3g== 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=UkABw7BYFHdiCdo1wSudiaIgL7ZSC/m7SHBN+4QLJvM=; b=mVY85ZTu/6rG5KvrCSCRICfjHOlbN0bJ39ORqBSn+ApjhEd1UGN8lbhmgWu0MyNzifmUmgCs2OHJpFf2/xpv8PqubEcdem7cYqJKTTOv9E6zCVJKV2aZ3N76o5l7eBz/TnqsgKwvp0Ai8H2gsnol73DBViuYbTU0YSaYritdDPT5g71ZE7RZvk7o7Xj7dkW68Memn6cN7XZqc69svcKORWkUXy2bKrXhKDAwtZgtDuK4tbkG61TrRv0BOzMPZwd3sCKDxEd3ofesZMQapuI+YvlJqbTdvgGWfzYgH8liujBIOplgm5rDn0MiagplNXXtlg60xrORjUOUi7gcMntb7A== 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=UkABw7BYFHdiCdo1wSudiaIgL7ZSC/m7SHBN+4QLJvM=; b=T3IxCJk9+IfIM/ddxAE+hsC+FUoSzAw6u+Bp11id+/C6THd1pYt+BWGOn45Hg3ppuhFw6zRzlBnoz1KSSJnYQBLxl418QVrzebVMtkysGhf9pWeXN22KyPxBjbBfO+79o/mO6+VksqsKrnQmhX+P5k+D5/gGYQOFOMhE6uDJsPs+EDlUoeY++Pa75iMKIBYo3MINMSDtDIZt2qNxRlVh304V6DQuaUyGMLAm2g72u7rmKOLb2w0gMDQaIzCU7xviYSD2Y1iDqlzkHnpXXI8oJd8zryTCDeWi4fCpSnWm49yeDz21aR6CNJpH1+iblNnajvppzEJnPKDJeCFC1B9CNQ== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by PUZPR06MB6068.apcprd06.prod.outlook.com (2603:1096:301:112::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.28; Sat, 27 Jan 2024 04:15:19 +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.028; Sat, 27 Jan 2024 04:15:19 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Jan 2024 12:15:10 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240127041512.14079-1-nuomi2021@gmail.com> References: <20240127041512.14079-1-nuomi2021@gmail.com> X-TMN: [tvdX6nzaz1OBJZGEIz2WAJMMOoJkXEmn] X-ClientProxiedBy: TYCP286CA0165.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:383::11) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240127041512.14079-5-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|PUZPR06MB6068:EE_ X-MS-Office365-Filtering-Correlation-Id: 2c74338e-f58c-4a85-8843-08dc1eee9278 X-MS-Exchange-SLBlob-MailProps: znQPCv1HvwXO1xbyOgO7FIf1KJkfnrOvEjhoGjlVazpKxTU3oNDCkScPb676CyMopMPerwzykrj7/aNO/BPWFZW0/ZNf6JaTYdqIn2yHPJM6u5N5YveZootkO46XeM+/iv0ksiQ08y5NIRYxMUKnmaOkQjQY4zVNJ3+7rEbSxxJbJDUb/5GMS5I3el+CQYULUKIQZ+gnBTsuyMnSIOheCgayjoXC7m8uTwyBCO9EbE8zH7TC9F5tH9MrQtPtmKfYvDRiT5gVdHWvNVHjof/QJk//o50vbjomhy9vd0gGQxVk4Oki4DP7PQRd53mQHU6JxFknnwo2RxPjGpywuh+Mlb809LyvPBVn5E97skKa/7oLVS1yOjW1ghdhWtJQPh7UJ4Kiy/GQ0U/B6EcV3vr9wPgwN1HteBLy1FyKUIq/0fDkV/voQTVr268c1fXL4EqdyNJAFHw7n+Y9L0X0BJnD+ocSQ6fNHRvIxanZ3I/mq5zEbCV1bnsaEgjLrdsemkvZrWbYn76a/T0AbbJElnmw/TZLAP1v+OmTUDWpJD65Gxki36yBVZ1+TMz0tWfP/55qyGSB3IyGu/LZDMrAsg2D82P8QtJeNIVGb9vVSVBWK1ajPIoLT2Lo5o8WpkfUkTyUuJMaS5VG8yNc+1RStG1gm6Xthn+LbJXedslw/zlA23pDBivRROBPtPF4o0MQ0JD0DQGIh7viUWx55BfciyADFPpWQlnYHisefpFBFq5XngOkGRvksHRJg7g5LF+BvZvyr4Osom7+RRk= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 1/YtT+DvkW3J1rx4aSzl1LJvPnrHo5ov7MT0Q8b0EbuxfYsQj4DcjmRCWdX4kpHcfCMf5lDbnxJz3g2JUKj2zyRxkxt4lYNi+MGenOAHmzbanLAa8r7PJZBcpT8C0EL0x+g4WUkZVaKOz1Ha6rFFEYVIdoECsmj9orhck2Z23dlt7otfh1k55aUFdtphzfFiasy5+FmYSy3mBEWIuVE5ECH2DsCaTtExrQo5mX+gHVGF/m8Z8W4niBZ08AK9oBoTFUFNk/Sp0qJCAkcJv2PhV6mFLop/ffVVGMY6MQ/L1c/6DxbS1FMDAnhO+n2wwVEvnzxfHgc9/j2G11bL9JDYl+BgxxgCcMLo3FIuXwXPtLv1ajXABOkbECmcQfj8oR258acOPfQ/GIIzAqr/pdArgJyfaIx4S9K8zMs7OE0sOz6+/9tFT/1rYlzFqmQmL7kCDAg85v6kzZhw3zQvEKBr2ki/mGngp/RwHViy9o6QU88efBMIbsLPL4cpAdDRyUTprarImHKGVVhkEE30psOCo9yllgI6/XSRHojisjNjrSZFJ0ST6a7ShVXisTAEWeJVNy2ClshrsLgqokujkkD/nCqi2r3sJxtQEh9ndwE2uww5KYRMrNvZwEQqr0E/L0/3 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: XQOdn5fJAE71t/4krR0B/Hs6ulARo0DyRwGVPDRpHgonZ4qdGHib2qbjsNPncsiZOdRTrps4PMuiJ8+PSigpB9UN43s2RoPufaRZStA7le8gNvq0s96HmNM9PLtW9mnG0L3g9rUEpgJncH+HVRWkXCaVvQXcVBE9Z8OXcMPr43WWkRgEZO/tV/G+ngn7maDQICe5HRps6OOKidi4FA7lWi5YpTHcSH1LSUexRt6eQNbaISLuhMjHcfFjtHKWxofgQXCP8YHx9RtMVs2hutsgxSg3lrmsnI2L0dMiwwapG7FC14GK6+PtVNadAHYFHcRA9AWPCoZ9BH8+3bTo9iEgM+lLlJ4boPyi+09DenTS90s4G33IJYHZfm4jYb8jzHlX6SOZKi6r2xvSuZ2sRP/DDhhWpxT9fi/FCl4JTLGFZZXKVYM5jvog6M36gxMeWS2k+wY+pu4Nyh3aO00tO4hkb9eAuzQ6BUHVspkW9UU6j6euELgQ/PqlZ2Fld++q3ho1t+W4PqM++60SGWpYRzftWJaiJGvjBh73EuYdDNBEaNftwFf7S/CXC+V2i7KzX1H8tnegnvdfKH5G+sH5ISxmIVFqw5fWyui/E7TkYkL9V26rt/EVRtg5psowKA5e6McX4wgDbYPC8fxWQRS46o4/pEbI4Cq5UCOKfhUcCi1YFoZiakxa0qPbuFBFw6fWi6IYrrK8xfaO903efoBootDOIFr1dATzMg9K00X129eratNkwcW2toRCfFVWtFs1yMWU6AIj8j0Emne1IBkFXa8QVgXz41DXFTssAfIdvXXx4R9Ucf186iN8bW1q42u/TlKC4GSLHcdvRTrR2Lo90vGf78+py9+jwcgEacc3Yr/p4PLNfI2R7y8EElbNErm+4EdxmLZVR2kZd7e97ytH9kmrjt8cdCoON7SMmlu598OyEDVYx8TXm9jKs6GlzsYezSWf1GT9Oz6msovYGpEWQ9ploDFz2RK18+67QWPQL9LnElFP9kq/o8fYqR0QHlIkzXRR7lR9Oat7eWvGg3GQKrvPQD+6LrwETPOFauoy/mkfgxuaF5rMhdrLpQp+J8O2231I/w6bq2gsBaJv2EFmzcYE4b3DMzm5N14eSkqgxn18wvw5/QbxSSF2zpEe2atwnBMZ7uHvfejAiiqiPdGwXOCsW3gRGzZFj2OBhj4x+Jzndh0SSw6UCylgQZcRbGUbPDV2ijZ2lZSuGIPIWNxvBULgYw3Wokpa3JtrLcBzz8dofwhCQbbF5zwnXowdmwcYwEQD X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2c74338e-f58c-4a85-8843-08dc1eee9278 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2024 04:15:18.9845 (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: PUZPR06MB6068 Subject: [FFmpeg-devel] [PATCH v3 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: qtCk4woK8lnF --- libavformat/mpegtsenc.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 01b8c8d87a..0843516ee6 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 Sat Jan 27 04:15:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45856 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp370661pzb; Fri, 26 Jan 2024 20:16:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IFj3jY9VYA1OQCiWyaOlBTRqoCraoAiatg1+2/W9etHn90jZ+lFdNHh2LxCQmiK2FEtnRaP X-Received: by 2002:a5d:4e92:0:b0:336:6bf0:a005 with SMTP id e18-20020a5d4e92000000b003366bf0a005mr415749wru.92.1706328977710; Fri, 26 Jan 2024 20:16:17 -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 cx10-20020a170906c80a00b00a30f3e88390si1191330ejb.623.2024.01.26.20.16.17; Fri, 26 Jan 2024 20:16:17 -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=A81Uo5HJ; 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 E241268D185; Sat, 27 Jan 2024 06:15:44 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-PSA-obe.outbound.protection.outlook.com (mail-psaapc01olkn2067.outbound.protection.outlook.com [40.92.52.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C0C5168D17D for ; Sat, 27 Jan 2024 06:15:37 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gwXMQosJ7Eao52Hjpcvtsmg9Pfr+ZNrLgviknBMShpIUNdeQbrvd6bSF27wbTK2xTuM+aq+qitTRoNC4tSfY3kMvPbX1cCEPum57m4roWR/M+YSxNt5PLTRww2Ea7Fw0Wl2SO7NtyWcrdM2+np1fvpQ+9gABVIXCFKeHnm5y7XFVZ0b3yihqpzYiKwQUErewNEKuoVSY4ItfuMG0hPvVx2GJZiraYygeVZXTtJCuf3BqvLAuNRIm6r5qfEgwdtFlwWYwMgDv/5ze4usUu0H9XvXLY+6Wahm5lFNa09SQsT5lkrPbaO3+CLCvk5YN9bQqo9M1bK12kpEwNxsv7ocY0w== 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=H/8fTRIZULQ9pSCJRsxvxERy3WqcZrmlcAuKtDK4tTM=; b=hXDlwlPjik1CzI0YrM8RcKlcIjiCHozzswrrFXZQumz71n4j2wPRDPbzcKTx+O8pDCpt4GHp4pboxH/fk7lreinzGWEBM695Y1+q21Rgx2CMjspsU7PhykMdhnBeSadeXt/iWGYVfsx73vHlbw4rJzG74oJP2fMOIpSiNBE6fWyAclkDP18aPrvp/Xx7WT7QshlioSyBEnHXJABRJXFqpnuCyROuIMXEpEGFT0v8AnfS+UXS6zetqx7iEOB3JhjBIWJRswTDJWYsmKLI7UVinYZ4wQ/6okgNr62No5yUmFlxaJItfG1G9lkyxcighCnVJIFh0oN2LLxma9cK2hPIPQ== 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=H/8fTRIZULQ9pSCJRsxvxERy3WqcZrmlcAuKtDK4tTM=; b=A81Uo5HJGLMwKqTSNnumk2WJxv99RymWgxDsWm13mvOVIhDO+Wl0id74AHFascGwawjHNS5v4f7f4IaIZdX7aUz2IBr8WJjvZx0lNzafWqnQsaVvN2PVEtuDoR+Uh0HUKPfaNKldnNkLGXrX24BtAL7yoahQyfwITeREzluPf6OCyRj1DZJYv6yH3vUlpp4mFUkPn4vSJ08iA0nEB2ksTu/t9ygihe6wellmZl1w48ohvSx9DjsJmVXAZUlHffzm/6lR8/2rXAqLhJ1KUffYjebBNMJ5axw9xuFPZcE3yRxTqTA/hShrwVrlp6BjJnp5/AfCDd+wGBBfKBPcNIQE2Q== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by PUZPR06MB6068.apcprd06.prod.outlook.com (2603:1096:301:112::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.28; Sat, 27 Jan 2024 04:15:19 +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.028; Sat, 27 Jan 2024 04:15:19 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Jan 2024 12:15:11 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240127041512.14079-1-nuomi2021@gmail.com> References: <20240127041512.14079-1-nuomi2021@gmail.com> X-TMN: [a3JSRsq+dfekrXTu1dBTP1o5mCUA1AwK] X-ClientProxiedBy: TYCP286CA0165.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:383::11) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240127041512.14079-6-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|PUZPR06MB6068:EE_ X-MS-Office365-Filtering-Correlation-Id: 4abf614e-99a2-4efc-a101-08dc1eee92d9 X-MS-Exchange-SLBlob-MailProps: znQPCv1HvwXO1xbyOgO7FIf1KJkfnrOvh5WdK17e9S9I3kfkzF+gGnKmUR1s4ncUEKhdc51tiJEBg2pKlKyPDCzPe9QNr9sjbb3et1ymOxsqt6//Ap/gcOvAwZtW5V9trpuEB2l/nLxRW4Cc85yPkmPO8M6PyTu7WvImDMeVayiqB9m7w7CDUfxoUWqJtkyEUvFGfVwgF89lANfYTN7MUWUiK1G1gdYleOBw0nm9qrWd1ezuXIksDdwc6sIYndZU/RlzikarE86HaFHCXS+7PFNTRRk72YHGvlxo145kPsPWxhzWz9+Yb5mssZCR7/Z3Pb6VEhNVRl0mXCsTjKx+4Y+dQQCxbZZ7khuRH15+f2c9GcvTewztAVR+TZ4LiyqW7836VgQUrg1C0ulo75xvaJ1nNg67MKS/IqUmvdElfjVbCth1UCzyo21ABkOkFlYkvInWGqj26t7MXoN1ZfBnko4mrk+5c5YzFmasedynxCo+yBTE0gbDOzEyLb26lB6cIEZDp2mxK4L5eBU9tVqnb3RfQhWkH4sAtZbtlraQAf8lBQ6JgG1sqZt2GFNgXBlUCbbPcb/14wJdk6vg4pVQRApaUgrh4hwj+4pViPd4GV0i6SbHEFlwR7SevWy6bh3n6oihX+Ty6GlW9mRcHz8rxHouT5OudXMTYBGowUjkIm45q+OBfiMa8D1sX/qSxXnuMtxUxnpV5/uHRKewaMpnzEAXdGCNkW+RnrFVZOxOfwXi6R1pI+CqMy4Q7uAPtxFxJdSeAxTnT2A= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oVl2jo8a4PosGOccW5YSzqFRUaH8ESsEib4liFaKcniQH+XEgEyxht5APD6eudqPA6+gqzUq2nFJwI/EJ/px4OFYY95WfKvJCQQa2uRHrwJ2LGbEArFywvmsD4gEFM18HZ/nYyburEOgRJ/WIrkSQ64GZGt13T8Et6reueWfuB3ixJDYQUDUa3LbkvE89GLBfzpr+q/YgigEMMB1BVKUgMiLVrTVMOdWMwdBnmovR3YKUMsTOzmtOGhs0hehiPl9NKsiJMB47n3LKymwrIVbQ3WDhRUy36EMeRyCe+VKz2LX48IqX1leg5gmlycvnS3DAJoFM9Omi2iQ7uCnj0KLeSh0938phCDqF+zUr/kG5yai3x8YVgla+JavH1odv+0GRtIfOq9sQMh9bW4K3TP8bMZ474kNEBlBi54qop1p8uhO6uNetd51j/ME/N1N3BL52wGkswl91JIFx0Xs0kH2IEhJPFlBgx2SkKG2ZNtPHceaY8TR3/12pFwj5k5O0/n4hwO3ivzsNV6URkY3InRggtyiie5H2VrLaWAErqVSGE+19Q0r9pPMYxDq/mpSBwTH5F6iVCscczTLqdAp2j/uuiaKk1W/ZA37yrXQE0ZwLwJFHFTgU1mBXIh+xo/VOiZj X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ZCMCGU4fFEy75YFyPGFqUipjzKmFpsm4dFs8W6Odbpnj0E8InfjuWO0VugbKCVNpsKVYdhSVstpdqVwpEoUO/LhaTbSp3xTPMJ5XqsegKlY7YKmdu1YIL205zbkf2eVW34rbJxf4oA8YivmL+mFMSpA61rScI+iMaXQ+Qg5vgh0SpurvPuiMY/30MqYwLlylwzbKH7l17O0BAcdL86pIss2+rQOlAS7nHzjuEqGJ8yDJG4MXEsNrSHtm1mRx8YXR1Y8D1bETZ3ksn3oUifBisYn0Rhr3bXroqT/mqH/w/kJlA8lSLWuHkB/BMCz56NTzPWuQibLjd7el30mJIe0yMKF2mV9rTd656I5XGh98UznM9y9oOP/eAkdWgZhOzlfCfD4yFTSBdlFbxwr3ov08wl8f5FitBQ4PJ+sMR0zhb9++ZuL9Qn0WntpSBXR578sb4BYFjZ00jdLSfm2RGprl0WjYXMj7XyDnjWQVT6bnqPxqLFY9+SCrghQL0B5OiPkBEQ3GxIlifMB5O18XkGtRytyL4R0YVu+jVeQ5ZoXAff7kh0XrgpvgQwQ8PIa6p78fQq6og8KHsnk66LWEsXuxB4HlCSk6sNaN968tFz9L1Aepcl5EG5VoVpuEHwZWAlrYn8Ppu/ww7T8iyGsxxteyIsPiN7BSEIf6llYy+zxqToTelEhGsH5h6pEn1S/nqqcPkZUnhMaq2+ICGWb6lAD/lFGfxnThf6+Dhx1KG2LPEtJXr/p6JNv9lVb/LXpe8pNwByzp31H55X2gGDED6ujSVtAnydYoTz++jhfFZW8sbkfg2TZGtYzIZSAE3zzh7YdLS6E+3PQuRtxcAIaGkG68BE7qvN4MPLS1iKqmUeOCKxm+VqWp0VZCDR1nbnEnmwzGXNOf7XB8/ezFb447iJV5pm57Z7GOPFFjrvQUWN0AgLrVgO6gmyjE9+BIcXwZRGUJe2xy215JEDCvSQHZFr/A/CVNpcwjei0JHHrarmnbuKuQgmtJfH5RL95G2I6zQZMKdKFVMzs0FlZuTwH+sW2yddC+Vu7Z9JK3GJyS4/h9iMDPt5j7goJZRqAyhLIcCmedooPSzlyQH3JlvUU4mnJ85mkU4/Wm30CW9b2jr9Sqq3grWiMxqjOJGxmAXCv0caYcfJfy9yhzzQLnQhZsKJ7cmLZo+CcrVytmqv3KkH5CxoaFXVKTnkvBrq5ay1sZVgSE2Kef0EfH7wGD6DuuDIoZENmT0lfeE6NziB6lcepQ2CZtOHTIO6oR1xaRWL1OMVhw X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4abf614e-99a2-4efc-a101-08dc1eee92d9 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2024 04:15:19.6801 (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: PUZPR06MB6068 Subject: [FFmpeg-devel] [PATCH v3 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: hEr7zD1rqJz/ --- libavformat/mpegtsenc.c | 45 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 0843516ee6..ff1c4de640 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 Sat Jan 27 04:15:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuo Mi X-Patchwork-Id: 45857 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp370702pzb; Fri, 26 Jan 2024 20:16:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IHwONm55+7QOfxC3+HnctlMUh6lmMhSF4Przbq6g92TivuX0erbHgS3rMxi9bq3Z3kFRjgO X-Received: by 2002:a5d:5264:0:b0:337:c835:293e with SMTP id l4-20020a5d5264000000b00337c835293emr509661wrc.86.1706328986417; Fri, 26 Jan 2024 20:16:26 -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 ig8-20020a056402458800b0055d39743c19si1043650edb.349.2024.01.26.20.16.26; Fri, 26 Jan 2024 20:16:26 -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=oZV5AIEB; 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 1644D68D189; Sat, 27 Jan 2024 06:15:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from APC01-PSA-obe.outbound.protection.outlook.com (mail-psaapc01olkn2042.outbound.protection.outlook.com [40.92.52.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9202268D16F for ; Sat, 27 Jan 2024 06:15:39 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Yloh6yPfyZLx6S2JfvMyDv55+xDW1LRg5K/UOUfC2ZCq/DobhCwIUaSrkqJosd81RxLBfxxicvkFpPJ2JneUn1v3WsLym//8OM3XNaMPqkEQwwRolH13mNGP8Gn0nrsuVOQI4cUh6qCLTkDi0JgMwVWvRaeT9L1/9XHvbzQsOLD7FS/ntWRQt+2zGhdbwHTH3oKlQdg653cXtQTc8h2wqIP7cc+4/2c22GwwU9XxMN/CtEMvOhDHszHoCNFRu5k8FJzSSj5D4ol3aBApcXlLVbnETLw5/lctZ1JXcMWjH7tVQx8SZcuGpd8Q5JLW4ZOhf5cGkSllO08/9ywTZoKxIw== 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=FAOYdbndz+fQgCJ3TBpwBST2WDMvFiHoa1hxQySB8Gw=; b=VBtEV9c/GpUFkiHyhk46nMsCy5P9GRMl33Q8feepBItxrt3BWiQCT9R3ipYhr3Evllk4PCDIhZT9wtFVNXYNaleMB6Jh+MnxX1GLx6ckzYfpzLfH42OiKVG/1V4ZOHKmss+K5R0WEG0JRX6ln2UKT9H2ahgfCgpg0VK7sMR2E2Q7+4Az6Z25Zfbz58PMM1Z4rvg1xjt8P68N6kPsEb6R7HxkIac2LJ0QUO2FGcUY1+/eAjVUT4/tnmMiwRiK4CsphKuOdaPUz0BCz1mv3Gtz3LFbpGyfC5YqHfAtIZ6jNagQKeIEYtNJl3mn25t8O+A9xB4GYxLfSociFX/mn9S6xw== 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=FAOYdbndz+fQgCJ3TBpwBST2WDMvFiHoa1hxQySB8Gw=; b=oZV5AIEB45JO/48+kJA9bA1KkQ6ntKkDT2W0fj1MDNGOoFyfyO81jQj7LCTWEwvTZAV30CyA3ECB85nUB6IzGTscFS8kuvsX43Yojrov2xgsae5IepqABgpSawuLWoMlPJ+dN+1o4LGkgdrDsnjNToKJWvVAxKOSRo0FwHoMmr5vsljyPKWAoXgY/6KNB9g8gMkZfV2Gx4VbVgYOJbrSbvEvqk8tRu0uXVue8QsCBxFB5tMDJUsa9gbANBzyfgi7u+BMoUrVE/8OSBjaKmWSOh5zwiJ+V5Mhqb7jisLlpvntd61yTIrQ+T5U/w+ANe9btKi/Hc4Gho+OrhDB/8qT7A== Received: from TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) by PUZPR06MB6068.apcprd06.prod.outlook.com (2603:1096:301:112::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.28; Sat, 27 Jan 2024 04:15:20 +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.028; Sat, 27 Jan 2024 04:15:20 +0000 From: Nuo Mi To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Jan 2024 12:15:12 +0800 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240127041512.14079-1-nuomi2021@gmail.com> References: <20240127041512.14079-1-nuomi2021@gmail.com> X-TMN: [rDFENG+LtwsMsRa2hOw7mv4vtVqsjhCg] X-ClientProxiedBy: TYCP286CA0165.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:383::11) To TYSPR06MB6433.apcprd06.prod.outlook.com (2603:1096:400:47a::6) X-Microsoft-Original-Message-ID: <20240127041512.14079-7-nuomi2021@gmail.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 2 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: TYSPR06MB6433:EE_|PUZPR06MB6068:EE_ X-MS-Office365-Filtering-Correlation-Id: 76cf73a5-1ec1-404c-d9ad-08dc1eee9351 X-MS-Exchange-SLBlob-MailProps: WaIXnCbdHrNzfcV9bBs2YPdpUSHmB+XBx7nhcopr+QtyPvRoOmUTwd1m5feNAbey0nzci0iQmC2q3ups6wcjLXZI77NTZ8AZxQNFxmdpo1DHp1hP65hP0q2eB4h38kKyhTeKWHhJh2TxFDS9QaiIVNweOErWNcQnvXqbxFZZCsaTrAG+r4XMnsQr3+vkXtrQ9IEwKg+/GWpEvNTXeDhXsaIX0GhNRFmtLKhJUdGgSdwbk2oPtImDq+WE0EA4N5gqfnX8T7r72y8f6CKBJkqcyUqcg4Vx5ZwXwDbkTo558zFJHIlAhJAX8fsF4OrKVL61wUGBm3lRQEOJaJppys+/AXMNBLydTU0Y2vSLAaP21ol2xraRT32IjOZ/KJVEyGdPsFZBOvafniFJ5Ql2Cvw+2vymEpRU+Hn+E4xV4UGDxZqbW8GFaKXfIw4bCAYhF7aYFzQf/Cm73bxJgVCEdLuGp32FVvgQ5WOsbFSODVOyUxGoGT5W9x8muprupbra+QOk+Ep5Dm8BNbY3XiNKV48Iebj1Xur9Wq+F/NfXxbE7XZu0oa+xXm6tRW7DBBOTZTkCrLblIqngPqZ9c4B0IoHPMOIQ5xrG7ped9qZ5CID8EHTrXinRmaIho+iCPxx/oOYWj68JXZQaDeJuHloWkHwT68TRuhfmqFD6yKQutMp/0a4zlVllc5f6yLchYC7gME0YwEsjp3gfz9EPncZY7uab03ODIRhpNSj1Zm2VwRiQIY+xWixhbca7mzKp5eP7ORZzZvw68yy/ECo= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: qdHq0lRQVegaG7q1CXgVtRNMtXw/lk1EiqTcEiLS453H6F2REmn8bHH4hAqlqWTUqCVMLEAGdzA9wuvkYke+MCOGzO72icM5ArVth/kxxBRhbGbJ2i4Qme/ZVvmLO1H7JLBA3IYxFfVucpNEEaW4Z1bL/f6gBIhcso1/aXLpxU5/mM+v0ElFzl2EL8QdVk6lNntCxecIuxEe0QqY/mtgqfOyM0VsqxdfH3UH5YE+7rsdUQ1xcHGr3GfKBMuT2afW+fDpWeIAiwDMiyXGeIZcPWy5ACydt7boFThre3l0ilDIv5JLbKkENr6wMtIwDMEw/OCjf3ySuKWZIrLgREIB+DnvBBTreRn+bqS7uhDcYlLbdXNzF3R0AIlPxIKWozmOpOsNKzIQvpR2yjmC9mC0+d2rd/VScOhN8fCvxTMJ1V+BW/o1h9wwdb0zSk9hZxUpHDGq9k7jlGfT8T+nvq6NvKl443/TE30S2ZaZ8zDevNinAI8BbSwyLM1yEdwr93m6sVBrqaBU0KN7gOgjD1auJYIPLdIKakQ3RSZql0wYlFVrISDJEoWWkJPA02wSjCtFzWPe7eepuAzcsOoYtuBELUijMV+A/Xu67YTcqhBvbnOJBLDplynuYMbsWMbljMnF X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: CYpEBTSVgwcfCLn99EtlYHCQws8EAMcegVUUS7U99/r+7h0M0Ryi6iPXR45kHrS97KqwFHfgcSuOH29h7tcWTYvVzT7LqWc1BYF9b598RwWxU0ADH9Vbw7rl4aBfFMhKA/tDJ1vMgms/i/h2rgaj+Le615roXnY2Xt3M2uM5BSAdwX23O2pi2lLbPUOgdS/g0Hx1L1EJ6foHCOwllknhDVvaK0fbWdC1MMifhBcpeBwGZhNyuKTcYGd9x87EwLmgr/IJkZs1f8ybqd7T48A0wI3lld0boxMxJoKhZhz4RlzNpT0KxGhHm+6Qv8fs0Y6Al/mSpDx3UVtoijo/XaC29wuouMQydsQk63kveS9WPHK/glC51fXcqQl5WOT4EVzp2M6tdgY0NmbgpCSO3U6V+M15HRJHWqa24Gjzb1llwUAg0xBNs9Npr9YK5SVBNhvbkZ3MvEXSakD34GA5WlVidEMYSBohUKUhuqh5xJYdyZ9wtP8+M22yzZ3XoxVXP7UVV2mWRfCpFw5ixq8JuOo6f71Sh2m+NKpgIAS6GyZEOcFtrh/3DGBwxt+3EqOJbuFw1QWv3TqVGkWl+zSIRUkw5cAnEcG3nC991mt0shKug/+W3vVRWKJGW29gCoM+J9Q8vE7meRgOmHH0r1i9/GQDoJ3vjVu1YvUEJQz5XEavYUuwPDF2Rs2mazYovOW/qFzel2TwbYaMbfkNdm8lvVVMUsmb2C66cEZVtr3LMMT1en95FxrPv763ObPIYAGe7FeIfmkB6JbnX8ybdqkmia9o+bpANBmmRO9neghrmGYcjIT8oWMl9C+bONZhAY7zHwGfRPSeIzZgry8Go45jF2wDesJJbZK/+JiM0hW9x9y/KnlS3OEio82SUE92zYXsbhOQ1T+iaYuyPqwzW/KjIzWvFtVV05SvTkYpZ/9AuoNapoHkNUyyHSYZvDmlP6ev1HhBUm2EaLyjqPCc2SwPQoLnfUiTvDVpTNFJPAeaKWK3gDknUQUeQfz8shc2Ga7NNRUvOGLdkw34zLapi8VXNwcJkVmK7ElAJRX03mqML8nOF0WaHhPg+nV8Lg6KHa1FSnWPh5REhip+4k0STqC5wocAXyhrsKmya8kh6CKyGTzsapzKB+Ls72b/00IV5IzSajxe6/ej1e4WherpSBJtLktoc+ZFs1/f0e0J/xI6kQfxSh+LpYnoVZYxna53B2rbfgrKX9XuaSeLqmJR7JRU5qitg6zwBiQ47PAPsqqhYTLHEuoST4IvOGeu1bmrQDcI1axL X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 76cf73a5-1ec1-404c-d9ad-08dc1eee9351 X-MS-Exchange-CrossTenant-AuthSource: TYSPR06MB6433.apcprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2024 04:15:20.4138 (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: PUZPR06MB6068 Subject: [FFmpeg-devel] [PATCH v3 6/6] avformat: 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: N5b3VIeGelC0 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 | 6 ++++++ libavformat/mpeg.h | 1 + libavformat/mpegts.c | 2 ++ libavformat/mpegts.h | 1 + libavformat/mpegtsenc.c | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 50 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..4b0c65826e 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -546,6 +546,12 @@ 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_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 ff1c4de640..69ba47534a 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 }, { AV_CODEC_ID_HEVC, "hevc_mp4toannexb", 0xff, 0x01 }, + { AV_CODEC_ID_VVC, "vvc_mp4toannexb", 0xf8, 0xf8 }, }; for (int i = 0; i < FF_ARRAY_ELEMS(list); i++) {