[FFmpeg-devel] [PATCH v4 5/9] avcodec/h2645_parse: add nal header parser for h266/vvc

Nuo Mi nuomi2021 at gmail.com
Mon Jan 25 16:15:03 EET 2021


---
 libavcodec/h2645_parse.c | 74 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 3 deletions(-)

diff --git a/libavcodec/h2645_parse.c b/libavcodec/h2645_parse.c
index a36ef4f5a0..35f9d035a9 100644
--- a/libavcodec/h2645_parse.c
+++ b/libavcodec/h2645_parse.c
@@ -1,5 +1,5 @@
 /*
- * H.264/HEVC common parsing code
+ * H.264/HEVC/VVC common parsing code
  *
  * This file is part of FFmpeg.
  *
@@ -27,6 +27,7 @@
 #include "libavutil/mem.h"
 
 #include "bytestream.h"
+#include "vvc.h"
 #include "hevc.h"
 #include "h264.h"
 #include "h2645_parse.h"
@@ -146,6 +147,47 @@ nsc:
     return si;
 }
 
+static const char *const vvc_nal_type_name[32] = {
+    "TRAIL_NUT", // VVC_TRAIL_NUT
+    "STSA_NUT", // VVC_STSA_NUT
+    "RADL_NUT", // VVC_RADL_NUT
+    "RASL_NUT", // VVC_RASL_NUT
+    "RSV_VCL_4", // VVC_RSV_VCL_4
+    "RSV_VCL_5", // VVC_RSV_VCL_5
+    "RSV_VCL_6", // VVC_RSV_VCL_6
+    "IDR_W_RADL", // VVC_IDR_W_RADL
+    "IDR_N_LP", // VVC_IDR_N_LP
+    "CRA_NUT", // VVC_CRA_NUT
+    "GDR_NUT", // VVC_GDR_NUT
+    "RSV_IRAP_11", // VVC_RSV_IRAP_11
+    "OPI_NUT", // VVC_OPI_NUT
+    "DCI_NUT", // VVC_DCI_NUT
+    "VPS_NUT", // VVC_VPS_NUT
+    "SPS_NUT", // VVC_SPS_NUT
+    "PPS_NUT", // VVC_PPS_NUT
+    "PREFIX_APS_NUT",// VVC_PREFIX_APS_NUT
+    "SUFFIX_APS_NUT",// VVC_SUFFIX_APS_NUT
+    "PH_NUT", // VVC_PH_NUT
+    "AUD_NUT", // VVC_AUD_NUT
+    "EOS_NUT", // VVC_EOS_NUT
+    "EOB_NUT", // VVC_EOB_NUT
+    "PREFIX_SEI_NUT",// VVC_PREFIX_SEI_NUT
+    "SUFFIX_SEI_NUT",// VVC_SUFFIX_SEI_NUT
+    "FD_NUT", // VVC_FD_NUT
+    "RSV_NVCL_26", // VVC_RSV_NVCL_26
+    "RSV_NVCL_27", // VVC_RSV_NVCL_27
+    "UNSPEC_28", // VVC_UNSPEC_28
+    "UNSPEC_29", // VVC_UNSPEC_29
+    "UNSPEC_30", // VVC_UNSPEC_30
+    "UNSPEC_31", // VVC_UNSPEC_31
+};
+
+static const char *vvc_nal_unit_name(int nal_type)
+{
+    av_assert0(nal_type >= 0 && nal_type < 32);
+    return vvc_nal_type_name[nal_type];
+}
+
 static const char *const hevc_nal_type_name[64] = {
     "TRAIL_N", // HEVC_NAL_TRAIL_N
     "TRAIL_R", // HEVC_NAL_TRAIL_R
@@ -289,6 +331,31 @@ static int get_bit_length(H2645NAL *nal, int skip_trailing_zeros)
  * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit,
  * 0 otherwise
  */
+static int vvc_parse_nal_header(H2645NAL *nal, void *logctx)
+{
+    GetBitContext *gb = &nal->gb;
+
+    if (get_bits1(gb) != 0)     //forbidden_zero_bit
+        return AVERROR_INVALIDDATA;
+
+    skip_bits1(gb);             //nuh_reserved_zero_bit
+
+    nal->nuh_layer_id = get_bits(gb, 6);
+    nal->type = get_bits(gb, 5);
+    nal->temporal_id = get_bits(gb, 3) - 1;
+    if (nal->temporal_id < 0)
+        return AVERROR_INVALIDDATA;
+
+    if ((nal->type >= VVC_IDR_W_RADL && nal->type <= VVC_RSV_IRAP_11) && nal->temporal_id)
+        return AVERROR_INVALIDDATA;
+
+    av_log(logctx, AV_LOG_DEBUG,
+      "nal_unit_type: %d(%s), nuh_layer_id: %d, temporal_id: %d\n",
+           nal->type, vvc_nal_unit_name(nal->type), nal->nuh_layer_id, nal->temporal_id);
+
+    return 0;
+}
+
 static int hevc_parse_nal_header(H2645NAL *nal, void *logctx)
 {
     GetBitContext *gb = &nal->gb;
@@ -503,8 +570,9 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
 
         /* Reset type in case it contains a stale value from a previously parsed NAL */
         nal->type = 0;
-
-        if (codec_id == AV_CODEC_ID_HEVC)
+        if (codec_id == AV_CODEC_ID_VVC)
+            ret = vvc_parse_nal_header(nal, logctx);
+        else if (codec_id == AV_CODEC_ID_HEVC)
             ret = hevc_parse_nal_header(nal, logctx);
         else
             ret = h264_parse_nal_header(nal, logctx);
-- 
2.25.1



More information about the ffmpeg-devel mailing list