7676 HEVC_NAL_UNSPEC63 = 63 // Dolby Vision EL
7777};
7878
79+ enum
80+ {
81+ VVC_TRAIL_NUT = 0 ,
82+ VVC_STSA_NUT = 1 ,
83+ VVC_RADL_NUT = 2 ,
84+ VVC_RASL_NUT = 3 ,
85+ VVC_RSV_VCL_4 = 4 ,
86+ VVC_RSV_VCL_5 = 5 ,
87+ VVC_RSV_VCL_6 = 6 ,
88+ VVC_IDR_W_RADL = 7 ,
89+ VVC_IDR_N_LP = 8 ,
90+ VVC_CRA_NUT = 9 ,
91+ VVC_GDR_NUT = 10 ,
92+ VVC_RSV_IRAP_11 = 11 ,
93+ VVC_OPI_NUT = 12 ,
94+ VVC_DCI_NUT = 13 ,
95+ VVC_VPS_NUT = 14 ,
96+ VVC_SPS_NUT = 15 ,
97+ VVC_PPS_NUT = 16 ,
98+ VVC_PREFIX_APS_NUT = 17 ,
99+ VVC_SUFFIX_APS_NUT = 18 ,
100+ VVC_PH_NUT = 19 ,
101+ VVC_AUD_NUT = 20 ,
102+ VVC_EOS_NUT = 21 ,
103+ VVC_EOB_NUT = 22 ,
104+ VVC_PREFIX_SEI_NUT = 23 ,
105+ VVC_SUFFIX_SEI_NUT = 24 ,
106+ VVC_FD_NUT = 25 ,
107+ VVC_RSV_NVCL_26 = 26 ,
108+ VVC_RSV_NVCL_27 = 27 ,
109+ VVC_UNSPEC_28 = 28 ,
110+ VVC_UNSPEC_29 = 29 ,
111+ VVC_UNSPEC_30 = 30 ,
112+ VVC_UNSPEC_31 = 31 ,
113+ };
114+
79115enum {
80116 SEI_BUFFERING_PERIOD = 0 ,
81117 SEI_PIC_TIMING,
@@ -545,6 +581,23 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
545581 }
546582 return false ;
547583 break ;
584+ case AV_CODEC_ID_VVC:
585+ if (in_extradata && in_extradata[0 ] == 0xff && (in_extradata[1 ] & 0xf0 ) == 0x0 )
586+ {
587+ std::string extradatastr;
588+ CLog::Log (LOGINFO, " CBitstreamConverter::Open VVC, convert to annexb format" );
589+
590+ m_extraData = FFmpegExtraData (in_extradata, in_extrasize);
591+ m_convert_bytestream =
592+ BitstreamConvertInitVVC (m_extraData.GetData (), m_extraData.GetSize ());
593+ }
594+ else
595+ {
596+ CLog::Log (LOGINFO, " CBitstreamConverter::Open VVC, no extra data" );
597+ m_convert_bytestream = true ;
598+ }
599+ return true ;
600+ break ;
548601 default :
549602 return false ;
550603 break ;
@@ -759,6 +812,57 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
759812 return true ;
760813 }
761814 }
815+ else if (m_codec == AV_CODEC_ID_VVC)
816+ {
817+ if (m_to_annexb)
818+ {
819+ int nal_stream_pos = 0 ;
820+
821+ m_inputSize = iSize;
822+ m_inputBuffer = pData;
823+
824+ if (!m_start_decode)
825+ {
826+ uint32_t packet_format = AV_RB32 (m_inputBuffer);
827+ m_convert_bytestream = packet_format != 0x1 && packet_format != 0x100 ;
828+ }
829+
830+ while (nal_stream_pos < iSize)
831+ {
832+ if (m_convert_bytestream)
833+ {
834+ static const uint8_t nalu_header[4 ] = {0 , 0 , 0 , 1 };
835+ uint32_t unit_size = AV_RB32 (m_inputBuffer + nal_stream_pos) + 4 ;
836+ uint16_t unit_type = (AV_RB16 (m_inputBuffer + nal_stream_pos + 4 ) >> 3 ) & 0x1f ;
837+
838+ if (unit_type == VVC_SPS_NUT || IsIDR (unit_type))
839+ m_start_decode = true ;
840+
841+ memcpy (m_inputBuffer + nal_stream_pos, nalu_header, 4 );
842+ nal_stream_pos += unit_size;
843+ }
844+ else if (!m_start_decode)
845+ {
846+ uint8_t *buf = m_inputBuffer + nal_stream_pos;
847+
848+ if (buf[0 ] == 0x0 && buf[1 ] == 0x0 && buf[2 ] == 0x1 )
849+ {
850+ uint16_t unit_type = (AV_RB16 (m_inputBuffer + nal_stream_pos + 3 ) >> 3 ) & 0x1f ;
851+
852+ if (unit_type == VVC_SPS_NUT || IsIDR (unit_type))
853+ m_start_decode = true ;
854+
855+ nal_stream_pos += 5 ;
856+ }
857+ else
858+ nal_stream_pos++;
859+ }
860+ else
861+ break ;
862+ }
863+ }
864+ return true ;
865+ }
762866 }
763867
764868 return false ;
@@ -1116,6 +1220,122 @@ bool CBitstreamConverter::BitstreamConvertInitHEVC(void *in_extradata, int in_ex
11161220 return true ;
11171221}
11181222
1223+ bool CBitstreamConverter::BitstreamConvertInitVVC (void *in_extradata, int in_extrasize)
1224+ {
1225+ m_sps_pps_size = 0 ;
1226+ m_sps_pps_context.sps_pps_data = NULL ;
1227+
1228+ // nothing to filter
1229+ if (!in_extradata)
1230+ return false ;
1231+
1232+ uint16_t unit_size;
1233+ uint32_t total_size = 0 ;
1234+ uint8_t *out = NULL , array_nb, nal_type, sps_seen = 0 , pps_seen = 0 ;
1235+ uint8_t num_sublayers, num_bytes_constraint_info, ptl_sublayer_level_present_flags;
1236+ const uint8_t *extradata = (uint8_t *)in_extradata;
1237+ static const uint8_t nalu_header[4 ] = {0 , 0 , 0 , 1 };
1238+
1239+ // length coded size
1240+ m_sps_pps_context.length_size = sizeof (nalu_header);
1241+
1242+ // skip several fields of VVCDecoderConfigurationRecord
1243+ // extradata point to 00 after FF, 8b
1244+ extradata++;
1245+ // ols_idx, num_sublayers , constant_frame_rate, chroma_format_idc, 16b
1246+ num_sublayers = ((extradata[0 ] << 8 | extradata[1 ]) >> 4 ) & 0x7 ;
1247+ extradata += 2 ;
1248+ // bit_depth_minus8, 8b
1249+ extradata++;
1250+ // num_bytes_constraint_info, 8b
1251+ num_bytes_constraint_info = extradata[0 ] & 0x3f ;
1252+ extradata++;
1253+ // general_profile_idc, general_tier_flag, 8b
1254+ // general_level_idc, 8b
1255+ extradata += 2 ;
1256+ // constraint_info, 8b * num_bytes_constraint_info
1257+ extradata += num_bytes_constraint_info;
1258+ // ptl_sublayer_level_present_flag, 8b
1259+ ptl_sublayer_level_present_flags = *extradata++ & 0x3f ;
1260+ for (int i = num_sublayers - 2 ; i >= 0 ; i--)
1261+ if ((ptl_sublayer_level_present_flags >> 1 ) & 0x1 )
1262+ extradata++;
1263+ // ptl_num_sub_profiles, 8b
1264+ extradata++;
1265+ // max_picture_width, 16b
1266+ extradata += 2 ;
1267+ // max_picture_height, 16b
1268+ extradata += 2 ;
1269+ // avg_frame_rate, 16b
1270+ extradata += 2 ;
1271+ // num_of_arrays, 8b
1272+ array_nb = *extradata++;
1273+
1274+ while (array_nb--)
1275+ {
1276+ void *tmp;
1277+
1278+ extradata++; // array_completeness, 8b
1279+ if (extradata[0 ] == 0x0 && extradata[1 ] == 0x01 )
1280+ {
1281+ extradata += 2 ; // nal header, 16b
1282+ unit_size = extradata[0 ] << 8 | extradata[1 ];
1283+ extradata += 2 ; // nal unit size, 16b
1284+ nal_type = (extradata[1 ] >> 3 ) & 0x1f ;
1285+
1286+ if (nal_type == VVC_SPS_NUT)
1287+ {
1288+ sps_seen = 1 ;
1289+ m_start_decode = true ;
1290+ }
1291+ else if (nal_type == VVC_PPS_NUT)
1292+ {
1293+ pps_seen = 1 ;
1294+ }
1295+ else
1296+ {
1297+ extradata += unit_size;
1298+ continue ;
1299+ }
1300+ total_size += unit_size + 4 ;
1301+
1302+ if (total_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
1303+ (extradata + unit_size) > ((uint8_t *)in_extradata + in_extrasize))
1304+ {
1305+ av_free (out);
1306+ return false ;
1307+ }
1308+ tmp = av_realloc (out, total_size + AV_INPUT_BUFFER_PADDING_SIZE);
1309+ if (!tmp)
1310+ {
1311+ av_free (out);
1312+ return false ;
1313+ }
1314+ out = (uint8_t *)tmp;
1315+ memcpy (out + total_size - unit_size - 4 , nalu_header, 4 );
1316+ memcpy (out + total_size - unit_size, extradata, unit_size);
1317+ extradata += unit_size;
1318+ }
1319+ else
1320+ return false ;
1321+ }
1322+
1323+ if (out)
1324+ memset (out + total_size, 0 , AV_INPUT_BUFFER_PADDING_SIZE);
1325+
1326+ if (!sps_seen)
1327+ CLog::Log (LOGDEBUG, " SPS NALU missing or invalid. The resulting stream may not play" );
1328+ if (!pps_seen)
1329+ CLog::Log (LOGDEBUG, " PPS NALU missing or invalid. The resulting stream may not play" );
1330+
1331+ m_sps_pps_context.sps_pps_data = out;
1332+ m_sps_pps_context.size = total_size;
1333+ m_sps_pps_context.first_idr = 1 ;
1334+ m_sps_pps_context.idr_sps_pps_seen = 0 ;
1335+
1336+ return true ;
1337+ }
1338+
11191339bool CBitstreamConverter::IsIDR (uint8_t unit_type)
11201340{
11211341 switch (m_codec)
@@ -1126,6 +1346,10 @@ bool CBitstreamConverter::IsIDR(uint8_t unit_type)
11261346 return unit_type == HEVC_NAL_IDR_W_RADL ||
11271347 unit_type == HEVC_NAL_IDR_N_LP ||
11281348 unit_type == HEVC_NAL_CRA_NUT;
1349+ case AV_CODEC_ID_VVC:
1350+ return unit_type == VVC_IDR_W_RADL ||
1351+ unit_type == VVC_IDR_N_LP ||
1352+ unit_type == VVC_CRA_NUT;
11291353 default :
11301354 return false ;
11311355 }
0 commit comments