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
;
53 hxxx_helper_clean(struct hxxx_helper
*hh
)
58 for (size_t i
= 0; i
<= H264_SPS_ID_MAX
; ++i
)
60 struct hxxx_helper_nal
*hnal
= &hh
->h264
.sps_list
[i
];
63 block_Release(hnal
->b
);
64 h264_release_sps(hnal
->h264_sps
);
67 for (size_t i
= 0; i
<= H264_PPS_ID_MAX
; ++i
)
69 struct hxxx_helper_nal
*hnal
= &hh
->h264
.pps_list
[i
];
72 block_Release(hnal
->b
);
73 h264_release_pps(hnal
->h264_pps
);
78 free(hh
->hevc
.p_annexb_config_nal
);
81 vlc_assert_unreachable();
85 #define HELPER_FOREACH_NAL(it, p_nal_list, i_nal_count, i_nal_max) \
86 for (size_t ii = 0, i_nal_nb = 0; i < i_nal_max && i_nal_count > i_nal_nb; ++ii) \
87 if (p_nal_list[ii].b != NULL && (it = &p_nal_list[ii]) && ++i_nal_nb)
90 helper_dup_buf(struct hxxx_helper_nal
*p_nal
,
91 const uint8_t *p_nal_buf
, size_t i_nal_buf
)
95 p_nal
->b
= block_Alloc(i_nal_buf
);
99 else if (p_nal
->b
!= NULL
&& i_nal_buf
> p_nal
->b
->i_buffer
)
101 block_t
*b
= block_TryRealloc(p_nal
->b
, 0, i_nal_buf
);
106 memcpy(p_nal
->b
->p_buffer
, p_nal_buf
, i_nal_buf
);
107 p_nal
->b
->i_buffer
= i_nal_buf
;
111 static inline const struct hxxx_helper_nal
*
112 helper_search_nal(const struct hxxx_helper_nal
*p_nal_list
, size_t i_nal_count
,
113 size_t i_nal_max
, const void *p_nal_buf
, size_t i_nal_buf
)
116 for (size_t i
= 0; i
< i_nal_max
&& i_nal_count
> i_nal_nb
; ++i
)
118 const struct hxxx_helper_nal
*p_nal
= &p_nal_list
[i
];
119 if (p_nal
->b
== NULL
)
122 const int i_diff
= i_nal_buf
- p_nal
->b
->i_buffer
;
123 if (i_diff
== 0 && memcmp(p_nal_buf
, p_nal
->b
->p_buffer
, i_nal_buf
) == 0)
128 #define helper_search_sps(hh, p_nal, i_nal) \
129 helper_search_nal(hh->h264.sps_list, hh->h264.i_sps_count, \
130 H264_SPS_ID_MAX+1, p_nal, i_nal)
131 #define helper_search_pps(hh, p_nal, i_nal) \
132 helper_search_nal(hh->h264.pps_list, hh->h264.i_pps_count, \
133 H264_PPS_ID_MAX+1, p_nal, i_nal)
136 helper_nal_length_valid(struct hxxx_helper
*hh
)
138 return hh
->i_nal_length_size
== 1 || hh
->i_nal_length_size
== 2
139 || hh
->i_nal_length_size
== 4;
143 h264_helper_parse_nal(struct hxxx_helper
*hh
, const uint8_t *p_buf
, size_t i_buf
,
144 uint8_t i_nal_length_size
, bool *p_config_changed
)
146 const uint8_t *p_nal
;
148 hxxx_iterator_ctx_t it
;
149 hxxx_iterator_init(&it
, p_buf
, i_buf
, i_nal_length_size
);
150 *p_config_changed
= false;
152 while ((i_nal_length_size
) ? hxxx_iterate_next(&it
, &p_nal
, &i_nal
)
153 : hxxx_annexb_iterate_next(&it
, &p_nal
, &i_nal
))
158 const enum h264_nal_unit_type_e i_nal_type
= p_nal
[0] & 0x1F;
160 if (i_nal_type
== H264_NAL_SPS
)
162 if (helper_search_sps(hh
, p_nal
, i_nal
) != NULL
)
164 h264_sequence_parameter_set_t
*p_sps
=
165 h264_decode_sps(p_nal
, i_nal
, true);
169 struct hxxx_helper_nal
*hnal
= &hh
->h264
.sps_list
[p_sps
->i_id
];
170 if (helper_dup_buf(hnal
, p_nal
, i_nal
))
172 h264_release_sps(p_sps
);
176 h264_release_sps(hnal
->h264_sps
);
178 hh
->h264
.i_sps_count
++;
180 hnal
->h264_sps
= p_sps
;
181 *p_config_changed
= true;
182 hh
->h264
.i_current_sps
= p_sps
->i_id
;
183 msg_Dbg(hh
->p_obj
, "new SPS parsed: %u", p_sps
->i_id
);
185 else if (i_nal_type
== H264_NAL_PPS
)
187 if (helper_search_pps(hh
, p_nal
, i_nal
) != NULL
)
189 h264_picture_parameter_set_t
*p_pps
=
190 h264_decode_pps(p_nal
, i_nal
, true);
194 struct hxxx_helper_nal
*hnal
= &hh
->h264
.pps_list
[p_pps
->i_id
];
196 if (helper_dup_buf(hnal
, p_nal
, i_nal
))
198 h264_release_pps(p_pps
);
202 h264_release_pps(hnal
->h264_pps
);
204 hh
->h264
.i_pps_count
++;
206 hnal
->h264_pps
= p_pps
;
207 *p_config_changed
= true;
208 msg_Dbg(hh
->p_obj
, "new PPS parsed: %u", p_pps
->i_id
);
210 else if (i_nal_type
<= H264_NAL_SLICE_IDR
211 && i_nal_type
!= H264_NAL_UNKNOWN
)
213 if (hh
->h264
.i_sps_count
> 1)
215 /* There is more than one SPS. Get the PPS id of the current
216 * SLICE in order to get the current SPS id */
218 /* Get the PPS id from the slice: inspirated from
219 * h264_decode_slice() */
221 bs_init(&s
, p_nal
, i_nal
);
225 unsigned i_pps_id
= bs_read_ue(&s
);
226 if (i_pps_id
> H264_PPS_ID_MAX
)
229 struct hxxx_helper_nal
*hpps
= &hh
->h264
.pps_list
[i_pps_id
];
233 struct hxxx_helper_nal
*hsps
=
234 &hh
->h264
.sps_list
[hpps
->h264_pps
->i_sps_id
];
238 assert(hpps
->h264_pps
->i_sps_id
== hsps
->h264_sps
->i_id
);
239 if (hsps
->h264_sps
->i_id
!= hh
->h264
.i_current_sps
)
241 hh
->h264
.i_current_sps
= hsps
->h264_sps
->i_id
;
242 *p_config_changed
= true;
245 break; /* No need to parse further NAL */
252 helper_process_avcC_h264(struct hxxx_helper
*hh
, const uint8_t *p_buf
,
255 if (i_buf
< H264_MIN_AVCC_SIZE
)
258 p_buf
+= 5; i_buf
-= 5;
260 for (unsigned int j
= 0; j
< 2 && i_buf
> 0; j
++)
262 /* First time is SPS, Second is PPS */
263 const unsigned int i_num_nal
= p_buf
[0] & (j
== 0 ? 0x1f : 0xff);
266 for (unsigned int i
= 0; i
< i_num_nal
&& i_buf
>= 2; i
++)
268 uint16_t i_nal_size
= (p_buf
[0] << 8) | p_buf
[1];
269 if (i_nal_size
> i_buf
- 2)
272 int i_ret
= h264_helper_parse_nal(hh
, p_buf
, i_nal_size
+ 2, 2,
274 if (i_ret
!= VLC_SUCCESS
)
276 p_buf
+= i_nal_size
+ 2;
277 i_buf
-= i_nal_size
+ 2;
285 h264_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
291 hh
->i_nal_length_size
= 4;
294 else if (h264_isavcC(p_extra
, i_extra
))
296 hh
->i_nal_length_size
= (((uint8_t*)p_extra
)[4] & 0x03) + 1;
297 if (!helper_nal_length_valid(hh
))
299 hh
->b_is_xvcC
= true;
301 /* XXX h264_AVC_to_AnnexB() works only with a i_nal_length_size of 4.
302 * If nal_length_size is smaller than 4, fallback to SW decoding. I
303 * don't know if it's worth the effort to fix h264_AVC_to_AnnexB() for
304 * a smaller nal_length_size. Indeed, this case will happen only with
305 * very small resolutions, where hardware decoders are not that useful.
307 if (!hh
->b_need_xvcC
&& hh
->i_nal_length_size
!= 4)
309 msg_Dbg(hh
->p_obj
, "nal_length_size is too small");
313 return helper_process_avcC_h264(hh
, p_extra
, i_extra
);
315 else /* Can't handle extra that is not avcC */
320 hevc_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
326 hh
->i_nal_length_size
= 4;
329 else if (hevc_ishvcC(p_extra
, i_extra
))
331 hh
->i_nal_length_size
= hevc_getNALLengthSize(p_extra
);
332 if (!helper_nal_length_valid(hh
))
334 hh
->b_is_xvcC
= true;
340 uint8_t *p_buf
= hevc_hvcC_to_AnnexB_NAL(p_extra
, i_extra
, &i_buf
,
344 msg_Dbg(hh
->p_obj
, "hevc_hvcC_to_AnnexB_NAL failed");
348 hh
->hevc
.p_annexb_config_nal
= p_buf
;
349 hh
->hevc
.i_annexb_config_nal
= i_buf
;
352 else /* Can't handle extra that is not avcC */
357 helper_process_block_h264_annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
358 bool *p_config_changed
)
360 if (p_config_changed
!= NULL
)
362 int i_ret
= h264_helper_parse_nal(hh
, p_block
->p_buffer
,
363 p_block
->i_buffer
, 0, p_config_changed
);
364 if (i_ret
!= VLC_SUCCESS
)
366 block_Release(p_block
);
374 helper_process_block_xvcc2annexb(struct hxxx_helper
*hh
, block_t
*p_block
,
375 bool *p_config_changed
)
377 assert(helper_nal_length_valid(hh
));
378 h264_AVC_to_AnnexB(p_block
->p_buffer
, p_block
->i_buffer
,
379 hh
->i_nal_length_size
);
380 return helper_process_block_h264_annexb(hh
, p_block
, p_config_changed
);
384 helper_process_block_h264_annexb2avcc(struct hxxx_helper
*hh
, block_t
*p_block
,
385 bool *p_config_changed
)
387 p_block
= helper_process_block_h264_annexb(hh
, p_block
, p_config_changed
);
388 return p_block
? hxxx_AnnexB_to_xVC(p_block
, hh
->i_nal_length_size
) : NULL
;
392 helper_process_block_h264_avcc(struct hxxx_helper
*hh
, block_t
*p_block
,
393 bool *p_config_changed
)
395 if (p_config_changed
!= NULL
)
397 int i_ret
= h264_helper_parse_nal(hh
, p_block
->p_buffer
,
399 hh
->i_nal_length_size
,
401 if (i_ret
!= VLC_SUCCESS
)
403 block_Release(p_block
);
411 helper_process_block_dummy(struct hxxx_helper
*hh
, block_t
*p_block
,
412 bool *p_config_changed
)
415 (void) p_config_changed
;
420 hxxx_helper_set_extra(struct hxxx_helper
*hh
, const void *p_extra
,
427 i_ret
= h264_helper_set_extra(hh
, p_extra
, i_extra
);
430 i_ret
= hevc_helper_set_extra(hh
, p_extra
, i_extra
);
433 vlc_assert_unreachable();
435 if (i_ret
!= VLC_SUCCESS
)
444 hh
->pf_process_block
= helper_process_block_h264_avcc
;
446 hh
->pf_process_block
= helper_process_block_xvcc2annexb
;
451 hh
->pf_process_block
= helper_process_block_h264_annexb2avcc
;
453 hh
->pf_process_block
= helper_process_block_h264_annexb
;
460 hh
->pf_process_block
= helper_process_block_dummy
;
462 hh
->pf_process_block
= helper_process_block_xvcc2annexb
;
467 return VLC_EGENERIC
; /* TODO */
469 hh
->pf_process_block
= helper_process_block_dummy
;
473 vlc_assert_unreachable();
480 h264_helper_get_annexb_config(struct hxxx_helper
*hh
)
482 static const uint8_t annexb_startcode
[] = { 0x00, 0x00, 0x00, 0x01 };
484 if (hh
->h264
.i_sps_count
== 0 || hh
->h264
.i_pps_count
== 0)
487 const struct hxxx_helper_nal
*pp_nal_lists
[] = {
488 hh
->h264
.sps_list
, hh
->h264
.pps_list
};
489 const size_t p_nal_counts
[] = { hh
->h264
.i_sps_count
, hh
->h264
.i_pps_count
};
490 const size_t p_nal_maxs
[] = { H264_SPS_ID_MAX
+1, H264_PPS_ID_MAX
+1 };
492 block_t
*p_block_list
= NULL
;
493 for (size_t i
= 0; i
< 2; ++i
)
495 size_t i_nals_size
= 0;
496 const struct hxxx_helper_nal
*p_nal
;
497 HELPER_FOREACH_NAL(p_nal
, pp_nal_lists
[i
], p_nal_counts
[i
], p_nal_maxs
[i
])
499 i_nals_size
+= p_nal
->b
->i_buffer
+ sizeof annexb_startcode
;
502 block_t
*p_block
= block_Alloc(i_nals_size
);
505 if (p_block_list
!= NULL
)
506 block_Release(p_block_list
);
510 p_block
->i_buffer
= 0;
511 HELPER_FOREACH_NAL(p_nal
, pp_nal_lists
[i
], p_nal_counts
[i
], p_nal_maxs
[i
])
513 memcpy(&p_block
->p_buffer
[p_block
->i_buffer
], annexb_startcode
,
514 sizeof annexb_startcode
);
515 p_block
->i_buffer
+= sizeof annexb_startcode
;
516 memcpy(&p_block
->p_buffer
[p_block
->i_buffer
], p_nal
->b
->p_buffer
,
518 p_block
->i_buffer
+= p_nal
->b
->i_buffer
;
520 if (p_block_list
== NULL
)
521 p_block_list
= p_block
;
523 p_block_list
->p_next
= p_block
;
530 h264_helper_get_avcc_config(struct hxxx_helper
*hh
)
532 const struct hxxx_helper_nal
*p_nal
;
534 const uint8_t *pp_sps_bufs
[hh
->h264
.i_sps_count
];
535 size_t p_sps_sizes
[hh
->h264
.i_sps_count
];
536 HELPER_FOREACH_NAL(p_nal
, hh
->h264
.sps_list
, hh
->h264
.i_sps_count
,
539 pp_sps_bufs
[i
] = p_nal
->b
->p_buffer
;
540 p_sps_sizes
[i
] = p_nal
->b
->i_buffer
;
545 const uint8_t *pp_pps_bufs
[hh
->h264
.i_pps_count
];
546 size_t p_pps_sizes
[hh
->h264
.i_pps_count
];
547 HELPER_FOREACH_NAL(p_nal
, hh
->h264
.pps_list
, hh
->h264
.i_pps_count
,
550 pp_pps_bufs
[i
] = p_nal
->b
->p_buffer
;
551 p_pps_sizes
[i
] = p_nal
->b
->i_buffer
;
554 return h264_NAL_to_avcC(4, pp_sps_bufs
, p_sps_sizes
, hh
->h264
.i_sps_count
,
555 pp_pps_bufs
, p_pps_sizes
, hh
->h264
.i_pps_count
);
558 static const struct hxxx_helper_nal
*
559 h264_helper_get_current_sps(struct hxxx_helper
*hh
)
561 if (hh
->h264
.i_sps_count
== 0)
564 const struct hxxx_helper_nal
*hsps
=
565 &hh
->h264
.sps_list
[hh
->h264
.i_current_sps
];
566 assert(hsps
->b
!= NULL
);
571 h264_helper_get_current_picture_size(struct hxxx_helper
*hh
,
572 unsigned *p_w
, unsigned *p_h
,
573 unsigned *p_vw
, unsigned *p_vh
)
575 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
578 return h264_get_picture_size(hsps
->h264_sps
, p_w
, p_h
, p_vw
, p_vh
) ?
579 VLC_SUCCESS
: VLC_EGENERIC
;
583 h264_helper_get_current_sar(struct hxxx_helper
*hh
, int *p_num
, int *p_den
)
585 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
588 *p_num
= hsps
->h264_sps
->vui
.i_sar_num
;
589 *p_den
= hsps
->h264_sps
->vui
.i_sar_den
;
594 h264_helper_get_current_dpb_values(struct hxxx_helper
*hh
,
595 uint8_t *p_depth
, unsigned *p_delay
)
597 const struct hxxx_helper_nal
*hsps
= h264_helper_get_current_sps(hh
);
600 return h264_get_dpb_values(hsps
->h264_sps
, p_depth
, p_delay
) ?
601 VLC_SUCCESS
: VLC_EGENERIC
;