/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 | 108 | vlc_module_begin () |
59 | 54 | set_subcategory( SUBCAT_SOUT_PACKETIZER ) |
60 | 54 | set_description( N_("H.264 video packetizer") ) |
61 | 54 | set_capability( "video packetizer", 50 ) |
62 | 108 | set_callbacks( Open, Close ) |
63 | 54 | 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_SPS_ID_MAX + 1]; |
91 | | struct |
92 | | { |
93 | | block_t *p_block; |
94 | | h264_picture_parameter_set_t *p_pps; |
95 | | } pps[H264_PPS_ID_MAX + 1]; |
96 | | struct |
97 | | { |
98 | | block_t *p_block; |
99 | | } spsext[H264_SPSEXT_ID_MAX + 1]; |
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 | 259k | #define BLOCK_FLAG_PRIVATE_AUD (1 << BLOCK_FLAG_PRIVATE_SHIFT) |
138 | 111k | #define BLOCK_FLAG_PRIVATE_SEI (2 << BLOCK_FLAG_PRIVATE_SHIFT) |
139 | 243k | #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 | 35.3M | { |
170 | 35.3M | if( !p_block ) |
171 | 35.1M | return; |
172 | 243k | block_t *p_dup = block_Alloc( 4 + p_block->i_buffer ); |
173 | 243k | if( p_dup ) |
174 | 243k | { |
175 | 243k | memcpy( &p_dup->p_buffer[0], annexb_startcode4, 4 ); |
176 | 243k | memcpy( &p_dup->p_buffer[4], p_block->p_buffer, p_block->i_buffer ); |
177 | 243k | block_ChainLastAppend( ppp_last, p_dup ); |
178 | 243k | } |
179 | 243k | } |
180 | | |
181 | | static block_t * GatherSets( decoder_sys_t *p_sys, bool b_need_sps, bool b_need_pps ) |
182 | 236k | { |
183 | 236k | block_t *p_xpsnal = NULL; |
184 | 236k | block_t **pp_xpsnal_tail = &p_xpsnal; |
185 | 3.71M | for( int i = 0; i <= H264_SPS_ID_MAX && b_need_sps; i++ ) |
186 | 3.47M | { |
187 | 3.47M | 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 | 3.47M | LastAppendXPSCopy( p_sys->spsext[i].p_block, &pp_xpsnal_tail ); |
191 | 3.47M | } |
192 | 28.6M | for( int i = 0; i < H264_PPS_ID_MAX && b_need_pps; i++ ) |
193 | 28.4M | LastAppendXPSCopy( p_sys->pps[i].p_block, &pp_xpsnal_tail ); |
194 | 236k | return p_xpsnal; |
195 | 236k | } |
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 | 270k | { |
200 | 270k | decoder_sys_t *p_sys = p_dec->p_sys; |
201 | | |
202 | 270k | p_sys->p_active_pps = p_pps; |
203 | 270k | p_sys->p_active_sps = p_sps; |
204 | | |
205 | 270k | if( p_sps ) |
206 | 270k | { |
207 | 270k | uint8_t pl[2]; |
208 | 270k | if( h264_get_sps_profile_tier_level( p_sps, pl, &pl[1] ) ) |
209 | 270k | { |
210 | 270k | p_dec->fmt_out.i_profile = pl[0]; |
211 | 270k | p_dec->fmt_out.i_level = pl[1]; |
212 | 270k | } |
213 | | |
214 | 270k | (void) h264_get_picture_size( p_sps, |
215 | 270k | &p_dec->fmt_out.video.i_x_offset, |
216 | 270k | &p_dec->fmt_out.video.i_y_offset, |
217 | 270k | &p_dec->fmt_out.video.i_width, |
218 | 270k | &p_dec->fmt_out.video.i_height, |
219 | 270k | &p_dec->fmt_out.video.i_visible_width, |
220 | 270k | &p_dec->fmt_out.video.i_visible_height ); |
221 | | |
222 | 270k | h264_get_aspect_ratio( p_sps, |
223 | 270k | &p_dec->fmt_out.video.i_sar_num, |
224 | 270k | &p_dec->fmt_out.video.i_sar_den ); |
225 | | |
226 | 270k | if( !p_dec->fmt_out.video.i_frame_rate || |
227 | 266k | !p_dec->fmt_out.video.i_frame_rate_base ) |
228 | 3.98k | { |
229 | | /* on first run == if fmt_in does not provide frame rate info */ |
230 | | /* If we have frame rate info in the stream */ |
231 | 3.98k | unsigned nd[2]; |
232 | 3.98k | if( h264_get_frame_rate( p_sps, nd, &nd[1] ) ) |
233 | 718 | date_Change( &p_sys->dts, nd[0], nd[1] ); |
234 | | /* else use the default num/den */ |
235 | 3.98k | p_dec->fmt_out.video.i_frame_rate = p_sys->dts.i_divider_num >> 1; /* num_clock_ts == 2 */ |
236 | 3.98k | p_dec->fmt_out.video.i_frame_rate_base = p_sys->dts.i_divider_den; |
237 | 3.98k | } |
238 | | |
239 | 270k | if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF ) |
240 | 270k | { |
241 | 270k | h264_get_colorimetry( p_sps, &p_dec->fmt_out.video.primaries, |
242 | 270k | &p_dec->fmt_out.video.transfer, |
243 | 270k | &p_dec->fmt_out.video.space, |
244 | 270k | &p_dec->fmt_out.video.color_range ); |
245 | 270k | } |
246 | | |
247 | 270k | if( p_dec->fmt_out.i_extra == 0 && p_pps ) |
248 | 3.98k | { |
249 | 3.98k | block_t *p_xpsblocks = GatherSets( p_sys, true, true ); |
250 | 3.98k | if( p_xpsblocks ) |
251 | 3.98k | { |
252 | 3.98k | size_t i_total; |
253 | 3.98k | block_ChainProperties( p_xpsblocks, NULL, &i_total, NULL ); |
254 | 3.98k | p_dec->fmt_out.p_extra = malloc( i_total ); |
255 | 3.98k | if( p_dec->fmt_out.p_extra ) |
256 | 3.98k | { |
257 | 3.98k | p_dec->fmt_out.i_extra = i_total; |
258 | 3.98k | block_ChainExtract( p_xpsblocks, p_dec->fmt_out.p_extra, i_total ); |
259 | 3.98k | } |
260 | 3.98k | block_ChainRelease( p_xpsblocks ); |
261 | 3.98k | } |
262 | 3.98k | } |
263 | 270k | } |
264 | 270k | } |
265 | | |
266 | | static void DropStoredNAL( decoder_sys_t *p_sys ) |
267 | 43.7k | { |
268 | 43.7k | block_ChainRelease( p_sys->frame.p_head ); |
269 | 43.7k | block_ChainRelease( p_sys->leading.p_head ); |
270 | 43.7k | p_sys->frame.p_head = NULL; |
271 | 43.7k | p_sys->frame.pp_append = &p_sys->frame.p_head; |
272 | 43.7k | p_sys->leading.p_head = NULL; |
273 | 43.7k | p_sys->leading.pp_append = &p_sys->leading.p_head; |
274 | 43.7k | } |
275 | | |
276 | | /***************************************************************************** |
277 | | * Open: probe the packetizer and return score |
278 | | * When opening after demux, the packetizer is only loaded AFTER the decoder |
279 | | * That means that what you set in fmt_out is ignored by the decoder in this special case |
280 | | *****************************************************************************/ |
281 | | static int Open( vlc_object_t *p_this ) |
282 | 57.7k | { |
283 | 57.7k | decoder_t *p_dec = (decoder_t*)p_this; |
284 | 57.7k | decoder_sys_t *p_sys; |
285 | 57.7k | int i; |
286 | | |
287 | 57.7k | const bool b_avc = (p_dec->fmt_in->i_original_fourcc == VLC_FOURCC( 'a', 'v', 'c', '1' )); |
288 | | |
289 | 57.7k | if( p_dec->fmt_in->i_codec != VLC_CODEC_H264 ) |
290 | 41.7k | return VLC_EGENERIC; |
291 | 16.0k | if( b_avc && p_dec->fmt_in->i_extra < 7 ) |
292 | 11 | return VLC_EGENERIC; |
293 | | |
294 | | /* Allocate the memory needed to store the decoder's structure */ |
295 | 16.0k | if( ( p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) ) ) == NULL ) |
296 | 0 | { |
297 | 0 | return VLC_ENOMEM; |
298 | 0 | } |
299 | | |
300 | 16.0k | p_sys->p_ccs = cc_storage_new(); |
301 | 16.0k | if( unlikely(!p_sys->p_ccs) ) |
302 | 0 | { |
303 | 0 | free( p_sys ); |
304 | 0 | return VLC_ENOMEM; |
305 | 0 | } |
306 | | |
307 | 16.0k | packetizer_Init( &p_sys->packetizer, |
308 | 16.0k | annexb_startcode3, 3, startcode_FindAnnexB, |
309 | 16.0k | annexb_startcode3, 1, 5, |
310 | 16.0k | PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain, |
311 | 16.0k | p_dec ); |
312 | | |
313 | 16.0k | p_sys->p_slice = NULL; |
314 | 16.0k | p_sys->frame.p_head = NULL; |
315 | 16.0k | p_sys->frame.pp_append = &p_sys->frame.p_head; |
316 | 16.0k | p_sys->leading.p_head = NULL; |
317 | 16.0k | p_sys->leading.pp_append = &p_sys->leading.p_head; |
318 | 16.0k | p_sys->b_new_sps = false; |
319 | 16.0k | p_sys->b_new_pps = false; |
320 | | |
321 | 530k | for( i = 0; i <= H264_SPS_ID_MAX; i++ ) |
322 | 514k | { |
323 | 514k | p_sys->sps[i].p_sps = NULL; |
324 | 514k | p_sys->sps[i].p_block = NULL; |
325 | 514k | } |
326 | 16.0k | p_sys->p_active_sps = NULL; |
327 | 4.13M | for( i = 0; i <= H264_PPS_ID_MAX; i++ ) |
328 | 4.11M | { |
329 | 4.11M | p_sys->pps[i].p_pps = NULL; |
330 | 4.11M | p_sys->pps[i].p_block = NULL; |
331 | 4.11M | } |
332 | 16.0k | p_sys->p_active_pps = NULL; |
333 | 530k | for( i = 0; i <= H264_SPSEXT_ID_MAX; i++ ) |
334 | 514k | p_sys->spsext[i].p_block = NULL; |
335 | 16.0k | p_sys->i_recovery_frame_cnt = UINT_MAX; |
336 | | |
337 | 16.0k | p_sys->i_next_block_flags = 0; |
338 | 16.0k | p_sys->b_recovered = false; |
339 | 16.0k | p_sys->i_recoveryfnum = UINT_MAX; |
340 | 16.0k | p_sys->i_frame_dts = VLC_TICK_INVALID; |
341 | 16.0k | p_sys->i_frame_pts = VLC_TICK_INVALID; |
342 | 16.0k | p_sys->i_dpb_output_delay = 0; |
343 | | |
344 | | /* POC */ |
345 | 16.0k | h264_poc_context_init( &p_sys->pocctx ); |
346 | 16.0k | p_sys->prevdatedpoc.pts = VLC_TICK_INVALID; |
347 | | |
348 | 16.0k | date_Init( &p_sys->dts, 30000 * 2, 1001 ); |
349 | | |
350 | | /* Setup properties */ |
351 | 16.0k | es_format_Copy( &p_dec->fmt_out, p_dec->fmt_in ); |
352 | 16.0k | p_dec->fmt_out.i_codec = VLC_CODEC_H264; |
353 | 16.0k | p_dec->fmt_out.b_packetized = true; |
354 | | |
355 | 16.0k | if( p_dec->fmt_in->video.i_frame_rate_base && |
356 | 4.68k | p_dec->fmt_in->video.i_frame_rate && |
357 | 4.68k | p_dec->fmt_in->video.i_frame_rate <= UINT_MAX / 2 ) |
358 | 3.05k | { |
359 | 3.05k | date_Change( &p_sys->dts, p_dec->fmt_in->video.i_frame_rate * 2, |
360 | 3.05k | p_dec->fmt_in->video.i_frame_rate_base ); |
361 | 3.05k | } |
362 | | |
363 | 16.0k | if( b_avc ) |
364 | 1.99k | { |
365 | | /* This type of stream is produced by mp4 and matroska |
366 | | * when we want to store it in another streamformat, you need to convert |
367 | | * The fmt_in.p_extra should ALWAYS contain the avcC |
368 | | * The fmt_out.p_extra should contain all the SPS and PPS with 4 byte startcodes */ |
369 | 1.99k | if( h264_isavcC( p_dec->fmt_in->p_extra, p_dec->fmt_in->i_extra ) ) |
370 | 1.92k | { |
371 | 1.92k | free( p_dec->fmt_out.p_extra ); |
372 | 1.92k | size_t i_size; |
373 | 1.92k | p_dec->fmt_out.p_extra = h264_avcC_to_AnnexB_NAL( p_dec->fmt_in->p_extra, |
374 | 1.92k | p_dec->fmt_in->i_extra, |
375 | 1.92k | &i_size, |
376 | 1.92k | &p_sys->i_avcC_length_size ); |
377 | 1.92k | p_dec->fmt_out.i_extra = i_size; |
378 | 1.92k | p_sys->b_recovered = !!p_dec->fmt_out.i_extra; |
379 | | |
380 | 1.92k | if(!p_dec->fmt_out.p_extra) |
381 | 139 | { |
382 | 139 | msg_Err( p_dec, "Invalid AVC extradata"); |
383 | 139 | Close( p_this ); |
384 | 139 | return VLC_EGENERIC; |
385 | 139 | } |
386 | 1.92k | } |
387 | 68 | else |
388 | 68 | { |
389 | 68 | msg_Err( p_dec, "Invalid or missing AVC extradata"); |
390 | 68 | Close( p_this ); |
391 | 68 | return VLC_EGENERIC; |
392 | 68 | } |
393 | | |
394 | | /* Set callback */ |
395 | 1.78k | p_dec->pf_packetize = PacketizeAVC1; |
396 | 1.78k | } |
397 | 14.0k | else |
398 | 14.0k | { |
399 | | /* This type of stream contains data with 3 of 4 byte startcodes |
400 | | * The fmt_in.p_extra MAY contain SPS/PPS with 4 byte startcodes |
401 | | * The fmt_out.p_extra should be the same */ |
402 | | |
403 | | /* Set callback */ |
404 | 14.0k | p_dec->pf_packetize = Packetize; |
405 | 14.0k | } |
406 | | |
407 | | /* */ |
408 | 15.8k | if( p_dec->fmt_out.i_extra > 0 ) |
409 | 4.47k | { |
410 | 4.47k | packetizer_Header( &p_sys->packetizer, |
411 | 4.47k | p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra ); |
412 | 4.47k | } |
413 | | |
414 | 15.8k | if( b_avc ) |
415 | 1.78k | { |
416 | | /* FIXME: that's not correct for every AVC */ |
417 | 1.78k | if( !p_sys->b_new_pps || !p_sys->b_new_sps ) |
418 | 1.30k | { |
419 | 1.30k | msg_Err( p_dec, "Invalid or missing SPS %d or PPS %d in AVC extradata", |
420 | 1.30k | p_sys->b_new_sps, p_sys->b_new_pps ); |
421 | 1.30k | Close( p_this ); |
422 | 1.30k | return VLC_EGENERIC; |
423 | 1.30k | } |
424 | | |
425 | 480 | msg_Dbg( p_dec, "Packetizer fed with AVC, nal length size=%d", |
426 | 480 | p_sys->i_avcC_length_size ); |
427 | 480 | } |
428 | | |
429 | | /* CC are the same for H264/AVC in T35 sections (ETSI TS 101 154) */ |
430 | 14.5k | p_dec->pf_get_cc = GetCc; |
431 | 14.5k | p_dec->pf_flush = PacketizeFlush; |
432 | | |
433 | 14.5k | return VLC_SUCCESS; |
434 | 15.8k | } |
435 | | |
436 | | /***************************************************************************** |
437 | | * Close: clean up the packetizer |
438 | | *****************************************************************************/ |
439 | | static void Close( vlc_object_t *p_this ) |
440 | 16.0k | { |
441 | 16.0k | decoder_t *p_dec = (decoder_t*)p_this; |
442 | 16.0k | decoder_sys_t *p_sys = p_dec->p_sys; |
443 | | |
444 | 16.0k | DropStoredNAL( p_sys ); |
445 | 16.0k | ReleaseXPS( p_sys ); |
446 | | |
447 | 16.0k | if( p_sys->p_slice ) |
448 | 0 | h264_slice_release( p_sys->p_slice ); |
449 | | |
450 | 16.0k | packetizer_Clean( &p_sys->packetizer ); |
451 | | |
452 | 16.0k | cc_storage_delete( p_sys->p_ccs ); |
453 | | |
454 | 16.0k | free( p_sys ); |
455 | 16.0k | } |
456 | | |
457 | | static void PacketizeFlush( decoder_t *p_dec ) |
458 | 0 | { |
459 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
460 | |
|
461 | 0 | packetizer_Flush( &p_sys->packetizer ); |
462 | 0 | } |
463 | | |
464 | | /**************************************************************************** |
465 | | * Packetize: the whole thing |
466 | | * Search for the startcodes 3 or more bytes |
467 | | * Feed ParseNALBlock ALWAYS with 4 byte startcode prepended NALs |
468 | | ****************************************************************************/ |
469 | | static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) |
470 | 261k | { |
471 | 261k | decoder_sys_t *p_sys = p_dec->p_sys; |
472 | | |
473 | 261k | return packetizer_Packetize( &p_sys->packetizer, pp_block ); |
474 | 261k | } |
475 | | |
476 | | /**************************************************************************** |
477 | | * PacketizeAVC1: Takes VCL blocks of data and creates annexe B type NAL stream |
478 | | * Will always use 4 byte 0 0 0 1 startcodes |
479 | | * Will prepend a SPS and PPS before each keyframe |
480 | | ****************************************************************************/ |
481 | | static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block ) |
482 | 0 | { |
483 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
484 | |
|
485 | 0 | return PacketizeXXC1( p_dec, p_dec->obj.logger, |
486 | 0 | p_sys->i_avcC_length_size, pp_block, |
487 | 0 | ParseNALBlockW, PacketizeDrain ); |
488 | 0 | } |
489 | | |
490 | | /***************************************************************************** |
491 | | * GetCc: |
492 | | *****************************************************************************/ |
493 | | static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc ) |
494 | 0 | { |
495 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
496 | 0 | return cc_storage_get_current( p_sys->p_ccs, p_desc ); |
497 | 0 | } |
498 | | |
499 | | /**************************************************************************** |
500 | | * Helpers |
501 | | ****************************************************************************/ |
502 | | static void ResetOutputVariables( decoder_sys_t *p_sys ) |
503 | 248k | { |
504 | 248k | p_sys->i_frame_dts = VLC_TICK_INVALID; |
505 | 248k | p_sys->i_frame_pts = VLC_TICK_INVALID; |
506 | 248k | if( p_sys->p_slice ) |
507 | 248k | h264_slice_release( p_sys->p_slice ); |
508 | 248k | p_sys->p_slice = NULL; |
509 | 248k | p_sys->b_new_sps = false; |
510 | 248k | p_sys->b_new_pps = false; |
511 | | /* From SEI */ |
512 | 248k | p_sys->i_dpb_output_delay = 0; |
513 | 248k | p_sys->i_pic_struct = UINT8_MAX; |
514 | 248k | p_sys->i_recovery_frame_cnt = UINT_MAX; |
515 | 248k | } |
516 | | |
517 | | static void PacketizeReset( void *p_private, bool b_flush ) |
518 | 0 | { |
519 | 0 | decoder_t *p_dec = p_private; |
520 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
521 | |
|
522 | 0 | if( b_flush || !p_sys->p_slice ) |
523 | 0 | { |
524 | 0 | DropStoredNAL( p_sys ); |
525 | 0 | ResetOutputVariables( p_sys ); |
526 | 0 | p_sys->p_active_pps = NULL; |
527 | 0 | p_sys->p_active_sps = NULL; |
528 | 0 | p_sys->b_recovered = false; |
529 | 0 | p_sys->i_recoveryfnum = UINT_MAX; |
530 | | /* POC */ |
531 | 0 | h264_poc_context_init( &p_sys->pocctx ); |
532 | 0 | p_sys->prevdatedpoc.pts = VLC_TICK_INVALID; |
533 | 0 | } |
534 | 0 | p_sys->i_next_block_flags = BLOCK_FLAG_DISCONTINUITY; |
535 | 0 | date_Set( &p_sys->dts, VLC_TICK_INVALID ); |
536 | 0 | } |
537 | | static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block ) |
538 | 1.03M | { |
539 | 1.03M | decoder_t *p_dec = p_private; |
540 | | |
541 | | /* Remove trailing 0 bytes */ |
542 | 5.45M | while( p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 ) |
543 | 4.41M | p_block->i_buffer--; |
544 | | |
545 | 1.03M | return ParseNALBlock( p_dec, pb_ts_used, p_block ); |
546 | 1.03M | } |
547 | | static int PacketizeValidate( void *p_private, block_t *p_au ) |
548 | 222k | { |
549 | 222k | VLC_UNUSED(p_private); |
550 | 222k | VLC_UNUSED(p_au); |
551 | 222k | return VLC_SUCCESS; |
552 | 222k | } |
553 | | |
554 | | static block_t * PacketizeDrain( void *p_private ) |
555 | 15.7k | { |
556 | 15.7k | decoder_t *p_dec = p_private; |
557 | 15.7k | decoder_sys_t *p_sys = p_dec->p_sys; |
558 | | |
559 | 15.7k | if( !p_sys->p_slice ) |
560 | 12.0k | return NULL; |
561 | | |
562 | 3.72k | block_t *p_out = OutputPicture( p_dec ); |
563 | 3.72k | if( p_out && (p_out->i_flags & BLOCK_FLAG_DROP) ) |
564 | 967 | { |
565 | 967 | block_Release( p_out ); |
566 | 967 | p_out = NULL; |
567 | 967 | } |
568 | | |
569 | 3.72k | return p_out; |
570 | 15.7k | } |
571 | | |
572 | | /***************************************************************************** |
573 | | * ParseNALBlock: parses annexB type NALs |
574 | | * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode |
575 | | *****************************************************************************/ |
576 | | static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_frag ) |
577 | 1.03M | { |
578 | 1.03M | decoder_sys_t *p_sys = p_dec->p_sys; |
579 | 1.03M | block_t *p_pic = NULL; |
580 | | |
581 | 1.03M | const enum h264_nal_unit_type_e i_nal_type = h264_getNALType( &p_frag->p_buffer[4] ); |
582 | 1.03M | const vlc_tick_t i_frag_dts = p_frag->i_dts; |
583 | 1.03M | const vlc_tick_t i_frag_pts = p_frag->i_pts; |
584 | 1.03M | bool b_au_end = p_frag->i_flags & BLOCK_FLAG_AU_END; |
585 | 1.03M | p_frag->i_flags &= ~BLOCK_FLAG_AU_END; |
586 | | |
587 | 1.03M | if( p_sys->p_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) ) |
588 | 15.7k | { |
589 | 15.7k | msg_Warn( p_dec, "waiting for SPS/PPS" ); |
590 | | |
591 | | /* Reset context */ |
592 | 15.7k | DropStoredNAL( p_sys ); |
593 | 15.7k | ResetOutputVariables( p_sys ); |
594 | 15.7k | cc_storage_reset( p_sys->p_ccs ); |
595 | 15.7k | } |
596 | | |
597 | 1.03M | switch( i_nal_type ) |
598 | 1.03M | { |
599 | | /*** Slices ***/ |
600 | 77.9k | case H264_NAL_SLICE: |
601 | 87.5k | case H264_NAL_SLICE_DPA: |
602 | 210k | case H264_NAL_SLICE_DPB: |
603 | 227k | case H264_NAL_SLICE_DPC: |
604 | 517k | case H264_NAL_SLICE_IDR: |
605 | 517k | { |
606 | 517k | h264_slice_t *p_newslice; |
607 | | |
608 | 517k | if( i_nal_type == H264_NAL_SLICE_IDR ) |
609 | 290k | { |
610 | 290k | p_sys->b_recovered = true; |
611 | 290k | p_sys->i_recovery_frame_cnt = UINT_MAX; |
612 | 290k | p_sys->i_recoveryfnum = UINT_MAX; |
613 | 290k | } |
614 | | |
615 | 517k | if( (p_newslice = ParseSliceHeader( p_dec, p_frag )) ) |
616 | 270k | { |
617 | | /* Only IDR carries the id, to be propagated */ |
618 | 270k | h264_slice_copy_idr_id( p_sys->p_slice, p_newslice ); |
619 | | |
620 | 270k | bool b_new_picture = h264_IsFirstVCLNALUnit( p_sys->p_slice, p_newslice ); |
621 | 270k | if( b_new_picture ) |
622 | 248k | { |
623 | | /* Parse SEI for that frame now we should have matched SPS/PPS */ |
624 | 317k | for( block_t *p_sei = p_sys->leading.p_head; p_sei; p_sei = p_sei->p_next ) |
625 | 68.7k | { |
626 | 68.7k | if( (p_sei->i_flags & BLOCK_FLAG_PRIVATE_SEI) == 0 ) |
627 | 15.5k | continue; |
628 | 53.1k | HxxxParse_AnnexB_SEI( p_sei->p_buffer, p_sei->i_buffer, |
629 | 53.1k | 1 /* nal header */, ParseSeiCallback, p_dec ); |
630 | 53.1k | } |
631 | | |
632 | 248k | if( p_sys->p_slice ) |
633 | 199k | p_pic = OutputPicture( p_dec ); |
634 | 248k | } |
635 | | |
636 | | /* */ |
637 | 270k | h264_slice_release( p_sys->p_slice ); |
638 | 270k | p_sys->p_slice = p_newslice; |
639 | 270k | } |
640 | 247k | else |
641 | 247k | { |
642 | 247k | p_sys->p_active_pps = NULL; |
643 | | /* Fragment will be discarded later on */ |
644 | 247k | } |
645 | | |
646 | 517k | block_ChainLastAppend( &p_sys->frame.pp_append, p_frag ); |
647 | 517k | } break; |
648 | | |
649 | | /*** Prefix NALs ***/ |
650 | | |
651 | 11.7k | case H264_NAL_AU_DELIMITER: |
652 | 11.7k | if( p_sys->p_slice ) |
653 | 4.63k | p_pic = OutputPicture( p_dec ); |
654 | | |
655 | | /* clear junk if no pic, we're always the first nal */ |
656 | 11.7k | DropStoredNAL( p_sys ); |
657 | | |
658 | 11.7k | p_frag->i_flags |= BLOCK_FLAG_PRIVATE_AUD; |
659 | | |
660 | 11.7k | block_ChainLastAppend( &p_sys->leading.pp_append, p_frag ); |
661 | 11.7k | break; |
662 | | |
663 | 113k | case H264_NAL_SPS: |
664 | 243k | case H264_NAL_PPS: |
665 | 243k | if( p_sys->p_slice ) |
666 | 17.4k | p_pic = OutputPicture( p_dec ); |
667 | | |
668 | | /* Stored for insert on keyframes */ |
669 | 243k | if( i_nal_type == H264_NAL_SPS ) |
670 | 113k | p_sys->b_new_sps |= PutXPS( p_dec, i_nal_type, p_frag ); |
671 | 129k | else |
672 | 129k | p_sys->b_new_pps |= PutXPS( p_dec, i_nal_type, p_frag ); |
673 | 243k | break; |
674 | | |
675 | 43.1k | case H264_NAL_SEI: |
676 | 43.1k | if( p_sys->p_slice ) |
677 | 5.61k | p_pic = OutputPicture( p_dec ); |
678 | | |
679 | 43.1k | p_frag->i_flags |= BLOCK_FLAG_PRIVATE_SEI; |
680 | 43.1k | block_ChainLastAppend( &p_sys->leading.pp_append, p_frag ); |
681 | 43.1k | break; |
682 | | |
683 | 3.29k | case H264_NAL_SPS_EXT: |
684 | 3.29k | PutXPS( p_dec, i_nal_type, p_frag ); |
685 | 3.29k | if( p_sys->p_slice ) |
686 | 365 | p_pic = OutputPicture( p_dec ); |
687 | 3.29k | break; |
688 | | |
689 | 1.17k | case H264_NAL_PREFIX: /* first slice/VCL associated data */ |
690 | 3.70k | case H264_NAL_SUBSET_SPS: |
691 | 5.70k | case H264_NAL_DEPTH_PS: |
692 | 9.46k | case H264_NAL_RESERVED_17: |
693 | 11.6k | case H264_NAL_RESERVED_18: |
694 | 11.6k | if( p_sys->p_slice ) |
695 | 1.41k | p_pic = OutputPicture( p_dec ); |
696 | | |
697 | 11.6k | block_ChainLastAppend( &p_sys->leading.pp_append, p_frag ); |
698 | 11.6k | break; |
699 | | |
700 | | /*** Suffix NALs ***/ |
701 | | |
702 | 1.05k | case H264_NAL_END_OF_SEQ: |
703 | 5.62k | case H264_NAL_END_OF_STREAM: |
704 | | /* Early end of packetization */ |
705 | 5.62k | block_ChainLastAppend( &p_sys->frame.pp_append, p_frag ); |
706 | | |
707 | | /* important for still pictures/menus */ |
708 | 5.62k | p_sys->i_next_block_flags |= BLOCK_FLAG_END_OF_SEQUENCE; |
709 | 5.62k | if( p_sys->p_slice ) |
710 | 784 | p_pic = OutputPicture( p_dec ); |
711 | 5.62k | break; |
712 | | |
713 | 1.05k | case H264_NAL_SLICE_WP: // post |
714 | 183k | case H264_NAL_UNKNOWN: |
715 | 185k | case H264_NAL_FILLER_DATA: |
716 | 187k | case H264_NAL_SLICE_EXT: |
717 | 188k | case H264_NAL_SLICE_3D_EXT: |
718 | 189k | case H264_NAL_RESERVED_22: |
719 | 189k | case H264_NAL_RESERVED_23: |
720 | 199k | default: /* others 24..31, including unknown */ |
721 | 199k | block_ChainLastAppend( &p_sys->frame.pp_append, p_frag ); |
722 | 199k | break; |
723 | 1.03M | } |
724 | | |
725 | 1.03M | *pb_ts_used = false; |
726 | 1.03M | if( p_sys->i_frame_dts == VLC_TICK_INVALID && |
727 | 425k | p_sys->i_frame_pts == VLC_TICK_INVALID ) |
728 | 425k | { |
729 | 425k | p_sys->i_frame_dts = i_frag_dts; |
730 | 425k | p_sys->i_frame_pts = i_frag_pts; |
731 | 425k | *pb_ts_used = true; |
732 | 425k | if( i_frag_dts != VLC_TICK_INVALID ) |
733 | 218k | date_Set( &p_sys->dts, i_frag_dts ); |
734 | 425k | } |
735 | | |
736 | 1.03M | if( p_sys->p_slice && b_au_end && !p_pic ) |
737 | 0 | { |
738 | 0 | p_pic = OutputPicture( p_dec ); |
739 | 0 | } |
740 | | |
741 | 1.03M | if( p_pic && (p_pic->i_flags & BLOCK_FLAG_DROP) ) |
742 | 9.36k | { |
743 | 9.36k | block_Release( p_pic ); |
744 | 9.36k | p_pic = NULL; |
745 | 9.36k | } |
746 | | |
747 | 1.03M | return p_pic; |
748 | 1.03M | } |
749 | | |
750 | | static block_t *OutputPicture( decoder_t *p_dec ) |
751 | 232k | { |
752 | 232k | decoder_sys_t *p_sys = p_dec->p_sys; |
753 | 232k | block_t *p_pic = NULL; |
754 | 232k | block_t **pp_pic_last = &p_pic; |
755 | | |
756 | 232k | if( unlikely(!p_sys->frame.p_head) ) |
757 | 0 | { |
758 | 0 | assert( p_sys->frame.p_head ); |
759 | 0 | DropStoredNAL( p_sys ); |
760 | 0 | ResetOutputVariables( p_sys ); |
761 | 0 | cc_storage_reset( p_sys->p_ccs ); |
762 | 0 | return NULL; |
763 | 0 | } |
764 | | |
765 | | /* Bind matched/referred PPS and SPS */ |
766 | 232k | const h264_picture_parameter_set_t *p_pps = p_sys->p_active_pps; |
767 | 232k | const h264_sequence_parameter_set_t *p_sps = p_sys->p_active_sps; |
768 | 232k | if( !p_pps || !p_sps ) |
769 | 266 | { |
770 | 266 | DropStoredNAL( p_sys ); |
771 | 266 | ResetOutputVariables( p_sys ); |
772 | 266 | cc_storage_reset( p_sys->p_ccs ); |
773 | 266 | return NULL; |
774 | 266 | } |
775 | | |
776 | 232k | if( !p_sys->b_recovered && p_sys->i_recoveryfnum == UINT_MAX && |
777 | 11.0k | p_sys->i_recovery_frame_cnt == UINT_MAX && h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I ) |
778 | 504 | { |
779 | | /* No way to recover using SEI, just sync on I Slice */ |
780 | 504 | p_sys->b_recovered = true; |
781 | 504 | } |
782 | | |
783 | 232k | bool b_need_sps_pps = h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I && |
784 | 98.5k | p_sys->p_active_pps && p_sys->p_active_sps; |
785 | | |
786 | 232k | const unsigned i_frame_num = h264_get_frame_num(p_sys->p_slice); |
787 | | |
788 | | /* Handle SEI recovery */ |
789 | 232k | if ( !p_sys->b_recovered && p_sys->i_recovery_frame_cnt != UINT_MAX && |
790 | 495 | p_sys->i_recoveryfnum == UINT_MAX ) |
791 | 244 | { |
792 | 244 | p_sys->i_recoveryfnum = i_frame_num + p_sys->i_recovery_frame_cnt; |
793 | 244 | p_sys->i_recoverystartfnum = i_frame_num; |
794 | 244 | b_need_sps_pps = true; /* SPS/PPS must be inserted for SEI recovery */ |
795 | 244 | msg_Dbg( p_dec, "Recovering using SEI, prerolling %u reference pics", p_sys->i_recovery_frame_cnt ); |
796 | 244 | } |
797 | | |
798 | 232k | if( p_sys->i_recoveryfnum != UINT_MAX ) |
799 | 1.52k | { |
800 | 1.52k | assert(p_sys->b_recovered == false); |
801 | 1.52k | const unsigned maxFrameNum = h264_get_max_frame_num( p_sps ); |
802 | | |
803 | 1.52k | if( ( p_sys->i_recoveryfnum > maxFrameNum && |
804 | 1.23k | i_frame_num < p_sys->i_recoverystartfnum && |
805 | 376 | i_frame_num >= p_sys->i_recoveryfnum % maxFrameNum ) || |
806 | 1.50k | ( p_sys->i_recoveryfnum <= maxFrameNum && |
807 | 298 | i_frame_num >= p_sys->i_recoveryfnum ) ) |
808 | 53 | { |
809 | 53 | p_sys->i_recoveryfnum = UINT_MAX; |
810 | 53 | p_sys->b_recovered = true; |
811 | 53 | msg_Dbg( p_dec, "Recovery from SEI recovery point complete" ); |
812 | 53 | } |
813 | 1.52k | } |
814 | | |
815 | | /* Gather PPS/SPS if required */ |
816 | 232k | block_t *p_xpsnal = GatherSets( p_sys, b_need_sps_pps|p_sys->b_new_sps, |
817 | 232k | b_need_sps_pps|p_sys->b_new_pps ); |
818 | | |
819 | | /* Now rebuild NAL Sequence, inserting PPS/SPS if any */ |
820 | 232k | if( p_sys->leading.p_head && |
821 | 14.5k | (p_sys->leading.p_head->i_flags & BLOCK_FLAG_PRIVATE_AUD) ) |
822 | 5.36k | { |
823 | 5.36k | block_t *p_au = p_sys->leading.p_head; |
824 | 5.36k | p_sys->leading.p_head = p_au->p_next; |
825 | 5.36k | p_au->p_next = NULL; |
826 | 5.36k | block_ChainLastAppend( &pp_pic_last, p_au ); |
827 | 5.36k | } |
828 | | |
829 | 232k | if( p_xpsnal ) |
830 | 109k | block_ChainLastAppend( &pp_pic_last, p_xpsnal ); |
831 | | |
832 | 232k | if( p_sys->leading.p_head ) |
833 | 12.5k | block_ChainLastAppend( &pp_pic_last, p_sys->leading.p_head ); |
834 | | |
835 | 232k | assert( p_sys->frame.p_head ); |
836 | 232k | if( p_sys->frame.p_head ) |
837 | 232k | block_ChainLastAppend( &pp_pic_last, p_sys->frame.p_head ); |
838 | | |
839 | | /* Reset chains, now empty */ |
840 | 232k | p_sys->frame.p_head = NULL; |
841 | 232k | p_sys->frame.pp_append = &p_sys->frame.p_head; |
842 | 232k | p_sys->leading.p_head = NULL; |
843 | 232k | p_sys->leading.pp_append = &p_sys->leading.p_head; |
844 | | |
845 | 232k | p_pic = block_ChainGather( p_pic ); |
846 | | |
847 | 232k | if( !p_pic ) |
848 | 0 | { |
849 | 0 | ResetOutputVariables( p_sys ); |
850 | 0 | cc_storage_reset( p_sys->p_ccs ); |
851 | 0 | return NULL; |
852 | 0 | } |
853 | | |
854 | | /* clear up flags gathered */ |
855 | 232k | p_pic->i_flags &= ~BLOCK_FLAG_PRIVATE_MASK; |
856 | | |
857 | | /* for PTS Fixup, interlaced fields (multiple AU/block) */ |
858 | 232k | int tFOC = 0, bFOC = 0, PictureOrderCount = 0; |
859 | 232k | h264_compute_poc( p_sps, p_sys->p_slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC ); |
860 | | |
861 | 232k | unsigned i_num_clock_ts = h264_get_num_ts( p_sps, p_sys->p_slice, p_sys->i_pic_struct, tFOC, bFOC ); |
862 | | |
863 | 232k | if( !h264_is_frames_only( p_sps ) && p_sys->i_pic_struct != UINT8_MAX ) |
864 | 2.83k | { |
865 | 2.83k | switch( p_sys->i_pic_struct ) |
866 | 2.83k | { |
867 | | /* Top and Bottom field slices */ |
868 | 251 | case 1: |
869 | 511 | case 2: |
870 | 511 | p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD; |
871 | 511 | p_pic->i_flags |= h264_slice_top_field(p_sys->p_slice) ? BLOCK_FLAG_TOP_FIELD_FIRST |
872 | 511 | : BLOCK_FLAG_BOTTOM_FIELD_FIRST; |
873 | 511 | break; |
874 | | /* Each of the following slices contains multiple fields */ |
875 | 1.00k | case 3: |
876 | 1.00k | p_pic->i_flags |= BLOCK_FLAG_TOP_FIELD_FIRST; |
877 | 1.00k | break; |
878 | 346 | case 4: |
879 | 346 | p_pic->i_flags |= BLOCK_FLAG_BOTTOM_FIELD_FIRST; |
880 | 346 | break; |
881 | 298 | case 5: |
882 | 298 | p_pic->i_flags |= BLOCK_FLAG_TOP_FIELD_FIRST; |
883 | 298 | break; |
884 | 226 | case 6: |
885 | 226 | p_pic->i_flags |= BLOCK_FLAG_BOTTOM_FIELD_FIRST; |
886 | 226 | break; |
887 | 456 | default: |
888 | 456 | break; |
889 | 2.83k | } |
890 | 2.83k | } |
891 | | |
892 | | /* set dts/pts to current block timestamps */ |
893 | 232k | p_pic->i_dts = p_sys->i_frame_dts; |
894 | 232k | p_pic->i_pts = p_sys->i_frame_pts; |
895 | | |
896 | | /* Fixup missing timestamps after split (multiple AU/block)*/ |
897 | 232k | if( p_pic->i_dts == VLC_TICK_INVALID ) |
898 | 28.6k | p_pic->i_dts = date_Get( &p_sys->dts ); |
899 | | |
900 | 232k | if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I ) |
901 | 98.5k | p_sys->prevdatedpoc.pts = VLC_TICK_INVALID; |
902 | | |
903 | 232k | if( p_pic->i_pts == VLC_TICK_INVALID ) |
904 | 232k | { |
905 | 232k | if( p_sys->prevdatedpoc.pts != VLC_TICK_INVALID && |
906 | 39.2k | date_Get( &p_sys->dts ) != VLC_TICK_INVALID ) |
907 | 39.2k | { |
908 | 39.2k | date_t pts = p_sys->dts; |
909 | 39.2k | date_Set( &pts, p_sys->prevdatedpoc.pts ); |
910 | | |
911 | 39.2k | int diff = tFOC - p_sys->prevdatedpoc.num; |
912 | 39.2k | if( diff > 0 ) |
913 | 13.6k | date_Increment( &pts, diff ); |
914 | 25.5k | else |
915 | 25.5k | date_Decrement( &pts, -diff ); |
916 | | |
917 | 39.2k | p_pic->i_pts = date_Get( &pts ); |
918 | | /* non monotonically increasing dts on some videos 33333 33333...35000 */ |
919 | 39.2k | if( p_pic->i_pts < p_pic->i_dts ) |
920 | 10.0k | p_pic->i_pts = p_pic->i_dts; |
921 | 39.2k | } |
922 | | /* In case there's no PTS at all */ |
923 | 193k | else if( h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) ) |
924 | 13.0k | { |
925 | 13.0k | p_pic->i_pts = p_pic->i_dts; |
926 | 13.0k | } |
927 | 180k | else if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I && |
928 | 91.5k | date_Get( &p_sys->dts ) != VLC_TICK_INVALID ) |
929 | 91.2k | { |
930 | | /* Hell no PTS on IDR. We're totally blind */ |
931 | 91.2k | date_t pts = p_sys->dts; |
932 | 91.2k | date_Increment( &pts, 2 ); |
933 | 91.2k | p_pic->i_pts = date_Get( &pts ); |
934 | 91.2k | } |
935 | 232k | } |
936 | 0 | else if( p_pic->i_dts == VLC_TICK_INVALID && |
937 | 0 | h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) ) |
938 | 0 | { |
939 | 0 | p_pic->i_dts = p_pic->i_pts; |
940 | 0 | if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID ) |
941 | 0 | date_Set( &p_sys->dts, p_pic->i_pts ); |
942 | 0 | } |
943 | | |
944 | 232k | if( p_pic->i_pts != VLC_TICK_INVALID ) |
945 | 139k | { |
946 | 139k | p_sys->prevdatedpoc.pts = p_pic->i_pts; |
947 | 139k | p_sys->prevdatedpoc.num = PictureOrderCount; |
948 | 139k | } |
949 | | |
950 | 232k | if( p_pic->i_length == 0 ) |
951 | 232k | { |
952 | 232k | date_t next = p_sys->dts; |
953 | 232k | date_Increment( &next, i_num_clock_ts ); |
954 | 232k | p_pic->i_length = date_Get( &next ) - date_Get( &p_sys->dts ); |
955 | 232k | } |
956 | | |
957 | | #if 0 |
958 | | 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", |
959 | | tFOC, bFOC, PictureOrderCount, |
960 | | h264_get_slice_type(p_sys->p_slice), p_sys->b_recovered, p_pic->i_flags, |
961 | | h264_get_nal_ref_idc(p_sys->p_slice), h264_get_frame_num(p_sys->p_slice), |
962 | | h264_is_field_pic(p_sys->p_slice), |
963 | | p_pic->i_pts - p_pic->i_dts, p_pic->i_pts % VLC_TICK_FROM_SEC(100), p_pic->i_length); |
964 | | #endif |
965 | | |
966 | | /* save for next pic fixups */ |
967 | 232k | if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID ) |
968 | 222k | { |
969 | 222k | if( p_sys->i_next_block_flags & BLOCK_FLAG_DISCONTINUITY ) |
970 | 0 | date_Set( &p_sys->dts, VLC_TICK_INVALID ); |
971 | 222k | else |
972 | 222k | date_Increment( &p_sys->dts, i_num_clock_ts ); |
973 | 222k | } |
974 | | |
975 | 232k | if( p_pic ) |
976 | 232k | { |
977 | 232k | p_pic->i_flags |= p_sys->i_next_block_flags; |
978 | 232k | p_sys->i_next_block_flags = 0; |
979 | 232k | } |
980 | | |
981 | 232k | switch( h264_get_slice_type( p_sys->p_slice ) ) |
982 | 232k | { |
983 | 114k | case H264_SLICE_TYPE_P: |
984 | 114k | p_pic->i_flags |= BLOCK_FLAG_TYPE_P; |
985 | 114k | break; |
986 | 16.4k | case H264_SLICE_TYPE_B: |
987 | 16.4k | p_pic->i_flags |= BLOCK_FLAG_TYPE_B; |
988 | 16.4k | break; |
989 | 98.5k | case H264_SLICE_TYPE_I: |
990 | 98.5k | p_pic->i_flags |= BLOCK_FLAG_TYPE_I; |
991 | 101k | default: |
992 | 101k | break; |
993 | 232k | } |
994 | | |
995 | 232k | if( !p_sys->b_recovered ) |
996 | 11.8k | { |
997 | 11.8k | if( p_sys->i_recoveryfnum != UINT_MAX ) /* recovering from SEI */ |
998 | 1.47k | p_pic->i_flags |= BLOCK_FLAG_PREROLL; |
999 | 10.3k | else |
1000 | 10.3k | p_pic->i_flags |= BLOCK_FLAG_DROP; |
1001 | 11.8k | } |
1002 | | |
1003 | 232k | p_pic->i_flags &= ~BLOCK_FLAG_PRIVATE_AUD; |
1004 | | |
1005 | | /* reset after output */ |
1006 | 232k | ResetOutputVariables( p_sys ); |
1007 | | |
1008 | | /* CC */ |
1009 | 232k | cc_storage_commit( p_sys->p_ccs, p_pic ); |
1010 | | |
1011 | 232k | return p_pic; |
1012 | 232k | } |
1013 | | |
1014 | | static int CmpXPS( const block_t *p_ref, const block_t *p_nal ) |
1015 | 232k | { |
1016 | 232k | return p_ref == NULL || |
1017 | 162k | p_ref->i_buffer != p_nal->i_buffer || |
1018 | 23.1k | memcmp( p_ref->p_buffer, p_nal->p_buffer, p_nal->i_buffer ); |
1019 | 232k | } |
1020 | | |
1021 | | #define wrap_h264_xps_decode(funcname ) \ |
1022 | | static void *funcname ## _wrapper ( const uint8_t *a, size_t b, bool c ) \ |
1023 | 217k | { return funcname(a,b,c); } h264.c:h264_decode_sps_wrapper Line | Count | Source | 1023 | 99.5k | { return funcname(a,b,c); } |
h264.c:h264_decode_pps_wrapper Line | Count | Source | 1023 | 117k | { return funcname(a,b,c); } |
|
1024 | | |
1025 | | wrap_h264_xps_decode(h264_decode_sps) |
1026 | | wrap_h264_xps_decode(h264_decode_pps) |
1027 | | |
1028 | | #define wrap_h264_xps_release(funcname, typecast) \ |
1029 | 96.8k | static void funcname ## _wrapper ( void *a ) { funcname((typecast *)a); } h264.c:h264_release_sps_wrapper Line | Count | Source | 1029 | 14.6k | static void funcname ## _wrapper ( void *a ) { funcname((typecast *)a); } |
h264.c:h264_release_pps_wrapper Line | Count | Source | 1029 | 82.2k | static void funcname ## _wrapper ( void *a ) { funcname((typecast *)a); } |
|
1030 | | |
1031 | | wrap_h264_xps_release(h264_release_sps, h264_sequence_parameter_set_t) |
1032 | | wrap_h264_xps_release(h264_release_pps, h264_picture_parameter_set_t) |
1033 | | |
1034 | | static void ReleaseXPS( decoder_sys_t *p_sys ) |
1035 | 16.0k | { |
1036 | 530k | for( int i = 0; i <= H264_SPS_ID_MAX; i++ ) |
1037 | 514k | { |
1038 | 514k | if( !p_sys->sps[i].p_block ) |
1039 | 501k | continue; |
1040 | 12.7k | block_Release( p_sys->sps[i].p_block ); |
1041 | 12.7k | h264_release_sps( p_sys->sps[i].p_sps ); |
1042 | 12.7k | } |
1043 | 4.13M | for( int i = 0; i <= H264_PPS_ID_MAX; i++ ) |
1044 | 4.11M | { |
1045 | 4.11M | if( !p_sys->pps[i].p_block ) |
1046 | 4.10M | continue; |
1047 | 11.5k | block_Release( p_sys->pps[i].p_block ); |
1048 | 11.5k | h264_release_pps( p_sys->pps[i].p_pps ); |
1049 | 11.5k | } |
1050 | 530k | for( int i = 0; i <= H264_SPSEXT_ID_MAX; i++ ) |
1051 | 514k | { |
1052 | 514k | if( p_sys->spsext[i].p_block ) |
1053 | 519 | block_Release( p_sys->spsext[i].p_block ); |
1054 | 514k | } |
1055 | 16.0k | p_sys->p_active_sps = NULL; |
1056 | 16.0k | p_sys->p_active_pps = NULL; |
1057 | 16.0k | } |
1058 | | |
1059 | | static bool PutXPS( decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag ) |
1060 | 246k | { |
1061 | 246k | decoder_sys_t *p_sys = p_dec->p_sys; |
1062 | | |
1063 | 246k | uint8_t i_id; |
1064 | 246k | if( !hxxx_strip_AnnexB_startcode( (const uint8_t **)&p_frag->p_buffer, |
1065 | 246k | &p_frag->i_buffer ) || |
1066 | 246k | !h264_get_xps_id( p_frag->p_buffer, p_frag->i_buffer, &i_id ) ) |
1067 | 14.1k | { |
1068 | 14.1k | block_Release( p_frag ); |
1069 | 14.1k | return false; |
1070 | 14.1k | } |
1071 | | |
1072 | 232k | const char * rgsz_types[3] = {"SPS", "PPS", "SPSEXT"}; |
1073 | 232k | const char *psz_type; |
1074 | 232k | block_t **pp_block_dst; |
1075 | | /* all depend on pp_xps_dst */ |
1076 | 232k | void **pp_xps_dst = NULL; |
1077 | 232k | const void **pp_active = NULL; /* optional */ |
1078 | 232k | void * (* pf_decode_xps)(const uint8_t *, size_t, bool) = NULL; |
1079 | 232k | void (* pf_release_xps)(void *) = NULL; |
1080 | | |
1081 | 232k | switch( i_nal_type ) |
1082 | 232k | { |
1083 | 104k | case H264_NAL_SPS: |
1084 | 104k | psz_type = rgsz_types[0]; |
1085 | 104k | pp_active = (const void **) &p_sys->p_active_sps; |
1086 | 104k | pp_block_dst = &p_sys->sps[i_id].p_block; |
1087 | 104k | pp_xps_dst = (void **) &p_sys->sps[i_id].p_sps; |
1088 | 104k | pf_decode_xps = h264_decode_sps_wrapper; |
1089 | 104k | pf_release_xps = h264_release_sps_wrapper; |
1090 | 104k | break; |
1091 | 125k | case H264_NAL_PPS: |
1092 | 125k | psz_type = rgsz_types[1]; |
1093 | 125k | pp_active = (const void **) &p_sys->p_active_pps; |
1094 | 125k | pp_block_dst = &p_sys->pps[i_id].p_block; |
1095 | 125k | pp_xps_dst = (void **) &p_sys->pps[i_id].p_pps; |
1096 | 125k | pf_decode_xps = h264_decode_pps_wrapper; |
1097 | 125k | pf_release_xps = h264_release_pps_wrapper; |
1098 | 125k | break; |
1099 | 2.76k | case H264_NAL_SPS_EXT: |
1100 | 2.76k | psz_type = rgsz_types[2]; |
1101 | 2.76k | pp_block_dst = &p_sys->spsext[i_id].p_block; |
1102 | 2.76k | break; |
1103 | 0 | default: |
1104 | 0 | block_Release( p_frag ); |
1105 | 0 | return false; |
1106 | 232k | } |
1107 | | |
1108 | 232k | if( !CmpXPS( *pp_block_dst, p_frag ) ) |
1109 | 13.0k | { |
1110 | 13.0k | block_Release( p_frag ); |
1111 | 13.0k | return false; |
1112 | 13.0k | } |
1113 | | |
1114 | 219k | msg_Dbg( p_dec, "found NAL_%s (id=%" PRIu8 ")", psz_type, i_id ); |
1115 | | |
1116 | 219k | if( pp_xps_dst != NULL ) |
1117 | 217k | { |
1118 | 217k | void *p_xps = pf_decode_xps( p_frag->p_buffer, p_frag->i_buffer, true ); |
1119 | 217k | if( !p_xps ) |
1120 | 96.1k | { |
1121 | 96.1k | block_Release( p_frag ); |
1122 | 96.1k | return false; |
1123 | 96.1k | } |
1124 | 121k | if( *pp_xps_dst ) |
1125 | 96.8k | { |
1126 | 96.8k | if( pp_active && *pp_active == *pp_xps_dst ) |
1127 | 7.31k | *pp_active = NULL; |
1128 | 96.8k | pf_release_xps( *pp_xps_dst ); |
1129 | 96.8k | } |
1130 | 121k | *pp_xps_dst = p_xps; |
1131 | 121k | } |
1132 | | |
1133 | 123k | if( *pp_block_dst ) |
1134 | 98.3k | block_Release( *pp_block_dst ); |
1135 | 123k | *pp_block_dst = p_frag; |
1136 | | |
1137 | 123k | return true; |
1138 | 219k | } |
1139 | | |
1140 | | static void GetSPSPPS( uint8_t i_pps_id, void *priv, |
1141 | | const h264_sequence_parameter_set_t **pp_sps, |
1142 | | const h264_picture_parameter_set_t **pp_pps ) |
1143 | 616k | { |
1144 | 616k | decoder_sys_t *p_sys = priv; |
1145 | | |
1146 | 616k | *pp_pps = p_sys->pps[i_pps_id].p_pps; |
1147 | 616k | if( *pp_pps == NULL ) |
1148 | 20.1k | *pp_sps = NULL; |
1149 | 596k | else |
1150 | 596k | *pp_sps = p_sys->sps[h264_get_pps_sps_id(*pp_pps)].p_sps; |
1151 | 616k | } |
1152 | | |
1153 | | static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag ) |
1154 | 517k | { |
1155 | 517k | decoder_sys_t *p_sys = p_dec->p_sys; |
1156 | | |
1157 | 517k | const uint8_t *p_stripped = p_frag->p_buffer; |
1158 | 517k | size_t i_stripped = p_frag->i_buffer; |
1159 | | |
1160 | 517k | if( !hxxx_strip_AnnexB_startcode( &p_stripped, &i_stripped ) || i_stripped < 2 ) |
1161 | 158k | return NULL; |
1162 | | |
1163 | 359k | h264_slice_t *p_slice = h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys ); |
1164 | 359k | if( !p_slice ) |
1165 | 89.3k | return NULL; |
1166 | | |
1167 | 270k | const h264_sequence_parameter_set_t *p_sps; |
1168 | 270k | const h264_picture_parameter_set_t *p_pps; |
1169 | 270k | GetSPSPPS( h264_get_slice_pps_id( p_slice ), p_sys, &p_sps, &p_pps ); |
1170 | 270k | if( unlikely( !p_sps || !p_pps) ) |
1171 | 0 | { |
1172 | 0 | h264_slice_release( p_slice ); |
1173 | 0 | return NULL; |
1174 | 0 | } |
1175 | | |
1176 | 270k | ActivateSets( p_dec, p_sps, p_pps ); |
1177 | | |
1178 | 270k | return p_slice; |
1179 | 270k | } |
1180 | | |
1181 | | static bool ParseSeiCallback( const hxxx_sei_data_t *p_sei_data, void *cbdata ) |
1182 | 27.4k | { |
1183 | 27.4k | decoder_t *p_dec = (decoder_t *) cbdata; |
1184 | 27.4k | decoder_sys_t *p_sys = p_dec->p_sys; |
1185 | | |
1186 | 27.4k | switch( p_sei_data->i_type ) |
1187 | 27.4k | { |
1188 | | /* Look for pic timing */ |
1189 | 19.8k | case HXXX_SEI_PIC_TIMING: |
1190 | 19.8k | { |
1191 | 19.8k | const h264_sequence_parameter_set_t *p_sps = p_sys->p_active_sps; |
1192 | 19.8k | if( unlikely( p_sps == NULL ) ) |
1193 | 0 | { |
1194 | 0 | assert( p_sps ); |
1195 | 0 | break; |
1196 | 0 | } |
1197 | | |
1198 | 19.8k | h264_decode_sei_pic_timing( p_sei_data->p_bs, p_sps, |
1199 | 19.8k | &p_sys->i_pic_struct, |
1200 | 19.8k | &p_sys->i_dpb_output_delay ); |
1201 | 19.8k | } break; |
1202 | | |
1203 | | /* Look for user_data_registered_itu_t_t35 */ |
1204 | 4.01k | case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35: |
1205 | 4.01k | { |
1206 | 4.01k | if( p_sei_data->itu_t35.type == HXXX_ITU_T35_TYPE_CC ) |
1207 | 4.01k | { |
1208 | 4.01k | cc_storage_append( p_sys->p_ccs, true, p_sei_data->itu_t35.u.cc.p_data, |
1209 | 4.01k | p_sei_data->itu_t35.u.cc.i_data ); |
1210 | 4.01k | } |
1211 | 4.01k | } break; |
1212 | | |
1213 | 0 | case HXXX_SEI_FRAME_PACKING_ARRANGEMENT: |
1214 | 0 | { |
1215 | 0 | if( p_dec->fmt_in->video.multiview_mode == MULTIVIEW_2D ) |
1216 | 0 | { |
1217 | 0 | video_multiview_mode_t mode; |
1218 | 0 | switch( p_sei_data->frame_packing.type ) |
1219 | 0 | { |
1220 | 0 | case FRAME_PACKING_INTERLEAVED_CHECKERBOARD: |
1221 | 0 | mode = MULTIVIEW_STEREO_CHECKERBOARD; break; |
1222 | 0 | case FRAME_PACKING_INTERLEAVED_COLUMN: |
1223 | 0 | mode = MULTIVIEW_STEREO_COL; break; |
1224 | 0 | case FRAME_PACKING_INTERLEAVED_ROW: |
1225 | 0 | mode = MULTIVIEW_STEREO_ROW; break; |
1226 | 0 | case FRAME_PACKING_SIDE_BY_SIDE: |
1227 | 0 | mode = MULTIVIEW_STEREO_SBS; break; |
1228 | 0 | case FRAME_PACKING_TOP_BOTTOM: |
1229 | 0 | mode = MULTIVIEW_STEREO_TB; break; |
1230 | 0 | case FRAME_PACKING_TEMPORAL: |
1231 | 0 | mode = MULTIVIEW_STEREO_FRAME; break; |
1232 | 0 | case FRAME_PACKING_TILED: |
1233 | 0 | default: |
1234 | 0 | mode = MULTIVIEW_2D; break; |
1235 | 0 | } |
1236 | 0 | p_dec->fmt_out.video.multiview_mode = mode; |
1237 | 0 | } |
1238 | 0 | } break; |
1239 | | |
1240 | | /* Look for SEI recovery point */ |
1241 | 1.99k | case HXXX_SEI_RECOVERY_POINT: |
1242 | 1.99k | { |
1243 | 1.99k | h264_sei_recovery_point_t reco; |
1244 | 1.99k | if( !p_sys->b_recovered && |
1245 | 1.12k | h264_decode_sei_recovery_point( p_sei_data->p_bs, &reco ) ) |
1246 | 1.12k | { |
1247 | 1.12k | msg_Dbg( p_dec, "Seen SEI recovery point, %u recovery frames", reco.i_frames ); |
1248 | 1.12k | p_sys->i_recovery_frame_cnt = reco.i_frames; |
1249 | 1.12k | } |
1250 | 1.99k | } break; |
1251 | | |
1252 | 1.58k | default: |
1253 | | /* Will skip */ |
1254 | 1.58k | break; |
1255 | 27.4k | } |
1256 | | |
1257 | 27.4k | return true; |
1258 | 27.4k | } |
1259 | | |