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
));
84 vlc_assert_unreachable();
88 #define HELPER_FOREACH_NAL(it, p_nal_list, i_nal_count, i_nal_max) \
89 for (size_t ii = 0, i_nal_nb = 0; i < i_nal_max && i_nal_count > i_nal_nb; ++ii) \
90 if (p_nal_list[ii].b != NULL && (it = &p_nal_list[ii]) && ++i_nal_nb)
93 helper_dup_buf(struct hxxx_helper_nal
*p_nal
,
94 const uint8_t *p_nal_buf
, size_t i_nal_buf
)
98 p_nal
->b
= block_Alloc(i_nal_buf
);
102 else if (p_nal
->b
!= NULL
&& i_nal_buf
> p_nal
->b
->i_buffer
)
104 block_t
*b
= block_TryRealloc(p_nal
->b
, 0, i_nal_buf
);
109 memcpy(p_nal
->b
->p_buffer
, p_nal_buf
, i_nal_buf
);
110 p_nal
->b
->i_buffer
= i_nal_buf
;
114 static inline const struct hxxx_helper_nal
*
115 helper_search_nal(const struct hxxx_helper_nal
*p_nal_list
, size_t i_nal_count
,
116 size_t i_nal_max
, const void *p_nal_buf
, size_t i_nal_buf
)
119 for (size_t i
= 0; i
< i_nal_max
&& i_nal_count
> i_nal_nb
; ++i
)
121 const struct hxxx_helper_nal
*p_nal
= &p_nal_list
[i
];
122 if (p_nal
->b
== NULL
)
125 const int i_diff
= i_nal_buf
- p_nal
->b
->i_buffer
;
126 if (i_diff
== 0 && memcmp(p_nal_buf
, p_nal
->b
->p_buffer
, i_nal_buf
) == 0)
133 helper_nal_length_valid(struct hxxx_helper
*hh
)
135 return hh
->i_nal_length_size
== 1 || hh
->i_nal_length_size
== 2
136 || hh
->i_nal_length_size
== 4;
139 #define LOAD_xPS(list, count, id, max, xpstype, xpsdecode, xpsrelease) \
140 if (helper_search_nal(list, count, max+1, p_nal, i_nal) != NULL)\
142 xpstype *p_xps = xpsdecode(p_nal, i_nal, true);\
144 return VLC_EGENERIC;\
146 struct hxxx_helper_nal *hnal = &list[id];\
147 if (helper_dup_buf(hnal, p_nal, i_nal))\
150 return VLC_EGENERIC;\
153 xpsrelease(hnal->xps);\
158 *p_config_changed = true
161 h264_helper_parse_nal(struct hxxx_helper
*hh
, const uint8_t *p_buf
, size_t i_buf
,
162 uint8_t i_nal_length_size
, bool *p_config_changed
)
164 const uint8_t *p_nal
;
166 hxxx_iterator_ctx_t it
;
167 hxxx_iterator_init(&it
, p_buf
, i_buf
, i_nal_length_size
);
168 *p_config_changed
= false;
170 while ((i_nal_length_size
) ? hxxx_iterate_next(&it
, &p_nal
, &i_nal
)
171 : hxxx_annexb_iterate_next(&it
, &p_nal
, &i_nal
))
176 const enum h264_nal_unit_type_e i_nal_type
= p_nal
[0] & 0x1F;
178 if (i_nal_type
== H264_NAL_SPS
)
180 LOAD_xPS(hh
->h264
.sps_list
, hh
->h264
.i_sps_count
,
181 p_xps
->i_id
, H264_SPS_ID_MAX
,
182 h264_sequence_parameter_set_t
,
185 hh
->h264
.i_current_sps
= ((h264_sequence_parameter_set_t
*)p_xps
)->i_id
;
186 msg_Dbg(hh
->p_obj
, "new SPS parsed: %u", hh
->h264
.i_current_sps
);
188 else if (i_nal_type
== H264_NAL_PPS
)
190 LOAD_xPS(hh
->h264
.pps_list
, hh
->h264
.i_pps_count
,
191 p_xps
->i_id
, H264_PPS_ID_MAX
,
192 h264_picture_parameter_set_t
,
195 msg_Dbg(hh
->p_obj
, "new PPS parsed: %u", ((h264_picture_parameter_set_t
*)p_xps
)->i_id
);
197 else if (i_nal_type
<= H264_NAL_SLICE_IDR
198 && i_nal_type
!= H264_NAL_UNKNOWN
)
200 if (hh
->h264
.i_sps_count
> 1)
202 /* There is more than one SPS. Get the PPS id of the current
203 * SLICE in order to get the current SPS id */
205 /* Get the PPS id from the slice: inspirated from
206 * h264_decode_slice() */
208 bs_init(&s
, p_nal
, i_nal
);
212 unsigned i_pps_id
= bs_read_ue(&s
);
213 if (i_pps_id
> H264_PPS_ID_MAX
)
216 struct hxxx_helper_nal
*hpps
= &hh
->h264
.pps_list
[i_pps_id
];
220 struct hxxx_helper_nal
*hsps
=
221 &hh
->h264
.sps_list
[hpps
->h264_pps
->i_sps_id
];
225 assert(hpps
->h264_pps
->i_sps_id
== hsps
->h264_sps
->i_id
);
226 if (hsps
->h264_sps
->i_id
!= hh
->h264
.i_current_sps
)
228 hh
->h264
.i_current_sps
= hsps
->h264_sps
->i_id
;
229 *p_config_changed
= true;
232 break; /* No need to parse further NAL */
239 hevc_helper_parse_nal(struct hxxx_helper
*hh
, const uint8_t *p_buf
, size_t i_buf
,
240 uint8_t i_nal_length_size
, bool *p_config_changed
)
242 const uint8_t *p_nal
;
244 hxxx_iterator_ctx_t it
;
245 hxxx_iterator_init(&it
, p_buf
, i_buf
, i_nal_length_size
);
246 *p_config_changed
= false;
248 while ((i_nal_length_size
) ? hxxx_iterate_next(&it
, &p_nal
, &i_nal
)
249 : hxxx_annexb_iterate_next(&it
, &p_nal
, &i_nal
))
251 if (i_nal
< 2 || hevc_getNALLayer(p_nal
) > 0)
254 const uint8_t i_nal_type
= hevc_getNALType(p_nal
);
255 if (i_nal_type
== HEVC_NAL_VPS
)
258 if( !hevc_get_xps_id(p_nal
, i_nal
, &i_id
) )
260 LOAD_xPS(hh
->hevc
.vps_list
, hh
->hevc
.i_vps_count
,
261 i_id
, HEVC_VPS_ID_MAX
,
262 hevc_video_parameter_set_t
,
264 hevc_rbsp_release_vps
);
265 msg_Dbg(hh
->p_obj
, "new VPS parsed: %u", i_id
);
267 else if (i_nal_type
== HEVC_NAL_SPS
)
270 if( !hevc_get_xps_id(p_nal
, i_nal
, &i_id
) )
272 LOAD_xPS(hh
->hevc
.sps_list
, hh
->hevc
.i_sps_count
,
273 i_id
, HEVC_SPS_ID_MAX
,
274 hevc_sequence_parameter_set_t
,
276 hevc_rbsp_release_sps
);
277 msg_Dbg(hh
->p_obj
, "new SPS parsed: %u", i_id
);
279 else if (i_nal_type
== HEVC_NAL_PPS
)
282 if( !hevc_get_xps_id(p_nal
, i_nal
, &i_id
) )
284 LOAD_xPS(hh
->hevc
.pps_list
, hh
->hevc
.i_pps_count
,
285 i_id
, HEVC_PPS_ID_MAX
,
286 hevc_picture_parameter_set_t
,
288 hevc_rbsp_release_pps
);
289 msg_Dbg(hh
->p_obj
, "new PPS parsed: %u", i_id
);
291 else if (i_nal_type
<= HEVC_NAL_IRAP_VCL23
)
293 if (hh
->hevc
.i_sps_count
> 1 || hh
->hevc
.i_vps_count
> 1)
295 /* Get the PPS id from the slice: inspirated from
296 * h264_decode_slice() */
298 bs_init(&s
, p_nal
, i_nal
);
300 unsigned i_id
= bs_read_ue(&s
);
301 if (i_id
> HEVC_PPS_ID_MAX
)
304 struct hxxx_helper_nal
*xps
= &hh
->hevc
.pps_list
[i_id
];
308 const uint8_t i_spsid
= hevc_get_pps_sps_id(xps
->hevc_pps
);
309 xps
= &hh
->hevc
.sps_list
[i_spsid
];
313 i_id
= hevc_get_sps_vps_id(xps
->hevc_sps
);
314 xps
= &hh
->hevc
.vps_list
[i_id
];
316 if (i_spsid
!= hh
->hevc
.i_current_sps
||
317 i_id
!= hh
->hevc
.i_current_vps
)
319 hh
->hevc
.i_current_sps
= i_spsid
;
320 hh
->hevc
.i_current_vps
= i_id
;
321 *p_config_changed
= true;
324 break; /* No need to parse further NAL */
331 helper_process_avcC_h264(struct hxxx_helper
*hh
, const uint8_t *p_buf
,
334 if (i_buf
< H264_MIN_AVCC_SIZE
)
337 p_buf
+= 5; i_buf
-= 5;
339 for (unsigned int j
= 0; j
< 2 && i_buf
> 0; j
++)
341 /* First time is SPS, Second is PPS */
342 const unsigned int i_num_nal
= p_buf
[0] & (j
== 0 ? 0x1f : 0xff);
345 for (unsigned int i
= 0; i
< i_num_nal
&& i_buf
>= 2; i
++)
347 uint16_t i_nal_size
= (p_buf
[0] << 8) | p_buf
[1];
348 if (i_nal_size
> i_buf
- 2)
351 int i_ret
= h264_helper_parse_nal(hh
, p_buf
, i_nal_size
+ 2, 2,
353 if (i_ret
!= VLC_SUCCESS
)
355 p_buf
+= i_nal_size
+ 2;
356 i_buf
-= i_nal_size
+ 2;
364 h264_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
370 hh
->i_nal_length_size
= 4;
373 else if (h264_isavcC(p_extra
, i_extra
))
375 hh
->i_nal_length_size
= (((uint8_t*)p_extra
)[4] & 0x03) + 1;
376 if (!helper_nal_length_valid(hh
))
378 hh
->b_is_xvcC
= true;
380 /* XXX h264_AVC_to_AnnexB() works only with a i_nal_length_size of 4.
381 * If nal_length_size is smaller than 4, fallback to SW decoding. I
382 * don't know if it's worth the effort to fix h264_AVC_to_AnnexB() for
383 * a smaller nal_length_size. Indeed, this case will happen only with
384 * very small resolutions, where hardware decoders are not that useful.
386 if (!hh
->b_need_xvcC
&& hh
->i_nal_length_size
!= 4)
388 msg_Dbg(hh
->p_obj
, "nal_length_size is too small");
392 return helper_process_avcC_h264(hh
, p_extra
, i_extra
);
394 else /* Can't handle extra that is not avcC */
399 helper_process_hvcC_hevc(struct hxxx_helper
*hh
, const uint8_t *p_buf
,
402 if (i_buf
< HEVC_MIN_HVCC_SIZE
)
405 const uint8_t i_num_array
= p_buf
[22];
406 p_buf
+= 23; i_buf
-= 23;
408 for( uint8_t i
= 0; i
< i_num_array
; i
++ )
413 const uint16_t i_num_nalu
= p_buf
[1] << 8 | p_buf
[2];
414 p_buf
+= 3; i_buf
-= 3;
416 for( uint16_t j
= 0; j
< i_num_nalu
; j
++ )
421 const uint16_t i_nalu_length
= p_buf
[0] << 8 | p_buf
[1];
422 if(i_buf
< (size_t)i_nalu_length
+ 2)
426 hevc_helper_parse_nal( hh
, &p_buf
[0],
427 i_nalu_length
+ 2, 2, &foo
);
429 p_buf
+= i_nalu_length
+ 2;
430 i_buf
-= i_nalu_length
+ 2;
438 hevc_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
444 hh
->i_nal_length_size
= 4;
447 else if (hevc_ishvcC(p_extra
, i_extra
))
449 hh
->i_nal_length_size
= hevc_getNALLengthSize(p_extra
);
450 if (!helper_nal_length_valid(hh
))
452 hh
->b_is_xvcC
= true;
454 return helper_process_hvcC_hevc( hh
, p_extra
, i_extra
);
456 else /* Can't handle extra that is not hvcC */
460 static inline block_t
*
461 helper_process_block_hxxx_annexb(struct hxxx_helper
*hh
,
462 int(*parser
)(struct hxxx_helper
*,
463 const uint8_t*, size_t,uint8_t,bool*),
464 block_t
*p_block
, bool *p_config_changed
)
466 if (p_config_changed
!= NULL
)
468 int i_ret
= parser(hh
, p_block
->p_buffer
, p_block
->i_buffer
,
469 0, p_config_changed
);
470 if (i_ret
!= VLC_SUCCESS
)
472 block_Release(p_block
);
480 helper_process_block_h264_annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
481 bool *p_config_changed
)
483 if (p_config_changed
!= NULL
)
484 return helper_process_block_hxxx_annexb(hh
, h264_helper_parse_nal
,
485 p_block
,p_config_changed
);
490 helper_process_block_hevc_annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
491 bool *p_config_changed
)
493 if (p_config_changed
!= NULL
)
494 return helper_process_block_hxxx_annexb(hh
, hevc_helper_parse_nal
,
495 p_block
,p_config_changed
);
500 helper_process_block_xvcc2annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
501 bool *p_config_changed
)
503 assert(helper_nal_length_valid(hh
));
504 h264_AVC_to_AnnexB(p_block
->p_buffer
, p_block
->i_buffer
,
505 hh
->i_nal_length_size
);
506 return helper_process_block_h264_annexb(hh
, p_block
, p_config_changed
);
510 helper_process_block_h264_annexb2avcc(struct hxxx_helper
*hh
, block_t
*p_block
,
511 bool *p_config_changed
)
513 p_block
= helper_process_block_h264_annexb(hh
, p_block
, p_config_changed
);
514 return p_block
? hxxx_AnnexB_to_xVC(p_block
, hh
->i_nal_length_size
) : NULL
;
518 helper_process_block_hevc_annexb2hvcc(struct hxxx_helper
*hh
, block_t
*p_block
,
519 bool *p_config_changed
)
521 p_block
= helper_process_block_hevc_annexb(hh
, p_block
, p_config_changed
);
522 return p_block
? hxxx_AnnexB_to_xVC(p_block
, hh
->i_nal_length_size
) : NULL
;
526 helper_process_block_h264_avcc(struct hxxx_helper
*hh
, block_t
*p_block
,
527 bool *p_config_changed
)
529 if (p_config_changed
!= NULL
)
531 int i_ret
= h264_helper_parse_nal(hh
, p_block
->p_buffer
,
533 hh
->i_nal_length_size
,
535 if (i_ret
!= VLC_SUCCESS
)
537 block_Release(p_block
);
545 helper_process_block_hevc_hvcc(struct hxxx_helper
*hh
, block_t
*p_block
,
546 bool *p_config_changed
)
548 if (p_config_changed
!= NULL
)
550 int i_ret
= hevc_helper_parse_nal(hh
, p_block
->p_buffer
,
552 hh
->i_nal_length_size
,
554 if (i_ret
!= VLC_SUCCESS
)
556 block_Release(p_block
);
564 hxxx_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
571 i_ret
= h264_helper_set_extra(hh
, p_extra
, i_extra
);
574 i_ret
= hevc_helper_set_extra(hh
, p_extra
, i_extra
);
577 vlc_assert_unreachable();
579 if (i_ret
!= VLC_SUCCESS
)
588 hh
->pf_process_block
= helper_process_block_h264_avcc
;
590 hh
->pf_process_block
= helper_process_block_xvcc2annexb
;
595 hh
->pf_process_block
= helper_process_block_h264_annexb2avcc
;
597 hh
->pf_process_block
= helper_process_block_h264_annexb
;
604 hh
->pf_process_block
= helper_process_block_hevc_hvcc
;
606 hh
->pf_process_block
= helper_process_block_xvcc2annexb
;
611 hh
->pf_process_block
= helper_process_block_hevc_annexb2hvcc
;
613 hh
->pf_process_block
= helper_process_block_hevc_annexb
;
617 vlc_assert_unreachable();
623 hxxx_helper_get_annexb_config( const struct hxxx_helper_nal
*pp_nal_lists
[],
624 const size_t p_nal_counts
[],
625 const size_t p_nal_maxs
[],
626 size_t i_lists_size
)
628 static const uint8_t annexb_startcode
[] = { 0x00, 0x00, 0x00, 0x01 };
630 block_t
*p_block_list
= NULL
, *p_current
;
631 for (size_t i
= 0; i
< i_lists_size
; ++i
)
633 size_t i_nals_size
= 0;
634 const struct hxxx_helper_nal
*p_nal
;
635 HELPER_FOREACH_NAL(p_nal
, pp_nal_lists
[i
], p_nal_counts
[i
], p_nal_maxs
[i
])
637 i_nals_size
+= p_nal
->b
->i_buffer
+ sizeof annexb_startcode
;
640 block_t
*p_block
= block_Alloc(i_nals_size
);
643 if (p_block_list
!= NULL
)
644 block_Release(p_block_list
);
648 p_block
->i_buffer
= 0;
649 HELPER_FOREACH_NAL(p_nal
, pp_nal_lists
[i
], p_nal_counts
[i
], p_nal_maxs
[i
])
651 memcpy(&p_block
->p_buffer
[p_block
->i_buffer
], annexb_startcode
,
652 sizeof annexb_startcode
);
653 p_block
->i_buffer
+= sizeof annexb_startcode
;
654 memcpy(&p_block
->p_buffer
[p_block
->i_buffer
], p_nal
->b
->p_buffer
,
656 p_block
->i_buffer
+= p_nal
->b
->i_buffer
;
658 if (p_block_list
== NULL
)
659 p_current
= p_block_list
= p_block
;
662 p_current
->p_next
= p_block
;
671 h264_helper_get_annexb_config(const struct hxxx_helper
*hh
)
673 if (hh
->h264
.i_sps_count
== 0 || hh
->h264
.i_pps_count
== 0)
676 const struct hxxx_helper_nal
*pp_nal_lists
[] = {
677 hh
->h264
.sps_list
, hh
->h264
.pps_list
};
678 const size_t p_nal_counts
[] = { hh
->h264
.i_sps_count
, hh
->h264
.i_pps_count
};
679 const size_t p_nal_maxs
[] = { H264_SPS_ID_MAX
+1, H264_PPS_ID_MAX
+1 };
681 return hxxx_helper_get_annexb_config( pp_nal_lists
, p_nal_counts
, p_nal_maxs
, 2 );
685 hevc_helper_get_annexb_config(const struct hxxx_helper
*hh
)
687 if (hh
->hevc
.i_vps_count
== 0 || hh
->hevc
.i_sps_count
== 0 ||
688 hh
->hevc
.i_pps_count
== 0 )
691 const struct hxxx_helper_nal
*pp_nal_lists
[] = {
692 hh
->hevc
.vps_list
, hh
->hevc
.sps_list
, hh
->hevc
.pps_list
};
693 const size_t p_nal_counts
[] = { hh
->hevc
.i_vps_count
, hh
->hevc
.i_sps_count
,
694 hh
->hevc
.i_pps_count
};
695 const size_t p_nal_maxs
[] = { HEVC_VPS_ID_MAX
+1, HEVC_SPS_ID_MAX
+1, HEVC_PPS_ID_MAX
+1 };
697 return hxxx_helper_get_annexb_config( pp_nal_lists
, p_nal_counts
, p_nal_maxs
, 3 );
701 h264_helper_get_avcc_config(const struct hxxx_helper
*hh
)
703 const struct hxxx_helper_nal
*p_nal
;
705 const uint8_t *pp_sps_bufs
[hh
->h264
.i_sps_count
];
706 size_t p_sps_sizes
[hh
->h264
.i_sps_count
];
707 HELPER_FOREACH_NAL(p_nal
, hh
->h264
.sps_list
, hh
->h264
.i_sps_count
,
710 pp_sps_bufs
[i
] = p_nal
->b
->p_buffer
;
711 p_sps_sizes
[i
] = p_nal
->b
->i_buffer
;
716 const uint8_t *pp_pps_bufs
[hh
->h264
.i_pps_count
];
717 size_t p_pps_sizes
[hh
->h264
.i_pps_count
];
718 HELPER_FOREACH_NAL(p_nal
, hh
->h264
.pps_list
, hh
->h264
.i_pps_count
,
721 pp_pps_bufs
[i
] = p_nal
->b
->p_buffer
;
722 p_pps_sizes
[i
] = p_nal
->b
->i_buffer
;
725 return h264_NAL_to_avcC(4, pp_sps_bufs
, p_sps_sizes
, hh
->h264
.i_sps_count
,
726 pp_pps_bufs
, p_pps_sizes
, hh
->h264
.i_pps_count
);
730 hevc_helper_get_hvcc_config(const struct hxxx_helper
*hh
)
732 struct hevc_dcr_params params
= {};
733 const struct hxxx_helper_nal
*p_nal
;
736 HELPER_FOREACH_NAL(p_nal
, hh
->hevc
.vps_list
, hh
->hevc
.i_vps_count
,
739 params
.p_vps
[params
.i_vps_count
] = p_nal
->b
->p_buffer
;
740 params
.rgi_vps
[params
.i_vps_count
++] = p_nal
->b
->i_buffer
;
744 HELPER_FOREACH_NAL(p_nal
, hh
->hevc
.sps_list
, hh
->hevc
.i_sps_count
,
747 params
.p_sps
[params
.i_sps_count
] = p_nal
->b
->p_buffer
;
748 params
.rgi_sps
[params
.i_sps_count
++] = p_nal
->b
->i_buffer
;
752 HELPER_FOREACH_NAL(p_nal
, hh
->hevc
.pps_list
, hh
->hevc
.i_pps_count
,
755 params
.p_pps
[params
.i_pps_count
] = p_nal
->b
->p_buffer
;
756 params
.rgi_pps
[params
.i_pps_count
++] = p_nal
->b
->i_buffer
;
761 uint8_t *p_dcr
= hevc_create_dcr(¶ms
, 4, true, &i_dcr
);
765 return block_heap_Alloc(p_dcr
, i_dcr
);
768 static const struct hxxx_helper_nal
*
769 h264_helper_get_current_sps(const struct hxxx_helper
*hh
)
771 if (hh
->h264
.i_sps_count
== 0)
774 const struct hxxx_helper_nal
*hsps
=
775 &hh
->h264
.sps_list
[hh
->h264
.i_current_sps
];
776 assert(hsps
->b
!= NULL
);
781 hxxx_helper_get_current_picture_size(const struct hxxx_helper
*hh
,
782 unsigned *p_w
, unsigned *p_h
,
783 unsigned *p_vw
, unsigned *p_vh
)
785 if(hh
->i_codec
== VLC_CODEC_H264
)
787 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
788 if (hsps
&& h264_get_picture_size(hsps
->h264_sps
, p_w
, p_h
, p_vw
, p_vh
))
791 else if(hh
->i_codec
== VLC_CODEC_HEVC
)
793 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
794 if(hsps
&& hevc_get_picture_size(hsps
->hevc_sps
, p_w
, p_h
, p_vw
, p_vh
))
801 hxxx_helper_get_current_sar(const struct hxxx_helper
*hh
, int *p_num
, int *p_den
)
803 if(hh
->i_codec
== VLC_CODEC_H264
)
805 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
808 *p_num
= hsps
->h264_sps
->vui
.i_sar_num
;
809 *p_den
= hsps
->h264_sps
->vui
.i_sar_den
;
813 else if(hh
->i_codec
== VLC_CODEC_HEVC
)
815 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
817 if(hsps
&& hevc_get_aspect_ratio(hsps
->hevc_sps
, &num
, &den
))
828 h264_helper_get_current_dpb_values(const struct hxxx_helper
*hh
,
829 uint8_t *p_depth
, unsigned *p_delay
)
831 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
834 return h264_get_dpb_values(hsps
->h264_sps
, p_depth
, p_delay
) ?
835 VLC_SUCCESS
: VLC_EGENERIC
;
839 hxxx_helper_get_current_profile_level(const struct hxxx_helper
*hh
,
840 uint8_t *p_profile
, uint8_t *p_level
)
842 if(hh
->i_codec
== VLC_CODEC_H264
)
844 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
847 *p_profile
= hsps
->h264_sps
->i_profile
;
848 *p_level
= hsps
->h264_sps
->i_level
;
852 else if(hh
->i_codec
== VLC_CODEC_HEVC
)
854 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
856 hevc_get_sps_profile_tier_level(hsps
->hevc_sps
, p_profile
, p_level
))
863 hxxx_helper_get_colorimetry(const struct hxxx_helper
*hh
,
864 video_color_primaries_t
*p_primaries
,
865 video_transfer_func_t
*p_transfer
,
866 video_color_space_t
*p_colorspace
,
873 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
876 return h264_get_colorimetry(hsps
->h264_sps
, p_primaries
, p_transfer
,
877 p_colorspace
, p_full_range
)
878 == true ? VLC_SUCCESS
: VLC_EGENERIC
;
882 const struct hxxx_helper_nal
*hsps
= &hh
->hevc
.sps_list
[hh
->hevc
.i_current_sps
];
886 return hevc_get_colorimetry(hsps
->hevc_sps
, p_primaries
, p_transfer
,
887 p_colorspace
, p_full_range
)
888 == true ? VLC_SUCCESS
: VLC_EGENERIC
;
891 vlc_assert_unreachable();