Coverage Report

Created: 2025-10-10 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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