- GetBitContext *gb = &nal->gb;
- int nuh_layer_id;
-
- if (get_bits1(gb) != 0)
- return AVERROR_INVALIDDATA;
-
- nal->type = get_bits(gb, 6);
-
- nuh_layer_id = get_bits(gb, 6);
- nal->temporal_id = get_bits(gb, 3) - 1;
- if (nal->temporal_id < 0)
- return AVERROR_INVALIDDATA;
-
- av_log(avctx, AV_LOG_DEBUG,
- "nal_unit_type: %d(%s), nuh_layer_id: %d, temporal_id: %d\n",
- nal->type, nal_unit_name(nal->type), nuh_layer_id, nal->temporal_id);
-
- return nuh_layer_id == 0;
-}
-
-
-int ff_hevc_split_packet(HEVCContext *s, HEVCPacket *pkt, const uint8_t *buf, int length,
- AVCodecContext *avctx, int is_nalff, int nal_length_size)
-{
- int consumed, ret = 0;
-
- pkt->nb_nals = 0;
- while (length >= 4) {
- HEVCNAL *nal;
- int extract_length = 0;
-
- if (is_nalff) {
- int i;
- for (i = 0; i < nal_length_size; i++)
- extract_length = (extract_length << 8) | buf[i];
- buf += nal_length_size;
- length -= nal_length_size;
+ int ret = 0;
+ GetByteContext gb;
+
+ bytestream2_init(&gb, data, size);
+
+ if (size > 3 && (data[0] || data[1] || data[2] > 1)) {
+ /* It seems the extradata is encoded as hvcC format.
+ * Temporarily, we support configurationVersion==0 until 14496-15 3rd
+ * is finalized. When finalized, configurationVersion will be 1 and we
+ * can recognize hvcC by checking if avctx->extradata[0]==1 or not. */
+ int i, j, num_arrays, nal_len_size;
+
+ *is_nalff = 1;
+
+ bytestream2_skip(&gb, 21);
+ nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1;
+ num_arrays = bytestream2_get_byte(&gb);
+
+ /* nal units in the hvcC always have length coded with 2 bytes,
+ * so put a fake nal_length_size = 2 while parsing them */
+ *nal_length_size = 2;
+
+ /* Decode nal units from hvcC. */
+ for (i = 0; i < num_arrays; i++) {
+ int type = bytestream2_get_byte(&gb) & 0x3f;
+ int cnt = bytestream2_get_be16(&gb);
+
+ for (j = 0; j < cnt; j++) {
+ // +2 for the nal size field
+ int nalsize = bytestream2_peek_be16(&gb) + 2;
+ if (bytestream2_get_bytes_left(&gb) < nalsize) {
+ av_log(logctx, AV_LOG_ERROR,
+ "Invalid NAL unit size in extradata.\n");
+ return AVERROR_INVALIDDATA;
+ }