1 /*****************************************************************************
2 * hxxx_helper.c: AnnexB / avcC helper for dumb decoders
3 *****************************************************************************
4 * Copyright (C) 2017 VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
28 #include <vlc_common.h>
31 #include "hxxx_helper.h"
32 #include "../packetizer/hxxx_nal.h"
33 #include "../packetizer/h264_slice.h"
36 hxxx_helper_init(struct hxxx_helper
*hh
, vlc_object_t
*p_obj
,
37 vlc_fourcc_t i_codec
, bool b_need_xvcC
)
39 assert(i_codec
== VLC_CODEC_H264
|| i_codec
== VLC_CODEC_HEVC
);
41 memset(hh
, 0, sizeof(struct hxxx_helper
));
43 hh
->i_codec
= i_codec
;
49 hh
->b_need_xvcC
= b_need_xvcC
;
52 #define RELEASE_NALS(list, max, release) \
53 for (size_t i = 0; i <= max; ++i) \
58 block_Release(hnal->b); \
64 hxxx_helper_clean(struct hxxx_helper
*hh
)
66 struct hxxx_helper_nal
*hnal
;
70 RELEASE_NALS(hh
->h264
.sps_list
, H264_SPS_ID_MAX
,
71 h264_release_sps(hnal
->h264_sps
));
72 RELEASE_NALS(hh
->h264
.pps_list
, H264_PPS_ID_MAX
,
73 h264_release_pps(hnal
->h264_pps
));
76 RELEASE_NALS(hh
->hevc
.vps_list
, HEVC_VPS_ID_MAX
,
77 hevc_rbsp_release_vps(hnal
->hevc_vps
));
78 RELEASE_NALS(hh
->hevc
.sps_list
, HEVC_SPS_ID_MAX
,
79 hevc_rbsp_release_sps(hnal
->hevc_sps
));
80 RELEASE_NALS(hh
->hevc
.pps_list
, HEVC_PPS_ID_MAX
,
81 hevc_rbsp_release_pps(hnal
->hevc_pps
));
82 free(hh
->hevc
.p_annexb_config_nal
);
85 vlc_assert_unreachable();
89 #define HELPER_FOREACH_NAL(it, p_nal_list, i_nal_count, i_nal_max) \
90 for (size_t ii = 0, i_nal_nb = 0; i < i_nal_max && i_nal_count > i_nal_nb; ++ii) \
91 if (p_nal_list[ii].b != NULL && (it = &p_nal_list[ii]) && ++i_nal_nb)
94 helper_dup_buf(struct hxxx_helper_nal
*p_nal
,
95 const uint8_t *p_nal_buf
, size_t i_nal_buf
)
99 p_nal
->b
= block_Alloc(i_nal_buf
);
103 else if (p_nal
->b
!= NULL
&& i_nal_buf
> p_nal
->b
->i_buffer
)
105 block_t
*b
= block_TryRealloc(p_nal
->b
, 0, i_nal_buf
);
110 memcpy(p_nal
->b
->p_buffer
, p_nal_buf
, i_nal_buf
);
111 p_nal
->b
->i_buffer
= i_nal_buf
;
115 static inline const struct hxxx_helper_nal
*
116 helper_search_nal(const struct hxxx_helper_nal
*p_nal_list
, size_t i_nal_count
,
117 size_t i_nal_max
, const void *p_nal_buf
, size_t i_nal_buf
)
120 for (size_t i
= 0; i
< i_nal_max
&& i_nal_count
> i_nal_nb
; ++i
)
122 const struct hxxx_helper_nal
*p_nal
= &p_nal_list
[i
];
123 if (p_nal
->b
== NULL
)
126 const int i_diff
= i_nal_buf
- p_nal
->b
->i_buffer
;
127 if (i_diff
== 0 && memcmp(p_nal_buf
, p_nal
->b
->p_buffer
, i_nal_buf
) == 0)
134 helper_nal_length_valid(struct hxxx_helper
*hh
)
136 return hh
->i_nal_length_size
== 1 || hh
->i_nal_length_size
== 2
137 || hh
->i_nal_length_size
== 4;
140 #define LOAD_xPS(list, count, id, max, xpstype, xpsdecode, xpsrelease) \
141 if (helper_search_nal(list, count, max+1, p_nal, i_nal) != NULL)\
143 xpstype *p_xps = xpsdecode(p_nal, i_nal, true);\
145 return VLC_EGENERIC;\
147 struct hxxx_helper_nal *hnal = &list[id];\
148 if (helper_dup_buf(hnal, p_nal, i_nal))\
151 return VLC_EGENERIC;\
154 xpsrelease(hnal->xps);\
159 *p_config_changed = true
162 h264_helper_parse_nal(struct hxxx_helper
*hh
, const uint8_t *p_buf
, size_t i_buf
,
163 uint8_t i_nal_length_size
, bool *p_config_changed
)
165 const uint8_t *p_nal
;
167 hxxx_iterator_ctx_t it
;
168 hxxx_iterator_init(&it
, p_buf
, i_buf
, i_nal_length_size
);
169 *p_config_changed
= false;
171 while ((i_nal_length_size
) ? hxxx_iterate_next(&it
, &p_nal
, &i_nal
)
172 : hxxx_annexb_iterate_next(&it
, &p_nal
, &i_nal
))
177 const enum h264_nal_unit_type_e i_nal_type
= p_nal
[0] & 0x1F;
179 if (i_nal_type
== H264_NAL_SPS
)
181 LOAD_xPS(hh
->h264
.sps_list
, hh
->h264
.i_sps_count
,
182 p_xps
->i_id
, H264_SPS_ID_MAX
,
183 h264_sequence_parameter_set_t
,
186 hh
->h264
.i_current_sps
= ((h264_sequence_parameter_set_t
*)p_xps
)->i_id
;
187 msg_Dbg(hh
->p_obj
, "new SPS parsed: %u", hh
->h264
.i_current_sps
);
189 else if (i_nal_type
== H264_NAL_PPS
)
191 LOAD_xPS(hh
->h264
.pps_list
, hh
->h264
.i_pps_count
,
192 p_xps
->i_id
, H264_PPS_ID_MAX
,
193 h264_picture_parameter_set_t
,
196 msg_Dbg(hh
->p_obj
, "new PPS parsed: %u", ((h264_picture_parameter_set_t
*)p_xps
)->i_id
);
198 else if (i_nal_type
<= H264_NAL_SLICE_IDR
199 && i_nal_type
!= H264_NAL_UNKNOWN
)
201 if (hh
->h264
.i_sps_count
> 1)
203 /* There is more than one SPS. Get the PPS id of the current
204 * SLICE in order to get the current SPS id */
206 /* Get the PPS id from the slice: inspirated from
207 * h264_decode_slice() */
209 bs_init(&s
, p_nal
, i_nal
);
213 unsigned i_pps_id
= bs_read_ue(&s
);
214 if (i_pps_id
> H264_PPS_ID_MAX
)
217 struct hxxx_helper_nal
*hpps
= &hh
->h264
.pps_list
[i_pps_id
];
221 struct hxxx_helper_nal
*hsps
=
222 &hh
->h264
.sps_list
[hpps
->h264_pps
->i_sps_id
];
226 assert(hpps
->h264_pps
->i_sps_id
== hsps
->h264_sps
->i_id
);
227 if (hsps
->h264_sps
->i_id
!= hh
->h264
.i_current_sps
)
229 hh
->h264
.i_current_sps
= hsps
->h264_sps
->i_id
;
230 *p_config_changed
= true;
233 break; /* No need to parse further NAL */
240 hevc_helper_parse_nal(struct hxxx_helper
*hh
, const uint8_t *p_buf
, size_t i_buf
,
241 uint8_t i_nal_length_size
, bool *p_config_changed
)
243 const uint8_t *p_nal
;
245 hxxx_iterator_ctx_t it
;
246 hxxx_iterator_init(&it
, p_buf
, i_buf
, i_nal_length_size
);
247 *p_config_changed
= false;
249 while ((i_nal_length_size
) ? hxxx_iterate_next(&it
, &p_nal
, &i_nal
)
250 : hxxx_annexb_iterate_next(&it
, &p_nal
, &i_nal
))
252 if (i_nal
< 2 || hevc_getNALLayer(p_nal
) > 0)
255 const uint8_t i_nal_type
= hevc_getNALType(p_nal
);
256 if (i_nal_type
== HEVC_NAL_VPS
)
259 if( !hevc_get_xps_id(p_nal
, i_nal
, &i_id
) )
261 LOAD_xPS(hh
->hevc
.vps_list
, hh
->hevc
.i_vps_count
,
262 i_id
, HEVC_VPS_ID_MAX
,
263 hevc_video_parameter_set_t
,
265 hevc_rbsp_release_vps
);
266 msg_Dbg(hh
->p_obj
, "new VPS parsed: %u", i_id
);
268 else if (i_nal_type
== HEVC_NAL_SPS
)
271 if( !hevc_get_xps_id(p_nal
, i_nal
, &i_id
) )
273 LOAD_xPS(hh
->hevc
.sps_list
, hh
->hevc
.i_sps_count
,
274 i_id
, HEVC_SPS_ID_MAX
,
275 hevc_sequence_parameter_set_t
,
277 hevc_rbsp_release_sps
);
278 msg_Dbg(hh
->p_obj
, "new SPS parsed: %u", i_id
);
280 else if (i_nal_type
== HEVC_NAL_PPS
)
283 if( !hevc_get_xps_id(p_nal
, i_nal
, &i_id
) )
285 LOAD_xPS(hh
->hevc
.pps_list
, hh
->hevc
.i_pps_count
,
286 i_id
, HEVC_PPS_ID_MAX
,
287 hevc_picture_parameter_set_t
,
289 hevc_rbsp_release_pps
);
290 msg_Dbg(hh
->p_obj
, "new PPS parsed: %u", i_id
);
292 else if (i_nal_type
<= HEVC_NAL_IRAP_VCL23
)
294 if (hh
->hevc
.i_sps_count
> 1 || hh
->hevc
.i_vps_count
> 1)
296 /* Get the PPS id from the slice: inspirated from
297 * h264_decode_slice() */
299 bs_init(&s
, p_nal
, i_nal
);
301 unsigned i_id
= bs_read_ue(&s
);
302 if (i_id
> HEVC_PPS_ID_MAX
)
305 struct hxxx_helper_nal
*xps
= &hh
->hevc
.pps_list
[i_id
];
309 const uint8_t i_spsid
= hevc_get_pps_sps_id(xps
->hevc_pps
);
310 xps
= &hh
->hevc
.sps_list
[i_spsid
];
314 i_id
= hevc_get_sps_vps_id(xps
->hevc_sps
);
315 xps
= &hh
->hevc
.vps_list
[i_id
];
317 if (i_spsid
!= hh
->hevc
.i_current_sps
||
318 i_id
!= hh
->hevc
.i_current_vps
)
320 hh
->hevc
.i_current_sps
= i_spsid
;
321 hh
->hevc
.i_current_vps
= i_id
;
322 *p_config_changed
= true;
325 break; /* No need to parse further NAL */
332 helper_process_avcC_h264(struct hxxx_helper
*hh
, const uint8_t *p_buf
,
335 if (i_buf
< H264_MIN_AVCC_SIZE
)
338 p_buf
+= 5; i_buf
-= 5;
340 for (unsigned int j
= 0; j
< 2 && i_buf
> 0; j
++)
342 /* First time is SPS, Second is PPS */
343 const unsigned int i_num_nal
= p_buf
[0] & (j
== 0 ? 0x1f : 0xff);
346 for (unsigned int i
= 0; i
< i_num_nal
&& i_buf
>= 2; i
++)
348 uint16_t i_nal_size
= (p_buf
[0] << 8) | p_buf
[1];
349 if (i_nal_size
> i_buf
- 2)
352 int i_ret
= h264_helper_parse_nal(hh
, p_buf
, i_nal_size
+ 2, 2,
354 if (i_ret
!= VLC_SUCCESS
)
356 p_buf
+= i_nal_size
+ 2;
357 i_buf
-= i_nal_size
+ 2;
365 h264_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
371 hh
->i_nal_length_size
= 4;
374 else if (h264_isavcC(p_extra
, i_extra
))
376 hh
->i_nal_length_size
= (((uint8_t*)p_extra
)[4] & 0x03) + 1;
377 if (!helper_nal_length_valid(hh
))
379 hh
->b_is_xvcC
= true;
381 /* XXX h264_AVC_to_AnnexB() works only with a i_nal_length_size of 4.
382 * If nal_length_size is smaller than 4, fallback to SW decoding. I
383 * don't know if it's worth the effort to fix h264_AVC_to_AnnexB() for
384 * a smaller nal_length_size. Indeed, this case will happen only with
385 * very small resolutions, where hardware decoders are not that useful.
387 if (!hh
->b_need_xvcC
&& hh
->i_nal_length_size
!= 4)
389 msg_Dbg(hh
->p_obj
, "nal_length_size is too small");
393 return helper_process_avcC_h264(hh
, p_extra
, i_extra
);
395 else /* Can't handle extra that is not avcC */
400 hevc_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
406 hh
->i_nal_length_size
= 4;
409 else if (hevc_ishvcC(p_extra
, i_extra
))
411 hh
->i_nal_length_size
= hevc_getNALLengthSize(p_extra
);
412 if (!helper_nal_length_valid(hh
))
414 hh
->b_is_xvcC
= true;
420 uint8_t *p_buf
= hevc_hvcC_to_AnnexB_NAL(p_extra
, i_extra
, &i_buf
,
424 msg_Dbg(hh
->p_obj
, "hevc_hvcC_to_AnnexB_NAL failed");
428 hh
->hevc
.p_annexb_config_nal
= p_buf
;
429 hh
->hevc
.i_annexb_config_nal
= i_buf
;
432 else /* Can't handle extra that is not avcC */
436 static inline block_t
*
437 helper_process_block_hxxx_annexb(struct hxxx_helper
*hh
,
438 int(*parser
)(struct hxxx_helper
*,
439 const uint8_t*, size_t,uint8_t,bool*),
440 block_t
*p_block
, bool *p_config_changed
)
442 if (p_config_changed
!= NULL
)
444 int i_ret
= parser(hh
, p_block
->p_buffer
, p_block
->i_buffer
,
445 0, p_config_changed
);
446 if (i_ret
!= VLC_SUCCESS
)
448 block_Release(p_block
);
456 helper_process_block_h264_annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
457 bool *p_config_changed
)
459 if (p_config_changed
!= NULL
)
460 return helper_process_block_hxxx_annexb(hh
, h264_helper_parse_nal
,
461 p_block
,p_config_changed
);
466 helper_process_block_hevc_annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
467 bool *p_config_changed
)
469 if (p_config_changed
!= NULL
)
470 return helper_process_block_hxxx_annexb(hh
, hevc_helper_parse_nal
,
471 p_block
,p_config_changed
);
476 helper_process_block_xvcc2annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
477 bool *p_config_changed
)
479 assert(helper_nal_length_valid(hh
));
480 h264_AVC_to_AnnexB(p_block
->p_buffer
, p_block
->i_buffer
,
481 hh
->i_nal_length_size
);
482 return helper_process_block_h264_annexb(hh
, p_block
, p_config_changed
);
486 helper_process_block_h264_annexb2avcc(struct hxxx_helper
*hh
, block_t
*p_block
,
487 bool *p_config_changed
)
489 p_block
= helper_process_block_h264_annexb(hh
, p_block
, p_config_changed
);
490 return p_block
? hxxx_AnnexB_to_xVC(p_block
, hh
->i_nal_length_size
) : NULL
;
494 helper_process_block_hevc_annexb2hvcc(struct hxxx_helper
*hh
, block_t
*p_block
,
495 bool *p_config_changed
)
497 p_block
= helper_process_block_hevc_annexb(hh
, p_block
, p_config_changed
);
498 return p_block
? hxxx_AnnexB_to_xVC(p_block
, hh
->i_nal_length_size
) : NULL
;
502 helper_process_block_h264_avcc(struct hxxx_helper
*hh
, block_t
*p_block
,
503 bool *p_config_changed
)
505 if (p_config_changed
!= NULL
)
507 int i_ret
= h264_helper_parse_nal(hh
, p_block
->p_buffer
,
509 hh
->i_nal_length_size
,
511 if (i_ret
!= VLC_SUCCESS
)
513 block_Release(p_block
);
521 helper_process_block_hevc_hvcc(struct hxxx_helper
*hh
, block_t
*p_block
,
522 bool *p_config_changed
)
524 if (p_config_changed
!= NULL
)
526 int i_ret
= hevc_helper_parse_nal(hh
, p_block
->p_buffer
,
528 hh
->i_nal_length_size
,
530 if (i_ret
!= VLC_SUCCESS
)
532 block_Release(p_block
);
540 hxxx_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
547 i_ret
= h264_helper_set_extra(hh
, p_extra
, i_extra
);
550 i_ret
= hevc_helper_set_extra(hh
, p_extra
, i_extra
);
553 vlc_assert_unreachable();
555 if (i_ret
!= VLC_SUCCESS
)
564 hh
->pf_process_block
= helper_process_block_h264_avcc
;
566 hh
->pf_process_block
= helper_process_block_xvcc2annexb
;
571 hh
->pf_process_block
= helper_process_block_h264_annexb2avcc
;
573 hh
->pf_process_block
= helper_process_block_h264_annexb
;
580 hh
->pf_process_block
= helper_process_block_hevc_hvcc
;
582 hh
->pf_process_block
= helper_process_block_xvcc2annexb
;
587 hh
->pf_process_block
= helper_process_block_hevc_annexb2hvcc
;
589 hh
->pf_process_block
= helper_process_block_hevc_annexb
;
593 vlc_assert_unreachable();
599 h264_helper_get_annexb_config(const struct hxxx_helper
*hh
)
601 static const uint8_t annexb_startcode
[] = { 0x00, 0x00, 0x00, 0x01 };
603 if (hh
->h264
.i_sps_count
== 0 || hh
->h264
.i_pps_count
== 0)
606 const struct hxxx_helper_nal
*pp_nal_lists
[] = {
607 hh
->h264
.sps_list
, hh
->h264
.pps_list
};
608 const size_t p_nal_counts
[] = { hh
->h264
.i_sps_count
, hh
->h264
.i_pps_count
};
609 const size_t p_nal_maxs
[] = { H264_SPS_ID_MAX
+1, H264_PPS_ID_MAX
+1 };
611 block_t
*p_block_list
= NULL
;
612 for (size_t i
= 0; i
< 2; ++i
)
614 size_t i_nals_size
= 0;
615 const struct hxxx_helper_nal
*p_nal
;
616 HELPER_FOREACH_NAL(p_nal
, pp_nal_lists
[i
], p_nal_counts
[i
], p_nal_maxs
[i
])
618 i_nals_size
+= p_nal
->b
->i_buffer
+ sizeof annexb_startcode
;
621 block_t
*p_block
= block_Alloc(i_nals_size
);
624 if (p_block_list
!= NULL
)
625 block_Release(p_block_list
);
629 p_block
->i_buffer
= 0;
630 HELPER_FOREACH_NAL(p_nal
, pp_nal_lists
[i
], p_nal_counts
[i
], p_nal_maxs
[i
])
632 memcpy(&p_block
->p_buffer
[p_block
->i_buffer
], annexb_startcode
,
633 sizeof annexb_startcode
);
634 p_block
->i_buffer
+= sizeof annexb_startcode
;
635 memcpy(&p_block
->p_buffer
[p_block
->i_buffer
], p_nal
->b
->p_buffer
,
637 p_block
->i_buffer
+= p_nal
->b
->i_buffer
;
639 if (p_block_list
== NULL
)
640 p_block_list
= p_block
;
642 p_block_list
->p_next
= p_block
;
649 h264_helper_get_avcc_config(const struct hxxx_helper
*hh
)
651 const struct hxxx_helper_nal
*p_nal
;
653 const uint8_t *pp_sps_bufs
[hh
->h264
.i_sps_count
];
654 size_t p_sps_sizes
[hh
->h264
.i_sps_count
];
655 HELPER_FOREACH_NAL(p_nal
, hh
->h264
.sps_list
, hh
->h264
.i_sps_count
,
658 pp_sps_bufs
[i
] = p_nal
->b
->p_buffer
;
659 p_sps_sizes
[i
] = p_nal
->b
->i_buffer
;
664 const uint8_t *pp_pps_bufs
[hh
->h264
.i_pps_count
];
665 size_t p_pps_sizes
[hh
->h264
.i_pps_count
];
666 HELPER_FOREACH_NAL(p_nal
, hh
->h264
.pps_list
, hh
->h264
.i_pps_count
,
669 pp_pps_bufs
[i
] = p_nal
->b
->p_buffer
;
670 p_pps_sizes
[i
] = p_nal
->b
->i_buffer
;
673 return h264_NAL_to_avcC(4, pp_sps_bufs
, p_sps_sizes
, hh
->h264
.i_sps_count
,
674 pp_pps_bufs
, p_pps_sizes
, hh
->h264
.i_pps_count
);
677 static const struct hxxx_helper_nal
*
678 h264_helper_get_current_sps(const struct hxxx_helper
*hh
)
680 if (hh
->h264
.i_sps_count
== 0)
683 const struct hxxx_helper_nal
*hsps
=
684 &hh
->h264
.sps_list
[hh
->h264
.i_current_sps
];
685 assert(hsps
->b
!= NULL
);
690 hxxx_helper_get_current_picture_size(const struct hxxx_helper
*hh
,
691 unsigned *p_w
, unsigned *p_h
,
692 unsigned *p_vw
, unsigned *p_vh
)
694 if(hh
->i_codec
== VLC_CODEC_H264
)
696 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
697 if (hsps
&& h264_get_picture_size(hsps
->h264_sps
, p_w
, p_h
, p_vw
, p_vh
))
700 else if(hh
->i_codec
== VLC_CODEC_HEVC
)
702 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
703 if(hsps
&& hevc_get_picture_size(hsps
->hevc_sps
, p_w
, p_h
, p_vw
, p_vh
))
710 hxxx_helper_get_current_sar(const struct hxxx_helper
*hh
, int *p_num
, int *p_den
)
712 if(hh
->i_codec
== VLC_CODEC_H264
)
714 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
717 *p_num
= hsps
->h264_sps
->vui
.i_sar_num
;
718 *p_den
= hsps
->h264_sps
->vui
.i_sar_den
;
722 else if(hh
->i_codec
== VLC_CODEC_HEVC
)
724 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
726 if(hsps
&& hevc_get_aspect_ratio(hsps
->hevc_sps
, &num
, &den
))
737 h264_helper_get_current_dpb_values(const struct hxxx_helper
*hh
,
738 uint8_t *p_depth
, unsigned *p_delay
)
740 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
743 return h264_get_dpb_values(hsps
->h264_sps
, p_depth
, p_delay
) ?
744 VLC_SUCCESS
: VLC_EGENERIC
;
748 hxxx_helper_get_current_profile_level(const struct hxxx_helper
*hh
,
749 uint8_t *p_profile
, uint8_t *p_level
)
751 if(hh
->i_codec
== VLC_CODEC_H264
)
753 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
756 *p_profile
= hsps
->h264_sps
->i_profile
;
757 *p_level
= hsps
->h264_sps
->i_level
;
761 else if(hh
->i_codec
== VLC_CODEC_HEVC
)
763 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
765 hevc_get_sps_profile_tier_level(hsps
->hevc_sps
, p_profile
, p_level
))
772 hxxx_helper_get_colorimetry(const struct hxxx_helper
*hh
,
773 video_color_primaries_t
*p_primaries
,
774 video_transfer_func_t
*p_transfer
,
775 video_color_space_t
*p_colorspace
,
782 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
785 return h264_get_colorimetry(hsps
->h264_sps
, p_primaries
, p_transfer
,
786 p_colorspace
, p_full_range
)
787 == true ? VLC_SUCCESS
: VLC_EGENERIC
;
793 vlc_assert_unreachable();