/src/vlc/modules/packetizer/h264.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * h264.c: h264/avc video packetizer |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2001, 2002, 2006 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Eric Petit <titer@videolan.org> |
8 | | * Gildas Bazin <gbazin@videolan.org> |
9 | | * Derk-Jan Hartman <hartman at videolan dot org> |
10 | | * |
11 | | * This program is free software; you can redistribute it and/or modify it |
12 | | * under the terms of the GNU Lesser General Public License as published by |
13 | | * the Free Software Foundation; either version 2.1 of the License, or |
14 | | * (at your option) any later version. |
15 | | * |
16 | | * This program is distributed in the hope that it will be useful, |
17 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | | * GNU Lesser General Public License for more details. |
20 | | * |
21 | | * You should have received a copy of the GNU Lesser General Public License |
22 | | * along with this program; if not, write to the Free Software Foundation, |
23 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
24 | | *****************************************************************************/ |
25 | | |
26 | | /***************************************************************************** |
27 | | * Preamble |
28 | | *****************************************************************************/ |
29 | | |
30 | | #ifdef HAVE_CONFIG_H |
31 | | # include "config.h" |
32 | | #endif |
33 | | |
34 | | #include <vlc_common.h> |
35 | | #include <vlc_plugin.h> |
36 | | #include <vlc_sout.h> |
37 | | #include <vlc_codec.h> |
38 | | #include <vlc_block.h> |
39 | | |
40 | | #include <vlc_block_helper.h> |
41 | | #include <vlc_bits.h> |
42 | | #include "h264_nal.h" |
43 | | #include "h264_slice.h" |
44 | | #include "hxxx_nal.h" |
45 | | #include "hxxx_sei.h" |
46 | | #include "hxxx_common.h" |
47 | | #include "packetizer_helper.h" |
48 | | #include "startcode_helper.h" |
49 | | |
50 | | #include <limits.h> |
51 | | |
52 | | /***************************************************************************** |
53 | | * Module descriptor |
54 | | *****************************************************************************/ |
55 | | static int Open ( vlc_object_t * ); |
56 | | static void Close( vlc_object_t * ); |
57 | | |
58 | 174 | vlc_module_begin () |
59 | 87 | set_subcategory( SUBCAT_SOUT_PACKETIZER ) |
60 | 87 | set_description( N_("H.264 video packetizer") ) |
61 | 87 | set_capability( "video packetizer", 50 ) |
62 | 174 | set_callbacks( Open, Close ) |
63 | 87 | vlc_module_end () |
64 | | |
65 | | |
66 | | /**************************************************************************** |
67 | | * Local prototypes |
68 | | ****************************************************************************/ |
69 | | |
70 | | typedef struct |
71 | | { |
72 | | /* */ |
73 | | packetizer_t packetizer; |
74 | | |
75 | | /* */ |
76 | | struct |
77 | | { |
78 | | block_t *p_head; |
79 | | block_t **pp_append; |
80 | | } frame, leading; |
81 | | |
82 | | /* a new sps/pps can be transmitted outside of iframes */ |
83 | | bool b_new_sps; |
84 | | bool b_new_pps; |
85 | | |
86 | | struct |
87 | | { |
88 | | block_t *p_block; |
89 | | h264_sequence_parameter_set_t *p_sps; |
90 | | } sps[H264_MAX_NUM_SPS]; |
91 | | struct |
92 | | { |
93 | | block_t *p_block; |
94 | | h264_picture_parameter_set_t *p_pps; |
95 | | } pps[H264_MAX_NUM_PPS]; |
96 | | struct |
97 | | { |
98 | | block_t *p_block; |
99 | | } spsext[H264_MAX_NUM_SPSEXT]; |
100 | | const h264_sequence_parameter_set_t *p_active_sps; |
101 | | const h264_picture_parameter_set_t *p_active_pps; |
102 | | |
103 | | /* avcC data */ |
104 | | uint8_t i_avcC_length_size; |
105 | | |
106 | | /* From SEI for current frame */ |
107 | | uint8_t i_pic_struct; |
108 | | uint8_t i_dpb_output_delay; |
109 | | unsigned i_recovery_frame_cnt; |
110 | | |
111 | | /* Current Slice Header */ |
112 | | h264_slice_t *p_slice; |
113 | | |
114 | | /* */ |
115 | | int i_next_block_flags; |
116 | | bool b_recovered; |
117 | | unsigned i_recoveryfnum; |
118 | | unsigned i_recoverystartfnum; |
119 | | |
120 | | /* POC */ |
121 | | h264_poc_context_t pocctx; |
122 | | struct |
123 | | { |
124 | | vlc_tick_t pts; |
125 | | int num; |
126 | | } prevdatedpoc; |
127 | | |
128 | | vlc_tick_t i_frame_pts; |
129 | | vlc_tick_t i_frame_dts; |
130 | | |
131 | | date_t dts; |
132 | | |
133 | | /* */ |
134 | | cc_storage_t *p_ccs; |
135 | | } decoder_sys_t; |
136 | | |
137 | 246k | #define BLOCK_FLAG_PRIVATE_AUD (1 << BLOCK_FLAG_PRIVATE_SHIFT) |
138 | 244k | #define BLOCK_FLAG_PRIVATE_SEI (2 << BLOCK_FLAG_PRIVATE_SHIFT) |
139 | 222k | #define BLOCK_FLAG_DROP (4 << BLOCK_FLAG_PRIVATE_SHIFT) |
140 | | |
141 | | static block_t *Packetize( decoder_t *, block_t ** ); |
142 | | static block_t *PacketizeAVC1( decoder_t *, block_t ** ); |
143 | | static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t * ); |
144 | | static void PacketizeFlush( decoder_t * ); |
145 | | |
146 | | static void PacketizeReset( void *p_private, bool b_broken ); |
147 | | static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * ); |
148 | | static int PacketizeValidate( void *p_private, block_t * ); |
149 | | static block_t * PacketizeDrain( void *p_private ); |
150 | | |
151 | | static block_t *ParseNALBlock( decoder_t *, bool *pb_ts_used, block_t * ); |
152 | | static inline block_t *ParseNALBlockW( void *opaque, bool *pb_ts_used, block_t *p_frag ) |
153 | 0 | { |
154 | 0 | return ParseNALBlock( (decoder_t *) opaque, pb_ts_used, p_frag ); |
155 | 0 | } |
156 | | |
157 | | static block_t *OutputPicture( decoder_t *p_dec ); |
158 | | static void ReleaseXPS( decoder_sys_t *p_sys ); |
159 | | static bool PutXPS( decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag ); |
160 | | static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag ); |
161 | | static bool ParseSeiCallback( const hxxx_sei_data_t *, void * ); |
162 | | |
163 | | |
164 | | |
165 | | /***************************************************************************** |
166 | | * Helpers |
167 | | *****************************************************************************/ |
168 | | static void LastAppendXPSCopy( const block_t *p_block, block_t ***ppp_last ) |
169 | 18.7M | { |
170 | 18.7M | if( !p_block ) |
171 | 18.5M | return; |
172 | 204k | block_t *p_dup = block_Alloc( 4 + p_block->i_buffer ); |
173 | 204k | if( p_dup ) |
174 | 204k | { |
175 | 204k | memcpy( &p_dup->p_buffer[0], annexb_startcode4, 4 ); |
176 | 204k | memcpy( &p_dup->p_buffer[4], p_block->p_buffer, p_block->i_buffer ); |
177 | 204k | block_ChainLastAppend( ppp_last, p_dup ); |
178 | 204k | } |
179 | 204k | } |
180 | | |
181 | | static block_t * GatherSets( decoder_sys_t *p_sys, bool b_need_sps, bool b_need_pps ) |
182 | 190k | { |
183 | 190k | block_t *p_xpsnal = NULL; |
184 | 190k | block_t **pp_xpsnal_tail = &p_xpsnal; |
185 | 1.96M | for( int i = 0; i <= H264_SPS_ID_MAX && b_need_sps; i++ ) |
186 | 1.77M | { |
187 | 1.77M | LastAppendXPSCopy( p_sys->sps[i].p_block, &pp_xpsnal_tail ); |
188 | | /* 7.4.1.2.3, shall be the next NAL unit after a sequence parameter set NAL unit |
189 | | * having the same value of seq_parameter_set_id */ |
190 | 1.77M | LastAppendXPSCopy( p_sys->spsext[i].p_block, &pp_xpsnal_tail ); |
191 | 1.77M | } |
192 | 15.3M | for( int i = 0; i < H264_PPS_ID_MAX && b_need_pps; i++ ) |
193 | 15.2M | LastAppendXPSCopy( p_sys->pps[i].p_block, &pp_xpsnal_tail ); |
194 | 190k | return p_xpsnal; |
195 | 190k | } |
196 | | |
197 | | static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t *p_sps, |
198 | | const h264_picture_parameter_set_t *p_pps ) |
199 | 247k | { |
200 | 247k | decoder_sys_t *p_sys = p_dec->p_sys; |
201 | | |
202 | 247k | p_sys->p_active_pps = p_pps; |
203 | 247k | p_sys->p_active_sps = p_sps; |
204 | | |
205 | 247k | if( p_sps ) |
206 | 247k | { |
207 | 247k | uint8_t pl[2]; |
208 | 247k | if( h264_get_sps_profile_tier_level( p_sps, pl, &pl[1] ) ) |
209 | 247k | { |
210 | 247k | p_dec->fmt_out.i_profile = pl[0]; |
211 | 247k | p_dec->fmt_out.i_level = pl[1]; |
212 | 247k | } |
213 | | |
214 | 247k | unsigned x_offset, y_offset, width, height, visible_width, visible_height; |
215 | 247k | if( h264_get_picture_size( p_sps, |
216 | 247k | &x_offset, &y_offset, |
217 | 247k | &width, &height, |
218 | 247k | &visible_width, &visible_height ) ) |
219 | 229k | { |
220 | 229k | p_dec->fmt_out.video.i_x_offset = x_offset; |
221 | 229k | p_dec->fmt_out.video.i_y_offset = y_offset; |
222 | 229k | p_dec->fmt_out.video.i_width = width; |
223 | 229k | p_dec->fmt_out.video.i_height = height; |
224 | 229k | p_dec->fmt_out.video.i_visible_width = visible_width; |
225 | 229k | p_dec->fmt_out.video.i_visible_height = visible_height; |
226 | 229k | } |
227 | | |
228 | 247k | h264_get_aspect_ratio( p_sps, |
229 | 247k | &p_dec->fmt_out.video.i_sar_num, |
230 | 247k | &p_dec->fmt_out.video.i_sar_den ); |
231 | | |
232 | 247k | if( !p_dec->fmt_out.video.i_frame_rate || |
233 | 240k | !p_dec->fmt_out.video.i_frame_rate_base ) |
234 | 6.35k | { |
235 | | /* on first run == if fmt_in does not provide frame rate info */ |
236 | | /* If we have frame rate info in the stream */ |
237 | 6.35k | unsigned nd[2]; |
238 | 6.35k | if( h264_get_frame_rate( p_sps, nd, &nd[1] ) ) |
239 | 1.52k | date_Change( &p_sys->dts, nd[0], nd[1] ); |
240 | | /* else use the default num/den */ |
241 | 6.35k | p_dec->fmt_out.video.i_frame_rate = p_sys->dts.i_divider_num >> 1; /* num_clock_ts == 2 */ |
242 | 6.35k | p_dec->fmt_out.video.i_frame_rate_base = p_sys->dts.i_divider_den; |
243 | 6.35k | } |
244 | | |
245 | 247k | if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF ) |
246 | 247k | { |
247 | 247k | h264_get_colorimetry( p_sps, &p_dec->fmt_out.video.primaries, |
248 | 247k | &p_dec->fmt_out.video.transfer, |
249 | 247k | &p_dec->fmt_out.video.space, |
250 | 247k | &p_dec->fmt_out.video.color_range ); |
251 | 247k | } |
252 | | |
253 | 247k | if( p_dec->fmt_out.i_extra == 0 && p_pps ) |
254 | 1.52k | { |
255 | 1.52k | block_t *p_xpsblocks = GatherSets( p_sys, true, true ); |
256 | 1.52k | if( p_xpsblocks ) |
257 | 1.52k | { |
258 | 1.52k | size_t i_total; |
259 | 1.52k | block_ChainProperties( p_xpsblocks, NULL, &i_total, NULL ); |
260 | 1.52k | p_dec->fmt_out.p_extra = malloc( i_total ); |
261 | 1.52k | if( p_dec->fmt_out.p_extra ) |
262 | 1.52k | { |
263 | 1.52k | p_dec->fmt_out.i_extra = i_total; |
264 | 1.52k | block_ChainExtract( p_xpsblocks, p_dec->fmt_out.p_extra, i_total ); |
265 | 1.52k | } |
266 | 1.52k | block_ChainRelease( p_xpsblocks ); |
267 | 1.52k | } |
268 | 1.52k | } |
269 | 247k | } |
270 | 247k | } |
271 | | |
272 | | static void DropStoredNAL( decoder_sys_t *p_sys ) |
273 | 242k | { |
274 | 242k | block_ChainRelease( p_sys->frame.p_head ); |
275 | 242k | block_ChainRelease( p_sys->leading.p_head ); |
276 | 242k | p_sys->frame.p_head = NULL; |
277 | 242k | p_sys->frame.pp_append = &p_sys->frame.p_head; |
278 | 242k | p_sys->leading.p_head = NULL; |
279 | 242k | p_sys->leading.pp_append = &p_sys->leading.p_head; |
280 | 242k | } |
281 | | |
282 | | /***************************************************************************** |
283 | | * Open: probe the packetizer and return score |
284 | | * When opening after demux, the packetizer is only loaded AFTER the decoder |
285 | | * That means that what you set in fmt_out is ignored by the decoder in this special case |
286 | | *****************************************************************************/ |
287 | | static int Open( vlc_object_t *p_this ) |
288 | 210k | { |
289 | 210k | decoder_t *p_dec = (decoder_t*)p_this; |
290 | 210k | decoder_sys_t *p_sys; |
291 | 210k | int i; |
292 | | |
293 | 210k | const bool b_avc = (p_dec->fmt_in->i_original_fourcc == VLC_FOURCC( 'a', 'v', 'c', '1' )); |
294 | | |
295 | 210k | if( p_dec->fmt_in->i_codec != VLC_CODEC_H264 ) |
296 | 141k | return VLC_EGENERIC; |
297 | 69.2k | if( b_avc && p_dec->fmt_in->i_extra < 7 ) |
298 | 40 | return VLC_EGENERIC; |
299 | | |
300 | | /* Allocate the memory needed to store the decoder's structure */ |
301 | 69.1k | if( ( p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) ) ) == NULL ) |
302 | 0 | { |
303 | 0 | return VLC_ENOMEM; |
304 | 0 | } |
305 | | |
306 | 69.1k | p_sys->p_ccs = cc_storage_new(); |
307 | 69.1k | if( unlikely(!p_sys->p_ccs) ) |
308 | 0 | { |
309 | 0 | free( p_sys ); |
310 | 0 | return VLC_ENOMEM; |
311 | 0 | } |
312 | | |
313 | 69.1k | packetizer_Init( &p_sys->packetizer, |
314 | 69.1k | annexb_startcode3, 3, startcode_FindAnnexB, |
315 | 69.1k | annexb_startcode3, 1, 5, |
316 | 69.1k | PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain, |
317 | 69.1k | p_dec ); |
318 | | |
319 | 69.1k | p_sys->p_slice = NULL; |
320 | 69.1k | p_sys->frame.p_head = NULL; |
321 | 69.1k | p_sys->frame.pp_append = &p_sys->frame.p_head; |
322 | 69.1k | p_sys->leading.p_head = NULL; |
323 | 69.1k | p_sys->leading.pp_append = &p_sys->leading.p_head; |
324 | 69.1k | p_sys->b_new_sps = false; |
325 | 69.1k | p_sys->b_new_pps = false; |
326 | | |
327 | 2.28M | for( i = 0; i < H264_MAX_NUM_SPS; i++ ) |
328 | 2.21M | { |
329 | 2.21M | p_sys->sps[i].p_sps = NULL; |
330 | 2.21M | p_sys->sps[i].p_block = NULL; |
331 | 2.21M | } |
332 | 69.1k | p_sys->p_active_sps = NULL; |
333 | 17.7M | for( i = 0; i < H264_MAX_NUM_PPS; i++ ) |
334 | 17.7M | { |
335 | 17.7M | p_sys->pps[i].p_pps = NULL; |
336 | 17.7M | p_sys->pps[i].p_block = NULL; |
337 | 17.7M | } |
338 | 69.1k | p_sys->p_active_pps = NULL; |
339 | 2.28M | for( i = 0; i < H264_MAX_NUM_SPSEXT; i++ ) |
340 | 2.21M | p_sys->spsext[i].p_block = NULL; |
341 | 69.1k | p_sys->i_recovery_frame_cnt = UINT_MAX; |
342 | | |
343 | 69.1k | p_sys->i_next_block_flags = 0; |
344 | 69.1k | p_sys->b_recovered = false; |
345 | 69.1k | p_sys->i_recoveryfnum = UINT_MAX; |
346 | 69.1k | p_sys->i_frame_dts = VLC_TICK_INVALID; |
347 | 69.1k | p_sys->i_frame_pts = VLC_TICK_INVALID; |
348 | 69.1k | p_sys->i_dpb_output_delay = 0; |
349 | | |
350 | | /* POC */ |
351 | 69.1k | h264_poc_context_init( &p_sys->pocctx ); |
352 | 69.1k | p_sys->prevdatedpoc.pts = VLC_TICK_INVALID; |
353 | | |
354 | 69.1k | date_Init( &p_sys->dts, 30000 * 2, 1001 ); |
355 | | |
356 | | /* Setup properties */ |
357 | 69.1k | es_format_Copy( &p_dec->fmt_out, p_dec->fmt_in ); |
358 | 69.1k | p_dec->fmt_out.i_codec = VLC_CODEC_H264; |
359 | 69.1k | p_dec->fmt_out.b_packetized = true; |
360 | | |
361 | 69.1k | if( p_dec->fmt_in->video.i_frame_rate_base && |
362 | 9 | p_dec->fmt_in->video.i_frame_rate && |
363 | 9 | p_dec->fmt_in->video.i_frame_rate <= UINT_MAX / 2 ) |
364 | 9 | { |
365 | 9 | date_Change( &p_sys->dts, p_dec->fmt_in->video.i_frame_rate * 2, |
366 | 9 | p_dec->fmt_in->video.i_frame_rate_base ); |
367 | 9 | } |
368 | | |
369 | 69.1k | if( b_avc ) |
370 | 0 | { |
371 | | /* This type of stream is produced by mp4 and matroska |
372 | | * when we want to store it in another streamformat, you need to convert |
373 | | * The fmt_in.p_extra should ALWAYS contain the avcC |
374 | | * The fmt_out.p_extra should contain all the SPS and PPS with 4 byte startcodes */ |
375 | 0 | if( h264_isavcC( p_dec->fmt_in->p_extra, p_dec->fmt_in->i_extra ) ) |
376 | 0 | { |
377 | 0 | size_t i_newextra_size; uint8_t *p_newextra; |
378 | 0 | if( !h264_avcC_to_AnnexB_NAL( p_dec->fmt_in->p_extra, |
379 | 0 | p_dec->fmt_in->i_extra, |
380 | 0 | &p_newextra, &i_newextra_size, |
381 | 0 | &p_sys->i_avcC_length_size ) ) |
382 | 0 | { |
383 | 0 | msg_Err( p_dec, "Invalid AVC extradata"); |
384 | 0 | Close( p_this ); |
385 | 0 | return VLC_EGENERIC; |
386 | 0 | } |
387 | 0 | free( p_dec->fmt_out.p_extra ); |
388 | 0 | p_dec->fmt_out.p_extra = p_newextra; |
389 | 0 | p_dec->fmt_out.i_extra = i_newextra_size; |
390 | 0 | p_sys->b_recovered = !!p_dec->fmt_out.i_extra; |
391 | 0 | } |
392 | 0 | else |
393 | 0 | { |
394 | 0 | msg_Err( p_dec, "Invalid or missing AVC extradata"); |
395 | 0 | Close( p_this ); |
396 | 0 | return VLC_EGENERIC; |
397 | 0 | } |
398 | | |
399 | | /* Set callback */ |
400 | 0 | p_dec->pf_packetize = PacketizeAVC1; |
401 | 0 | } |
402 | 69.1k | else |
403 | 69.1k | { |
404 | | /* This type of stream contains data with 3 of 4 byte startcodes |
405 | | * The fmt_in.p_extra MAY contain SPS/PPS with 4 byte startcodes |
406 | | * The fmt_out.p_extra should be the same */ |
407 | | |
408 | | /* Set callback */ |
409 | 69.1k | p_dec->pf_packetize = Packetize; |
410 | 69.1k | } |
411 | | |
412 | | /* */ |
413 | 69.1k | if( p_dec->fmt_out.i_extra > 0 ) |
414 | 46.6k | { |
415 | 46.6k | packetizer_Header( &p_sys->packetizer, |
416 | 46.6k | p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra ); |
417 | 46.6k | } |
418 | | |
419 | 69.1k | if( b_avc ) |
420 | 0 | { |
421 | | /* FIXME: that's not correct for every AVC */ |
422 | 0 | if( !p_sys->b_new_pps || !p_sys->b_new_sps ) |
423 | 0 | { |
424 | 0 | msg_Err( p_dec, "Invalid or missing SPS %d or PPS %d in AVC extradata", |
425 | 0 | p_sys->b_new_sps, p_sys->b_new_pps ); |
426 | 0 | Close( p_this ); |
427 | 0 | return VLC_EGENERIC; |
428 | 0 | } |
429 | | |
430 | 0 | msg_Dbg( p_dec, "Packetizer fed with AVC, nal length size=%d", |
431 | 0 | p_sys->i_avcC_length_size ); |
432 | 0 | } |
433 | | |
434 | | /* CC are the same for H264/AVC in T35 sections (ETSI TS 101 154) */ |
435 | 69.1k | p_dec->pf_get_cc = GetCc; |
436 | 69.1k | p_dec->pf_flush = PacketizeFlush; |
437 | | |
438 | 69.1k | return VLC_SUCCESS; |
439 | 69.1k | } |
440 | | |
441 | | /***************************************************************************** |
442 | | * Close: clean up the packetizer |
443 | | *****************************************************************************/ |
444 | | static void Close( vlc_object_t *p_this ) |
445 | 69.1k | { |
446 | 69.1k | decoder_t *p_dec = (decoder_t*)p_this; |
447 | 69.1k | decoder_sys_t *p_sys = p_dec->p_sys; |
448 | | |
449 | 69.1k | DropStoredNAL( p_sys ); |
450 | 69.1k | ReleaseXPS( p_sys ); |
451 | | |
452 | 69.1k | if( p_sys->p_slice ) |
453 | 0 | h264_slice_release( p_sys->p_slice ); |
454 | | |
455 | 69.1k | packetizer_Clean( &p_sys->packetizer ); |
456 | | |
457 | 69.1k | cc_storage_delete( p_sys->p_ccs ); |
458 | | |
459 | 69.1k | free( p_sys ); |
460 | 69.1k | } |
461 | | |
462 | | static void PacketizeFlush( decoder_t *p_dec ) |
463 | 0 | { |
464 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
465 | |
|
466 | 0 | packetizer_Flush( &p_sys->packetizer ); |
467 | 0 | } |
468 | | |
469 | | /**************************************************************************** |
470 | | * Packetize: the whole thing |
471 | | * Search for the startcodes 3 or more bytes |
472 | | * Feed ParseNALBlock ALWAYS with 4 byte startcode prepended NALs |
473 | | ****************************************************************************/ |
474 | | static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) |
475 | 539k | { |
476 | 539k | decoder_sys_t *p_sys = p_dec->p_sys; |
477 | | |
478 | 539k | return packetizer_Packetize( &p_sys->packetizer, pp_block ); |
479 | 539k | } |
480 | | |
481 | | /**************************************************************************** |
482 | | * PacketizeAVC1: Takes VCL blocks of data and creates annexe B type NAL stream |
483 | | * Will always use 4 byte 0 0 0 1 startcodes |
484 | | * Will prepend a SPS and PPS before each keyframe |
485 | | ****************************************************************************/ |
486 | | static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block ) |
487 | 0 | { |
488 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
489 | |
|
490 | 0 | return PacketizeXXC1( p_dec, p_dec->obj.logger, |
491 | 0 | p_sys->i_avcC_length_size, pp_block, |
492 | 0 | ParseNALBlockW, PacketizeDrain ); |
493 | 0 | } |
494 | | |
495 | | /***************************************************************************** |
496 | | * GetCc: |
497 | | *****************************************************************************/ |
498 | | static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc ) |
499 | 155k | { |
500 | 155k | decoder_sys_t *p_sys = p_dec->p_sys; |
501 | 155k | return cc_storage_get_current( p_sys->p_ccs, p_desc ); |
502 | 155k | } |
503 | | |
504 | | /**************************************************************************** |
505 | | * Helpers |
506 | | ****************************************************************************/ |
507 | | static void ResetOutputVariables( decoder_sys_t *p_sys ) |
508 | 353k | { |
509 | 353k | p_sys->i_frame_dts = VLC_TICK_INVALID; |
510 | 353k | p_sys->i_frame_pts = VLC_TICK_INVALID; |
511 | 353k | if( p_sys->p_slice ) |
512 | 214k | h264_slice_release( p_sys->p_slice ); |
513 | 353k | p_sys->p_slice = NULL; |
514 | 353k | p_sys->b_new_sps = false; |
515 | 353k | p_sys->b_new_pps = false; |
516 | | /* From SEI */ |
517 | 353k | p_sys->i_dpb_output_delay = 0; |
518 | 353k | p_sys->i_pic_struct = UINT8_MAX; |
519 | 353k | p_sys->i_recovery_frame_cnt = UINT_MAX; |
520 | 353k | } |
521 | | |
522 | | static void PacketizeReset( void *p_private, bool b_flush ) |
523 | 189k | { |
524 | 189k | decoder_t *p_dec = p_private; |
525 | 189k | decoder_sys_t *p_sys = p_dec->p_sys; |
526 | | |
527 | 189k | if( b_flush || !p_sys->p_slice ) |
528 | 138k | { |
529 | 138k | DropStoredNAL( p_sys ); |
530 | 138k | ResetOutputVariables( p_sys ); |
531 | 138k | p_sys->p_active_pps = NULL; |
532 | 138k | p_sys->p_active_sps = NULL; |
533 | 138k | p_sys->b_recovered = false; |
534 | 138k | p_sys->i_recoveryfnum = UINT_MAX; |
535 | | /* POC */ |
536 | 138k | h264_poc_context_init( &p_sys->pocctx ); |
537 | 138k | p_sys->prevdatedpoc.pts = VLC_TICK_INVALID; |
538 | 138k | } |
539 | 189k | p_sys->i_next_block_flags = BLOCK_FLAG_DISCONTINUITY; |
540 | 189k | date_Set( &p_sys->dts, VLC_TICK_INVALID ); |
541 | 189k | } |
542 | | static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block ) |
543 | 1.66M | { |
544 | 1.66M | decoder_t *p_dec = p_private; |
545 | | |
546 | | /* Remove trailing 0 bytes */ |
547 | 195M | while( p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 ) |
548 | 193M | p_block->i_buffer--; |
549 | | |
550 | 1.66M | return ParseNALBlock( p_dec, pb_ts_used, p_block ); |
551 | 1.66M | } |
552 | | static int PacketizeValidate( void *p_private, block_t *p_au ) |
553 | 155k | { |
554 | 155k | VLC_UNUSED(p_private); |
555 | 155k | VLC_UNUSED(p_au); |
556 | 155k | return VLC_SUCCESS; |
557 | 155k | } |
558 | | |
559 | | static block_t * PacketizeDrain( void *p_private ) |
560 | 118k | { |
561 | 118k | decoder_t *p_dec = p_private; |
562 | 118k | decoder_sys_t *p_sys = p_dec->p_sys; |
563 | | |
564 | 118k | if( !p_sys->p_slice ) |
565 | 114k | return NULL; |
566 | | |
567 | 3.92k | block_t *p_out = OutputPicture( p_dec ); |
568 | 3.92k | if( p_out && (p_out->i_flags & BLOCK_FLAG_DROP) ) |
569 | 781 | { |
570 | 781 | block_Release( p_out ); |
571 | 781 | p_out = NULL; |
572 | 781 | } |
573 | | |
574 | 3.92k | return p_out; |
575 | 118k | } |
576 | | |
577 | | /***************************************************************************** |
578 | | * ParseNALBlock: parses annexB type NALs |
579 | | * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode |
580 | | *****************************************************************************/ |
581 | | static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_frag ) |
582 | 1.66M | { |
583 | 1.66M | decoder_sys_t *p_sys = p_dec->p_sys; |
584 | 1.66M | block_t *p_pic = NULL; |
585 | | |
586 | 1.66M | const enum h264_nal_unit_type_e i_nal_type = h264_getNALType( &p_frag->p_buffer[4] ); |
587 | 1.66M | const vlc_tick_t i_frag_dts = p_frag->i_dts; |
588 | 1.66M | const vlc_tick_t i_frag_pts = p_frag->i_pts; |
589 | 1.66M | bool b_au_end = p_frag->i_flags & BLOCK_FLAG_AU_END; |
590 | 1.66M | p_frag->i_flags &= ~BLOCK_FLAG_AU_END; |
591 | | |
592 | 1.66M | if( p_sys->p_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) ) |
593 | 25.7k | { |
594 | 25.7k | msg_Warn( p_dec, "waiting for SPS/PPS" ); |
595 | | |
596 | | /* Reset context */ |
597 | 25.7k | DropStoredNAL( p_sys ); |
598 | 25.7k | ResetOutputVariables( p_sys ); |
599 | 25.7k | cc_storage_reset( p_sys->p_ccs ); |
600 | 25.7k | } |
601 | | |
602 | 1.66M | switch( i_nal_type ) |
603 | 1.66M | { |
604 | | /*** Slices ***/ |
605 | 186k | case H264_NAL_SLICE: |
606 | 269k | case H264_NAL_SLICE_DPA: |
607 | 299k | case H264_NAL_SLICE_DPB: |
608 | 365k | case H264_NAL_SLICE_DPC: |
609 | 465k | case H264_NAL_SLICE_IDR: |
610 | 465k | { |
611 | 465k | h264_slice_t *p_newslice; |
612 | | |
613 | 465k | if( i_nal_type == H264_NAL_SLICE_IDR ) |
614 | 100k | { |
615 | 100k | p_sys->b_recovered = true; |
616 | 100k | p_sys->i_recovery_frame_cnt = UINT_MAX; |
617 | 100k | p_sys->i_recoveryfnum = UINT_MAX; |
618 | 100k | } |
619 | | |
620 | 465k | if( (p_newslice = ParseSliceHeader( p_dec, p_frag )) ) |
621 | 247k | { |
622 | | /* Only IDR carries the id, to be propagated */ |
623 | 247k | h264_slice_copy_idr_id( p_sys->p_slice, p_newslice ); |
624 | | |
625 | 247k | bool b_new_picture = h264_IsFirstVCLNALUnit( p_sys->p_slice, p_newslice ); |
626 | 247k | if( b_new_picture ) |
627 | 214k | { |
628 | | /* Parse SEI for that frame now we should have matched SPS/PPS */ |
629 | 357k | for( block_t *p_sei = p_sys->leading.p_head; p_sei; p_sei = p_sei->p_next ) |
630 | 142k | { |
631 | 142k | if( (p_sei->i_flags & BLOCK_FLAG_PRIVATE_SEI) == 0 ) |
632 | 57.3k | continue; |
633 | 85.0k | HxxxParse_AnnexB_SEI( p_sei->p_buffer, p_sei->i_buffer, |
634 | 85.0k | 1 /* nal header */, ParseSeiCallback, p_dec ); |
635 | 85.0k | } |
636 | | |
637 | 214k | if( p_sys->p_slice ) |
638 | 87.9k | p_pic = OutputPicture( p_dec ); |
639 | 214k | } |
640 | | |
641 | | /* */ |
642 | 247k | h264_slice_release( p_sys->p_slice ); |
643 | 247k | p_sys->p_slice = p_newslice; |
644 | 247k | } |
645 | 218k | else |
646 | 218k | { |
647 | 218k | p_sys->p_active_pps = NULL; |
648 | | /* Fragment will be discarded later on */ |
649 | 218k | } |
650 | | |
651 | 465k | block_ChainLastAppend( &p_sys->frame.pp_append, p_frag ); |
652 | 465k | } break; |
653 | | |
654 | | /*** Prefix NALs ***/ |
655 | | |
656 | 8.17k | case H264_NAL_AU_DELIMITER: |
657 | 8.17k | if( p_sys->p_slice ) |
658 | 1.02k | p_pic = OutputPicture( p_dec ); |
659 | | |
660 | | /* clear junk if no pic, we're always the first nal */ |
661 | 8.17k | DropStoredNAL( p_sys ); |
662 | | |
663 | 8.17k | p_frag->i_flags |= BLOCK_FLAG_PRIVATE_AUD; |
664 | | |
665 | 8.17k | block_ChainLastAppend( &p_sys->leading.pp_append, p_frag ); |
666 | 8.17k | break; |
667 | | |
668 | 254k | case H264_NAL_SPS: |
669 | 480k | case H264_NAL_PPS: |
670 | 480k | if( p_sys->p_slice ) |
671 | 65.1k | p_pic = OutputPicture( p_dec ); |
672 | | |
673 | | /* Stored for insert on keyframes */ |
674 | 480k | if( i_nal_type == H264_NAL_SPS ) |
675 | 254k | p_sys->b_new_sps |= PutXPS( p_dec, i_nal_type, p_frag ); |
676 | 226k | else |
677 | 226k | p_sys->b_new_pps |= PutXPS( p_dec, i_nal_type, p_frag ); |
678 | 480k | break; |
679 | | |
680 | 101k | case H264_NAL_SEI: |
681 | 101k | if( p_sys->p_slice ) |
682 | 16.6k | p_pic = OutputPicture( p_dec ); |
683 | | |
684 | 101k | p_frag->i_flags |= BLOCK_FLAG_PRIVATE_SEI; |
685 | 101k | block_ChainLastAppend( &p_sys->leading.pp_append, p_frag ); |
686 | 101k | break; |
687 | | |
688 | 17.4k | case H264_NAL_SPS_EXT: |
689 | 17.4k | PutXPS( p_dec, i_nal_type, p_frag ); |
690 | 17.4k | if( p_sys->p_slice ) |
691 | 1.35k | p_pic = OutputPicture( p_dec ); |
692 | 17.4k | break; |
693 | | |
694 | 5.49k | case H264_NAL_PREFIX: /* first slice/VCL associated data */ |
695 | 17.0k | case H264_NAL_SUBSET_SPS: |
696 | 34.5k | case H264_NAL_DEPTH_PS: |
697 | 51.3k | case H264_NAL_RESERVED_17: |
698 | 70.1k | case H264_NAL_RESERVED_18: |
699 | 70.1k | if( p_sys->p_slice ) |
700 | 9.69k | p_pic = OutputPicture( p_dec ); |
701 | | |
702 | 70.1k | block_ChainLastAppend( &p_sys->leading.pp_append, p_frag ); |
703 | 70.1k | break; |
704 | | |
705 | | /*** Suffix NALs ***/ |
706 | | |
707 | 4.06k | case H264_NAL_END_OF_SEQ: |
708 | 26.4k | case H264_NAL_END_OF_STREAM: |
709 | | /* Early end of packetization */ |
710 | 26.4k | block_ChainLastAppend( &p_sys->frame.pp_append, p_frag ); |
711 | | |
712 | | /* important for still pictures/menus */ |
713 | 26.4k | p_sys->i_next_block_flags |= BLOCK_FLAG_END_OF_SEQUENCE; |
714 | 26.4k | if( p_sys->p_slice ) |
715 | 3.38k | p_pic = OutputPicture( p_dec ); |
716 | 26.4k | break; |
717 | | |
718 | 27.3k | case H264_NAL_SLICE_WP: // post |
719 | 289k | case H264_NAL_UNKNOWN: |
720 | 312k | case H264_NAL_FILLER_DATA: |
721 | 324k | case H264_NAL_SLICE_EXT: |
722 | 335k | case H264_NAL_SLICE_3D_EXT: |
723 | 344k | case H264_NAL_RESERVED_22: |
724 | 347k | case H264_NAL_RESERVED_23: |
725 | 498k | default: /* others 24..31, including unknown */ |
726 | 498k | block_ChainLastAppend( &p_sys->frame.pp_append, p_frag ); |
727 | 498k | break; |
728 | 1.66M | } |
729 | | |
730 | 1.66M | *pb_ts_used = false; |
731 | 1.66M | if( p_sys->i_frame_dts == VLC_TICK_INVALID && |
732 | 1.39M | p_sys->i_frame_pts == VLC_TICK_INVALID ) |
733 | 1.24M | { |
734 | 1.24M | p_sys->i_frame_dts = i_frag_dts; |
735 | 1.24M | p_sys->i_frame_pts = i_frag_pts; |
736 | 1.24M | *pb_ts_used = true; |
737 | 1.24M | if( i_frag_dts != VLC_TICK_INVALID ) |
738 | 39.2k | date_Set( &p_sys->dts, i_frag_dts ); |
739 | 1.24M | } |
740 | | |
741 | 1.66M | if( p_sys->p_slice && b_au_end && !p_pic ) |
742 | 0 | { |
743 | 0 | p_pic = OutputPicture( p_dec ); |
744 | 0 | } |
745 | | |
746 | 1.66M | if( p_pic && (p_pic->i_flags & BLOCK_FLAG_DROP) ) |
747 | 32.6k | { |
748 | 32.6k | block_Release( p_pic ); |
749 | 32.6k | p_pic = NULL; |
750 | 32.6k | } |
751 | | |
752 | 1.66M | return p_pic; |
753 | 1.66M | } |
754 | | |
755 | | static block_t *OutputPicture( decoder_t *p_dec ) |
756 | 189k | { |
757 | 189k | decoder_sys_t *p_sys = p_dec->p_sys; |
758 | 189k | block_t *p_pic = NULL; |
759 | 189k | block_t **pp_pic_last = &p_pic; |
760 | | |
761 | 189k | if( unlikely(!p_sys->frame.p_head) ) |
762 | 0 | { |
763 | 0 | assert( p_sys->frame.p_head ); |
764 | 0 | DropStoredNAL( p_sys ); |
765 | 0 | ResetOutputVariables( p_sys ); |
766 | 0 | cc_storage_reset( p_sys->p_ccs ); |
767 | 0 | return NULL; |
768 | 0 | } |
769 | | |
770 | | /* Bind matched/referred PPS and SPS */ |
771 | 189k | const h264_picture_parameter_set_t *p_pps = p_sys->p_active_pps; |
772 | 189k | const h264_sequence_parameter_set_t *p_sps = p_sys->p_active_sps; |
773 | 189k | if( !p_pps || !p_sps ) |
774 | 329 | { |
775 | 329 | DropStoredNAL( p_sys ); |
776 | 329 | ResetOutputVariables( p_sys ); |
777 | 329 | cc_storage_reset( p_sys->p_ccs ); |
778 | 329 | return NULL; |
779 | 329 | } |
780 | | |
781 | 188k | if( !p_sys->b_recovered && p_sys->i_recoveryfnum == UINT_MAX && |
782 | 37.5k | p_sys->i_recovery_frame_cnt == UINT_MAX && h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I ) |
783 | 1.42k | { |
784 | | /* No way to recover using SEI, just sync on I Slice */ |
785 | 1.42k | p_sys->b_recovered = true; |
786 | 1.42k | } |
787 | | |
788 | 188k | bool b_need_sps_pps = h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I && |
789 | 32.5k | p_sys->p_active_pps && p_sys->p_active_sps; |
790 | | |
791 | 188k | const unsigned i_frame_num = h264_get_frame_num(p_sys->p_slice); |
792 | | |
793 | | /* Handle SEI recovery */ |
794 | 188k | if ( !p_sys->b_recovered && p_sys->i_recovery_frame_cnt != UINT_MAX && |
795 | 4.05k | p_sys->i_recoveryfnum == UINT_MAX ) |
796 | 2.73k | { |
797 | 2.73k | p_sys->i_recoveryfnum = i_frame_num + p_sys->i_recovery_frame_cnt; |
798 | 2.73k | p_sys->i_recoverystartfnum = i_frame_num; |
799 | 2.73k | b_need_sps_pps = true; /* SPS/PPS must be inserted for SEI recovery */ |
800 | 2.73k | msg_Dbg( p_dec, "Recovering using SEI, prerolling %u reference pics", p_sys->i_recovery_frame_cnt ); |
801 | 2.73k | } |
802 | | |
803 | 188k | if( p_sys->i_recoveryfnum != UINT_MAX ) |
804 | 13.9k | { |
805 | 13.9k | assert(p_sys->b_recovered == false); |
806 | 13.9k | const unsigned maxFrameNum = h264_get_max_frame_num( p_sps ); |
807 | | |
808 | 13.9k | if( ( p_sys->i_recoveryfnum > maxFrameNum && |
809 | 8.37k | i_frame_num < p_sys->i_recoverystartfnum && |
810 | 2.91k | i_frame_num >= p_sys->i_recoveryfnum % maxFrameNum ) || |
811 | 13.7k | ( p_sys->i_recoveryfnum <= maxFrameNum && |
812 | 5.54k | i_frame_num >= p_sys->i_recoveryfnum ) ) |
813 | 1.09k | { |
814 | 1.09k | p_sys->i_recoveryfnum = UINT_MAX; |
815 | 1.09k | p_sys->b_recovered = true; |
816 | 1.09k | msg_Dbg( p_dec, "Recovery from SEI recovery point complete" ); |
817 | 1.09k | } |
818 | 13.9k | } |
819 | | |
820 | | /* Gather PPS/SPS if required */ |
821 | 188k | block_t *p_xpsnal = GatherSets( p_sys, b_need_sps_pps|p_sys->b_new_sps, |
822 | 188k | b_need_sps_pps|p_sys->b_new_pps ); |
823 | | |
824 | | /* Now rebuild NAL Sequence, inserting PPS/SPS if any */ |
825 | 188k | if( p_sys->leading.p_head && |
826 | 49.8k | (p_sys->leading.p_head->i_flags & BLOCK_FLAG_PRIVATE_AUD) ) |
827 | 1.95k | { |
828 | 1.95k | block_t *p_au = p_sys->leading.p_head; |
829 | 1.95k | p_sys->leading.p_head = p_au->p_next; |
830 | 1.95k | p_au->p_next = NULL; |
831 | 1.95k | block_ChainLastAppend( &pp_pic_last, p_au ); |
832 | 1.95k | } |
833 | | |
834 | 188k | if( p_xpsnal ) |
835 | 68.9k | block_ChainLastAppend( &pp_pic_last, p_xpsnal ); |
836 | | |
837 | 188k | if( p_sys->leading.p_head ) |
838 | 48.3k | block_ChainLastAppend( &pp_pic_last, p_sys->leading.p_head ); |
839 | | |
840 | 188k | assert( p_sys->frame.p_head ); |
841 | 188k | if( p_sys->frame.p_head ) |
842 | 188k | block_ChainLastAppend( &pp_pic_last, p_sys->frame.p_head ); |
843 | | |
844 | | /* Reset chains, now empty */ |
845 | 188k | p_sys->frame.p_head = NULL; |
846 | 188k | p_sys->frame.pp_append = &p_sys->frame.p_head; |
847 | 188k | p_sys->leading.p_head = NULL; |
848 | 188k | p_sys->leading.pp_append = &p_sys->leading.p_head; |
849 | | |
850 | 188k | p_pic = block_ChainGather( p_pic ); |
851 | | |
852 | 188k | if( !p_pic ) |
853 | 0 | { |
854 | 0 | ResetOutputVariables( p_sys ); |
855 | 0 | cc_storage_reset( p_sys->p_ccs ); |
856 | 0 | return NULL; |
857 | 0 | } |
858 | | |
859 | | /* clear up flags gathered */ |
860 | 188k | p_pic->i_flags &= ~BLOCK_FLAG_PRIVATE_MASK; |
861 | | |
862 | | /* for PTS Fixup, interlaced fields (multiple AU/block) */ |
863 | 188k | int tFOC = 0, bFOC = 0, PictureOrderCount = 0; |
864 | 188k | h264_compute_poc( p_sps, p_sys->p_slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC ); |
865 | | |
866 | 188k | unsigned i_num_clock_ts = h264_get_num_ts( p_sps, p_sys->p_slice, p_sys->i_pic_struct, tFOC, bFOC ); |
867 | | |
868 | 188k | if( !h264_is_frames_only( p_sps ) && p_sys->i_pic_struct != UINT8_MAX ) |
869 | 4.64k | { |
870 | 4.64k | switch( p_sys->i_pic_struct ) |
871 | 4.64k | { |
872 | | /* Top and Bottom field slices */ |
873 | 284 | case 1: |
874 | 2.26k | case 2: |
875 | 2.26k | p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD; |
876 | 2.26k | p_pic->i_flags |= h264_slice_top_field(p_sys->p_slice) ? BLOCK_FLAG_TOP_FIELD_FIRST |
877 | 2.26k | : BLOCK_FLAG_BOTTOM_FIELD_FIRST; |
878 | 2.26k | break; |
879 | | /* Each of the following slices contains multiple fields */ |
880 | 61 | case 3: |
881 | 61 | p_pic->i_flags |= BLOCK_FLAG_TOP_FIELD_FIRST; |
882 | 61 | break; |
883 | 318 | case 4: |
884 | 318 | p_pic->i_flags |= BLOCK_FLAG_BOTTOM_FIELD_FIRST; |
885 | 318 | break; |
886 | 145 | case 5: |
887 | 145 | p_pic->i_flags |= BLOCK_FLAG_TOP_FIELD_FIRST; |
888 | 145 | break; |
889 | 290 | case 6: |
890 | 290 | p_pic->i_flags |= BLOCK_FLAG_BOTTOM_FIELD_FIRST; |
891 | 290 | break; |
892 | 1.56k | default: |
893 | 1.56k | break; |
894 | 4.64k | } |
895 | 4.64k | } |
896 | | |
897 | | /* set dts/pts to current block timestamps */ |
898 | 188k | p_pic->i_dts = p_sys->i_frame_dts; |
899 | 188k | p_pic->i_pts = p_sys->i_frame_pts; |
900 | | |
901 | | /* Fixup missing timestamps after split (multiple AU/block)*/ |
902 | 188k | if( p_pic->i_dts == VLC_TICK_INVALID ) |
903 | 180k | p_pic->i_dts = date_Get( &p_sys->dts ); |
904 | | |
905 | 188k | if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I ) |
906 | 32.5k | p_sys->prevdatedpoc.pts = VLC_TICK_INVALID; |
907 | | |
908 | 188k | if( p_pic->i_pts == VLC_TICK_INVALID ) |
909 | 152k | { |
910 | 152k | if( p_sys->prevdatedpoc.pts != VLC_TICK_INVALID && |
911 | 76.8k | date_Get( &p_sys->dts ) != VLC_TICK_INVALID ) |
912 | 69.0k | { |
913 | 69.0k | date_t pts = p_sys->dts; |
914 | 69.0k | date_Set( &pts, p_sys->prevdatedpoc.pts ); |
915 | | |
916 | 69.0k | int diff = tFOC - p_sys->prevdatedpoc.num; |
917 | 69.0k | if( diff > 0 ) |
918 | 18.1k | date_Increment( &pts, diff ); |
919 | 50.9k | else |
920 | 50.9k | date_Decrement( &pts, -diff ); |
921 | | |
922 | 69.0k | p_pic->i_pts = date_Get( &pts ); |
923 | | /* non monotonically increasing dts on some videos 33333 33333...35000 */ |
924 | 69.0k | if( p_pic->i_pts < p_pic->i_dts ) |
925 | 36.7k | p_pic->i_pts = p_pic->i_dts; |
926 | 69.0k | } |
927 | | /* In case there's no PTS at all */ |
928 | 83.5k | else if( h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) ) |
929 | 53.9k | { |
930 | 53.9k | p_pic->i_pts = p_pic->i_dts; |
931 | 53.9k | } |
932 | 29.6k | else if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I && |
933 | 10.4k | date_Get( &p_sys->dts ) != VLC_TICK_INVALID ) |
934 | 743 | { |
935 | | /* Hell no PTS on IDR. We're totally blind */ |
936 | 743 | date_t pts = p_sys->dts; |
937 | 743 | date_Increment( &pts, 2 ); |
938 | 743 | p_pic->i_pts = date_Get( &pts ); |
939 | 743 | } |
940 | 152k | } |
941 | 36.1k | else if( p_pic->i_dts == VLC_TICK_INVALID && |
942 | 28.0k | h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) ) |
943 | 12.4k | { |
944 | 12.4k | p_pic->i_dts = p_pic->i_pts; |
945 | 12.4k | if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID ) |
946 | 12.4k | date_Set( &p_sys->dts, p_pic->i_pts ); |
947 | 12.4k | } |
948 | | |
949 | 188k | if( p_pic->i_pts != VLC_TICK_INVALID ) |
950 | 108k | { |
951 | 108k | p_sys->prevdatedpoc.pts = p_pic->i_pts; |
952 | 108k | p_sys->prevdatedpoc.num = PictureOrderCount; |
953 | 108k | } |
954 | | |
955 | 188k | if( p_pic->i_length == 0 ) |
956 | 188k | { |
957 | 188k | date_t next = p_sys->dts; |
958 | 188k | date_Increment( &next, i_num_clock_ts ); |
959 | 188k | p_pic->i_length = date_Get( &next ) - date_Get( &p_sys->dts ); |
960 | 188k | } |
961 | | |
962 | | #if 0 |
963 | | msg_Err(p_dec, "F/BOC %d/%d POC %d %d rec %d flags %x ref%d fn %d fp %d %ld pts %ld len %ld", |
964 | | tFOC, bFOC, PictureOrderCount, |
965 | | h264_get_slice_type(p_sys->p_slice), p_sys->b_recovered, p_pic->i_flags, |
966 | | h264_get_nal_ref_idc(p_sys->p_slice), h264_get_frame_num(p_sys->p_slice), |
967 | | h264_is_field_pic(p_sys->p_slice), |
968 | | p_pic->i_pts - p_pic->i_dts, p_pic->i_pts % VLC_TICK_FROM_SEC(100), p_pic->i_length); |
969 | | #endif |
970 | | |
971 | | /* save for next pic fixups */ |
972 | 188k | if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID ) |
973 | 92.5k | { |
974 | 92.5k | if( p_sys->i_next_block_flags & BLOCK_FLAG_DISCONTINUITY ) |
975 | 14.0k | date_Set( &p_sys->dts, VLC_TICK_INVALID ); |
976 | 78.5k | else |
977 | 78.5k | date_Increment( &p_sys->dts, i_num_clock_ts ); |
978 | 92.5k | } |
979 | | |
980 | 188k | if( p_pic ) |
981 | 188k | { |
982 | 188k | p_pic->i_flags |= p_sys->i_next_block_flags; |
983 | 188k | p_sys->i_next_block_flags = 0; |
984 | 188k | } |
985 | | |
986 | 188k | switch( h264_get_slice_type( p_sys->p_slice ) ) |
987 | 188k | { |
988 | 118k | case H264_SLICE_TYPE_P: |
989 | 118k | p_pic->i_flags |= BLOCK_FLAG_TYPE_P; |
990 | 118k | break; |
991 | 15.0k | case H264_SLICE_TYPE_B: |
992 | 15.0k | p_pic->i_flags |= BLOCK_FLAG_TYPE_B; |
993 | 15.0k | break; |
994 | 32.5k | case H264_SLICE_TYPE_I: |
995 | 32.5k | p_pic->i_flags |= BLOCK_FLAG_TYPE_I; |
996 | 55.2k | default: |
997 | 55.2k | break; |
998 | 188k | } |
999 | | |
1000 | 188k | if( !p_sys->b_recovered ) |
1001 | 46.2k | { |
1002 | 46.2k | if( p_sys->i_recoveryfnum != UINT_MAX ) /* recovering from SEI */ |
1003 | 12.8k | p_pic->i_flags |= BLOCK_FLAG_PREROLL; |
1004 | 33.3k | else |
1005 | 33.3k | p_pic->i_flags |= BLOCK_FLAG_DROP; |
1006 | 46.2k | } |
1007 | | |
1008 | 188k | p_pic->i_flags &= ~BLOCK_FLAG_PRIVATE_AUD; |
1009 | | |
1010 | | /* reset after output */ |
1011 | 188k | ResetOutputVariables( p_sys ); |
1012 | | |
1013 | | /* CC */ |
1014 | 188k | cc_storage_commit( p_sys->p_ccs, p_pic ); |
1015 | | |
1016 | 188k | return p_pic; |
1017 | 188k | } |
1018 | | |
1019 | | static int CmpXPS( const block_t *p_ref, const block_t *p_nal ) |
1020 | 453k | { |
1021 | 453k | return p_ref == NULL || |
1022 | 338k | p_ref->i_buffer != p_nal->i_buffer || |
1023 | 102k | memcmp( p_ref->p_buffer, p_nal->p_buffer, p_nal->i_buffer ); |
1024 | 453k | } |
1025 | | |
1026 | | #define wrap_h264_xps_decode(funcname ) \ |
1027 | | static void *funcname ## _wrapper ( const uint8_t *a, size_t b, bool c ) \ |
1028 | 360k | { return funcname(a,b,c); }h264.c:h264_decode_sps_wrapper Line | Count | Source | 1028 | 199k | { return funcname(a,b,c); } |
h264.c:h264_decode_pps_wrapper Line | Count | Source | 1028 | 160k | { return funcname(a,b,c); } |
|
1029 | | |
1030 | | wrap_h264_xps_decode(h264_decode_sps) |
1031 | | wrap_h264_xps_decode(h264_decode_pps) |
1032 | | |
1033 | | #define wrap_h264_xps_release(funcname, typecast) \ |
1034 | 167k | static void funcname ## _wrapper ( void *a ) { funcname((typecast *)a); }h264.c:h264_release_sps_wrapper Line | Count | Source | 1034 | 72.8k | static void funcname ## _wrapper ( void *a ) { funcname((typecast *)a); } |
h264.c:h264_release_pps_wrapper Line | Count | Source | 1034 | 94.3k | static void funcname ## _wrapper ( void *a ) { funcname((typecast *)a); } |
|
1035 | | |
1036 | | wrap_h264_xps_release(h264_release_sps, h264_sequence_parameter_set_t) |
1037 | | wrap_h264_xps_release(h264_release_pps, h264_picture_parameter_set_t) |
1038 | | |
1039 | | static void ReleaseXPS( decoder_sys_t *p_sys ) |
1040 | 69.1k | { |
1041 | 2.28M | for( int i = 0; i < H264_MAX_NUM_SPS; i++ ) |
1042 | 2.21M | { |
1043 | 2.21M | if( !p_sys->sps[i].p_block ) |
1044 | 2.19M | continue; |
1045 | 14.7k | block_Release( p_sys->sps[i].p_block ); |
1046 | 14.7k | h264_release_sps( p_sys->sps[i].p_sps ); |
1047 | 14.7k | } |
1048 | 17.7M | for( int i = 0; i < H264_MAX_NUM_PPS; i++ ) |
1049 | 17.7M | { |
1050 | 17.7M | if( !p_sys->pps[i].p_block ) |
1051 | 17.6M | continue; |
1052 | 17.1k | block_Release( p_sys->pps[i].p_block ); |
1053 | 17.1k | h264_release_pps( p_sys->pps[i].p_pps ); |
1054 | 17.1k | } |
1055 | 2.28M | for( int i = 0; i < H264_MAX_NUM_SPSEXT; i++ ) |
1056 | 2.21M | { |
1057 | 2.21M | if( p_sys->spsext[i].p_block ) |
1058 | 1.70k | block_Release( p_sys->spsext[i].p_block ); |
1059 | 2.21M | } |
1060 | 69.1k | p_sys->p_active_sps = NULL; |
1061 | 69.1k | p_sys->p_active_pps = NULL; |
1062 | 69.1k | } |
1063 | | |
1064 | | static bool PutXPS( decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag ) |
1065 | 498k | { |
1066 | 498k | decoder_sys_t *p_sys = p_dec->p_sys; |
1067 | | |
1068 | 498k | uint8_t i_id; |
1069 | 498k | if( !hxxx_strip_AnnexB_startcode( (const uint8_t **)&p_frag->p_buffer, |
1070 | 498k | &p_frag->i_buffer ) || |
1071 | 498k | !h264_get_xps_id( p_frag->p_buffer, p_frag->i_buffer, &i_id ) ) |
1072 | 44.2k | { |
1073 | 44.2k | block_Release( p_frag ); |
1074 | 44.2k | return false; |
1075 | 44.2k | } |
1076 | | |
1077 | 453k | const char * rgsz_types[3] = {"SPS", "PPS", "SPSEXT"}; |
1078 | 453k | const char *psz_type; |
1079 | 453k | block_t **pp_block_dst; |
1080 | | /* all depend on pp_xps_dst */ |
1081 | 453k | void **pp_xps_dst = NULL; |
1082 | 453k | const void **pp_active = NULL; /* optional */ |
1083 | 453k | void * (* pf_decode_xps)(const uint8_t *, size_t, bool) = NULL; |
1084 | 453k | void (* pf_release_xps)(void *) = NULL; |
1085 | | |
1086 | 453k | switch( i_nal_type ) |
1087 | 453k | { |
1088 | 237k | case H264_NAL_SPS: |
1089 | 237k | psz_type = rgsz_types[0]; |
1090 | 237k | pp_active = (const void **) &p_sys->p_active_sps; |
1091 | 237k | pp_block_dst = &p_sys->sps[i_id].p_block; |
1092 | 237k | pp_xps_dst = (void **) &p_sys->sps[i_id].p_sps; |
1093 | 237k | pf_decode_xps = h264_decode_sps_wrapper; |
1094 | 237k | pf_release_xps = h264_release_sps_wrapper; |
1095 | 237k | break; |
1096 | 206k | case H264_NAL_PPS: |
1097 | 206k | psz_type = rgsz_types[1]; |
1098 | 206k | pp_active = (const void **) &p_sys->p_active_pps; |
1099 | 206k | pp_block_dst = &p_sys->pps[i_id].p_block; |
1100 | 206k | pp_xps_dst = (void **) &p_sys->pps[i_id].p_pps; |
1101 | 206k | pf_decode_xps = h264_decode_pps_wrapper; |
1102 | 206k | pf_release_xps = h264_release_pps_wrapper; |
1103 | 206k | break; |
1104 | 9.90k | case H264_NAL_SPS_EXT: |
1105 | 9.90k | psz_type = rgsz_types[2]; |
1106 | 9.90k | pp_block_dst = &p_sys->spsext[i_id].p_block; |
1107 | 9.90k | break; |
1108 | 0 | default: |
1109 | 0 | block_Release( p_frag ); |
1110 | 0 | return false; |
1111 | 453k | } |
1112 | | |
1113 | 453k | if( !CmpXPS( *pp_block_dst, p_frag ) ) |
1114 | 86.1k | { |
1115 | 86.1k | block_Release( p_frag ); |
1116 | 86.1k | return false; |
1117 | 86.1k | } |
1118 | | |
1119 | 367k | msg_Dbg( p_dec, "found NAL_%s (id=%" PRIu8 ")", psz_type, i_id ); |
1120 | | |
1121 | 367k | if( pp_xps_dst != NULL ) |
1122 | 360k | { |
1123 | 360k | void *p_xps = pf_decode_xps( p_frag->p_buffer, p_frag->i_buffer, true ); |
1124 | 360k | if( !p_xps ) |
1125 | 161k | { |
1126 | 161k | block_Release( p_frag ); |
1127 | 161k | return false; |
1128 | 161k | } |
1129 | 199k | if( *pp_xps_dst ) |
1130 | 167k | { |
1131 | 167k | if( pp_active && *pp_active == *pp_xps_dst ) |
1132 | 30.4k | *pp_active = NULL; |
1133 | 167k | pf_release_xps( *pp_xps_dst ); |
1134 | 167k | } |
1135 | 199k | *pp_xps_dst = p_xps; |
1136 | 199k | } |
1137 | | |
1138 | 206k | if( *pp_block_dst ) |
1139 | 172k | block_Release( *pp_block_dst ); |
1140 | 206k | *pp_block_dst = p_frag; |
1141 | | |
1142 | 206k | return true; |
1143 | 367k | } |
1144 | | |
1145 | | static void GetSPSPPS( uint8_t i_pps_id, void *priv, |
1146 | | const h264_sequence_parameter_set_t **pp_sps, |
1147 | | const h264_picture_parameter_set_t **pp_pps ) |
1148 | 645k | { |
1149 | 645k | decoder_sys_t *p_sys = priv; |
1150 | | |
1151 | 645k | *pp_pps = p_sys->pps[i_pps_id].p_pps; |
1152 | 645k | if( *pp_pps == NULL ) |
1153 | 71.5k | *pp_sps = NULL; |
1154 | 574k | else |
1155 | 574k | *pp_sps = p_sys->sps[h264_get_pps_sps_id(*pp_pps)].p_sps; |
1156 | 645k | } |
1157 | | |
1158 | | static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag ) |
1159 | 465k | { |
1160 | 465k | decoder_sys_t *p_sys = p_dec->p_sys; |
1161 | | |
1162 | 465k | const uint8_t *p_stripped = p_frag->p_buffer; |
1163 | 465k | size_t i_stripped = p_frag->i_buffer; |
1164 | | |
1165 | 465k | if( !hxxx_strip_AnnexB_startcode( &p_stripped, &i_stripped ) || i_stripped < 2 ) |
1166 | 4.40k | return NULL; |
1167 | | |
1168 | 461k | h264_slice_t *p_slice = h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys ); |
1169 | 461k | if( !p_slice ) |
1170 | 213k | return NULL; |
1171 | | |
1172 | 247k | const h264_sequence_parameter_set_t *p_sps; |
1173 | 247k | const h264_picture_parameter_set_t *p_pps; |
1174 | 247k | GetSPSPPS( h264_get_slice_pps_id( p_slice ), p_sys, &p_sps, &p_pps ); |
1175 | 247k | if( unlikely( !p_sps || !p_pps) ) |
1176 | 0 | { |
1177 | 0 | h264_slice_release( p_slice ); |
1178 | 0 | return NULL; |
1179 | 0 | } |
1180 | | |
1181 | 247k | ActivateSets( p_dec, p_sps, p_pps ); |
1182 | | |
1183 | 247k | return p_slice; |
1184 | 247k | } |
1185 | | |
1186 | | static bool ParseSeiCallback( const hxxx_sei_data_t *p_sei_data, void *cbdata ) |
1187 | 62.0k | { |
1188 | 62.0k | decoder_t *p_dec = (decoder_t *) cbdata; |
1189 | 62.0k | decoder_sys_t *p_sys = p_dec->p_sys; |
1190 | | |
1191 | 62.0k | switch( p_sei_data->i_type ) |
1192 | 62.0k | { |
1193 | | /* Look for pic timing */ |
1194 | 26.9k | case HXXX_SEI_PIC_TIMING: |
1195 | 26.9k | { |
1196 | 26.9k | const h264_sequence_parameter_set_t *p_sps = p_sys->p_active_sps; |
1197 | 26.9k | if( unlikely( p_sps == NULL ) ) |
1198 | 0 | { |
1199 | 0 | assert( p_sps ); |
1200 | 0 | break; |
1201 | 0 | } |
1202 | | |
1203 | 26.9k | h264_decode_sei_pic_timing( p_sei_data->p_bs, p_sps, |
1204 | 26.9k | &p_sys->i_pic_struct, |
1205 | 26.9k | &p_sys->i_dpb_output_delay ); |
1206 | 26.9k | } break; |
1207 | | |
1208 | | /* Look for user_data_registered_itu_t_t35 */ |
1209 | 2 | case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35: |
1210 | 2 | { |
1211 | 2 | if( p_sei_data->itu_t35.type == HXXX_ITU_T35_TYPE_CC ) |
1212 | 2 | { |
1213 | 2 | cc_storage_append( p_sys->p_ccs, true, p_sei_data->itu_t35.u.cc.p_data, |
1214 | 2 | p_sei_data->itu_t35.u.cc.i_data ); |
1215 | 2 | } |
1216 | 2 | } break; |
1217 | | |
1218 | 0 | case HXXX_SEI_FRAME_PACKING_ARRANGEMENT: |
1219 | 0 | { |
1220 | 0 | if( p_dec->fmt_in->video.multiview_mode == MULTIVIEW_2D ) |
1221 | 0 | { |
1222 | 0 | video_multiview_mode_t mode; |
1223 | 0 | switch( p_sei_data->frame_packing.type ) |
1224 | 0 | { |
1225 | 0 | case FRAME_PACKING_INTERLEAVED_CHECKERBOARD: |
1226 | 0 | mode = MULTIVIEW_STEREO_CHECKERBOARD; break; |
1227 | 0 | case FRAME_PACKING_INTERLEAVED_COLUMN: |
1228 | 0 | mode = MULTIVIEW_STEREO_COL; break; |
1229 | 0 | case FRAME_PACKING_INTERLEAVED_ROW: |
1230 | 0 | mode = MULTIVIEW_STEREO_ROW; break; |
1231 | 0 | case FRAME_PACKING_SIDE_BY_SIDE: |
1232 | 0 | mode = MULTIVIEW_STEREO_SBS; break; |
1233 | 0 | case FRAME_PACKING_TOP_BOTTOM: |
1234 | 0 | mode = MULTIVIEW_STEREO_TB; break; |
1235 | 0 | case FRAME_PACKING_TEMPORAL: |
1236 | 0 | mode = MULTIVIEW_STEREO_FRAME; break; |
1237 | 0 | case FRAME_PACKING_TILED: |
1238 | 0 | default: |
1239 | 0 | mode = MULTIVIEW_2D; break; |
1240 | 0 | } |
1241 | 0 | p_dec->fmt_out.video.multiview_mode = mode; |
1242 | 0 | } |
1243 | 0 | } break; |
1244 | | |
1245 | | /* Look for SEI recovery point */ |
1246 | 20.4k | case HXXX_SEI_RECOVERY_POINT: |
1247 | 20.4k | { |
1248 | 20.4k | h264_sei_recovery_point_t reco; |
1249 | 20.4k | if( !p_sys->b_recovered && |
1250 | 18.0k | h264_decode_sei_recovery_point( p_sei_data->p_bs, &reco ) ) |
1251 | 18.0k | { |
1252 | 18.0k | msg_Dbg( p_dec, "Seen SEI recovery point, %u recovery frames", reco.i_frames ); |
1253 | 18.0k | p_sys->i_recovery_frame_cnt = reco.i_frames; |
1254 | 18.0k | } |
1255 | 20.4k | } break; |
1256 | | |
1257 | 14.6k | default: |
1258 | | /* Will skip */ |
1259 | 14.6k | break; |
1260 | 62.0k | } |
1261 | | |
1262 | 62.0k | return true; |
1263 | 62.0k | } |