/src/vlc/modules/packetizer/hevc.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * hevc.c: h.265/hevc video packetizer |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2014 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Denis Charmet <typx@videolan.org> |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify it |
9 | | * under the terms of the GNU Lesser General Public License as published by |
10 | | * the Free Software Foundation; either version 2.1 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program; if not, write to the Free Software Foundation, |
20 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
21 | | *****************************************************************************/ |
22 | | |
23 | | /***************************************************************************** |
24 | | * Preamble |
25 | | *****************************************************************************/ |
26 | | |
27 | | #ifdef HAVE_CONFIG_H |
28 | | # include "config.h" |
29 | | #endif |
30 | | |
31 | | #include <vlc_common.h> |
32 | | #include <vlc_plugin.h> |
33 | | #include <vlc_codec.h> |
34 | | #include <vlc_block.h> |
35 | | #include <vlc_bits.h> |
36 | | |
37 | | #include <vlc_block_helper.h> |
38 | | #include "packetizer_helper.h" |
39 | | #include "startcode_helper.h" |
40 | | #include "hevc_nal.h" |
41 | | #include "hxxx_nal.h" |
42 | | #include "hxxx_sei.h" |
43 | | #include "hxxx_common.h" |
44 | | |
45 | | #include <limits.h> |
46 | | |
47 | | /***************************************************************************** |
48 | | * Module descriptor |
49 | | *****************************************************************************/ |
50 | | static int Open (vlc_object_t *); |
51 | | static void Close(vlc_object_t *); |
52 | | |
53 | 168 | vlc_module_begin () |
54 | 84 | set_subcategory(SUBCAT_SOUT_PACKETIZER) |
55 | 84 | set_description(N_("HEVC/H.265 video packetizer")) |
56 | 84 | set_capability("video packetizer", 50) |
57 | 168 | set_callbacks(Open, Close) |
58 | 84 | vlc_module_end () |
59 | | |
60 | | |
61 | | /**************************************************************************** |
62 | | * Local prototypes |
63 | | ****************************************************************************/ |
64 | | struct hevc_tuple_s |
65 | | { |
66 | | block_t *p_nal; |
67 | | void *p_decoded; |
68 | | }; |
69 | | |
70 | | typedef struct |
71 | | { |
72 | | /* */ |
73 | | packetizer_t packetizer; |
74 | | |
75 | | struct |
76 | | { |
77 | | block_t *p_chain; |
78 | | block_t **pp_chain_last; |
79 | | } frame, pre, post; |
80 | | |
81 | | uint8_t i_nal_length_size; |
82 | | |
83 | | struct hevc_tuple_s rg_vps[HEVC_MAX_NUM_VPS], |
84 | | rg_sps[HEVC_MAX_NUM_SPS], |
85 | | rg_pps[HEVC_MAX_NUM_PPS]; |
86 | | |
87 | | const hevc_video_parameter_set_t *p_active_vps; |
88 | | const hevc_sequence_parameter_set_t *p_active_sps; |
89 | | const hevc_picture_parameter_set_t *p_active_pps; |
90 | | enum |
91 | | { |
92 | | MISSING = 0, |
93 | | COMPLETE, |
94 | | SENT, |
95 | | } sets; |
96 | | /* Recovery starts from IFRAME or SEI recovery point */ |
97 | | bool b_recovery_point; |
98 | | |
99 | | hevc_sei_pic_timing_t *p_timing; |
100 | | |
101 | | date_t dts; |
102 | | vlc_tick_t pts; |
103 | | bool b_need_ts; |
104 | | |
105 | | /* */ |
106 | | cc_storage_t *p_ccs; |
107 | | } decoder_sys_t; |
108 | | |
109 | | static block_t *PacketizeAnnexB(decoder_t *, block_t **); |
110 | | static block_t *PacketizeHVC1(decoder_t *, block_t **); |
111 | | static void PacketizeFlush( decoder_t * ); |
112 | | static void PacketizeReset(void *p_private, bool b_broken); |
113 | | static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *); |
114 | | static block_t *ParseNALBlock(decoder_t *, bool *pb_ts_used, block_t *); |
115 | | static inline block_t *ParseNALBlockW( void *opaque, bool *pb_ts_used, block_t *p_frag ) |
116 | 605 | { |
117 | 605 | return ParseNALBlock( (decoder_t *) opaque, pb_ts_used, p_frag ); |
118 | 605 | } |
119 | | static int PacketizeValidate(void *p_private, block_t *); |
120 | | static block_t * PacketizeDrain(void *); |
121 | | static bool ParseSEICallback( const hxxx_sei_data_t *, void * ); |
122 | | static block_t *GetCc( decoder_t *, decoder_cc_desc_t * ); |
123 | | static block_t *GetXPSCopy(decoder_sys_t *); |
124 | | |
125 | 8.63M | #define BLOCK_FLAG_DROP (1 << BLOCK_FLAG_PRIVATE_SHIFT) |
126 | | |
127 | | /**************************************************************************** |
128 | | * Helpers |
129 | | ****************************************************************************/ |
130 | | static inline void InitQueue( block_t **pp_head, block_t ***ppp_tail ) |
131 | 3.13M | { |
132 | 3.13M | *pp_head = NULL; |
133 | 3.13M | *ppp_tail = pp_head; |
134 | 3.13M | } |
135 | 3.13M | #define INITQ(name) InitQueue(&p_sys->name.p_chain, &p_sys->name.pp_chain_last) |
136 | | |
137 | | static block_t * OutputQueues(decoder_sys_t *p_sys, bool b_valid) |
138 | 3.05M | { |
139 | 3.05M | block_t *p_output = NULL; |
140 | 3.05M | block_t *p_xps = NULL; |
141 | 3.05M | block_t **pp_output_last = &p_output; |
142 | 3.05M | uint32_t i_flags = 0; /* Because block_ChainGather does not merge flags or times */ |
143 | | |
144 | 3.05M | if(p_sys->b_recovery_point && p_sys->sets != SENT) |
145 | 23.9k | p_xps = GetXPSCopy(p_sys); |
146 | | |
147 | 3.05M | if(p_sys->pre.p_chain) |
148 | 160k | { |
149 | 160k | i_flags |= p_sys->pre.p_chain->i_flags; |
150 | | |
151 | 160k | if(p_sys->pre.p_chain->i_buffer >= 5 && |
152 | 160k | hevc_getNALType(&p_sys->pre.p_chain->p_buffer[4]) == HEVC_NAL_AUD) |
153 | 7.95k | { |
154 | 7.95k | block_t *p_au = p_sys->pre.p_chain; |
155 | 7.95k | p_sys->pre.p_chain = p_sys->pre.p_chain->p_next; |
156 | 7.95k | p_au->p_next = NULL; |
157 | 7.95k | block_ChainLastAppend(&pp_output_last, p_au); |
158 | 7.95k | } |
159 | | |
160 | 160k | if(p_xps) |
161 | 3.29k | block_ChainLastAppend(&pp_output_last, p_xps); |
162 | | |
163 | 160k | if(p_sys->pre.p_chain) |
164 | 154k | block_ChainLastAppend(&pp_output_last, p_sys->pre.p_chain); |
165 | 160k | INITQ(pre); |
166 | 160k | } |
167 | 2.89M | else if(p_xps) |
168 | 18.8k | { |
169 | 18.8k | block_ChainLastAppend(&pp_output_last, p_xps); |
170 | 18.8k | } |
171 | | |
172 | 3.05M | if(p_sys->frame.p_chain) |
173 | 2.80M | { |
174 | 2.80M | i_flags |= p_sys->frame.p_chain->i_flags; |
175 | 2.80M | block_ChainLastAppend(&pp_output_last, p_sys->frame.p_chain); |
176 | 2.80M | p_output->i_dts = date_Get(&p_sys->dts); |
177 | 2.80M | p_output->i_pts = p_sys->pts; |
178 | 2.80M | INITQ(frame); |
179 | 2.80M | } |
180 | | |
181 | 3.05M | if(p_sys->post.p_chain) |
182 | 113k | { |
183 | 113k | i_flags |= p_sys->post.p_chain->i_flags; |
184 | 113k | block_ChainLastAppend(&pp_output_last, p_sys->post.p_chain); |
185 | 113k | INITQ(post); |
186 | 113k | } |
187 | | |
188 | 3.05M | if(p_output) |
189 | 2.91M | { |
190 | 2.91M | p_output->i_flags |= i_flags; |
191 | 2.91M | if(!b_valid) |
192 | 251k | p_output->i_flags |= BLOCK_FLAG_DROP; |
193 | 2.91M | } |
194 | | |
195 | 3.05M | return p_output; |
196 | 3.05M | } |
197 | | |
198 | | |
199 | | /***************************************************************************** |
200 | | * Open |
201 | | *****************************************************************************/ |
202 | | static int Open(vlc_object_t *p_this) |
203 | 86.1k | { |
204 | 86.1k | decoder_t *p_dec = (decoder_t*)p_this; |
205 | 86.1k | decoder_sys_t *p_sys; |
206 | | |
207 | 86.1k | if (p_dec->fmt_in->i_codec != VLC_CODEC_HEVC) |
208 | 68.3k | return VLC_EGENERIC; |
209 | | |
210 | 17.7k | p_dec->p_sys = p_sys = calloc(1, sizeof(decoder_sys_t)); |
211 | 17.7k | if (!p_dec->p_sys) |
212 | 0 | return VLC_ENOMEM; |
213 | | |
214 | 17.7k | p_sys->p_ccs = cc_storage_new(); |
215 | 17.7k | if(unlikely(!p_sys->p_ccs)) |
216 | 0 | { |
217 | 0 | free(p_dec->p_sys); |
218 | 0 | return VLC_ENOMEM; |
219 | 0 | } |
220 | | |
221 | 17.7k | INITQ(pre); |
222 | 17.7k | INITQ(frame); |
223 | 17.7k | INITQ(post); |
224 | | |
225 | 17.7k | packetizer_Init(&p_sys->packetizer, |
226 | 17.7k | annexb_startcode3, 3, startcode_FindAnnexB, |
227 | 17.7k | annexb_startcode3, 1, 5, |
228 | 17.7k | PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain, |
229 | 17.7k | p_dec); |
230 | | |
231 | | /* Copy properties */ |
232 | 17.7k | es_format_Copy(&p_dec->fmt_out, p_dec->fmt_in); |
233 | 17.7k | p_dec->fmt_out.b_packetized = true; |
234 | | |
235 | | /* Init timings */ |
236 | 17.7k | if( p_dec->fmt_in->video.i_frame_rate_base && |
237 | 1.28k | p_dec->fmt_in->video.i_frame_rate && |
238 | 1.27k | p_dec->fmt_in->video.i_frame_rate <= UINT_MAX / 2 ) |
239 | 1.27k | date_Init( &p_sys->dts, p_dec->fmt_in->video.i_frame_rate * 2, |
240 | 1.27k | p_dec->fmt_in->video.i_frame_rate_base ); |
241 | 16.4k | else |
242 | 16.4k | date_Init( &p_sys->dts, 2 * 30000, 1001 ); |
243 | 17.7k | p_sys->pts = VLC_TICK_INVALID; |
244 | 17.7k | p_sys->b_need_ts = true; |
245 | 17.7k | p_sys->sets = MISSING; |
246 | | |
247 | | /* Set callbacks */ |
248 | 17.7k | const uint8_t *p_extra = p_dec->fmt_in->p_extra; |
249 | 17.7k | const size_t i_extra = p_dec->fmt_in->i_extra; |
250 | | /* Check if we have hvcC as extradata */ |
251 | 17.7k | if(hevc_ishvcC(p_extra, i_extra)) |
252 | 7 | { |
253 | 7 | uint8_t *p_new_extra; |
254 | 7 | size_t i_new_extra; |
255 | 7 | if(!hevc_hvcC_to_AnnexB_NAL(p_extra, i_extra, |
256 | 7 | &p_new_extra, &i_new_extra, |
257 | 7 | &p_sys->i_nal_length_size)) |
258 | 1 | { |
259 | 1 | msg_Err( p_dec, "Invalid HVCC extradata"); |
260 | 1 | Close( VLC_OBJECT(p_dec) ); |
261 | 1 | return VLC_EGENERIC; |
262 | 1 | } |
263 | | /* Clear hvcC/HVC1 extra, to be replaced with AnnexB */ |
264 | 6 | free(p_dec->fmt_out.p_extra); |
265 | 6 | p_dec->fmt_out.p_extra = p_new_extra; |
266 | 6 | p_dec->fmt_out.i_extra = i_new_extra; |
267 | 6 | p_dec->pf_packetize = PacketizeHVC1; |
268 | 6 | } |
269 | 17.7k | else |
270 | 17.7k | { |
271 | 17.7k | p_dec->pf_packetize = PacketizeAnnexB; |
272 | 17.7k | } |
273 | 17.7k | p_dec->pf_flush = PacketizeFlush; |
274 | 17.7k | p_dec->pf_get_cc = GetCc; |
275 | | |
276 | 17.7k | if(p_dec->fmt_out.i_extra) |
277 | 1.34k | { |
278 | | /* Feed with AnnexB VPS/SPS/PPS/SEI extradata */ |
279 | 1.34k | packetizer_Header(&p_sys->packetizer, |
280 | 1.34k | p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra); |
281 | 1.34k | } |
282 | | |
283 | 17.7k | return VLC_SUCCESS; |
284 | 17.7k | } |
285 | | |
286 | | /***************************************************************************** |
287 | | * Close |
288 | | *****************************************************************************/ |
289 | | static void Close(vlc_object_t *p_this) |
290 | 17.7k | { |
291 | 17.7k | decoder_t *p_dec = (decoder_t*)p_this; |
292 | 17.7k | decoder_sys_t *p_sys = p_dec->p_sys; |
293 | 17.7k | packetizer_Clean(&p_sys->packetizer); |
294 | | |
295 | 17.7k | block_ChainRelease(p_sys->frame.p_chain); |
296 | 17.7k | block_ChainRelease(p_sys->pre.p_chain); |
297 | 17.7k | block_ChainRelease(p_sys->post.p_chain); |
298 | | |
299 | 1.15M | for(unsigned i=0;i<HEVC_MAX_NUM_PPS; i++) |
300 | 1.13M | { |
301 | 1.13M | if(p_sys->rg_pps[i].p_decoded) |
302 | 7.48k | hevc_rbsp_release_pps(p_sys->rg_pps[i].p_decoded); |
303 | 1.13M | if(p_sys->rg_pps[i].p_nal) |
304 | 7.48k | block_Release(p_sys->rg_pps[i].p_nal); |
305 | 1.13M | } |
306 | | |
307 | 301k | for(unsigned i=0;i<HEVC_MAX_NUM_SPS; i++) |
308 | 283k | { |
309 | 283k | if(p_sys->rg_sps[i].p_decoded) |
310 | 4.03k | hevc_rbsp_release_sps(p_sys->rg_sps[i].p_decoded); |
311 | 283k | if(p_sys->rg_sps[i].p_nal) |
312 | 4.03k | block_Release(p_sys->rg_sps[i].p_nal); |
313 | 283k | } |
314 | | |
315 | 301k | for(unsigned i=0;i<HEVC_MAX_NUM_VPS; i++) |
316 | 283k | { |
317 | 283k | if(p_sys->rg_vps[i].p_decoded) |
318 | 4.17k | hevc_rbsp_release_vps(p_sys->rg_vps[i].p_decoded); |
319 | 283k | if(p_sys->rg_vps[i].p_nal) |
320 | 4.17k | block_Release(p_sys->rg_vps[i].p_nal); |
321 | 283k | } |
322 | | |
323 | 17.7k | hevc_release_sei_pic_timing( p_sys->p_timing ); |
324 | | |
325 | 17.7k | cc_storage_delete( p_sys->p_ccs ); |
326 | | |
327 | 17.7k | free(p_sys); |
328 | 17.7k | } |
329 | | |
330 | | /**************************************************************************** |
331 | | * Packetize |
332 | | ****************************************************************************/ |
333 | | static block_t *PacketizeHVC1(decoder_t *p_dec, block_t **pp_block) |
334 | 19.2k | { |
335 | 19.2k | decoder_sys_t *p_sys = p_dec->p_sys; |
336 | | |
337 | 19.2k | return PacketizeXXC1( p_dec, p_dec->obj.logger, |
338 | 19.2k | p_sys->i_nal_length_size, pp_block, |
339 | 19.2k | ParseNALBlockW, PacketizeDrain ); |
340 | 19.2k | } |
341 | | |
342 | | static block_t *PacketizeAnnexB(decoder_t *p_dec, block_t **pp_block) |
343 | 4.11M | { |
344 | 4.11M | decoder_sys_t *p_sys = p_dec->p_sys; |
345 | | |
346 | 4.11M | return packetizer_Packetize(&p_sys->packetizer, pp_block); |
347 | 4.11M | } |
348 | | |
349 | | static void PacketizeFlush( decoder_t *p_dec ) |
350 | 0 | { |
351 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
352 | |
|
353 | 0 | packetizer_Flush( &p_sys->packetizer ); |
354 | 0 | } |
355 | | |
356 | | /***************************************************************************** |
357 | | * GetCc: |
358 | | *****************************************************************************/ |
359 | | static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc ) |
360 | 1.33M | { |
361 | 1.33M | decoder_sys_t *p_sys = p_dec->p_sys; |
362 | 1.33M | return cc_storage_get_current( p_sys->p_ccs, p_desc ); |
363 | 1.33M | } |
364 | | |
365 | | /**************************************************************************** |
366 | | * Packetizer Helpers |
367 | | ****************************************************************************/ |
368 | | static void PacketizeReset(void *p_private, bool b_flush) |
369 | 3.68k | { |
370 | 3.68k | decoder_t *p_dec = p_private; |
371 | 3.68k | decoder_sys_t *p_sys = p_dec->p_sys; |
372 | | |
373 | 3.68k | block_t *p_out = OutputQueues(p_sys, false); |
374 | 3.68k | if(p_out) |
375 | 781 | block_ChainRelease(p_out); |
376 | | |
377 | 3.68k | if(b_flush) |
378 | 0 | { |
379 | 0 | p_sys->sets = MISSING; |
380 | 0 | p_sys->b_recovery_point = false; |
381 | 0 | } |
382 | 3.68k | p_sys->b_need_ts = true; |
383 | 3.68k | date_Set(&p_sys->dts, VLC_TICK_INVALID); |
384 | 3.68k | } |
385 | | |
386 | | static bool InsertXPS(decoder_t *p_dec, uint8_t i_nal_type, uint8_t i_id, |
387 | | const block_t *p_nalb) |
388 | 571k | { |
389 | 571k | decoder_sys_t *p_sys = p_dec->p_sys; |
390 | 571k | struct hevc_tuple_s *p_tuple; |
391 | 571k | void **pp_active; |
392 | | |
393 | 571k | switch(i_nal_type) |
394 | 571k | { |
395 | 107k | case HEVC_NAL_VPS: |
396 | 107k | if(i_id > HEVC_VPS_ID_MAX) |
397 | 0 | return false; |
398 | 107k | p_tuple = &p_sys->rg_vps[i_id]; |
399 | 107k | pp_active = (void**)&p_sys->p_active_vps; |
400 | 107k | break; |
401 | 263k | case HEVC_NAL_SPS: |
402 | 263k | if(i_id > HEVC_SPS_ID_MAX) |
403 | 0 | return false; |
404 | 263k | p_tuple = &p_sys->rg_sps[i_id]; |
405 | 263k | pp_active = (void**)&p_sys->p_active_sps; |
406 | 263k | break; |
407 | 200k | case HEVC_NAL_PPS: |
408 | 200k | if(i_id > HEVC_PPS_ID_MAX) |
409 | 0 | return false; |
410 | 200k | p_tuple = &p_sys->rg_pps[i_id]; |
411 | 200k | pp_active = (void**)&p_sys->p_active_pps; |
412 | 200k | break; |
413 | 0 | default: |
414 | 0 | return false; |
415 | 571k | } |
416 | | |
417 | | /* Check if we really need to re-decode/replace */ |
418 | 571k | if(p_tuple->p_nal) |
419 | 181k | { |
420 | 181k | const uint8_t *p_stored = p_tuple->p_nal->p_buffer; |
421 | 181k | size_t i_stored = p_tuple->p_nal->i_buffer; |
422 | 181k | hxxx_strip_AnnexB_startcode(&p_stored, &i_stored); |
423 | 181k | const uint8_t *p_new = p_nalb->p_buffer; |
424 | 181k | size_t i_new = p_nalb->i_buffer; |
425 | 181k | hxxx_strip_AnnexB_startcode(&p_new, &i_new); |
426 | 181k | if(i_stored == i_new && !memcmp(p_stored, p_new, i_new)) |
427 | 80.6k | return true; |
428 | 181k | } |
429 | | |
430 | | /* Free associated decoded version */ |
431 | 490k | if(p_tuple->p_decoded) |
432 | 101k | { |
433 | 101k | switch(i_nal_type) |
434 | 101k | { |
435 | 15.5k | case HEVC_NAL_VPS: |
436 | 15.5k | hevc_rbsp_release_vps(p_tuple->p_decoded); |
437 | 15.5k | break; |
438 | 52.2k | case HEVC_NAL_SPS: |
439 | 52.2k | hevc_rbsp_release_sps(p_tuple->p_decoded); |
440 | 52.2k | break; |
441 | 33.6k | case HEVC_NAL_PPS: |
442 | 33.6k | hevc_rbsp_release_pps(p_tuple->p_decoded); |
443 | 33.6k | break; |
444 | 101k | } |
445 | 101k | if(*pp_active == p_tuple->p_decoded) |
446 | 49.2k | *pp_active = NULL; |
447 | 52.0k | else |
448 | 52.0k | pp_active = NULL; /* don't change pointer */ |
449 | 101k | p_tuple->p_decoded = NULL; |
450 | 101k | } |
451 | 389k | else pp_active = NULL; |
452 | | |
453 | | /* Free raw stored version */ |
454 | 490k | if(p_tuple->p_nal) |
455 | 101k | { |
456 | 101k | block_Release(p_tuple->p_nal); |
457 | 101k | p_tuple->p_nal = NULL; |
458 | 101k | } |
459 | | |
460 | 490k | const uint8_t *p_buffer = p_nalb->p_buffer; |
461 | 490k | size_t i_buffer = p_nalb->i_buffer; |
462 | 490k | if( hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) ) |
463 | 490k | { |
464 | | /* Create decoded entries */ |
465 | 490k | switch(i_nal_type) |
466 | 490k | { |
467 | 252k | case HEVC_NAL_SPS: |
468 | 252k | p_tuple->p_decoded = hevc_decode_sps(p_buffer, i_buffer, true); |
469 | 252k | if(!p_tuple->p_decoded) |
470 | 196k | { |
471 | 196k | msg_Err(p_dec, "Failed decoding SPS id %d", i_id); |
472 | 196k | return false; |
473 | 196k | } |
474 | 56.2k | break; |
475 | 137k | case HEVC_NAL_PPS: |
476 | 137k | p_tuple->p_decoded = hevc_decode_pps(p_buffer, i_buffer, true); |
477 | 137k | if(!p_tuple->p_decoded) |
478 | 96.2k | { |
479 | 96.2k | msg_Err(p_dec, "Failed decoding PPS id %d", i_id); |
480 | 96.2k | return false; |
481 | 96.2k | } |
482 | 41.0k | break; |
483 | 101k | case HEVC_NAL_VPS: |
484 | 101k | p_tuple->p_decoded = hevc_decode_vps(p_buffer, i_buffer, true); |
485 | 101k | if(!p_tuple->p_decoded) |
486 | 81.5k | { |
487 | 81.5k | msg_Err(p_dec, "Failed decoding VPS id %d", i_id); |
488 | 81.5k | return false; |
489 | 81.5k | } |
490 | 19.6k | break; |
491 | 490k | } |
492 | | |
493 | 117k | if(p_tuple->p_decoded && pp_active) /* restore active by id */ |
494 | 32.6k | *pp_active = p_tuple->p_decoded; |
495 | | |
496 | 117k | p_tuple->p_nal = block_Duplicate((block_t *)p_nalb); |
497 | | |
498 | 117k | return true; |
499 | 490k | } |
500 | | |
501 | 0 | return false; |
502 | 490k | } |
503 | | |
504 | | static block_t *GetXPSCopy(decoder_sys_t *p_sys) |
505 | 23.9k | { |
506 | 23.9k | block_t *p_chain = NULL; |
507 | 23.9k | block_t **pp_append = &p_chain; |
508 | 23.9k | struct hevc_tuple_s *xpstype[3] = {p_sys->rg_vps, p_sys->rg_sps, p_sys->rg_pps}; |
509 | 23.9k | size_t xpsmax[3] = {HEVC_MAX_NUM_VPS, HEVC_MAX_NUM_SPS, HEVC_MAX_NUM_PPS}; |
510 | 95.9k | for(size_t i=0; i<3; i++) |
511 | 71.9k | { |
512 | 71.9k | struct hevc_tuple_s *xps = xpstype[i]; |
513 | 2.37M | for(size_t j=0; j<xpsmax[i]; j++) |
514 | 2.30M | { |
515 | 2.30M | block_t *p_dup; |
516 | 2.30M | if(xps[j].p_nal && |
517 | 68.1k | (p_dup = block_Duplicate(xps[j].p_nal))) |
518 | 68.1k | block_ChainLastAppend(&pp_append, p_dup); |
519 | 2.30M | }; |
520 | 71.9k | } |
521 | 23.9k | return p_chain; |
522 | 23.9k | } |
523 | | |
524 | | static bool XPSReady(decoder_sys_t *p_sys) |
525 | 98.3k | { |
526 | 6.19M | for(unsigned i=0;i<HEVC_MAX_NUM_PPS; i++) |
527 | 6.10M | { |
528 | 6.10M | const hevc_picture_parameter_set_t *p_pps = p_sys->rg_pps[i].p_decoded; |
529 | 6.10M | if (p_pps) |
530 | 34.7k | { |
531 | 34.7k | uint8_t id_sps = hevc_get_pps_sps_id(p_pps); |
532 | 34.7k | const hevc_sequence_parameter_set_t *p_sps = p_sys->rg_sps[id_sps].p_decoded; |
533 | 34.7k | if(p_sps) |
534 | 9.42k | { |
535 | 9.42k | uint8_t id_vps = hevc_get_sps_vps_id(p_sps); |
536 | 9.42k | if(p_sys->rg_vps[id_vps].p_decoded) |
537 | 3.18k | return true; |
538 | 9.42k | } |
539 | 34.7k | } |
540 | 6.10M | } |
541 | 95.1k | return false; |
542 | 98.3k | } |
543 | | |
544 | | static void AppendAsAnnexB(const block_t *p_block, |
545 | | uint8_t **pp_dst, size_t *pi_dst) |
546 | 6.74k | { |
547 | 6.74k | if(SIZE_MAX - p_block->i_buffer < *pi_dst ) |
548 | 0 | return; |
549 | | |
550 | 6.74k | size_t i_realloc = p_block->i_buffer + *pi_dst; |
551 | 6.74k | uint8_t *p_realloc = realloc(*pp_dst, i_realloc); |
552 | 6.74k | if(p_realloc) |
553 | 6.74k | { |
554 | 6.74k | memcpy(&p_realloc[*pi_dst], p_block->p_buffer, p_block->i_buffer); |
555 | 6.74k | *pi_dst = i_realloc; |
556 | 6.74k | *pp_dst = p_realloc; |
557 | 6.74k | } |
558 | 6.74k | } |
559 | | |
560 | | #define APPENDIF(maxcount, set, rg, b) \ |
561 | 172k | for(size_t i=0; i<maxcount; i++)\ |
562 | 167k | {\ |
563 | 167k | if(((set != rg[i].p_decoded) == !b) && rg[i].p_nal)\ |
564 | 167k | {\ |
565 | 6.74k | AppendAsAnnexB(rg[i].p_nal, &p_data, &i_data);\ |
566 | 6.74k | if(b) break;\ |
567 | 6.74k | }\ |
568 | 167k | } |
569 | | |
570 | | static void SetsToAnnexB(decoder_sys_t *p_sys, |
571 | | const hevc_picture_parameter_set_t *p_pps, |
572 | | const hevc_sequence_parameter_set_t *p_sps, |
573 | | const hevc_video_parameter_set_t *p_vps, |
574 | | uint8_t **pp_out, size_t *pi_out) |
575 | 1.65k | { |
576 | 1.65k | uint8_t *p_data = NULL; |
577 | 1.65k | size_t i_data = 0; |
578 | | |
579 | 1.65k | APPENDIF(HEVC_MAX_NUM_VPS, p_vps, p_sys->rg_vps, true); |
580 | 1.65k | APPENDIF(HEVC_MAX_NUM_VPS, p_vps, p_sys->rg_vps, false); |
581 | 1.65k | APPENDIF(HEVC_MAX_NUM_SPS, p_sps, p_sys->rg_sps, true); |
582 | 1.65k | APPENDIF(HEVC_MAX_NUM_SPS, p_sps, p_sys->rg_sps, false); |
583 | 1.65k | APPENDIF(HEVC_MAX_NUM_PPS, p_pps, p_sys->rg_pps, true); |
584 | 1.65k | APPENDIF(HEVC_MAX_NUM_PPS, p_pps, p_sys->rg_pps, false); |
585 | | |
586 | | /* because we copy to i_extra :/ */ |
587 | 1.65k | if(i_data <= INT_MAX) |
588 | 1.65k | { |
589 | 1.65k | *pp_out = p_data; |
590 | 1.65k | *pi_out = i_data; |
591 | 1.65k | } |
592 | 0 | else free(p_data); |
593 | 1.65k | } |
594 | | |
595 | | static void ActivateSets(decoder_t *p_dec, |
596 | | const hevc_picture_parameter_set_t *p_pps, |
597 | | const hevc_sequence_parameter_set_t *p_sps, |
598 | | const hevc_video_parameter_set_t *p_vps) |
599 | 94.7k | { |
600 | 94.7k | decoder_sys_t *p_sys = p_dec->p_sys; |
601 | 94.7k | p_sys->p_active_pps = p_pps; |
602 | 94.7k | p_sys->p_active_sps = p_sps; |
603 | 94.7k | p_sys->p_active_vps = p_vps; |
604 | 94.7k | if(p_sps) |
605 | 94.7k | { |
606 | 94.7k | if(!p_dec->fmt_out.video.i_frame_rate || !p_dec->fmt_out.video.i_frame_rate_base) |
607 | 2.04k | { |
608 | 2.04k | unsigned num, den; |
609 | 2.04k | if(hevc_get_frame_rate( p_sps, p_vps, &num, &den )) |
610 | 1.24k | { |
611 | 1.24k | p_dec->fmt_out.video.i_frame_rate = num; |
612 | 1.24k | p_dec->fmt_out.video.i_frame_rate_base = den; |
613 | 1.24k | if(num <= UINT_MAX / 2 && |
614 | 836 | (p_sys->dts.i_divider_den != den || |
615 | 30 | p_sys->dts.i_divider_num != 2 * num)) |
616 | 836 | { |
617 | 836 | date_Change(&p_sys->dts, 2 * num, den); |
618 | 836 | } |
619 | 1.24k | } |
620 | 2.04k | p_dec->fmt_out.video.i_frame_rate = p_sys->dts.i_divider_num >> 1; |
621 | 2.04k | p_dec->fmt_out.video.i_frame_rate_base = p_sys->dts.i_divider_den; |
622 | 2.04k | } |
623 | | |
624 | 94.7k | if(p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF) |
625 | 92.4k | { |
626 | 92.4k | (void) hevc_get_colorimetry( p_sps, |
627 | 92.4k | &p_dec->fmt_out.video.primaries, |
628 | 92.4k | &p_dec->fmt_out.video.transfer, |
629 | 92.4k | &p_dec->fmt_out.video.space, |
630 | 92.4k | &p_dec->fmt_out.video.color_range); |
631 | 92.4k | } |
632 | | |
633 | 94.7k | unsigned sizes[6]; |
634 | 94.7k | if( hevc_get_picture_size( p_sps, &sizes[0], &sizes[1], |
635 | 94.7k | &sizes[2], &sizes[3], |
636 | 94.7k | &sizes[4], &sizes[5] ) ) |
637 | 87.5k | { |
638 | 87.5k | p_dec->fmt_out.video.i_width = sizes[2]; |
639 | 87.5k | p_dec->fmt_out.video.i_height = sizes[3]; |
640 | 87.5k | if(p_dec->fmt_in->video.i_visible_width == 0) |
641 | 60.9k | { |
642 | 60.9k | p_dec->fmt_out.video.i_x_offset = sizes[0]; |
643 | 60.9k | p_dec->fmt_out.video.i_y_offset = sizes[1]; |
644 | 60.9k | p_dec->fmt_out.video.i_visible_width = sizes[4]; |
645 | 60.9k | p_dec->fmt_out.video.i_visible_height = sizes[5]; |
646 | 60.9k | } |
647 | 87.5k | } |
648 | | |
649 | 94.7k | if ( p_dec->fmt_in->video.i_sar_num == 0 || p_dec->fmt_in->video.i_sar_den == 0) |
650 | 87.4k | { |
651 | 87.4k | unsigned num, den; |
652 | 87.4k | if ( hevc_get_aspect_ratio( p_sps, &num, &den ) ) |
653 | 5.97k | { |
654 | 5.97k | p_dec->fmt_out.video.i_sar_num = num; |
655 | 5.97k | p_dec->fmt_out.video.i_sar_den = den; |
656 | 5.97k | } |
657 | 87.4k | } |
658 | | |
659 | 94.7k | if(p_dec->fmt_in->i_profile == -1) |
660 | 67.1k | { |
661 | 67.1k | uint8_t i_profile, i_level; |
662 | 67.1k | if( hevc_get_sps_profile_tier_level( p_sps, &i_profile, &i_level ) ) |
663 | 65.2k | { |
664 | 65.2k | p_dec->fmt_out.i_profile = i_profile; |
665 | 65.2k | p_dec->fmt_out.i_level = i_level; |
666 | 65.2k | } |
667 | 67.1k | } |
668 | | |
669 | 94.7k | if(p_dec->fmt_out.i_extra == 0 && p_vps && p_pps) |
670 | 1.65k | SetsToAnnexB(p_sys, p_pps, p_sps, p_vps, |
671 | 1.65k | (uint8_t **)&p_dec->fmt_out.p_extra, &p_dec->fmt_out.i_extra); |
672 | 94.7k | } |
673 | 94.7k | } |
674 | | |
675 | | static void GetXPSSet(uint8_t i_pps_id, void *priv, |
676 | | hevc_picture_parameter_set_t **pp_pps, |
677 | | hevc_sequence_parameter_set_t **pp_sps, |
678 | | hevc_video_parameter_set_t **pp_vps) |
679 | 403k | { |
680 | 403k | decoder_sys_t *p_sys = priv; |
681 | 403k | *pp_sps = NULL; |
682 | 403k | *pp_vps = NULL; |
683 | 403k | if((*pp_pps = p_sys->rg_pps[i_pps_id].p_decoded)) |
684 | 327k | if((*pp_sps = p_sys->rg_sps[hevc_get_pps_sps_id(*pp_pps)].p_decoded)) |
685 | 269k | *pp_vps = p_sys->rg_vps[hevc_get_sps_vps_id(*pp_sps)].p_decoded; |
686 | 403k | } |
687 | | |
688 | | static void ParseStoredSEI( decoder_t *p_dec ) |
689 | 2.68M | { |
690 | 2.68M | decoder_sys_t *p_sys = p_dec->p_sys; |
691 | | |
692 | 2.68M | for( block_t *p_nal = p_sys->pre.p_chain; |
693 | 2.91M | p_nal; p_nal = p_nal->p_next ) |
694 | 233k | { |
695 | 233k | if( p_nal->i_buffer < 5 ) |
696 | 0 | continue; |
697 | | |
698 | 233k | if( hevc_getNALType(&p_nal->p_buffer[4]) == HEVC_NAL_PREF_SEI ) |
699 | 3.83k | { |
700 | 3.83k | HxxxParse_AnnexB_SEI( p_nal->p_buffer, p_nal->i_buffer, |
701 | 3.83k | 2 /* nal header */, ParseSEICallback, p_dec ); |
702 | 3.83k | } |
703 | 233k | } |
704 | 2.68M | } |
705 | | |
706 | | static block_t *ParseVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag) |
707 | 3.06M | { |
708 | 3.06M | decoder_sys_t *p_sys = p_dec->p_sys; |
709 | 3.06M | block_t *p_outputchain = NULL; |
710 | | |
711 | 3.06M | const uint8_t *p_buffer = p_frag->p_buffer; |
712 | 3.06M | size_t i_buffer = p_frag->i_buffer; |
713 | | |
714 | 3.06M | if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buffer, &i_buffer) || i_buffer < 3)) |
715 | 118k | { |
716 | 118k | block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag); /* might be corrupted */ |
717 | 118k | return NULL; |
718 | 118k | } |
719 | | |
720 | 2.94M | const uint8_t i_layer = hevc_getNALLayer( p_buffer ); |
721 | 2.94M | bool b_first_slice_in_pic = p_buffer[2] & 0x80; |
722 | 2.94M | if (b_first_slice_in_pic) |
723 | 2.68M | { |
724 | 2.68M | if(p_sys->frame.p_chain) |
725 | 2.54M | { |
726 | | /* Starting new frame: return previous frame data for output */ |
727 | 2.54M | p_outputchain = OutputQueues(p_sys, p_sys->sets != MISSING && |
728 | 2.50M | p_sys->b_recovery_point); |
729 | 2.54M | } |
730 | | |
731 | 2.68M | hevc_slice_segment_header_t *p_sli = hevc_decode_slice_header(p_buffer, i_buffer, true, |
732 | 2.68M | GetXPSSet, p_sys); |
733 | 2.68M | if(p_sli && i_layer == 0) |
734 | 94.7k | { |
735 | 94.7k | hevc_sequence_parameter_set_t *p_sps; |
736 | 94.7k | hevc_picture_parameter_set_t *p_pps; |
737 | 94.7k | hevc_video_parameter_set_t *p_vps; |
738 | 94.7k | GetXPSSet(hevc_get_slice_pps_id(p_sli), p_sys, &p_pps, &p_sps, &p_vps); |
739 | 94.7k | ActivateSets(p_dec, p_pps, p_sps, p_vps); |
740 | 94.7k | } |
741 | | |
742 | 2.68M | ParseStoredSEI( p_dec ); |
743 | | |
744 | 2.68M | switch(i_nal_type) |
745 | 2.68M | { |
746 | 1.19k | case HEVC_NAL_BLA_W_LP: |
747 | 1.49k | case HEVC_NAL_BLA_W_RADL: |
748 | 97.8k | case HEVC_NAL_BLA_N_LP: |
749 | 114k | case HEVC_NAL_IDR_W_RADL: |
750 | 116k | case HEVC_NAL_IDR_N_LP: |
751 | 2.45M | case HEVC_NAL_CRA: |
752 | 2.45M | p_frag->i_flags |= BLOCK_FLAG_TYPE_I; |
753 | 2.45M | break; |
754 | | |
755 | 233k | default: |
756 | 233k | { |
757 | 233k | if(p_sli) |
758 | 40.0k | { |
759 | 40.0k | enum hevc_slice_type_e type; |
760 | 40.0k | if(hevc_get_slice_type( p_sli, &type )) |
761 | 40.0k | { |
762 | 40.0k | switch(type) |
763 | 40.0k | { |
764 | 37.5k | case HEVC_SLICE_TYPE_B: |
765 | 37.5k | p_frag->i_flags |= BLOCK_FLAG_TYPE_B; |
766 | 37.5k | break; |
767 | 468 | case HEVC_SLICE_TYPE_P: |
768 | 468 | p_frag->i_flags |= BLOCK_FLAG_TYPE_P; |
769 | 468 | break; |
770 | 2.02k | case HEVC_SLICE_TYPE_I: |
771 | 2.02k | p_frag->i_flags |= BLOCK_FLAG_TYPE_I; |
772 | 2.02k | break; |
773 | 40.0k | } |
774 | 40.0k | } |
775 | 40.0k | } |
776 | 193k | else p_frag->i_flags |= BLOCK_FLAG_TYPE_B; |
777 | 233k | } |
778 | 233k | break; |
779 | 2.68M | } |
780 | | |
781 | 2.68M | if(p_sli) |
782 | 102k | hevc_rbsp_release_slice_header(p_sli); |
783 | 2.68M | } |
784 | | |
785 | 2.94M | if(p_sys->sets == MISSING && i_layer == 0 && XPSReady(p_sys)) |
786 | 3.18k | p_sys->sets = COMPLETE; |
787 | | |
788 | 2.94M | if(p_sys->sets != MISSING && (p_frag->i_flags & BLOCK_FLAG_TYPE_I)) |
789 | 2.42M | { |
790 | 2.42M | p_sys->b_recovery_point = true; /* won't care about SEI recovery */ |
791 | 2.42M | } |
792 | | |
793 | 2.94M | if(!p_sys->b_recovery_point) /* content will be dropped */ |
794 | 226k | cc_storage_reset(p_sys->p_ccs); |
795 | | |
796 | 2.94M | block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag); |
797 | | |
798 | 2.94M | return p_outputchain; |
799 | 2.94M | } |
800 | | |
801 | | static block_t * ParseAUHead(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb) |
802 | 687k | { |
803 | 687k | decoder_sys_t *p_sys = p_dec->p_sys; |
804 | 687k | block_t *p_ret = NULL; |
805 | | |
806 | 687k | if(p_sys->post.p_chain || p_sys->frame.p_chain) |
807 | 200k | p_ret = OutputQueues(p_sys, p_sys->sets != MISSING && |
808 | 134k | p_sys->b_recovery_point); |
809 | | |
810 | 687k | switch(i_nal_type) |
811 | 687k | { |
812 | 8.06k | case HEVC_NAL_AUD: |
813 | 8.06k | if(!p_ret && p_sys->pre.p_chain) |
814 | 3.90k | p_ret = OutputQueues(p_sys, p_sys->sets != MISSING && |
815 | 1.59k | p_sys->b_recovery_point); |
816 | 8.06k | break; |
817 | | |
818 | 114k | case HEVC_NAL_VPS: |
819 | 381k | case HEVC_NAL_SPS: |
820 | 591k | case HEVC_NAL_PPS: |
821 | 591k | { |
822 | 591k | uint8_t i_id; |
823 | 591k | const uint8_t *p_xps = p_nalb->p_buffer; |
824 | 591k | size_t i_xps = p_nalb->i_buffer; |
825 | 591k | if(hxxx_strip_AnnexB_startcode(&p_xps, &i_xps) && |
826 | 591k | hevc_get_xps_id(p_xps, i_xps, &i_id)) |
827 | 571k | InsertXPS(p_dec, i_nal_type, i_id, p_nalb); |
828 | 591k | if(p_sys->sets != SENT) /* will store/inject on first recovery point */ |
829 | 341k | { |
830 | 341k | block_Release(p_nalb); |
831 | 341k | return p_ret; |
832 | 341k | } |
833 | 250k | break; |
834 | 591k | } |
835 | | |
836 | 250k | case HEVC_NAL_PREF_SEI: |
837 | | /* stored an parsed later when we get sps & frame */ |
838 | 87.9k | default: |
839 | 87.9k | break; |
840 | 687k | } |
841 | | |
842 | 346k | block_ChainLastAppend(&p_sys->pre.pp_chain_last, p_nalb); |
843 | | |
844 | 346k | return p_ret; |
845 | 687k | } |
846 | | |
847 | | static block_t * ParseAUTail(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb) |
848 | 170k | { |
849 | 170k | decoder_sys_t *p_sys = p_dec->p_sys; |
850 | 170k | block_t *p_ret = NULL; |
851 | | |
852 | 170k | block_ChainLastAppend(&p_sys->post.pp_chain_last, p_nalb); |
853 | | |
854 | 170k | switch(i_nal_type) |
855 | 170k | { |
856 | 8.52k | case HEVC_NAL_EOS: |
857 | 43.4k | case HEVC_NAL_EOB: |
858 | 43.4k | p_ret = OutputQueues(p_sys, p_sys->sets != MISSING && |
859 | 35.7k | p_sys->b_recovery_point); |
860 | 43.4k | if( p_ret ) |
861 | 43.4k | p_ret->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE; |
862 | 43.4k | break; |
863 | | |
864 | 105k | case HEVC_NAL_SUFF_SEI: |
865 | 105k | HxxxParse_AnnexB_SEI( p_nalb->p_buffer, p_nalb->i_buffer, |
866 | 105k | 2 /* nal header */, ParseSEICallback, p_dec ); |
867 | 105k | break; |
868 | 170k | } |
869 | | |
870 | 170k | if(!p_ret && p_sys->frame.p_chain == NULL) |
871 | 59.2k | p_ret = OutputQueues(p_sys, false); |
872 | | |
873 | 170k | return p_ret; |
874 | 170k | } |
875 | | |
876 | | static block_t * ParseNonVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb) |
877 | 857k | { |
878 | 857k | block_t *p_ret = NULL; |
879 | | |
880 | 857k | if ( (i_nal_type >= HEVC_NAL_VPS && i_nal_type <= HEVC_NAL_AUD) || |
881 | 258k | i_nal_type == HEVC_NAL_PREF_SEI || |
882 | 246k | (i_nal_type >= HEVC_NAL_RSV_NVCL41 && i_nal_type <= HEVC_NAL_RSV_NVCL44) || |
883 | 236k | (i_nal_type >= HEVC_NAL_UNSPEC48 && i_nal_type <= HEVC_NAL_UNSPEC55) ) |
884 | 687k | { |
885 | 687k | p_ret = ParseAUHead(p_dec, i_nal_type, p_nalb); |
886 | 687k | } |
887 | 170k | else |
888 | 170k | { |
889 | 170k | p_ret = ParseAUTail(p_dec, i_nal_type, p_nalb); |
890 | 170k | } |
891 | | |
892 | 857k | return p_ret; |
893 | 857k | } |
894 | | |
895 | | static block_t *GatherAndValidateChain(block_t *p_outputchain) |
896 | 4.11M | { |
897 | 4.11M | block_t *p_output = NULL; |
898 | | |
899 | 4.11M | if(p_outputchain) |
900 | 2.91M | { |
901 | 2.91M | if(p_outputchain->i_flags & BLOCK_FLAG_DROP) |
902 | 251k | p_output = p_outputchain; /* Avoid useless gather */ |
903 | 2.66M | else |
904 | 2.66M | p_output = block_ChainGather(p_outputchain); |
905 | 2.91M | } |
906 | | |
907 | 4.11M | if(p_output && (p_output->i_flags & BLOCK_FLAG_DROP)) |
908 | 251k | { |
909 | 251k | block_ChainRelease(p_output); /* Chain! see above */ |
910 | 251k | p_output = NULL; |
911 | 251k | } |
912 | | |
913 | 4.11M | return p_output; |
914 | 4.11M | } |
915 | | |
916 | | static void SetOutputBlockProperties(decoder_t *p_dec, block_t *p_output) |
917 | 2.66M | { |
918 | 2.66M | decoder_sys_t *p_sys = p_dec->p_sys; |
919 | | /* Set frame duration */ |
920 | 2.66M | if(p_sys->p_active_sps) |
921 | 840k | { |
922 | 840k | uint8_t i_num_clock_ts = hevc_get_num_clock_ts(p_sys->p_active_sps, |
923 | 840k | p_sys->p_timing); |
924 | 840k | const vlc_tick_t i_start = date_Get(&p_sys->dts); |
925 | 840k | if( i_start != VLC_TICK_INVALID ) |
926 | 839k | { |
927 | 839k | date_Increment(&p_sys->dts, i_num_clock_ts); |
928 | 839k | p_output->i_length = date_Get(&p_sys->dts) - i_start; |
929 | 839k | } |
930 | 840k | p_sys->pts = VLC_TICK_INVALID; |
931 | 840k | } |
932 | 2.66M | p_output->i_flags &= ~BLOCK_FLAG_AU_END; |
933 | 2.66M | hevc_release_sei_pic_timing(p_sys->p_timing); |
934 | 2.66M | p_sys->p_timing = NULL; |
935 | 2.66M | } |
936 | | |
937 | | /***************************************************************************** |
938 | | * ParseNALBlock: parses annexB type NALs |
939 | | * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode |
940 | | *****************************************************************************/ |
941 | | static block_t *ParseNALBlock(decoder_t *p_dec, bool *pb_ts_used, block_t *p_frag) |
942 | 4.11M | { |
943 | 4.11M | decoder_sys_t *p_sys = p_dec->p_sys; |
944 | 4.11M | *pb_ts_used = false; |
945 | 4.11M | bool b_au_end = p_frag->i_flags & BLOCK_FLAG_AU_END; |
946 | | |
947 | 4.11M | if(p_sys->b_need_ts) |
948 | 284k | { |
949 | 284k | if(p_frag->i_dts != VLC_TICK_INVALID) |
950 | 13.6k | date_Set(&p_sys->dts, p_frag->i_dts); |
951 | 284k | p_sys->pts = p_frag->i_pts; |
952 | 284k | if(date_Get( &p_sys->dts ) != VLC_TICK_INVALID) |
953 | 13.6k | p_sys->b_need_ts = false; |
954 | 284k | *pb_ts_used = true; |
955 | 284k | } |
956 | | |
957 | 4.11M | if(unlikely(p_frag->i_buffer < 5)) |
958 | 0 | { |
959 | 0 | msg_Warn(p_dec,"NAL too small"); |
960 | 0 | block_Release(p_frag); |
961 | 0 | return NULL; |
962 | 0 | } |
963 | | |
964 | 4.11M | if(p_frag->p_buffer[4] & 0x80) |
965 | 193k | { |
966 | 193k | msg_Warn(p_dec,"Forbidden zero bit not null, corrupted NAL"); |
967 | 193k | block_Release(p_frag); |
968 | 193k | return GatherAndValidateChain(OutputQueues(p_sys, false)); /* will drop */ |
969 | 193k | } |
970 | | |
971 | | /* Get NALU type */ |
972 | 3.92M | const vlc_tick_t dts = p_frag->i_dts, pts = p_frag->i_pts; |
973 | 3.92M | block_t * p_output = NULL; |
974 | 3.92M | uint8_t i_nal_type = hevc_getNALType(&p_frag->p_buffer[4]); |
975 | | |
976 | 3.92M | if (i_nal_type < HEVC_NAL_VPS) |
977 | 3.06M | { |
978 | | /* NAL is a VCL NAL */ |
979 | 3.06M | p_output = ParseVCL(p_dec, i_nal_type, p_frag); |
980 | 3.06M | if (p_output && (p_output->i_flags & BLOCK_FLAG_DROP)) |
981 | 3.06M | msg_Info(p_dec, "Waiting for VPS/SPS/PPS"); |
982 | 3.06M | } |
983 | 857k | else |
984 | 857k | { |
985 | 857k | p_output = ParseNonVCL(p_dec, i_nal_type, p_frag); |
986 | 857k | } |
987 | | |
988 | 3.92M | if( !p_output && b_au_end ) |
989 | 0 | p_output = OutputQueues(p_sys, p_sys->sets != MISSING && |
990 | 0 | p_sys->b_recovery_point); |
991 | | |
992 | 3.92M | p_output = GatherAndValidateChain(p_output); |
993 | 3.92M | if(p_output) |
994 | 2.66M | { |
995 | 2.66M | if(p_sys->sets != SENT) |
996 | 2.40k | { |
997 | 2.40k | assert(p_sys->sets == COMPLETE); |
998 | 2.40k | p_sys->sets = SENT; |
999 | 2.40k | } |
1000 | | |
1001 | 2.66M | SetOutputBlockProperties( p_dec, p_output ); |
1002 | 2.66M | if (dts != VLC_TICK_INVALID) |
1003 | 2.62M | date_Set(&p_sys->dts, dts); |
1004 | 2.66M | p_sys->pts = pts; |
1005 | 2.66M | *pb_ts_used = true; |
1006 | 2.66M | } |
1007 | | |
1008 | 3.92M | return p_output; |
1009 | 3.92M | } |
1010 | | |
1011 | | static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *p_block) |
1012 | 4.11M | { |
1013 | 4.11M | decoder_t *p_dec = p_private; |
1014 | 4.11M | decoder_sys_t *p_sys = p_dec->p_sys; |
1015 | | |
1016 | | /* Remove trailing 0 bytes */ |
1017 | 12.7M | while (p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 ) |
1018 | 8.65M | p_block->i_buffer--; |
1019 | | |
1020 | 4.11M | p_block = ParseNALBlock( p_dec, pb_ts_used, p_block ); |
1021 | 4.11M | if( p_block ) |
1022 | 2.66M | cc_storage_commit( p_sys->p_ccs, p_block ); |
1023 | | |
1024 | 4.11M | return p_block; |
1025 | 4.11M | } |
1026 | | |
1027 | | static int PacketizeValidate( void *p_private, block_t *p_au ) |
1028 | 2.66M | { |
1029 | 2.66M | VLC_UNUSED(p_private); |
1030 | 2.66M | VLC_UNUSED(p_au); |
1031 | 2.66M | return VLC_SUCCESS; |
1032 | 2.66M | } |
1033 | | |
1034 | | static block_t * PacketizeDrain(void *p_private) |
1035 | 21.8k | { |
1036 | 21.8k | decoder_t *p_dec = p_private; |
1037 | 21.8k | decoder_sys_t *p_sys = p_dec->p_sys; |
1038 | | |
1039 | 21.8k | block_t *p_out = NULL; |
1040 | | |
1041 | 21.8k | if( p_sys->frame.p_chain && |
1042 | 4.79k | p_sys->sets != MISSING && |
1043 | 2.90k | p_sys->b_recovery_point ) |
1044 | 2.81k | { |
1045 | 2.81k | p_out = OutputQueues(p_sys, true); |
1046 | 2.81k | if( p_out ) |
1047 | 2.81k | { |
1048 | 2.81k | p_out = GatherAndValidateChain(p_out); |
1049 | 2.81k | if( p_out ) |
1050 | 2.81k | SetOutputBlockProperties( p_dec, p_out ); |
1051 | 2.81k | } |
1052 | 2.81k | } |
1053 | 21.8k | return p_out; |
1054 | 21.8k | } |
1055 | | |
1056 | | static bool ParseSEICallback( const hxxx_sei_data_t *p_sei_data, void *cbdata ) |
1057 | 23.9k | { |
1058 | 23.9k | decoder_t *p_dec = (decoder_t *) cbdata; |
1059 | 23.9k | decoder_sys_t *p_sys = p_dec->p_sys; |
1060 | | |
1061 | 23.9k | switch( p_sei_data->i_type ) |
1062 | 23.9k | { |
1063 | 5.08k | case HXXX_SEI_PIC_TIMING: |
1064 | 5.08k | { |
1065 | 5.08k | if( p_sys->p_active_sps ) |
1066 | 2.95k | { |
1067 | 2.95k | hevc_release_sei_pic_timing( p_sys->p_timing ); |
1068 | 2.95k | p_sys->p_timing = hevc_decode_sei_pic_timing( p_sei_data->p_bs, |
1069 | 2.95k | p_sys->p_active_sps ); |
1070 | 2.95k | } |
1071 | 5.08k | } break; |
1072 | 14.8k | case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35: |
1073 | 14.8k | { |
1074 | 14.8k | if( p_sei_data->itu_t35.type == HXXX_ITU_T35_TYPE_CC ) |
1075 | 14.8k | { |
1076 | 14.8k | cc_storage_append( p_sys->p_ccs, true, p_sei_data->itu_t35.u.cc.p_data, |
1077 | 14.8k | p_sei_data->itu_t35.u.cc.i_data ); |
1078 | 14.8k | } |
1079 | 14.8k | } break; |
1080 | 2.30k | case HXXX_SEI_RECOVERY_POINT: |
1081 | 2.30k | { |
1082 | 2.30k | hevc_sei_recovery_point_t reco; |
1083 | 2.30k | if( !p_sys->b_recovery_point && |
1084 | 441 | hevc_decode_sei_recovery_point( p_sei_data->p_bs, &reco ) ) |
1085 | 441 | { |
1086 | 441 | msg_Dbg( p_dec, "Seen SEI recovery point, %d recovery frames", reco.i_frames ); |
1087 | 441 | p_sys->b_recovery_point = true; |
1088 | 441 | } |
1089 | 2.30k | } break; |
1090 | 0 | case HXXX_SEI_FRAME_PACKING_ARRANGEMENT: |
1091 | 0 | { |
1092 | 0 | if( p_dec->fmt_in->video.multiview_mode == MULTIVIEW_2D ) |
1093 | 0 | { |
1094 | 0 | video_multiview_mode_t mode; |
1095 | 0 | switch( p_sei_data->frame_packing.type ) |
1096 | 0 | { |
1097 | 0 | case FRAME_PACKING_INTERLEAVED_CHECKERBOARD: |
1098 | 0 | mode = MULTIVIEW_STEREO_CHECKERBOARD; break; |
1099 | 0 | case FRAME_PACKING_INTERLEAVED_COLUMN: |
1100 | 0 | mode = MULTIVIEW_STEREO_COL; break; |
1101 | 0 | case FRAME_PACKING_INTERLEAVED_ROW: |
1102 | 0 | mode = MULTIVIEW_STEREO_ROW; break; |
1103 | 0 | case FRAME_PACKING_SIDE_BY_SIDE: |
1104 | 0 | mode = MULTIVIEW_STEREO_SBS; break; |
1105 | 0 | case FRAME_PACKING_TOP_BOTTOM: |
1106 | 0 | mode = MULTIVIEW_STEREO_TB; break; |
1107 | 0 | case FRAME_PACKING_TEMPORAL: |
1108 | 0 | mode = MULTIVIEW_STEREO_FRAME; break; |
1109 | 0 | case FRAME_PACKING_TILED: |
1110 | 0 | default: |
1111 | 0 | mode = MULTIVIEW_2D; break; |
1112 | 0 | } |
1113 | 0 | p_dec->fmt_out.video.multiview_mode = mode; |
1114 | 0 | } |
1115 | 0 | } break; |
1116 | 865 | case HXXX_SEI_MASTERING_DISPLAY_COLOUR_VOLUME: |
1117 | 865 | { |
1118 | 865 | video_format_t *p_fmt = &p_dec->fmt_out.video; |
1119 | 6.05k | for (size_t i=0; i<ARRAY_SIZE(p_sei_data->colour_volume.primaries); ++i) |
1120 | 5.19k | p_fmt->mastering.primaries[i] = p_sei_data->colour_volume.primaries[i]; |
1121 | 2.59k | for (size_t i=0; i<ARRAY_SIZE(p_sei_data->colour_volume.white_point); ++i) |
1122 | 1.73k | p_fmt->mastering.white_point[i] = p_sei_data->colour_volume.white_point[i]; |
1123 | 865 | p_fmt->mastering.max_luminance = p_sei_data->colour_volume.max_luminance; |
1124 | 865 | p_fmt->mastering.min_luminance = p_sei_data->colour_volume.min_luminance; |
1125 | 865 | } break; |
1126 | 887 | case HXXX_SEI_CONTENT_LIGHT_LEVEL: |
1127 | 887 | { |
1128 | 887 | video_format_t *p_fmt = &p_dec->fmt_out.video; |
1129 | 887 | p_fmt->lighting.MaxCLL = p_sei_data->content_light_lvl.MaxCLL; |
1130 | 887 | p_fmt->lighting.MaxFALL = p_sei_data->content_light_lvl.MaxFALL; |
1131 | 887 | } break; |
1132 | 23.9k | } |
1133 | | |
1134 | 23.9k | return true; |
1135 | 23.9k | } |