/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 | 116 | vlc_module_begin () |
54 | 58 | set_subcategory(SUBCAT_SOUT_PACKETIZER) |
55 | 58 | set_description(N_("HEVC/H.265 video packetizer")) |
56 | 58 | set_capability("video packetizer", 50) |
57 | 116 | set_callbacks(Open, Close) |
58 | 58 | 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 | 2.41k | { |
117 | 2.41k | return ParseNALBlock( (decoder_t *) opaque, pb_ts_used, p_frag ); |
118 | 2.41k | } |
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 | 48.1M | #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 | 17.8M | { |
132 | 17.8M | *pp_head = NULL; |
133 | 17.8M | *ppp_tail = pp_head; |
134 | 17.8M | } |
135 | 17.8M | #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 | 17.0M | { |
139 | 17.0M | block_t *p_output = NULL; |
140 | 17.0M | block_t *p_xps = NULL; |
141 | 17.0M | block_t **pp_output_last = &p_output; |
142 | 17.0M | uint32_t i_flags = 0; /* Because block_ChainGather does not merge flags or times */ |
143 | | |
144 | 17.0M | if(p_sys->b_recovery_point && p_sys->sets != SENT) |
145 | 207k | p_xps = GetXPSCopy(p_sys); |
146 | | |
147 | 17.0M | if(p_sys->pre.p_chain) |
148 | 2.99M | { |
149 | 2.99M | i_flags |= p_sys->pre.p_chain->i_flags; |
150 | | |
151 | 2.99M | if(p_sys->pre.p_chain->i_buffer >= 5 && |
152 | 2.99M | hevc_getNALType(&p_sys->pre.p_chain->p_buffer[4]) == HEVC_NAL_AUD) |
153 | 913k | { |
154 | 913k | block_t *p_au = p_sys->pre.p_chain; |
155 | 913k | p_sys->pre.p_chain = p_sys->pre.p_chain->p_next; |
156 | 913k | p_au->p_next = NULL; |
157 | 913k | block_ChainLastAppend(&pp_output_last, p_au); |
158 | 913k | } |
159 | | |
160 | 2.99M | if(p_xps) |
161 | 16.5k | block_ChainLastAppend(&pp_output_last, p_xps); |
162 | | |
163 | 2.99M | if(p_sys->pre.p_chain) |
164 | 2.71M | block_ChainLastAppend(&pp_output_last, p_sys->pre.p_chain); |
165 | 2.99M | INITQ(pre); |
166 | 2.99M | } |
167 | 14.0M | else if(p_xps) |
168 | 106k | { |
169 | 106k | block_ChainLastAppend(&pp_output_last, p_xps); |
170 | 106k | } |
171 | | |
172 | 17.0M | if(p_sys->frame.p_chain) |
173 | 7.90M | { |
174 | 7.90M | i_flags |= p_sys->frame.p_chain->i_flags; |
175 | 7.90M | block_ChainLastAppend(&pp_output_last, p_sys->frame.p_chain); |
176 | 7.90M | p_output->i_dts = date_Get(&p_sys->dts); |
177 | 7.90M | p_output->i_pts = p_sys->pts; |
178 | 7.90M | INITQ(frame); |
179 | 7.90M | } |
180 | | |
181 | 17.0M | if(p_sys->post.p_chain) |
182 | 6.91M | { |
183 | 6.91M | i_flags |= p_sys->post.p_chain->i_flags; |
184 | 6.91M | block_ChainLastAppend(&pp_output_last, p_sys->post.p_chain); |
185 | 6.91M | INITQ(post); |
186 | 6.91M | } |
187 | | |
188 | 17.0M | if(p_output) |
189 | 15.7M | { |
190 | 15.7M | p_output->i_flags |= i_flags; |
191 | 15.7M | if(!b_valid) |
192 | 13.0M | p_output->i_flags |= BLOCK_FLAG_DROP; |
193 | 15.7M | } |
194 | | |
195 | 17.0M | return p_output; |
196 | 17.0M | } |
197 | | |
198 | | |
199 | | /***************************************************************************** |
200 | | * Open |
201 | | *****************************************************************************/ |
202 | | static int Open(vlc_object_t *p_this) |
203 | 85.2k | { |
204 | 85.2k | decoder_t *p_dec = (decoder_t*)p_this; |
205 | 85.2k | decoder_sys_t *p_sys; |
206 | | |
207 | 85.2k | if (p_dec->fmt_in->i_codec != VLC_CODEC_HEVC) |
208 | 62.8k | return VLC_EGENERIC; |
209 | | |
210 | 22.4k | p_dec->p_sys = p_sys = calloc(1, sizeof(decoder_sys_t)); |
211 | 22.4k | if (!p_dec->p_sys) |
212 | 0 | return VLC_ENOMEM; |
213 | | |
214 | 22.4k | p_sys->p_ccs = cc_storage_new(); |
215 | 22.4k | if(unlikely(!p_sys->p_ccs)) |
216 | 0 | { |
217 | 0 | free(p_dec->p_sys); |
218 | 0 | return VLC_ENOMEM; |
219 | 0 | } |
220 | | |
221 | 22.4k | INITQ(pre); |
222 | 22.4k | INITQ(frame); |
223 | 22.4k | INITQ(post); |
224 | | |
225 | 22.4k | packetizer_Init(&p_sys->packetizer, |
226 | 22.4k | annexb_startcode3, 3, startcode_FindAnnexB, |
227 | 22.4k | annexb_startcode3, 1, 5, |
228 | 22.4k | PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain, |
229 | 22.4k | p_dec); |
230 | | |
231 | | /* Copy properties */ |
232 | 22.4k | es_format_Copy(&p_dec->fmt_out, p_dec->fmt_in); |
233 | 22.4k | p_dec->fmt_out.b_packetized = true; |
234 | | |
235 | | /* Init timings */ |
236 | 22.4k | if( p_dec->fmt_in->video.i_frame_rate_base && |
237 | 1.61k | p_dec->fmt_in->video.i_frame_rate && |
238 | 1.56k | p_dec->fmt_in->video.i_frame_rate <= UINT_MAX / 2 ) |
239 | 1.56k | date_Init( &p_sys->dts, p_dec->fmt_in->video.i_frame_rate * 2, |
240 | 1.56k | p_dec->fmt_in->video.i_frame_rate_base ); |
241 | 20.8k | else |
242 | 20.8k | date_Init( &p_sys->dts, 2 * 30000, 1001 ); |
243 | 22.4k | p_sys->pts = VLC_TICK_INVALID; |
244 | 22.4k | p_sys->b_need_ts = true; |
245 | 22.4k | p_sys->sets = MISSING; |
246 | | |
247 | | /* Set callbacks */ |
248 | 22.4k | const uint8_t *p_extra = p_dec->fmt_in->p_extra; |
249 | 22.4k | const size_t i_extra = p_dec->fmt_in->i_extra; |
250 | | /* Check if we have hvcC as extradata */ |
251 | 22.4k | if(hevc_ishvcC(p_extra, i_extra)) |
252 | 960 | { |
253 | 960 | uint8_t *p_new_extra; |
254 | 960 | size_t i_new_extra; |
255 | 960 | if(!hevc_hvcC_to_AnnexB_NAL(p_extra, i_extra, |
256 | 960 | &p_new_extra, &i_new_extra, |
257 | 960 | &p_sys->i_nal_length_size)) |
258 | 280 | { |
259 | 280 | msg_Err( p_dec, "Invalid HVCC extradata"); |
260 | 280 | Close( VLC_OBJECT(p_dec) ); |
261 | 280 | return VLC_EGENERIC; |
262 | 280 | } |
263 | | /* Clear hvcC/HVC1 extra, to be replaced with AnnexB */ |
264 | 680 | free(p_dec->fmt_out.p_extra); |
265 | 680 | p_dec->fmt_out.p_extra = p_new_extra; |
266 | 680 | p_dec->fmt_out.i_extra = i_new_extra; |
267 | 680 | p_dec->pf_packetize = PacketizeHVC1; |
268 | 680 | } |
269 | 21.4k | else |
270 | 21.4k | { |
271 | 21.4k | p_dec->pf_packetize = PacketizeAnnexB; |
272 | 21.4k | } |
273 | 22.1k | p_dec->pf_flush = PacketizeFlush; |
274 | 22.1k | p_dec->pf_get_cc = GetCc; |
275 | | |
276 | 22.1k | if(p_dec->fmt_out.i_extra) |
277 | 5.47k | { |
278 | | /* Feed with AnnexB VPS/SPS/PPS/SEI extradata */ |
279 | 5.47k | packetizer_Header(&p_sys->packetizer, |
280 | 5.47k | p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra); |
281 | 5.47k | } |
282 | | |
283 | 22.1k | return VLC_SUCCESS; |
284 | 22.4k | } |
285 | | |
286 | | /***************************************************************************** |
287 | | * Close |
288 | | *****************************************************************************/ |
289 | | static void Close(vlc_object_t *p_this) |
290 | 22.4k | { |
291 | 22.4k | decoder_t *p_dec = (decoder_t*)p_this; |
292 | 22.4k | decoder_sys_t *p_sys = p_dec->p_sys; |
293 | 22.4k | packetizer_Clean(&p_sys->packetizer); |
294 | | |
295 | 22.4k | block_ChainRelease(p_sys->frame.p_chain); |
296 | 22.4k | block_ChainRelease(p_sys->pre.p_chain); |
297 | 22.4k | block_ChainRelease(p_sys->post.p_chain); |
298 | | |
299 | 1.45M | for(unsigned i=0;i<HEVC_MAX_NUM_PPS; i++) |
300 | 1.43M | { |
301 | 1.43M | if(p_sys->rg_pps[i].p_decoded) |
302 | 9.04k | hevc_rbsp_release_pps(p_sys->rg_pps[i].p_decoded); |
303 | 1.43M | if(p_sys->rg_pps[i].p_nal) |
304 | 9.04k | block_Release(p_sys->rg_pps[i].p_nal); |
305 | 1.43M | } |
306 | | |
307 | 380k | for(unsigned i=0;i<HEVC_MAX_NUM_SPS; i++) |
308 | 358k | { |
309 | 358k | if(p_sys->rg_sps[i].p_decoded) |
310 | 6.35k | hevc_rbsp_release_sps(p_sys->rg_sps[i].p_decoded); |
311 | 358k | if(p_sys->rg_sps[i].p_nal) |
312 | 6.35k | block_Release(p_sys->rg_sps[i].p_nal); |
313 | 358k | } |
314 | | |
315 | 380k | for(unsigned i=0;i<HEVC_MAX_NUM_VPS; i++) |
316 | 358k | { |
317 | 358k | if(p_sys->rg_vps[i].p_decoded) |
318 | 6.71k | hevc_rbsp_release_vps(p_sys->rg_vps[i].p_decoded); |
319 | 358k | if(p_sys->rg_vps[i].p_nal) |
320 | 6.71k | block_Release(p_sys->rg_vps[i].p_nal); |
321 | 358k | } |
322 | | |
323 | 22.4k | hevc_release_sei_pic_timing( p_sys->p_timing ); |
324 | | |
325 | 22.4k | cc_storage_delete( p_sys->p_ccs ); |
326 | | |
327 | 22.4k | free(p_sys); |
328 | 22.4k | } |
329 | | |
330 | | /**************************************************************************** |
331 | | * Packetize |
332 | | ****************************************************************************/ |
333 | | static block_t *PacketizeHVC1(decoder_t *p_dec, block_t **pp_block) |
334 | 14.6k | { |
335 | 14.6k | decoder_sys_t *p_sys = p_dec->p_sys; |
336 | | |
337 | 14.6k | return PacketizeXXC1( p_dec, p_dec->obj.logger, |
338 | 14.6k | p_sys->i_nal_length_size, pp_block, |
339 | 14.6k | ParseNALBlockW, PacketizeDrain ); |
340 | 14.6k | } |
341 | | |
342 | | static block_t *PacketizeAnnexB(decoder_t *p_dec, block_t **pp_block) |
343 | 4.28M | { |
344 | 4.28M | decoder_sys_t *p_sys = p_dec->p_sys; |
345 | | |
346 | 4.28M | return packetizer_Packetize(&p_sys->packetizer, pp_block); |
347 | 4.28M | } |
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.34M | { |
361 | 1.34M | decoder_sys_t *p_sys = p_dec->p_sys; |
362 | 1.34M | return cc_storage_get_current( p_sys->p_ccs, p_desc ); |
363 | 1.34M | } |
364 | | |
365 | | /**************************************************************************** |
366 | | * Packetizer Helpers |
367 | | ****************************************************************************/ |
368 | | static void PacketizeReset(void *p_private, bool b_flush) |
369 | 350 | { |
370 | 350 | decoder_t *p_dec = p_private; |
371 | 350 | decoder_sys_t *p_sys = p_dec->p_sys; |
372 | | |
373 | 350 | block_t *p_out = OutputQueues(p_sys, false); |
374 | 350 | if(p_out) |
375 | 118 | block_ChainRelease(p_out); |
376 | | |
377 | 350 | if(b_flush) |
378 | 0 | { |
379 | 0 | p_sys->sets = MISSING; |
380 | 0 | p_sys->b_recovery_point = false; |
381 | 0 | } |
382 | 350 | p_sys->b_need_ts = true; |
383 | 350 | date_Set(&p_sys->dts, VLC_TICK_INVALID); |
384 | 350 | } |
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 | 2.12M | { |
389 | 2.12M | decoder_sys_t *p_sys = p_dec->p_sys; |
390 | 2.12M | struct hevc_tuple_s *p_tuple; |
391 | 2.12M | void **pp_active; |
392 | | |
393 | 2.12M | switch(i_nal_type) |
394 | 2.12M | { |
395 | 400k | case HEVC_NAL_VPS: |
396 | 400k | if(i_id > HEVC_VPS_ID_MAX) |
397 | 0 | return false; |
398 | 400k | p_tuple = &p_sys->rg_vps[i_id]; |
399 | 400k | pp_active = (void**)&p_sys->p_active_vps; |
400 | 400k | break; |
401 | 1.44M | case HEVC_NAL_SPS: |
402 | 1.44M | if(i_id > HEVC_SPS_ID_MAX) |
403 | 0 | return false; |
404 | 1.44M | p_tuple = &p_sys->rg_sps[i_id]; |
405 | 1.44M | pp_active = (void**)&p_sys->p_active_sps; |
406 | 1.44M | break; |
407 | 279k | case HEVC_NAL_PPS: |
408 | 279k | if(i_id > HEVC_PPS_ID_MAX) |
409 | 0 | return false; |
410 | 279k | p_tuple = &p_sys->rg_pps[i_id]; |
411 | 279k | pp_active = (void**)&p_sys->p_active_pps; |
412 | 279k | break; |
413 | 0 | default: |
414 | 0 | return false; |
415 | 2.12M | } |
416 | | |
417 | | /* Check if we really need to re-decode/replace */ |
418 | 2.12M | if(p_tuple->p_nal) |
419 | 817k | { |
420 | 817k | const uint8_t *p_stored = p_tuple->p_nal->p_buffer; |
421 | 817k | size_t i_stored = p_tuple->p_nal->i_buffer; |
422 | 817k | hxxx_strip_AnnexB_startcode(&p_stored, &i_stored); |
423 | 817k | const uint8_t *p_new = p_nalb->p_buffer; |
424 | 817k | size_t i_new = p_nalb->i_buffer; |
425 | 817k | hxxx_strip_AnnexB_startcode(&p_new, &i_new); |
426 | 817k | if(i_stored == i_new && !memcmp(p_stored, p_new, i_new)) |
427 | 98.3k | return true; |
428 | 817k | } |
429 | | |
430 | | /* Free associated decoded version */ |
431 | 2.02M | if(p_tuple->p_decoded) |
432 | 718k | { |
433 | 718k | switch(i_nal_type) |
434 | 718k | { |
435 | 149k | case HEVC_NAL_VPS: |
436 | 149k | hevc_rbsp_release_vps(p_tuple->p_decoded); |
437 | 149k | break; |
438 | 529k | case HEVC_NAL_SPS: |
439 | 529k | hevc_rbsp_release_sps(p_tuple->p_decoded); |
440 | 529k | break; |
441 | 40.1k | case HEVC_NAL_PPS: |
442 | 40.1k | hevc_rbsp_release_pps(p_tuple->p_decoded); |
443 | 40.1k | break; |
444 | 718k | } |
445 | 718k | if(*pp_active == p_tuple->p_decoded) |
446 | 48.6k | *pp_active = NULL; |
447 | 670k | else |
448 | 670k | pp_active = NULL; /* don't change pointer */ |
449 | 718k | p_tuple->p_decoded = NULL; |
450 | 718k | } |
451 | 1.30M | else pp_active = NULL; |
452 | | |
453 | | /* Free raw stored version */ |
454 | 2.02M | if(p_tuple->p_nal) |
455 | 718k | { |
456 | 718k | block_Release(p_tuple->p_nal); |
457 | 718k | p_tuple->p_nal = NULL; |
458 | 718k | } |
459 | | |
460 | 2.02M | const uint8_t *p_buffer = p_nalb->p_buffer; |
461 | 2.02M | size_t i_buffer = p_nalb->i_buffer; |
462 | 2.02M | if( hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) ) |
463 | 2.02M | { |
464 | | /* Create decoded entries */ |
465 | 2.02M | switch(i_nal_type) |
466 | 2.02M | { |
467 | 1.43M | case HEVC_NAL_SPS: |
468 | 1.43M | p_tuple->p_decoded = hevc_decode_sps(p_buffer, i_buffer, true); |
469 | 1.43M | if(!p_tuple->p_decoded) |
470 | 895k | { |
471 | 895k | msg_Err(p_dec, "Failed decoding SPS id %d", i_id); |
472 | 895k | return false; |
473 | 895k | } |
474 | 535k | break; |
475 | 535k | case HEVC_NAL_PPS: |
476 | 208k | p_tuple->p_decoded = hevc_decode_pps(p_buffer, i_buffer, true); |
477 | 208k | if(!p_tuple->p_decoded) |
478 | 158k | { |
479 | 158k | msg_Err(p_dec, "Failed decoding PPS id %d", i_id); |
480 | 158k | return false; |
481 | 158k | } |
482 | 49.1k | break; |
483 | 389k | case HEVC_NAL_VPS: |
484 | 389k | p_tuple->p_decoded = hevc_decode_vps(p_buffer, i_buffer, true); |
485 | 389k | if(!p_tuple->p_decoded) |
486 | 233k | { |
487 | 233k | msg_Err(p_dec, "Failed decoding VPS id %d", i_id); |
488 | 233k | return false; |
489 | 233k | } |
490 | 156k | break; |
491 | 2.02M | } |
492 | | |
493 | 740k | if(p_tuple->p_decoded && pp_active) /* restore active by id */ |
494 | 31.9k | *pp_active = p_tuple->p_decoded; |
495 | | |
496 | 740k | p_tuple->p_nal = block_Duplicate((block_t *)p_nalb); |
497 | | |
498 | 740k | return true; |
499 | 2.02M | } |
500 | | |
501 | 0 | return false; |
502 | 2.02M | } |
503 | | |
504 | | static block_t *GetXPSCopy(decoder_sys_t *p_sys) |
505 | 207k | { |
506 | 207k | block_t *p_chain = NULL; |
507 | 207k | block_t **pp_append = &p_chain; |
508 | 207k | struct hevc_tuple_s *xpstype[3] = {p_sys->rg_vps, p_sys->rg_sps, p_sys->rg_pps}; |
509 | 207k | size_t xpsmax[3] = {HEVC_MAX_NUM_VPS, HEVC_MAX_NUM_SPS, HEVC_MAX_NUM_PPS}; |
510 | 828k | for(size_t i=0; i<3; i++) |
511 | 621k | { |
512 | 621k | struct hevc_tuple_s *xps = xpstype[i]; |
513 | 20.5M | for(size_t j=0; j<xpsmax[i]; j++) |
514 | 19.8M | { |
515 | 19.8M | block_t *p_dup; |
516 | 19.8M | if(xps[j].p_nal && |
517 | 233k | (p_dup = block_Duplicate(xps[j].p_nal))) |
518 | 233k | block_ChainLastAppend(&pp_append, p_dup); |
519 | 19.8M | }; |
520 | 621k | } |
521 | 207k | return p_chain; |
522 | 207k | } |
523 | | |
524 | | static bool XPSReady(decoder_sys_t *p_sys) |
525 | 10.3M | { |
526 | 673M | for(unsigned i=0;i<HEVC_MAX_NUM_PPS; i++) |
527 | 663M | { |
528 | 663M | const hevc_picture_parameter_set_t *p_pps = p_sys->rg_pps[i].p_decoded; |
529 | 663M | if (p_pps) |
530 | 563k | { |
531 | 563k | uint8_t id_sps = hevc_get_pps_sps_id(p_pps); |
532 | 563k | const hevc_sequence_parameter_set_t *p_sps = p_sys->rg_sps[id_sps].p_decoded; |
533 | 563k | if(p_sps) |
534 | 37.9k | { |
535 | 37.9k | uint8_t id_vps = hevc_get_sps_vps_id(p_sps); |
536 | 37.9k | if(p_sys->rg_vps[id_vps].p_decoded) |
537 | 3.88k | return true; |
538 | 37.9k | } |
539 | 563k | } |
540 | 663M | } |
541 | 10.3M | return false; |
542 | 10.3M | } |
543 | | |
544 | | static void AppendAsAnnexB(const block_t *p_block, |
545 | | uint8_t **pp_dst, size_t *pi_dst) |
546 | 8.96k | { |
547 | 8.96k | if(SIZE_MAX - p_block->i_buffer < *pi_dst ) |
548 | 0 | return; |
549 | | |
550 | 8.96k | size_t i_realloc = p_block->i_buffer + *pi_dst; |
551 | 8.96k | uint8_t *p_realloc = realloc(*pp_dst, i_realloc); |
552 | 8.96k | if(p_realloc) |
553 | 8.96k | { |
554 | 8.96k | memcpy(&p_realloc[*pi_dst], p_block->p_buffer, p_block->i_buffer); |
555 | 8.96k | *pi_dst = i_realloc; |
556 | 8.96k | *pp_dst = p_realloc; |
557 | 8.96k | } |
558 | 8.96k | } |
559 | | |
560 | | #define APPENDIF(maxcount, set, rg, b) \ |
561 | 224k | for(size_t i=0; i<maxcount; i++)\ |
562 | 217k | {\ |
563 | 217k | if(((set != rg[i].p_decoded) == !b) && rg[i].p_nal)\ |
564 | 217k | {\ |
565 | 8.96k | AppendAsAnnexB(rg[i].p_nal, &p_data, &i_data);\ |
566 | 8.96k | if(b) break;\ |
567 | 8.96k | }\ |
568 | 217k | } |
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 | 2.14k | { |
576 | 2.14k | uint8_t *p_data = NULL; |
577 | 2.14k | size_t i_data = 0; |
578 | | |
579 | 2.14k | APPENDIF(HEVC_MAX_NUM_VPS, p_vps, p_sys->rg_vps, true); |
580 | 2.14k | APPENDIF(HEVC_MAX_NUM_VPS, p_vps, p_sys->rg_vps, false); |
581 | 2.14k | APPENDIF(HEVC_MAX_NUM_SPS, p_sps, p_sys->rg_sps, true); |
582 | 2.14k | APPENDIF(HEVC_MAX_NUM_SPS, p_sps, p_sys->rg_sps, false); |
583 | 2.14k | APPENDIF(HEVC_MAX_NUM_PPS, p_pps, p_sys->rg_pps, true); |
584 | 2.14k | APPENDIF(HEVC_MAX_NUM_PPS, p_pps, p_sys->rg_pps, false); |
585 | | |
586 | | /* because we copy to i_extra :/ */ |
587 | 2.14k | if(i_data <= INT_MAX) |
588 | 2.14k | { |
589 | 2.14k | *pp_out = p_data; |
590 | 2.14k | *pi_out = i_data; |
591 | 2.14k | } |
592 | 0 | else free(p_data); |
593 | 2.14k | } |
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 | 96.6k | { |
600 | 96.6k | decoder_sys_t *p_sys = p_dec->p_sys; |
601 | 96.6k | p_sys->p_active_pps = p_pps; |
602 | 96.6k | p_sys->p_active_sps = p_sps; |
603 | 96.6k | p_sys->p_active_vps = p_vps; |
604 | 96.6k | if(p_sps) |
605 | 96.6k | { |
606 | 96.6k | if(!p_dec->fmt_out.video.i_frame_rate || !p_dec->fmt_out.video.i_frame_rate_base) |
607 | 2.77k | { |
608 | 2.77k | unsigned num, den; |
609 | 2.77k | if(hevc_get_frame_rate( p_sps, p_vps, &num, &den )) |
610 | 1.63k | { |
611 | 1.63k | p_dec->fmt_out.video.i_frame_rate = num; |
612 | 1.63k | p_dec->fmt_out.video.i_frame_rate_base = den; |
613 | 1.63k | if(num <= UINT_MAX / 2 && |
614 | 1.10k | (p_sys->dts.i_divider_den != den || |
615 | 39 | p_sys->dts.i_divider_num != 2 * num)) |
616 | 1.09k | { |
617 | 1.09k | date_Change(&p_sys->dts, 2 * num, den); |
618 | 1.09k | } |
619 | 1.63k | } |
620 | 2.77k | p_dec->fmt_out.video.i_frame_rate = p_sys->dts.i_divider_num >> 1; |
621 | 2.77k | p_dec->fmt_out.video.i_frame_rate_base = p_sys->dts.i_divider_den; |
622 | 2.77k | } |
623 | | |
624 | 96.6k | if(p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF) |
625 | 93.9k | { |
626 | 93.9k | (void) hevc_get_colorimetry( p_sps, |
627 | 93.9k | &p_dec->fmt_out.video.primaries, |
628 | 93.9k | &p_dec->fmt_out.video.transfer, |
629 | 93.9k | &p_dec->fmt_out.video.space, |
630 | 93.9k | &p_dec->fmt_out.video.color_range); |
631 | 93.9k | } |
632 | | |
633 | 96.6k | unsigned sizes[6]; |
634 | 96.6k | if( hevc_get_picture_size( p_sps, &sizes[0], &sizes[1], |
635 | 96.6k | &sizes[2], &sizes[3], |
636 | 96.6k | &sizes[4], &sizes[5] ) ) |
637 | 89.1k | { |
638 | 89.1k | p_dec->fmt_out.video.i_x_offset = sizes[0]; |
639 | 89.1k | p_dec->fmt_out.video.i_y_offset = sizes[1]; |
640 | 89.1k | p_dec->fmt_out.video.i_width = sizes[2]; |
641 | 89.1k | p_dec->fmt_out.video.i_height = sizes[3]; |
642 | 89.1k | if(p_dec->fmt_in->video.i_visible_width == 0) |
643 | 60.9k | { |
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 | 89.1k | } |
648 | | |
649 | 96.6k | if ( p_dec->fmt_in->video.i_sar_num == 0 || p_dec->fmt_in->video.i_sar_den == 0) |
650 | 89.7k | { |
651 | 89.7k | unsigned num, den; |
652 | 89.7k | if ( hevc_get_aspect_ratio( p_sps, &num, &den ) ) |
653 | 6.10k | { |
654 | 6.10k | p_dec->fmt_out.video.i_sar_num = num; |
655 | 6.10k | p_dec->fmt_out.video.i_sar_den = den; |
656 | 6.10k | } |
657 | 89.7k | } |
658 | | |
659 | 96.6k | if(p_dec->fmt_in->i_profile == -1) |
660 | 68.9k | { |
661 | 68.9k | uint8_t i_profile, i_level; |
662 | 68.9k | if( hevc_get_sps_profile_tier_level( p_sps, &i_profile, &i_level ) ) |
663 | 66.9k | { |
664 | 66.9k | p_dec->fmt_out.i_profile = i_profile; |
665 | 66.9k | p_dec->fmt_out.i_level = i_level; |
666 | 66.9k | } |
667 | 68.9k | } |
668 | | |
669 | 96.6k | if(p_dec->fmt_out.i_extra == 0 && p_vps && p_pps) |
670 | 2.14k | SetsToAnnexB(p_sys, p_pps, p_sps, p_vps, |
671 | 2.14k | (uint8_t **)&p_dec->fmt_out.p_extra, &p_dec->fmt_out.i_extra); |
672 | 96.6k | } |
673 | 96.6k | } |
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 | 433k | { |
680 | 433k | decoder_sys_t *p_sys = priv; |
681 | 433k | *pp_sps = NULL; |
682 | 433k | *pp_vps = NULL; |
683 | 433k | if((*pp_pps = p_sys->rg_pps[i_pps_id].p_decoded)) |
684 | 333k | if((*pp_sps = p_sys->rg_sps[hevc_get_pps_sps_id(*pp_pps)].p_decoded)) |
685 | 274k | *pp_vps = p_sys->rg_vps[hevc_get_sps_vps_id(*pp_sps)].p_decoded; |
686 | 433k | } |
687 | | |
688 | | static void ParseStoredSEI( decoder_t *p_dec ) |
689 | 4.24M | { |
690 | 4.24M | decoder_sys_t *p_sys = p_dec->p_sys; |
691 | | |
692 | 4.24M | for( block_t *p_nal = p_sys->pre.p_chain; |
693 | 4.49M | p_nal; p_nal = p_nal->p_next ) |
694 | 247k | { |
695 | 247k | if( p_nal->i_buffer < 5 ) |
696 | 0 | continue; |
697 | | |
698 | 247k | if( hevc_getNALType(&p_nal->p_buffer[4]) == HEVC_NAL_PREF_SEI ) |
699 | 5.74k | { |
700 | 5.74k | HxxxParse_AnnexB_SEI( p_nal->p_buffer, p_nal->i_buffer, |
701 | 5.74k | 2 /* nal header */, ParseSEICallback, p_dec ); |
702 | 5.74k | } |
703 | 247k | } |
704 | 4.24M | } |
705 | | |
706 | | static block_t *ParseVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag) |
707 | 41.7M | { |
708 | 41.7M | decoder_sys_t *p_sys = p_dec->p_sys; |
709 | 41.7M | block_t *p_outputchain = NULL; |
710 | | |
711 | 41.7M | const uint8_t *p_buffer = p_frag->p_buffer; |
712 | 41.7M | size_t i_buffer = p_frag->i_buffer; |
713 | | |
714 | 41.7M | if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buffer, &i_buffer) || i_buffer < 3)) |
715 | 26.2M | { |
716 | 26.2M | block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag); /* might be corrupted */ |
717 | 26.2M | return NULL; |
718 | 26.2M | } |
719 | | |
720 | 15.4M | const uint8_t i_layer = hevc_getNALLayer( p_buffer ); |
721 | 15.4M | bool b_first_slice_in_pic = p_buffer[2] & 0x80; |
722 | 15.4M | if (b_first_slice_in_pic) |
723 | 4.24M | { |
724 | 4.24M | if(p_sys->frame.p_chain) |
725 | 3.64M | { |
726 | | /* Starting new frame: return previous frame data for output */ |
727 | 3.64M | p_outputchain = OutputQueues(p_sys, p_sys->sets != MISSING && |
728 | 2.51M | p_sys->b_recovery_point); |
729 | 3.64M | } |
730 | | |
731 | 4.24M | hevc_slice_segment_header_t *p_sli = hevc_decode_slice_header(p_buffer, i_buffer, true, |
732 | 4.24M | GetXPSSet, p_sys); |
733 | 4.24M | if(p_sli && i_layer == 0) |
734 | 96.6k | { |
735 | 96.6k | hevc_sequence_parameter_set_t *p_sps; |
736 | 96.6k | hevc_picture_parameter_set_t *p_pps; |
737 | 96.6k | hevc_video_parameter_set_t *p_vps; |
738 | 96.6k | GetXPSSet(hevc_get_slice_pps_id(p_sli), p_sys, &p_pps, &p_sps, &p_vps); |
739 | 96.6k | ActivateSets(p_dec, p_pps, p_sps, p_vps); |
740 | 96.6k | } |
741 | | |
742 | 4.24M | ParseStoredSEI( p_dec ); |
743 | | |
744 | 4.24M | switch(i_nal_type) |
745 | 4.24M | { |
746 | 1.31k | case HEVC_NAL_BLA_W_LP: |
747 | 2.55k | case HEVC_NAL_BLA_W_RADL: |
748 | 102k | case HEVC_NAL_BLA_N_LP: |
749 | 127k | case HEVC_NAL_IDR_W_RADL: |
750 | 129k | case HEVC_NAL_IDR_N_LP: |
751 | 2.51M | case HEVC_NAL_CRA: |
752 | 2.51M | p_frag->i_flags |= BLOCK_FLAG_TYPE_I; |
753 | 2.51M | break; |
754 | | |
755 | 1.73M | default: |
756 | 1.73M | { |
757 | 1.73M | if(p_sli) |
758 | 43.1k | { |
759 | 43.1k | enum hevc_slice_type_e type; |
760 | 43.1k | if(hevc_get_slice_type( p_sli, &type )) |
761 | 43.1k | { |
762 | 43.1k | switch(type) |
763 | 43.1k | { |
764 | 40.5k | case HEVC_SLICE_TYPE_B: |
765 | 40.5k | p_frag->i_flags |= BLOCK_FLAG_TYPE_B; |
766 | 40.5k | break; |
767 | 380 | case HEVC_SLICE_TYPE_P: |
768 | 380 | p_frag->i_flags |= BLOCK_FLAG_TYPE_P; |
769 | 380 | break; |
770 | 2.21k | case HEVC_SLICE_TYPE_I: |
771 | 2.21k | p_frag->i_flags |= BLOCK_FLAG_TYPE_I; |
772 | 2.21k | break; |
773 | 43.1k | } |
774 | 43.1k | } |
775 | 43.1k | } |
776 | 1.68M | else p_frag->i_flags |= BLOCK_FLAG_TYPE_B; |
777 | 1.73M | } |
778 | 1.73M | break; |
779 | 4.24M | } |
780 | | |
781 | 4.24M | if(p_sli) |
782 | 104k | hevc_rbsp_release_slice_header(p_sli); |
783 | 4.24M | } |
784 | | |
785 | 15.4M | if(p_sys->sets == MISSING && i_layer == 0 && XPSReady(p_sys)) |
786 | 3.88k | p_sys->sets = COMPLETE; |
787 | | |
788 | 15.4M | if(p_sys->sets != MISSING && (p_frag->i_flags & BLOCK_FLAG_TYPE_I)) |
789 | 2.43M | { |
790 | 2.43M | p_sys->b_recovery_point = true; /* won't care about SEI recovery */ |
791 | 2.43M | } |
792 | | |
793 | 15.4M | if(!p_sys->b_recovery_point) /* content will be dropped */ |
794 | 12.4M | cc_storage_reset(p_sys->p_ccs); |
795 | | |
796 | 15.4M | block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag); |
797 | | |
798 | 15.4M | return p_outputchain; |
799 | 15.4M | } |
800 | | |
801 | | static block_t * ParseAUHead(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb) |
802 | 7.68M | { |
803 | 7.68M | decoder_sys_t *p_sys = p_dec->p_sys; |
804 | 7.68M | block_t *p_ret = NULL; |
805 | | |
806 | 7.68M | if(p_sys->post.p_chain || p_sys->frame.p_chain) |
807 | 1.54M | p_ret = OutputQueues(p_sys, p_sys->sets != MISSING && |
808 | 131k | p_sys->b_recovery_point); |
809 | | |
810 | 7.68M | switch(i_nal_type) |
811 | 7.68M | { |
812 | 914k | case HEVC_NAL_AUD: |
813 | 914k | if(!p_ret && p_sys->pre.p_chain) |
814 | 394k | p_ret = OutputQueues(p_sys, p_sys->sets != MISSING && |
815 | 2.08k | p_sys->b_recovery_point); |
816 | 914k | break; |
817 | | |
818 | 410k | case HEVC_NAL_VPS: |
819 | 2.49M | case HEVC_NAL_SPS: |
820 | 3.28M | case HEVC_NAL_PPS: |
821 | 3.28M | { |
822 | 3.28M | uint8_t i_id; |
823 | 3.28M | const uint8_t *p_xps = p_nalb->p_buffer; |
824 | 3.28M | size_t i_xps = p_nalb->i_buffer; |
825 | 3.28M | if(hxxx_strip_AnnexB_startcode(&p_xps, &i_xps) && |
826 | 3.28M | hevc_get_xps_id(p_xps, i_xps, &i_id)) |
827 | 2.12M | InsertXPS(p_dec, i_nal_type, i_id, p_nalb); |
828 | 3.28M | if(p_sys->sets != SENT) /* will store/inject on first recovery point */ |
829 | 3.02M | { |
830 | 3.02M | block_Release(p_nalb); |
831 | 3.02M | return p_ret; |
832 | 3.02M | } |
833 | 254k | break; |
834 | 3.28M | } |
835 | | |
836 | 1.05M | case HEVC_NAL_PREF_SEI: |
837 | | /* stored an parsed later when we get sps & frame */ |
838 | 3.48M | default: |
839 | 3.48M | break; |
840 | 7.68M | } |
841 | | |
842 | 4.65M | block_ChainLastAppend(&p_sys->pre.pp_chain_last, p_nalb); |
843 | | |
844 | 4.65M | return p_ret; |
845 | 7.68M | } |
846 | | |
847 | | static block_t * ParseAUTail(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb) |
848 | 7.02M | { |
849 | 7.02M | decoder_sys_t *p_sys = p_dec->p_sys; |
850 | 7.02M | block_t *p_ret = NULL; |
851 | | |
852 | 7.02M | block_ChainLastAppend(&p_sys->post.pp_chain_last, p_nalb); |
853 | | |
854 | 7.02M | switch(i_nal_type) |
855 | 7.02M | { |
856 | 1.30M | case HEVC_NAL_EOS: |
857 | 1.98M | case HEVC_NAL_EOB: |
858 | 1.98M | p_ret = OutputQueues(p_sys, p_sys->sets != MISSING && |
859 | 41.8k | p_sys->b_recovery_point); |
860 | 1.98M | if( p_ret ) |
861 | 1.98M | p_ret->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE; |
862 | 1.98M | break; |
863 | | |
864 | 343k | case HEVC_NAL_SUFF_SEI: |
865 | 343k | HxxxParse_AnnexB_SEI( p_nalb->p_buffer, p_nalb->i_buffer, |
866 | 343k | 2 /* nal header */, ParseSEICallback, p_dec ); |
867 | 343k | break; |
868 | 7.02M | } |
869 | | |
870 | 7.02M | if(!p_ret && p_sys->frame.p_chain == NULL) |
871 | 4.52M | p_ret = OutputQueues(p_sys, false); |
872 | | |
873 | 7.02M | return p_ret; |
874 | 7.02M | } |
875 | | |
876 | | static block_t * ParseNonVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb) |
877 | 14.7M | { |
878 | 14.7M | block_t *p_ret = NULL; |
879 | | |
880 | 14.7M | if ( (i_nal_type >= HEVC_NAL_VPS && i_nal_type <= HEVC_NAL_AUD) || |
881 | 10.5M | i_nal_type == HEVC_NAL_PREF_SEI || |
882 | 9.45M | (i_nal_type >= HEVC_NAL_RSV_NVCL41 && i_nal_type <= HEVC_NAL_RSV_NVCL44) || |
883 | 8.64M | (i_nal_type >= HEVC_NAL_UNSPEC48 && i_nal_type <= HEVC_NAL_UNSPEC55) ) |
884 | 7.68M | { |
885 | 7.68M | p_ret = ParseAUHead(p_dec, i_nal_type, p_nalb); |
886 | 7.68M | } |
887 | 7.02M | else |
888 | 7.02M | { |
889 | 7.02M | p_ret = ParseAUTail(p_dec, i_nal_type, p_nalb); |
890 | 7.02M | } |
891 | | |
892 | 14.7M | return p_ret; |
893 | 14.7M | } |
894 | | |
895 | | static block_t *GatherAndValidateChain(block_t *p_outputchain) |
896 | 61.4M | { |
897 | 61.4M | block_t *p_output = NULL; |
898 | | |
899 | 61.4M | if(p_outputchain) |
900 | 15.7M | { |
901 | 15.7M | if(p_outputchain->i_flags & BLOCK_FLAG_DROP) |
902 | 13.0M | p_output = p_outputchain; /* Avoid useless gather */ |
903 | 2.67M | else |
904 | 2.67M | p_output = block_ChainGather(p_outputchain); |
905 | 15.7M | } |
906 | | |
907 | 61.4M | if(p_output && (p_output->i_flags & BLOCK_FLAG_DROP)) |
908 | 13.0M | { |
909 | 13.0M | block_ChainRelease(p_output); /* Chain! see above */ |
910 | 13.0M | p_output = NULL; |
911 | 13.0M | } |
912 | | |
913 | 61.4M | return p_output; |
914 | 61.4M | } |
915 | | |
916 | | static void SetOutputBlockProperties(decoder_t *p_dec, block_t *p_output) |
917 | 2.67M | { |
918 | 2.67M | decoder_sys_t *p_sys = p_dec->p_sys; |
919 | | /* Set frame duration */ |
920 | 2.67M | if(p_sys->p_active_sps) |
921 | 846k | { |
922 | 846k | uint8_t i_num_clock_ts = hevc_get_num_clock_ts(p_sys->p_active_sps, |
923 | 846k | p_sys->p_timing); |
924 | 846k | const vlc_tick_t i_start = date_Get(&p_sys->dts); |
925 | 846k | if( i_start != VLC_TICK_INVALID ) |
926 | 846k | { |
927 | 846k | date_Increment(&p_sys->dts, i_num_clock_ts); |
928 | 846k | p_output->i_length = date_Get(&p_sys->dts) - i_start; |
929 | 846k | } |
930 | 846k | p_sys->pts = VLC_TICK_INVALID; |
931 | 846k | } |
932 | 2.67M | p_output->i_flags &= ~BLOCK_FLAG_AU_END; |
933 | 2.67M | hevc_release_sei_pic_timing(p_sys->p_timing); |
934 | 2.67M | p_sys->p_timing = NULL; |
935 | 2.67M | } |
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 | 61.4M | { |
943 | 61.4M | decoder_sys_t *p_sys = p_dec->p_sys; |
944 | 61.4M | *pb_ts_used = false; |
945 | 61.4M | bool b_au_end = p_frag->i_flags & BLOCK_FLAG_AU_END; |
946 | | |
947 | 61.4M | if(p_sys->b_need_ts) |
948 | 27.0M | { |
949 | 27.0M | if(p_frag->i_dts != VLC_TICK_INVALID) |
950 | 19.2k | date_Set(&p_sys->dts, p_frag->i_dts); |
951 | 27.0M | p_sys->pts = p_frag->i_pts; |
952 | 27.0M | if(date_Get( &p_sys->dts ) != VLC_TICK_INVALID) |
953 | 19.2k | p_sys->b_need_ts = false; |
954 | 27.0M | *pb_ts_used = true; |
955 | 27.0M | } |
956 | | |
957 | 61.4M | 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 | 61.4M | if(p_frag->p_buffer[4] & 0x80) |
965 | 4.98M | { |
966 | 4.98M | msg_Warn(p_dec,"Forbidden zero bit not null, corrupted NAL"); |
967 | 4.98M | block_Release(p_frag); |
968 | 4.98M | return GatherAndValidateChain(OutputQueues(p_sys, false)); /* will drop */ |
969 | 4.98M | } |
970 | | |
971 | | /* Get NALU type */ |
972 | 56.4M | const vlc_tick_t dts = p_frag->i_dts, pts = p_frag->i_pts; |
973 | 56.4M | block_t * p_output = NULL; |
974 | 56.4M | uint8_t i_nal_type = hevc_getNALType(&p_frag->p_buffer[4]); |
975 | | |
976 | 56.4M | if (i_nal_type < HEVC_NAL_VPS) |
977 | 41.7M | { |
978 | | /* NAL is a VCL NAL */ |
979 | 41.7M | p_output = ParseVCL(p_dec, i_nal_type, p_frag); |
980 | 41.7M | if (p_output && (p_output->i_flags & BLOCK_FLAG_DROP)) |
981 | 41.7M | msg_Info(p_dec, "Waiting for VPS/SPS/PPS"); |
982 | 41.7M | } |
983 | 14.7M | else |
984 | 14.7M | { |
985 | 14.7M | p_output = ParseNonVCL(p_dec, i_nal_type, p_frag); |
986 | 14.7M | } |
987 | | |
988 | 56.4M | 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 | 56.4M | p_output = GatherAndValidateChain(p_output); |
993 | 56.4M | if(p_output) |
994 | 2.66M | { |
995 | 2.66M | if(p_sys->sets != SENT) |
996 | 2.85k | { |
997 | 2.85k | assert(p_sys->sets == COMPLETE); |
998 | 2.85k | p_sys->sets = SENT; |
999 | 2.85k | } |
1000 | | |
1001 | 2.66M | SetOutputBlockProperties( p_dec, p_output ); |
1002 | 2.66M | if (dts != VLC_TICK_INVALID) |
1003 | 2.64M | 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 | 56.4M | return p_output; |
1009 | 56.4M | } |
1010 | | |
1011 | | static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *p_block) |
1012 | 61.4M | { |
1013 | 61.4M | decoder_t *p_dec = p_private; |
1014 | 61.4M | decoder_sys_t *p_sys = p_dec->p_sys; |
1015 | | |
1016 | | /* Remove trailing 0 bytes */ |
1017 | 488M | while (p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 ) |
1018 | 426M | p_block->i_buffer--; |
1019 | | |
1020 | 61.4M | p_block = ParseNALBlock( p_dec, pb_ts_used, p_block ); |
1021 | 61.4M | if( p_block ) |
1022 | 2.66M | cc_storage_commit( p_sys->p_ccs, p_block ); |
1023 | | |
1024 | 61.4M | return p_block; |
1025 | 61.4M | } |
1026 | | |
1027 | | static int PacketizeValidate( void *p_private, block_t *p_au ) |
1028 | 2.67M | { |
1029 | 2.67M | VLC_UNUSED(p_private); |
1030 | 2.67M | VLC_UNUSED(p_au); |
1031 | 2.67M | return VLC_SUCCESS; |
1032 | 2.67M | } |
1033 | | |
1034 | | static block_t * PacketizeDrain(void *p_private) |
1035 | 29.9k | { |
1036 | 29.9k | decoder_t *p_dec = p_private; |
1037 | 29.9k | decoder_sys_t *p_sys = p_dec->p_sys; |
1038 | | |
1039 | 29.9k | block_t *p_out = NULL; |
1040 | | |
1041 | 29.9k | if( p_sys->frame.p_chain && |
1042 | 11.0k | p_sys->sets != MISSING && |
1043 | 2.65k | p_sys->b_recovery_point ) |
1044 | 2.41k | { |
1045 | 2.41k | p_out = OutputQueues(p_sys, true); |
1046 | 2.41k | if( p_out ) |
1047 | 2.41k | { |
1048 | 2.41k | p_out = GatherAndValidateChain(p_out); |
1049 | 2.41k | if( p_out ) |
1050 | 2.41k | SetOutputBlockProperties( p_dec, p_out ); |
1051 | 2.41k | } |
1052 | 2.41k | } |
1053 | 29.9k | return p_out; |
1054 | 29.9k | } |
1055 | | |
1056 | | static bool ParseSEICallback( const hxxx_sei_data_t *p_sei_data, void *cbdata ) |
1057 | 39.0k | { |
1058 | 39.0k | decoder_t *p_dec = (decoder_t *) cbdata; |
1059 | 39.0k | decoder_sys_t *p_sys = p_dec->p_sys; |
1060 | | |
1061 | 39.0k | switch( p_sei_data->i_type ) |
1062 | 39.0k | { |
1063 | 12.0k | case HXXX_SEI_PIC_TIMING: |
1064 | 12.0k | { |
1065 | 12.0k | if( p_sys->p_active_sps ) |
1066 | 4.73k | { |
1067 | 4.73k | hevc_release_sei_pic_timing( p_sys->p_timing ); |
1068 | 4.73k | p_sys->p_timing = hevc_decode_sei_pic_timing( p_sei_data->p_bs, |
1069 | 4.73k | p_sys->p_active_sps ); |
1070 | 4.73k | } |
1071 | 12.0k | } break; |
1072 | 15.9k | case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35: |
1073 | 15.9k | { |
1074 | 15.9k | if( p_sei_data->itu_t35.type == HXXX_ITU_T35_TYPE_CC ) |
1075 | 15.9k | { |
1076 | 15.9k | cc_storage_append( p_sys->p_ccs, true, p_sei_data->itu_t35.u.cc.p_data, |
1077 | 15.9k | p_sei_data->itu_t35.u.cc.i_data ); |
1078 | 15.9k | } |
1079 | 15.9k | } break; |
1080 | 7.35k | case HXXX_SEI_RECOVERY_POINT: |
1081 | 7.35k | { |
1082 | 7.35k | hevc_sei_recovery_point_t reco; |
1083 | 7.35k | if( !p_sys->b_recovery_point && |
1084 | 938 | hevc_decode_sei_recovery_point( p_sei_data->p_bs, &reco ) ) |
1085 | 938 | { |
1086 | 938 | msg_Dbg( p_dec, "Seen SEI recovery point, %d recovery frames", reco.i_frames ); |
1087 | 938 | p_sys->b_recovery_point = true; |
1088 | 938 | } |
1089 | 7.35k | } 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 | 1.62k | case HXXX_SEI_MASTERING_DISPLAY_COLOUR_VOLUME: |
1117 | 1.62k | { |
1118 | 1.62k | video_format_t *p_fmt = &p_dec->fmt_out.video; |
1119 | 11.3k | for (size_t i=0; i<ARRAY_SIZE(p_sei_data->colour_volume.primaries); ++i) |
1120 | 9.76k | p_fmt->mastering.primaries[i] = p_sei_data->colour_volume.primaries[i]; |
1121 | 4.88k | for (size_t i=0; i<ARRAY_SIZE(p_sei_data->colour_volume.white_point); ++i) |
1122 | 3.25k | p_fmt->mastering.white_point[i] = p_sei_data->colour_volume.white_point[i]; |
1123 | 1.62k | p_fmt->mastering.max_luminance = p_sei_data->colour_volume.max_luminance; |
1124 | 1.62k | p_fmt->mastering.min_luminance = p_sei_data->colour_volume.min_luminance; |
1125 | 1.62k | } break; |
1126 | 2.13k | case HXXX_SEI_CONTENT_LIGHT_LEVEL: |
1127 | 2.13k | { |
1128 | 2.13k | video_format_t *p_fmt = &p_dec->fmt_out.video; |
1129 | 2.13k | p_fmt->lighting.MaxCLL = p_sei_data->content_light_lvl.MaxCLL; |
1130 | 2.13k | p_fmt->lighting.MaxFALL = p_sei_data->content_light_lvl.MaxFALL; |
1131 | 2.13k | } break; |
1132 | 39.0k | } |
1133 | | |
1134 | 39.0k | return true; |
1135 | 39.0k | } |