codec: hxxx_helper: handle annexB in extradata
[vlc.git] / modules / codec / hxxx_helper.c
1 /*****************************************************************************
2  * hxxx_helper.c: AnnexB / avcC helper for dumb decoders
3  *****************************************************************************
4  * Copyright (C) 2017 VLC authors and VideoLAN
5  *
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.
10  *
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.
15  *
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  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <stdint.h>
26 #include <assert.h>
27
28 #include <vlc_common.h>
29 #include <vlc_bits.h>
30
31 #include "hxxx_helper.h"
32 #include "../packetizer/hxxx_nal.h"
33 #include "../packetizer/h264_slice.h"
34
35 void
36 hxxx_helper_init(struct hxxx_helper *hh, vlc_object_t *p_obj,
37                  vlc_fourcc_t i_codec, bool b_need_xvcC)
38 {
39     assert(i_codec == VLC_CODEC_H264 || i_codec == VLC_CODEC_HEVC);
40
41     memset(hh, 0, sizeof(struct hxxx_helper));
42     hh->p_obj = p_obj;
43     hh->i_codec = i_codec;
44     switch (i_codec)
45     {
46         case VLC_CODEC_H264:
47             break;
48     }
49     hh->b_need_xvcC = b_need_xvcC;
50 }
51
52 #define RELEASE_NALS(list, max, release) \
53     for (size_t i = 0; i <= max; ++i) \
54     { \
55         hnal = &list[i]; \
56         if (hnal->b) \
57         { \
58             block_Release(hnal->b); \
59             release; \
60         } \
61     }
62
63 static void
64 helper_clear_sei(struct hxxx_helper *hh)
65 {
66     if (hh->i_codec != VLC_CODEC_HEVC)
67         return;
68
69     for (uint8_t i=0; i<hh->hevc.i_sei_count; i++)
70     {
71         if(hh->hevc.sei_list[i].b)
72         {
73             block_Release(hh->hevc.sei_list[i].b);
74             hh->hevc.sei_list[i].b = NULL;
75         }
76     }
77     hh->hevc.i_sei_count = 0;
78 }
79
80 void
81 hxxx_helper_clean(struct hxxx_helper *hh)
82 {
83     struct hxxx_helper_nal *hnal;
84     switch (hh->i_codec)
85     {
86         case VLC_CODEC_H264:
87             RELEASE_NALS(hh->h264.sps_list, H264_SPS_ID_MAX,
88                          h264_release_sps(hnal->h264_sps));
89             RELEASE_NALS(hh->h264.pps_list, H264_PPS_ID_MAX,
90                          h264_release_pps(hnal->h264_pps));
91             memset(&hh->h264, 0, sizeof(hh->h264));
92             break;
93         case VLC_CODEC_HEVC:
94             RELEASE_NALS(hh->hevc.vps_list, HEVC_VPS_ID_MAX,
95                          hevc_rbsp_release_vps(hnal->hevc_vps));
96             RELEASE_NALS(hh->hevc.sps_list, HEVC_SPS_ID_MAX,
97                          hevc_rbsp_release_sps(hnal->hevc_sps));
98             RELEASE_NALS(hh->hevc.pps_list, HEVC_PPS_ID_MAX,
99                          hevc_rbsp_release_pps(hnal->hevc_pps));
100             helper_clear_sei(hh);
101             memset(&hh->hevc, 0, sizeof(hh->hevc));
102             break;
103         default:
104             vlc_assert_unreachable();
105     }
106 }
107
108 #define HELPER_FOREACH_NAL(it, p_nal_list, i_nal_count, i_nal_max) \
109     for (size_t ii = 0, i_nal_found = 0; ii < i_nal_max && i_nal_count > i_nal_found; ++ii) \
110         if (p_nal_list[ii].b != NULL && (it = &p_nal_list[ii]) && ++i_nal_found)
111
112 static int
113 helper_dup_buf(struct hxxx_helper_nal *p_nal,
114                const uint8_t *p_nal_buf, size_t i_nal_buf)
115 {
116     if (!p_nal->b)
117     {
118         p_nal->b = block_Alloc(i_nal_buf);
119         if (!p_nal->b)
120             return VLC_ENOMEM;
121     }
122     else if (p_nal->b != NULL && i_nal_buf > p_nal->b->i_buffer)
123     {
124         block_t *b = block_TryRealloc(p_nal->b, 0, i_nal_buf);
125         if (b == NULL)
126             return VLC_ENOMEM;
127         p_nal->b = b;
128     }
129     memcpy(p_nal->b->p_buffer, p_nal_buf, i_nal_buf);
130     p_nal->b->i_buffer = i_nal_buf;
131     return VLC_SUCCESS;
132 }
133
134 static inline const struct hxxx_helper_nal *
135 helper_search_nal(const struct hxxx_helper_nal *p_nal_list, size_t i_nal_count,
136                   size_t i_nal_max, const void *p_nal_buf, size_t i_nal_buf)
137 {
138     size_t i_nal_nb = 0;
139     for (size_t i = 0; i < i_nal_max && i_nal_count > i_nal_nb; ++i)
140     {
141         const struct hxxx_helper_nal *p_nal = &p_nal_list[i];
142         if (p_nal->b == NULL)
143             continue;
144         i_nal_nb++;
145         const int i_diff = i_nal_buf - p_nal->b->i_buffer;
146         if (i_diff == 0 && memcmp(p_nal_buf, p_nal->b->p_buffer, i_nal_buf) == 0)
147             return p_nal;
148     }
149     return NULL;
150 }
151
152 static inline bool
153 helper_nal_length_valid(struct hxxx_helper *hh)
154 {
155     return hh->i_nal_length_size == 1 || hh->i_nal_length_size == 2
156         || hh->i_nal_length_size == 4;
157 }
158
159 static void
160 helper_load_sei(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal)
161 {
162     if(hh->i_codec != VLC_CODEC_HEVC)
163         return;
164
165     if(hh->hevc.i_sei_count == HXXX_HELPER_SEI_COUNT)
166         return;
167
168     struct hxxx_helper_nal *hnal = &hh->hevc.sei_list[hh->hevc.i_sei_count];
169     if (helper_dup_buf(hnal, p_nal, i_nal))
170         return;
171     hh->hevc.i_sei_count++;
172 }
173
174 #define LOAD_xPS(list, count, id, max, xpstype, xpsdecode, xpsrelease) \
175     if (helper_search_nal(list, count, max+1, p_nal, i_nal) != NULL)\
176         continue;\
177     xpstype *p_xps = xpsdecode(p_nal, i_nal, true);\
178     if (!p_xps)\
179         return VLC_EGENERIC;\
180 \
181     struct hxxx_helper_nal *hnal = &list[id];\
182     if (helper_dup_buf(hnal, p_nal, i_nal))\
183     {\
184         xpsrelease(p_xps);\
185         return VLC_EGENERIC;\
186     }\
187     if (hnal->xps)\
188         xpsrelease(hnal->xps);\
189     else\
190         count++;\
191 \
192     hnal->xps = p_xps;\
193     *p_config_changed = true
194
195 static int
196 h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_buf, size_t i_buf,
197                       uint8_t i_nal_length_size, bool *p_config_changed)
198 {
199     const uint8_t *p_nal;
200     size_t i_nal;
201     hxxx_iterator_ctx_t it;
202     hxxx_iterator_init(&it, p_buf, i_buf, i_nal_length_size);
203     *p_config_changed = false;
204
205     while ((i_nal_length_size) ? hxxx_iterate_next(&it, &p_nal, &i_nal)
206                                : hxxx_annexb_iterate_next(&it, &p_nal, &i_nal))
207     {
208         if (i_nal < 2)
209             continue;
210
211         const enum h264_nal_unit_type_e i_nal_type = p_nal[0] & 0x1F;
212
213         if (i_nal_type == H264_NAL_SPS)
214         {
215             LOAD_xPS(hh->h264.sps_list, hh->h264.i_sps_count,
216                      p_xps->i_id, H264_SPS_ID_MAX,
217                      h264_sequence_parameter_set_t,
218                      h264_decode_sps,
219                      h264_release_sps);
220             hh->h264.i_current_sps = ((h264_sequence_parameter_set_t*)p_xps)->i_id;
221             msg_Dbg(hh->p_obj, "new SPS parsed: %u", hh->h264.i_current_sps);
222         }
223         else if (i_nal_type == H264_NAL_PPS)
224         {
225             LOAD_xPS(hh->h264.pps_list, hh->h264.i_pps_count,
226                      p_xps->i_id, H264_PPS_ID_MAX,
227                      h264_picture_parameter_set_t,
228                      h264_decode_pps,
229                      h264_release_pps);
230             msg_Dbg(hh->p_obj, "new PPS parsed: %u", ((h264_picture_parameter_set_t*)p_xps)->i_id);
231         }
232         else if (i_nal_type <= H264_NAL_SLICE_IDR
233               && i_nal_type != H264_NAL_UNKNOWN)
234         {
235             if (hh->h264.i_sps_count > 1)
236             {
237                 /* There is more than one SPS. Get the PPS id of the current
238                  * SLICE in order to get the current SPS id */
239
240                 /* Get the PPS id from the slice: inspirated from
241                  * h264_decode_slice() */
242                 bs_t s;
243                 bs_init(&s, p_nal, i_nal);
244                 bs_skip(&s, 8);
245                 bs_read_ue(&s);
246                 bs_read_ue(&s);
247                 unsigned i_pps_id = bs_read_ue(&s);
248                 if (i_pps_id > H264_PPS_ID_MAX)
249                     return VLC_EGENERIC;
250
251                 struct hxxx_helper_nal *hpps = &hh->h264.pps_list[i_pps_id];
252                 if (hpps->b == NULL)
253                     return VLC_EGENERIC;
254
255                 struct hxxx_helper_nal *hsps =
256                     &hh->h264.sps_list[hpps->h264_pps->i_sps_id];
257                 if (hsps->b == NULL)
258                     return VLC_EGENERIC;
259
260                 assert(hpps->h264_pps->i_sps_id == hsps->h264_sps->i_id);
261                 if (hsps->h264_sps->i_id != hh->h264.i_current_sps)
262                 {
263                     hh->h264.i_current_sps = hsps->h264_sps->i_id;
264                     *p_config_changed = true;
265                 }
266             }
267             break; /* No need to parse further NAL */
268         }
269     }
270     return VLC_SUCCESS;
271 }
272
273 static void
274 helper_check_sei_au(struct hxxx_helper *hh, uint8_t i_nal_type)
275 {
276     if ((i_nal_type <= HEVC_NAL_IRAP_VCL23 &&
277          hh->hevc.i_previous_nal_type != HEVC_NAL_PREF_SEI) ||
278         (i_nal_type == HEVC_NAL_PREF_SEI &&
279          hh->hevc.i_previous_nal_type != HEVC_NAL_PREF_SEI))
280         helper_clear_sei(hh);
281     hh->hevc.i_previous_nal_type = i_nal_type;
282 }
283
284 static int
285 hevc_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_buf, size_t i_buf,
286                       uint8_t i_nal_length_size, bool *p_config_changed)
287 {
288     const uint8_t *p_nal;
289     size_t i_nal;
290     hxxx_iterator_ctx_t it;
291     hxxx_iterator_init(&it, p_buf, i_buf, i_nal_length_size);
292     *p_config_changed = false;
293
294     while ((i_nal_length_size) ? hxxx_iterate_next(&it, &p_nal, &i_nal)
295                                : hxxx_annexb_iterate_next(&it, &p_nal, &i_nal))
296     {
297         if (i_nal < 2 || hevc_getNALLayer(p_nal) > 0)
298             continue;
299
300         const uint8_t i_nal_type = hevc_getNALType(p_nal);
301
302         /* we need to clear sei not belonging to this access unit */
303         helper_check_sei_au(hh, i_nal_type);
304
305         if (i_nal_type == HEVC_NAL_VPS)
306         {
307             uint8_t i_id;
308             if( !hevc_get_xps_id(p_nal, i_nal, &i_id) )
309                 return VLC_EGENERIC;
310             LOAD_xPS(hh->hevc.vps_list, hh->hevc.i_vps_count,
311                      i_id, HEVC_VPS_ID_MAX,
312                      hevc_video_parameter_set_t,
313                      hevc_decode_vps,
314                      hevc_rbsp_release_vps);
315             msg_Dbg(hh->p_obj, "new VPS parsed: %u", i_id);
316         }
317         else if (i_nal_type == HEVC_NAL_SPS)
318         {
319             uint8_t i_id;
320             if( !hevc_get_xps_id(p_nal, i_nal, &i_id) )
321                 return VLC_EGENERIC;
322             LOAD_xPS(hh->hevc.sps_list, hh->hevc.i_sps_count,
323                      i_id, HEVC_SPS_ID_MAX,
324                      hevc_sequence_parameter_set_t,
325                      hevc_decode_sps,
326                      hevc_rbsp_release_sps);
327             msg_Dbg(hh->p_obj, "new SPS parsed: %u", i_id);
328         }
329         else if (i_nal_type == HEVC_NAL_PPS)
330         {
331             uint8_t i_id;
332             if( !hevc_get_xps_id(p_nal, i_nal, &i_id) )
333                 return VLC_EGENERIC;
334             LOAD_xPS(hh->hevc.pps_list, hh->hevc.i_pps_count,
335                      i_id, HEVC_PPS_ID_MAX,
336                      hevc_picture_parameter_set_t,
337                      hevc_decode_pps,
338                      hevc_rbsp_release_pps);
339             msg_Dbg(hh->p_obj, "new PPS parsed: %u", i_id);
340         }
341         else if (i_nal_type <= HEVC_NAL_IRAP_VCL23)
342         {
343             if (hh->hevc.i_sps_count > 1 || hh->hevc.i_vps_count > 1)
344             {
345                 /* Get the PPS id from the slice: inspirated from
346                  * h264_decode_slice() */
347                 bs_t s;
348                 bs_init(&s, p_nal, i_nal);
349                 bs_skip(&s, 2);
350                 unsigned i_id = bs_read_ue(&s);
351                 if (i_id > HEVC_PPS_ID_MAX)
352                     return VLC_EGENERIC;
353
354                 struct hxxx_helper_nal *xps = &hh->hevc.pps_list[i_id];
355                 if (xps->b == NULL)
356                     return VLC_EGENERIC;
357
358                 const uint8_t i_spsid = hevc_get_pps_sps_id(xps->hevc_pps);
359                 xps = &hh->hevc.sps_list[i_spsid];
360                 if (xps->b == NULL)
361                     return VLC_EGENERIC;
362
363                 i_id = hevc_get_sps_vps_id(xps->hevc_sps);
364                 xps = &hh->hevc.vps_list[i_id];
365
366                 if (i_spsid != hh->hevc.i_current_sps ||
367                     i_id != hh->hevc.i_current_vps)
368                 {
369                     hh->hevc.i_current_sps = i_spsid;
370                     hh->hevc.i_current_vps = i_id;
371                     *p_config_changed = true;
372                 }
373             }
374             break; /* No need to parse further NAL */
375         }
376         else if(i_nal_type == HEVC_NAL_PREF_SEI||
377                 i_nal_type == HEVC_NAL_SUFF_SEI)
378         {
379             helper_load_sei(hh, p_nal, i_nal);
380         }
381     }
382     return VLC_SUCCESS;
383 }
384
385 static int
386 helper_process_avcC_h264(struct hxxx_helper *hh, const uint8_t *p_buf,
387                          size_t i_buf)
388 {
389     if (i_buf < H264_MIN_AVCC_SIZE)
390         return VLC_EGENERIC;
391
392     p_buf += 5; i_buf -= 5;
393
394     for (unsigned int j = 0; j < 2 && i_buf > 0; j++)
395     {
396         /* First time is SPS, Second is PPS */
397         const unsigned int i_num_nal = p_buf[0] & (j == 0 ? 0x1f : 0xff);
398         p_buf++; i_buf--;
399
400         for (unsigned int i = 0; i < i_num_nal && i_buf >= 2; i++)
401         {
402             uint16_t i_nal_size = (p_buf[0] << 8) | p_buf[1];
403             if (i_nal_size > i_buf - 2)
404                 return VLC_EGENERIC;
405             bool b_unused;
406             int i_ret = h264_helper_parse_nal(hh, p_buf, i_nal_size + 2, 2,
407                                               &b_unused);
408             if (i_ret != VLC_SUCCESS)
409                 return i_ret;
410             p_buf += i_nal_size + 2;
411             i_buf -= i_nal_size + 2;
412         }
413     }
414
415     return VLC_SUCCESS;
416 }
417
418 static bool
419 hxxx_extra_isannexb(const void *p_extra, size_t i_extra)
420 {
421     return i_extra == 0
422         || (i_extra > 4 && memcmp(p_extra, annexb_startcode4, 4) == 0);
423 }
424
425 static int
426 h264_helper_set_extra(struct hxxx_helper *hh, const void *p_extra,
427                       size_t i_extra)
428 {
429     if (h264_isavcC(p_extra, i_extra))
430     {
431         hh->i_nal_length_size = (((uint8_t*)p_extra)[4] & 0x03) + 1;
432         if (!helper_nal_length_valid(hh))
433             return VLC_EGENERIC;
434         hh->b_is_xvcC = true;
435
436         /* XXX h264_AVC_to_AnnexB() works only with a i_nal_length_size of 4.
437          * If nal_length_size is smaller than 4, fallback to SW decoding. I
438          * don't know if it's worth the effort to fix h264_AVC_to_AnnexB() for
439          * a smaller nal_length_size. Indeed, this case will happen only with
440          * very small resolutions, where hardware decoders are not that useful.
441          * -Thomas */
442         if (!hh->b_need_xvcC && hh->i_nal_length_size != 4)
443         {
444             msg_Dbg(hh->p_obj, "nal_length_size is too small");
445             return VLC_EGENERIC;
446         }
447
448         return helper_process_avcC_h264(hh, p_extra, i_extra);
449     }
450     else if (hxxx_extra_isannexb(p_extra, i_extra))
451     {
452         hh->i_nal_length_size = 4;
453         bool unused;
454         return i_extra == 0 ? VLC_SUCCESS :
455                h264_helper_parse_nal(hh, p_extra, i_extra, 0, &unused);
456     }
457     else
458         return VLC_EGENERIC;
459 }
460
461 static int
462 helper_process_hvcC_hevc(struct hxxx_helper *hh, const uint8_t *p_buf,
463                          size_t i_buf)
464 {
465     if (i_buf < HEVC_MIN_HVCC_SIZE)
466         return VLC_EGENERIC;
467
468     const uint8_t i_num_array = p_buf[22];
469     p_buf += 23; i_buf -= 23;
470
471     for( uint8_t i = 0; i < i_num_array; i++ )
472     {
473         if(i_buf < 3)
474             return VLC_EGENERIC;
475
476         const uint16_t i_num_nalu = p_buf[1] << 8 | p_buf[2];
477         p_buf += 3; i_buf -= 3;
478
479         for( uint16_t j = 0; j < i_num_nalu; j++ )
480         {
481             if(i_buf < 2)
482                 return VLC_EGENERIC;
483
484             const uint16_t i_nalu_length = p_buf[0] << 8 | p_buf[1];
485             if(i_buf < (size_t)i_nalu_length + 2)
486                 return VLC_EGENERIC;
487
488             bool foo;
489             hevc_helper_parse_nal( hh, &p_buf[0],
490                                    i_nalu_length + 2, 2, &foo );
491
492             p_buf += i_nalu_length + 2;
493             i_buf -= i_nalu_length + 2;
494         }
495     }
496
497     return VLC_SUCCESS;
498 }
499
500 static int
501 hevc_helper_set_extra(struct hxxx_helper *hh, const void *p_extra,
502                       size_t i_extra)
503 {
504     if (hevc_ishvcC(p_extra, i_extra))
505     {
506         hh->i_nal_length_size = hevc_getNALLengthSize(p_extra);
507         if (!helper_nal_length_valid(hh))
508             return VLC_EGENERIC;
509         hh->b_is_xvcC = true;
510
511         return helper_process_hvcC_hevc( hh, p_extra, i_extra );
512     }
513     else if (hxxx_extra_isannexb(p_extra, i_extra))
514     {
515         hh->i_nal_length_size = 4;
516         bool unused;
517         return i_extra == 0 ? VLC_SUCCESS :
518                hevc_helper_parse_nal(hh, p_extra, i_extra, 0, &unused);
519     }
520     else
521         return VLC_EGENERIC;
522 }
523
524 static inline block_t *
525 helper_process_block_hxxx_annexb(struct hxxx_helper *hh,
526                                  int(*parser)(struct hxxx_helper *,
527                                               const uint8_t*, size_t,uint8_t,bool*),
528                                  block_t *p_block, bool *p_config_changed)
529 {
530     if (p_config_changed != NULL)
531     {
532         int i_ret = parser(hh, p_block->p_buffer, p_block->i_buffer,
533                            0, p_config_changed);
534         if (i_ret != VLC_SUCCESS)
535         {
536             block_Release(p_block);
537             return NULL;
538         }
539     }
540     return p_block;
541 }
542
543 static block_t *
544 helper_process_block_h264_annexb(struct hxxx_helper *hh, block_t *p_block,
545                                  bool *p_config_changed)
546 {
547     if (p_config_changed != NULL)
548         return helper_process_block_hxxx_annexb(hh, h264_helper_parse_nal,
549                                                 p_block,p_config_changed);
550     return p_block;
551 }
552
553 static block_t *
554 helper_process_block_hevc_annexb(struct hxxx_helper *hh, block_t *p_block,
555                                  bool *p_config_changed)
556 {
557     if (p_config_changed != NULL)
558         return helper_process_block_hxxx_annexb(hh, hevc_helper_parse_nal,
559                                                 p_block,p_config_changed);
560     return p_block;
561 }
562
563 static block_t *
564 helper_process_block_xvcc2annexb(struct hxxx_helper *hh, block_t *p_block,
565                                  bool *p_config_changed)
566 {
567     assert(helper_nal_length_valid(hh));
568     h264_AVC_to_AnnexB(p_block->p_buffer, p_block->i_buffer,
569                        hh->i_nal_length_size);
570     return helper_process_block_h264_annexb(hh, p_block, p_config_changed);
571 }
572
573 static block_t *
574 helper_process_block_h264_annexb2avcc(struct hxxx_helper *hh, block_t *p_block,
575                                       bool *p_config_changed)
576 {
577     p_block = helper_process_block_h264_annexb(hh, p_block, p_config_changed);
578     return p_block ? hxxx_AnnexB_to_xVC(p_block, hh->i_nal_length_size) : NULL;
579 }
580
581 static block_t *
582 helper_process_block_hevc_annexb2hvcc(struct hxxx_helper *hh, block_t *p_block,
583                                       bool *p_config_changed)
584 {
585     p_block = helper_process_block_hevc_annexb(hh, p_block, p_config_changed);
586     return p_block ? hxxx_AnnexB_to_xVC(p_block, hh->i_nal_length_size) : NULL;
587 }
588
589 static block_t *
590 helper_process_block_h264_avcc(struct hxxx_helper *hh, block_t *p_block,
591                                bool *p_config_changed)
592 {
593     if (p_config_changed != NULL)
594     {
595         int i_ret = h264_helper_parse_nal(hh, p_block->p_buffer,
596                                           p_block->i_buffer,
597                                           hh->i_nal_length_size,
598                                           p_config_changed);
599         if (i_ret != VLC_SUCCESS)
600         {
601             block_Release(p_block);
602             return NULL;
603         }
604     }
605     return p_block;
606 }
607
608 static block_t *
609 helper_process_block_hevc_hvcc(struct hxxx_helper *hh, block_t *p_block,
610                                bool *p_config_changed)
611 {
612     if (p_config_changed != NULL)
613     {
614         int i_ret = hevc_helper_parse_nal(hh, p_block->p_buffer,
615                                           p_block->i_buffer,
616                                           hh->i_nal_length_size,
617                                           p_config_changed);
618         if (i_ret != VLC_SUCCESS)
619         {
620             block_Release(p_block);
621             return NULL;
622         }
623     }
624     return p_block;
625 }
626
627 int
628 hxxx_helper_set_extra(struct hxxx_helper *hh, const void *p_extra,
629                       size_t i_extra)
630 {
631     int i_ret;
632     switch (hh->i_codec)
633     {
634         case VLC_CODEC_H264:
635             i_ret = h264_helper_set_extra(hh, p_extra, i_extra);
636             break;
637         case VLC_CODEC_HEVC:
638             i_ret = hevc_helper_set_extra(hh, p_extra, i_extra);
639             break;
640         default:
641             vlc_assert_unreachable();
642     }
643     if (i_ret != VLC_SUCCESS)
644         return i_ret;
645
646     switch (hh->i_codec)
647     {
648         case VLC_CODEC_H264:
649             if (hh->b_is_xvcC)
650             {
651                 if (hh->b_need_xvcC)
652                     hh->pf_process_block = helper_process_block_h264_avcc;
653                 else
654                     hh->pf_process_block = helper_process_block_xvcc2annexb;
655             }
656             else /* AnnexB */
657             {
658                 if (hh->b_need_xvcC)
659                     hh->pf_process_block = helper_process_block_h264_annexb2avcc;
660                 else
661                     hh->pf_process_block = helper_process_block_h264_annexb;
662             }
663             break;
664         case VLC_CODEC_HEVC:
665             if (hh->b_is_xvcC)
666             {
667                 if (hh->b_need_xvcC)
668                     hh->pf_process_block = helper_process_block_hevc_hvcc;
669                 else
670                     hh->pf_process_block = helper_process_block_xvcc2annexb;
671             }
672             else /* AnnexB */
673             {
674                 if (hh->b_need_xvcC)
675                     hh->pf_process_block = helper_process_block_hevc_annexb2hvcc;
676                 else
677                     hh->pf_process_block = helper_process_block_hevc_annexb;
678             }
679             break;
680         default:
681             vlc_assert_unreachable();
682     }
683     return VLC_SUCCESS;;
684 }
685
686 static block_t *
687 hxxx_helper_get_annexb_config( const struct hxxx_helper_nal *pp_nal_lists[],
688                                const size_t p_nal_counts[],
689                                const size_t p_nal_maxs[],
690                                size_t i_lists_size )
691 {
692     static const uint8_t annexb_startcode[] = { 0x00, 0x00, 0x00, 0x01 };
693
694     block_t *p_block_list = NULL, *p_current;
695     for (size_t i = 0; i < i_lists_size; ++i)
696     {
697         size_t i_nals_size = 0;
698         const struct hxxx_helper_nal *p_nal;
699         HELPER_FOREACH_NAL(p_nal, pp_nal_lists[i], p_nal_counts[i], p_nal_maxs[i])
700         {
701             i_nals_size += p_nal->b->i_buffer + sizeof annexb_startcode;
702         }
703
704         block_t *p_block = block_Alloc(i_nals_size);
705         if (p_block == NULL)
706         {
707             if (p_block_list != NULL)
708                 block_Release(p_block_list);
709             return NULL;
710         }
711
712         p_block->i_buffer = 0;
713         HELPER_FOREACH_NAL(p_nal, pp_nal_lists[i], p_nal_counts[i], p_nal_maxs[i])
714         {
715             memcpy(&p_block->p_buffer[p_block->i_buffer], annexb_startcode,
716                    sizeof annexb_startcode);
717             p_block->i_buffer += sizeof annexb_startcode;
718             memcpy(&p_block->p_buffer[p_block->i_buffer], p_nal->b->p_buffer,
719                    p_nal->b->i_buffer);
720             p_block->i_buffer += p_nal->b->i_buffer;
721         }
722         if (p_block_list == NULL)
723             p_current = p_block_list = p_block;
724         else
725         {
726             p_current->p_next = p_block;
727             p_current = p_block;
728         }
729     }
730
731     return p_block_list;
732 }
733
734 block_t *
735 h264_helper_get_annexb_config(const struct hxxx_helper *hh)
736 {
737     if (hh->h264.i_sps_count == 0 || hh->h264.i_pps_count == 0)
738         return NULL;
739
740     const struct hxxx_helper_nal *pp_nal_lists[] = {
741         hh->h264.sps_list, hh->h264.pps_list };
742     const size_t p_nal_counts[] = { hh->h264.i_sps_count, hh->h264.i_pps_count };
743     const size_t p_nal_maxs[] = { H264_SPS_ID_MAX+1, H264_PPS_ID_MAX+1 };
744
745     return hxxx_helper_get_annexb_config( pp_nal_lists, p_nal_counts, p_nal_maxs, 2 );
746 }
747
748 block_t *
749 hevc_helper_get_annexb_config(const struct hxxx_helper *hh)
750 {
751     if (hh->hevc.i_vps_count == 0 || hh->hevc.i_sps_count == 0 ||
752         hh->hevc.i_pps_count == 0 )
753         return NULL;
754
755     const struct hxxx_helper_nal *pp_nal_lists[] = {
756         hh->hevc.vps_list, hh->hevc.sps_list, hh->hevc.pps_list };
757     const size_t p_nal_counts[] = { hh->hevc.i_vps_count, hh->hevc.i_sps_count,
758                                     hh->hevc.i_pps_count };
759     const size_t p_nal_maxs[] = { HEVC_VPS_ID_MAX+1, HEVC_SPS_ID_MAX+1, HEVC_PPS_ID_MAX+1 };
760
761     return hxxx_helper_get_annexb_config( pp_nal_lists, p_nal_counts, p_nal_maxs, 3 );
762 }
763
764 block_t *
765 h264_helper_get_avcc_config(const struct hxxx_helper *hh)
766 {
767     const struct hxxx_helper_nal *p_nal;
768     const uint8_t *pp_sps_bufs[hh->h264.i_sps_count];
769     size_t p_sps_sizes[hh->h264.i_sps_count];
770     HELPER_FOREACH_NAL(p_nal, hh->h264.sps_list, hh->h264.i_sps_count,
771                        H264_SPS_ID_MAX+1)
772     {
773         pp_sps_bufs[i_nal_found - 1] = p_nal->b->p_buffer;
774         p_sps_sizes[i_nal_found - 1] = p_nal->b->i_buffer;
775     }
776
777     const uint8_t *pp_pps_bufs[hh->h264.i_pps_count];
778     size_t p_pps_sizes[hh->h264.i_pps_count];
779     HELPER_FOREACH_NAL(p_nal, hh->h264.pps_list, hh->h264.i_pps_count,
780                        H264_PPS_ID_MAX+1)
781     {
782         pp_pps_bufs[i_nal_found - 1] = p_nal->b->p_buffer;
783         p_pps_sizes[i_nal_found - 1] = p_nal->b->i_buffer;
784     }
785     return h264_NAL_to_avcC(4, pp_sps_bufs, p_sps_sizes, hh->h264.i_sps_count,
786                             pp_pps_bufs, p_pps_sizes, hh->h264.i_pps_count);
787 }
788
789 block_t *
790 hevc_helper_get_hvcc_config(const struct hxxx_helper *hh)
791 {
792     struct hevc_dcr_params params = {};
793     const struct hxxx_helper_nal *p_nal;
794
795     HELPER_FOREACH_NAL(p_nal, hh->hevc.vps_list, hh->hevc.i_vps_count,
796                        HEVC_VPS_ID_MAX+1)
797     {
798         params.p_vps[params.i_vps_count] = p_nal->b->p_buffer;
799         params.rgi_vps[params.i_vps_count++] = p_nal->b->i_buffer;
800     }
801
802     HELPER_FOREACH_NAL(p_nal, hh->hevc.sps_list, hh->hevc.i_sps_count,
803                        HEVC_SPS_ID_MAX+1)
804     {
805         params.p_sps[params.i_sps_count] = p_nal->b->p_buffer;
806         params.rgi_sps[params.i_sps_count++] = p_nal->b->i_buffer;
807     }
808
809     HELPER_FOREACH_NAL(p_nal, hh->hevc.pps_list, hh->hevc.i_pps_count,
810                        HEVC_PPS_ID_MAX+1)
811     {
812         params.p_pps[params.i_pps_count] = p_nal->b->p_buffer;
813         params.rgi_pps[params.i_pps_count++] = p_nal->b->i_buffer;
814     }
815
816     HELPER_FOREACH_NAL(p_nal, hh->hevc.sei_list, hh->hevc.i_sei_count,
817                        HEVC_DCR_SEI_COUNT)
818     {
819         if (hevc_getNALType(p_nal->b->p_buffer) == HEVC_NAL_PREF_SEI)
820         {
821             params.p_seipref[params.i_seipref_count] = p_nal->b->p_buffer;
822             params.rgi_seipref[params.i_seipref_count++] = p_nal->b->i_buffer;
823         }
824         else
825         {
826             params.p_seisuff[params.i_seisuff_count] = p_nal->b->p_buffer;
827             params.rgi_seisuff[params.i_seisuff_count++] = p_nal->b->i_buffer;
828         }
829     }
830
831     size_t i_dcr;
832     uint8_t *p_dcr = hevc_create_dcr(&params, 4, true, &i_dcr);
833     if(p_dcr == NULL)
834         return NULL;
835
836     return block_heap_Alloc(p_dcr, i_dcr);
837 }
838
839 static const struct hxxx_helper_nal *
840 h264_helper_get_current_sps(const struct hxxx_helper *hh)
841 {
842     if (hh->h264.i_sps_count == 0)
843         return NULL;
844
845     const struct hxxx_helper_nal *hsps =
846         &hh->h264.sps_list[hh->h264.i_current_sps];
847     assert(hsps->b != NULL);
848     return hsps;
849 }
850
851 int
852 hxxx_helper_get_current_picture_size(const struct hxxx_helper *hh,
853                                      unsigned *p_w, unsigned *p_h,
854                                      unsigned *p_vw, unsigned *p_vh)
855 {
856     if(hh->i_codec == VLC_CODEC_H264)
857     {
858         const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
859         if (hsps && h264_get_picture_size(hsps->h264_sps, p_w, p_h, p_vw, p_vh))
860                return VLC_SUCCESS;
861     }
862     else if(hh->i_codec == VLC_CODEC_HEVC)
863     {
864         const struct hxxx_helper_nal *hsps = &hh->hevc.sps_list[hh->hevc.i_current_sps];
865         if(hsps && hevc_get_picture_size(hsps->hevc_sps, p_w, p_h, p_vw, p_vh))
866             return VLC_SUCCESS;
867     }
868     return VLC_EGENERIC;
869 }
870
871 int
872 hxxx_helper_get_current_sar(const struct hxxx_helper *hh, int *p_num, int *p_den)
873 {
874     if(hh->i_codec == VLC_CODEC_H264)
875     {
876         const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
877         if (hsps)
878         {
879             *p_num = hsps->h264_sps->vui.i_sar_num;
880             *p_den = hsps->h264_sps->vui.i_sar_den;
881             return VLC_SUCCESS;
882         }
883     }
884     else if(hh->i_codec == VLC_CODEC_HEVC)
885     {
886         const struct hxxx_helper_nal *hsps = &hh->hevc.sps_list[hh->hevc.i_current_sps];
887         unsigned num, den;
888         if(hsps && hevc_get_aspect_ratio(hsps->hevc_sps, &num, &den))
889         {
890             *p_num = num;
891             *p_den = den;
892             return VLC_SUCCESS;
893         }
894     }
895     return VLC_EGENERIC;
896 }
897
898 int
899 h264_helper_get_current_dpb_values(const struct hxxx_helper *hh,
900                                    uint8_t *p_depth, unsigned *p_delay)
901 {
902     const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
903     if (hsps == NULL)
904         return VLC_EGENERIC;
905     return h264_get_dpb_values(hsps->h264_sps, p_depth, p_delay) ?
906            VLC_SUCCESS : VLC_EGENERIC;
907 }
908
909 int
910 hxxx_helper_get_current_profile_level(const struct hxxx_helper *hh,
911                                       uint8_t *p_profile, uint8_t *p_level)
912 {
913     if(hh->i_codec == VLC_CODEC_H264)
914     {
915         const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
916         if (hsps)
917         {
918             *p_profile = hsps->h264_sps->i_profile;
919             *p_level = hsps->h264_sps->i_level;
920             return VLC_SUCCESS;
921         }
922     }
923     else if(hh->i_codec == VLC_CODEC_HEVC)
924     {
925         const struct hxxx_helper_nal *hsps = &hh->hevc.sps_list[hh->hevc.i_current_sps];
926         if (hsps &&
927             hevc_get_sps_profile_tier_level(hsps->hevc_sps, p_profile, p_level))
928             return VLC_SUCCESS;
929     }
930     return VLC_EGENERIC;
931 }
932
933 int
934 hxxx_helper_get_colorimetry(const struct hxxx_helper *hh,
935                             video_color_primaries_t *p_primaries,
936                             video_transfer_func_t *p_transfer,
937                             video_color_space_t *p_colorspace,
938                             bool *p_full_range)
939 {
940     switch (hh->i_codec)
941     {
942         case VLC_CODEC_H264:
943         {
944             const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
945             if (hsps == NULL)
946                 return VLC_EGENERIC;
947             return h264_get_colorimetry(hsps->h264_sps, p_primaries, p_transfer,
948                                         p_colorspace, p_full_range)
949                 == true ? VLC_SUCCESS : VLC_EGENERIC;
950         }
951         case VLC_CODEC_HEVC:
952         {
953             const struct hxxx_helper_nal *hsps = &hh->hevc.sps_list[hh->hevc.i_current_sps];
954             if (hsps == NULL)
955                 return VLC_EGENERIC;
956
957             return hevc_get_colorimetry(hsps->hevc_sps, p_primaries, p_transfer,
958                                         p_colorspace, p_full_range)
959                 == true ? VLC_SUCCESS : VLC_EGENERIC;
960         }
961         default:
962             vlc_assert_unreachable();
963     }
964 }