Coverage Report

Created: 2025-11-11 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/packetizer/packetizer_helper.h
Line
Count
Source
1
/*****************************************************************************
2
 * packetizer_helper.h: Packetizer helpers
3
 *****************************************************************************
4
 * Copyright (C) 2009 Laurent Aimar
5
 *
6
 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program; if not, write to the Free Software Foundation,
20
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22
23
#ifndef VLC_PACKETIZER_HELPER_H_
24
#define VLC_PACKETIZER_HELPER_H_
25
26
#include <vlc_block.h>
27
28
enum
29
{
30
    STATE_NOSYNC,
31
    STATE_SYNC,
32
    STATE_HEADER,
33
    STATE_NEXT_SYNC,
34
    STATE_GET_DATA,
35
    STATE_SEND_DATA,
36
    STATE_CUSTOM_FIRST,
37
};
38
39
typedef void (*packetizer_reset_t)( void *p_private, bool b_flush );
40
typedef block_t *(*packetizer_parse_t)( void *p_private, bool *pb_ts_used, block_t * );
41
typedef block_t *(*packetizer_drain_t)( void *p_private );
42
typedef int (*packetizer_validate_t)( void *p_private, block_t * );
43
44
typedef struct
45
{
46
    int i_state;
47
    block_bytestream_t bytestream;
48
    size_t i_offset;
49
50
    int i_startcode;
51
    const uint8_t *p_startcode;
52
    block_startcode_helper_t pf_startcode_helper;
53
54
    int i_au_prepend;
55
    const uint8_t *p_au_prepend;
56
57
    unsigned i_au_min_size;
58
59
    void *p_private;
60
    packetizer_reset_t    pf_reset;
61
    packetizer_parse_t    pf_parse;
62
    packetizer_validate_t pf_validate;
63
    packetizer_drain_t    pf_drain;
64
65
} packetizer_t;
66
67
static inline void packetizer_Init( packetizer_t *p_pack,
68
                                    const uint8_t *p_startcode, int i_startcode,
69
                                    block_startcode_helper_t pf_start_helper,
70
                                    const uint8_t *p_au_prepend, int i_au_prepend,
71
                                    unsigned i_au_min_size,
72
                                    packetizer_reset_t pf_reset,
73
                                    packetizer_parse_t pf_parse,
74
                                    packetizer_validate_t pf_validate,
75
                                    packetizer_drain_t pf_drain,
76
                                    void *p_private )
77
35.0k
{
78
35.0k
    p_pack->i_state = STATE_NOSYNC;
79
35.0k
    block_BytestreamInit( &p_pack->bytestream );
80
35.0k
    p_pack->i_offset = 0;
81
82
35.0k
    p_pack->i_au_prepend = i_au_prepend;
83
35.0k
    p_pack->p_au_prepend = p_au_prepend;
84
35.0k
    p_pack->i_au_min_size = i_au_min_size;
85
86
35.0k
    p_pack->i_startcode = i_startcode;
87
35.0k
    p_pack->p_startcode = p_startcode;
88
35.0k
    p_pack->pf_startcode_helper = pf_start_helper;
89
35.0k
    p_pack->pf_reset = pf_reset;
90
35.0k
    p_pack->pf_parse = pf_parse;
91
35.0k
    p_pack->pf_validate = pf_validate;
92
35.0k
    p_pack->pf_drain = pf_drain;
93
35.0k
    p_pack->p_private = p_private;
94
35.0k
}
Unexecuted instantiation: a52.c:packetizer_Init
Unexecuted instantiation: dts.c:packetizer_Init
Unexecuted instantiation: flac.c:packetizer_Init
h264.c:packetizer_Init
Line
Count
Source
77
17.0k
{
78
17.0k
    p_pack->i_state = STATE_NOSYNC;
79
17.0k
    block_BytestreamInit( &p_pack->bytestream );
80
17.0k
    p_pack->i_offset = 0;
81
82
17.0k
    p_pack->i_au_prepend = i_au_prepend;
83
17.0k
    p_pack->p_au_prepend = p_au_prepend;
84
17.0k
    p_pack->i_au_min_size = i_au_min_size;
85
86
17.0k
    p_pack->i_startcode = i_startcode;
87
17.0k
    p_pack->p_startcode = p_startcode;
88
17.0k
    p_pack->pf_startcode_helper = pf_start_helper;
89
17.0k
    p_pack->pf_reset = pf_reset;
90
17.0k
    p_pack->pf_parse = pf_parse;
91
17.0k
    p_pack->pf_validate = pf_validate;
92
17.0k
    p_pack->pf_drain = pf_drain;
93
17.0k
    p_pack->p_private = p_private;
94
17.0k
}
hevc.c:packetizer_Init
Line
Count
Source
77
11.7k
{
78
11.7k
    p_pack->i_state = STATE_NOSYNC;
79
11.7k
    block_BytestreamInit( &p_pack->bytestream );
80
11.7k
    p_pack->i_offset = 0;
81
82
11.7k
    p_pack->i_au_prepend = i_au_prepend;
83
11.7k
    p_pack->p_au_prepend = p_au_prepend;
84
11.7k
    p_pack->i_au_min_size = i_au_min_size;
85
86
11.7k
    p_pack->i_startcode = i_startcode;
87
11.7k
    p_pack->p_startcode = p_startcode;
88
11.7k
    p_pack->pf_startcode_helper = pf_start_helper;
89
11.7k
    p_pack->pf_reset = pf_reset;
90
11.7k
    p_pack->pf_parse = pf_parse;
91
11.7k
    p_pack->pf_validate = pf_validate;
92
11.7k
    p_pack->pf_drain = pf_drain;
93
11.7k
    p_pack->p_private = p_private;
94
11.7k
}
Unexecuted instantiation: mlp.c:packetizer_Init
Unexecuted instantiation: mpeg4audio.c:packetizer_Init
mpeg4video.c:packetizer_Init
Line
Count
Source
77
474
{
78
474
    p_pack->i_state = STATE_NOSYNC;
79
474
    block_BytestreamInit( &p_pack->bytestream );
80
474
    p_pack->i_offset = 0;
81
82
474
    p_pack->i_au_prepend = i_au_prepend;
83
474
    p_pack->p_au_prepend = p_au_prepend;
84
474
    p_pack->i_au_min_size = i_au_min_size;
85
86
474
    p_pack->i_startcode = i_startcode;
87
474
    p_pack->p_startcode = p_startcode;
88
474
    p_pack->pf_startcode_helper = pf_start_helper;
89
474
    p_pack->pf_reset = pf_reset;
90
474
    p_pack->pf_parse = pf_parse;
91
474
    p_pack->pf_validate = pf_validate;
92
474
    p_pack->pf_drain = pf_drain;
93
474
    p_pack->p_private = p_private;
94
474
}
Unexecuted instantiation: mpegaudio.c:packetizer_Init
mpegvideo.c:packetizer_Init
Line
Count
Source
77
5.02k
{
78
5.02k
    p_pack->i_state = STATE_NOSYNC;
79
5.02k
    block_BytestreamInit( &p_pack->bytestream );
80
5.02k
    p_pack->i_offset = 0;
81
82
5.02k
    p_pack->i_au_prepend = i_au_prepend;
83
5.02k
    p_pack->p_au_prepend = p_au_prepend;
84
5.02k
    p_pack->i_au_min_size = i_au_min_size;
85
86
5.02k
    p_pack->i_startcode = i_startcode;
87
5.02k
    p_pack->p_startcode = p_startcode;
88
5.02k
    p_pack->pf_startcode_helper = pf_start_helper;
89
5.02k
    p_pack->pf_reset = pf_reset;
90
5.02k
    p_pack->pf_parse = pf_parse;
91
5.02k
    p_pack->pf_validate = pf_validate;
92
5.02k
    p_pack->pf_drain = pf_drain;
93
5.02k
    p_pack->p_private = p_private;
94
5.02k
}
vc1.c:packetizer_Init
Line
Count
Source
77
778
{
78
778
    p_pack->i_state = STATE_NOSYNC;
79
778
    block_BytestreamInit( &p_pack->bytestream );
80
778
    p_pack->i_offset = 0;
81
82
778
    p_pack->i_au_prepend = i_au_prepend;
83
778
    p_pack->p_au_prepend = p_au_prepend;
84
778
    p_pack->i_au_min_size = i_au_min_size;
85
86
778
    p_pack->i_startcode = i_startcode;
87
778
    p_pack->p_startcode = p_startcode;
88
778
    p_pack->pf_startcode_helper = pf_start_helper;
89
778
    p_pack->pf_reset = pf_reset;
90
778
    p_pack->pf_parse = pf_parse;
91
778
    p_pack->pf_validate = pf_validate;
92
778
    p_pack->pf_drain = pf_drain;
93
778
    p_pack->p_private = p_private;
94
778
}
95
96
static inline void packetizer_Clean( packetizer_t *p_pack )
97
35.0k
{
98
35.0k
    block_BytestreamRelease( &p_pack->bytestream );
99
35.0k
}
Unexecuted instantiation: a52.c:packetizer_Clean
Unexecuted instantiation: dts.c:packetizer_Clean
Unexecuted instantiation: flac.c:packetizer_Clean
h264.c:packetizer_Clean
Line
Count
Source
97
17.0k
{
98
17.0k
    block_BytestreamRelease( &p_pack->bytestream );
99
17.0k
}
hevc.c:packetizer_Clean
Line
Count
Source
97
11.7k
{
98
11.7k
    block_BytestreamRelease( &p_pack->bytestream );
99
11.7k
}
Unexecuted instantiation: mlp.c:packetizer_Clean
Unexecuted instantiation: mpeg4audio.c:packetizer_Clean
mpeg4video.c:packetizer_Clean
Line
Count
Source
97
474
{
98
474
    block_BytestreamRelease( &p_pack->bytestream );
99
474
}
Unexecuted instantiation: mpegaudio.c:packetizer_Clean
mpegvideo.c:packetizer_Clean
Line
Count
Source
97
5.02k
{
98
5.02k
    block_BytestreamRelease( &p_pack->bytestream );
99
5.02k
}
vc1.c:packetizer_Clean
Line
Count
Source
97
778
{
98
778
    block_BytestreamRelease( &p_pack->bytestream );
99
778
}
100
101
static inline void packetizer_Flush( packetizer_t *p_pack )
102
0
{
103
0
    p_pack->i_state = STATE_NOSYNC;
104
0
    block_BytestreamEmpty( &p_pack->bytestream );
105
0
    p_pack->i_offset = 0;
106
0
    p_pack->pf_reset( p_pack->p_private, true );
107
0
}
Unexecuted instantiation: a52.c:packetizer_Flush
Unexecuted instantiation: dts.c:packetizer_Flush
Unexecuted instantiation: flac.c:packetizer_Flush
Unexecuted instantiation: h264.c:packetizer_Flush
Unexecuted instantiation: hevc.c:packetizer_Flush
Unexecuted instantiation: mlp.c:packetizer_Flush
Unexecuted instantiation: mpeg4audio.c:packetizer_Flush
Unexecuted instantiation: mpeg4video.c:packetizer_Flush
Unexecuted instantiation: mpegaudio.c:packetizer_Flush
Unexecuted instantiation: mpegvideo.c:packetizer_Flush
Unexecuted instantiation: vc1.c:packetizer_Flush
108
109
static block_t *packetizer_PacketizeBlock( packetizer_t *p_pack, block_t **pp_block )
110
1.05M
{
111
1.05M
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
1.05M
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
368
        return NULL;
115
116
1.05M
    if( p_block && unlikely( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) )
117
0
    {
118
0
        block_t *p_drained = packetizer_PacketizeBlock( p_pack, NULL );
119
0
        if( p_drained )
120
0
            return p_drained;
121
122
0
        p_pack->i_state = STATE_NOSYNC;
123
0
        block_BytestreamEmpty( &p_pack->bytestream );
124
0
        p_pack->i_offset = 0;
125
0
        p_pack->pf_reset( p_pack->p_private, false );
126
0
    }
127
128
1.05M
    if( p_block )
129
1.02M
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
1.05M
    for( ;; )
132
2.65M
    {
133
2.65M
        bool b_used_ts;
134
2.65M
        block_t *p_pic;
135
136
2.65M
        switch( p_pack->i_state )
137
2.65M
        {
138
2.55M
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
2.55M
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
2.55M
                                                p_pack->p_startcode, p_pack->i_startcode,
142
2.55M
                                                p_pack->pf_startcode_helper, NULL ) )
143
2.52M
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
2.55M
            if( p_pack->i_offset )
146
22.8k
            {
147
22.8k
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
22.8k
                p_pack->i_offset = 0;
149
22.8k
                block_BytestreamFlush( &p_pack->bytestream );
150
22.8k
            }
151
152
2.55M
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
31.2k
                return NULL; /* Need more data */
154
155
2.52M
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
2.62M
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
2.62M
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
2.62M
                                               p_pack->p_startcode, p_pack->i_startcode,
162
2.62M
                                               p_pack->pf_startcode_helper, NULL ) )
163
123k
            {
164
123k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
97.8k
                    return NULL; /* Need more data */
166
167
                /* When flushing and we don't find a startcode, suppose that
168
                 * the data extend up to the end */
169
25.6k
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
25.6k
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
25.6k
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
1.40k
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
1.40k
                    return NULL;
176
25.6k
            }
177
178
2.52M
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
2.52M
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
2.52M
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
2.52M
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
2.52M
            p_pic->i_pts = p_block_bytestream->i_pts;
190
2.52M
            p_pic->i_dts = p_block_bytestream->i_dts;
191
192
            /* Do not wait for next sync code if notified block ends AU */
193
2.52M
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
0
                 p_block_bytestream->i_buffer == p_pack->i_offset )
195
0
            {
196
0
                p_pic->i_flags |= BLOCK_FLAG_AU_END;
197
0
            }
198
199
2.52M
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
2.52M
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
2.52M
            if( p_pack->i_au_prepend > 0 )
202
2.50M
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
2.52M
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
2.52M
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
30.1k
            {
209
30.1k
                block_Release( p_pic );
210
30.1k
                p_pic = NULL;
211
30.1k
            }
212
2.49M
            else
213
2.49M
            {
214
2.49M
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
2.49M
                if( b_used_ts )
216
1.19M
                {
217
1.19M
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
1.19M
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
1.19M
                }
220
2.49M
            }
221
222
2.52M
            if( !p_pic )
223
1.59M
            {
224
1.59M
                p_pack->i_state = STATE_NOSYNC;
225
1.59M
                break;
226
1.59M
            }
227
927k
            if( p_pack->pf_validate( p_pack->p_private, p_pic ) )
228
1.23k
            {
229
1.23k
                p_pack->i_state = STATE_NOSYNC;
230
1.23k
                block_Release( p_pic );
231
1.23k
                break;
232
1.23k
            }
233
234
            /* So p_block doesn't get re-added several times */
235
925k
            if( pp_block )
236
924k
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
925k
            p_pack->i_state = STATE_NOSYNC;
239
240
925k
            return p_pic;
241
2.65M
        }
242
2.65M
    }
243
1.05M
}
Unexecuted instantiation: a52.c:packetizer_PacketizeBlock
Unexecuted instantiation: dts.c:packetizer_PacketizeBlock
Unexecuted instantiation: flac.c:packetizer_PacketizeBlock
h264.c:packetizer_PacketizeBlock
Line
Count
Source
110
272k
{
111
272k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
272k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
63
        return NULL;
115
116
272k
    if( p_block && unlikely( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) )
117
0
    {
118
0
        block_t *p_drained = packetizer_PacketizeBlock( p_pack, NULL );
119
0
        if( p_drained )
120
0
            return p_drained;
121
122
0
        p_pack->i_state = STATE_NOSYNC;
123
0
        block_BytestreamEmpty( &p_pack->bytestream );
124
0
        p_pack->i_offset = 0;
125
0
        p_pack->pf_reset( p_pack->p_private, false );
126
0
    }
127
128
272k
    if( p_block )
129
254k
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
272k
    for( ;; )
132
1.10M
    {
133
1.10M
        bool b_used_ts;
134
1.10M
        block_t *p_pic;
135
136
1.10M
        switch( p_pack->i_state )
137
1.10M
        {
138
1.05M
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
1.05M
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
1.05M
                                                p_pack->p_startcode, p_pack->i_startcode,
142
1.05M
                                                p_pack->pf_startcode_helper, NULL ) )
143
1.04M
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
1.05M
            if( p_pack->i_offset )
146
11.7k
            {
147
11.7k
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
11.7k
                p_pack->i_offset = 0;
149
11.7k
                block_BytestreamFlush( &p_pack->bytestream );
150
11.7k
            }
151
152
1.05M
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
16.6k
                return NULL; /* Need more data */
154
155
1.04M
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
1.08M
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
1.08M
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
1.08M
                                               p_pack->p_startcode, p_pack->i_startcode,
162
1.08M
                                               p_pack->pf_startcode_helper, NULL ) )
163
57.1k
            {
164
57.1k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
43.3k
                    return NULL; /* Need more data */
166
167
                /* When flushing and we don't find a startcode, suppose that
168
                 * the data extend up to the end */
169
13.8k
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
13.8k
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
13.8k
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
1.13k
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
1.13k
                    return NULL;
176
13.8k
            }
177
178
1.04M
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
1.04M
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
1.04M
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
1.04M
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
1.04M
            p_pic->i_pts = p_block_bytestream->i_pts;
190
1.04M
            p_pic->i_dts = p_block_bytestream->i_dts;
191
192
            /* Do not wait for next sync code if notified block ends AU */
193
1.04M
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
0
                 p_block_bytestream->i_buffer == p_pack->i_offset )
195
0
            {
196
0
                p_pic->i_flags |= BLOCK_FLAG_AU_END;
197
0
            }
198
199
1.04M
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
1.04M
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
1.04M
            if( p_pack->i_au_prepend > 0 )
202
1.04M
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
1.04M
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
1.04M
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
9.89k
            {
209
9.89k
                block_Release( p_pic );
210
9.89k
                p_pic = NULL;
211
9.89k
            }
212
1.03M
            else
213
1.03M
            {
214
1.03M
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
1.03M
                if( b_used_ts )
216
405k
                {
217
405k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
405k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
405k
                }
220
1.03M
            }
221
222
1.04M
            if( !p_pic )
223
831k
            {
224
831k
                p_pack->i_state = STATE_NOSYNC;
225
831k
                break;
226
831k
            }
227
211k
            if( p_pack->pf_validate( p_pack->p_private, p_pic ) )
228
0
            {
229
0
                p_pack->i_state = STATE_NOSYNC;
230
0
                block_Release( p_pic );
231
0
                break;
232
0
            }
233
234
            /* So p_block doesn't get re-added several times */
235
211k
            if( pp_block )
236
209k
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
211k
            p_pack->i_state = STATE_NOSYNC;
239
240
211k
            return p_pic;
241
1.10M
        }
242
1.10M
    }
243
272k
}
hevc.c:packetizer_PacketizeBlock
Line
Count
Source
110
782k
{
111
782k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
782k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
153
        return NULL;
115
116
782k
    if( p_block && unlikely( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) )
117
0
    {
118
0
        block_t *p_drained = packetizer_PacketizeBlock( p_pack, NULL );
119
0
        if( p_drained )
120
0
            return p_drained;
121
122
0
        p_pack->i_state = STATE_NOSYNC;
123
0
        block_BytestreamEmpty( &p_pack->bytestream );
124
0
        p_pack->i_offset = 0;
125
0
        p_pack->pf_reset( p_pack->p_private, false );
126
0
    }
127
128
782k
    if( p_block )
129
770k
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
782k
    for( ;; )
132
1.53M
    {
133
1.53M
        bool b_used_ts;
134
1.53M
        block_t *p_pic;
135
136
1.53M
        switch( p_pack->i_state )
137
1.53M
        {
138
1.47M
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
1.47M
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
1.47M
                                                p_pack->p_startcode, p_pack->i_startcode,
142
1.47M
                                                p_pack->pf_startcode_helper, NULL ) )
143
1.46M
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
1.47M
            if( p_pack->i_offset )
146
10.3k
            {
147
10.3k
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
10.3k
                p_pack->i_offset = 0;
149
10.3k
                block_BytestreamFlush( &p_pack->bytestream );
150
10.3k
            }
151
152
1.47M
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
13.7k
                return NULL; /* Need more data */
154
155
1.46M
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
1.51M
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
1.51M
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
1.51M
                                               p_pack->p_startcode, p_pack->i_startcode,
162
1.51M
                                               p_pack->pf_startcode_helper, NULL ) )
163
65.0k
            {
164
65.0k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
53.8k
                    return NULL; /* Need more data */
166
167
                /* When flushing and we don't find a startcode, suppose that
168
                 * the data extend up to the end */
169
11.1k
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
11.1k
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
11.1k
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
246
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
246
                    return NULL;
176
11.1k
            }
177
178
1.46M
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
1.46M
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
1.46M
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
1.46M
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
1.46M
            p_pic->i_pts = p_block_bytestream->i_pts;
190
1.46M
            p_pic->i_dts = p_block_bytestream->i_dts;
191
192
            /* Do not wait for next sync code if notified block ends AU */
193
1.46M
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
0
                 p_block_bytestream->i_buffer == p_pack->i_offset )
195
0
            {
196
0
                p_pic->i_flags |= BLOCK_FLAG_AU_END;
197
0
            }
198
199
1.46M
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
1.46M
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
1.46M
            if( p_pack->i_au_prepend > 0 )
202
1.46M
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
1.46M
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
1.46M
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
18.0k
            {
209
18.0k
                block_Release( p_pic );
210
18.0k
                p_pic = NULL;
211
18.0k
            }
212
1.44M
            else
213
1.44M
            {
214
1.44M
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
1.44M
                if( b_used_ts )
216
782k
                {
217
782k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
782k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
782k
                }
220
1.44M
            }
221
222
1.46M
            if( !p_pic )
223
748k
            {
224
748k
                p_pack->i_state = STATE_NOSYNC;
225
748k
                break;
226
748k
            }
227
714k
            if( p_pack->pf_validate( p_pack->p_private, p_pic ) )
228
0
            {
229
0
                p_pack->i_state = STATE_NOSYNC;
230
0
                block_Release( p_pic );
231
0
                break;
232
0
            }
233
234
            /* So p_block doesn't get re-added several times */
235
714k
            if( pp_block )
236
714k
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
714k
            p_pack->i_state = STATE_NOSYNC;
239
240
714k
            return p_pic;
241
1.53M
        }
242
1.53M
    }
243
782k
}
Unexecuted instantiation: mlp.c:packetizer_PacketizeBlock
Unexecuted instantiation: mpeg4audio.c:packetizer_PacketizeBlock
Unexecuted instantiation: mpeg4video.c:packetizer_PacketizeBlock
Unexecuted instantiation: mpegaudio.c:packetizer_PacketizeBlock
Unexecuted instantiation: mpegvideo.c:packetizer_PacketizeBlock
vc1.c:packetizer_PacketizeBlock
Line
Count
Source
110
1.54k
{
111
1.54k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
1.54k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
152
        return NULL;
115
116
1.39k
    if( p_block && unlikely( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) )
117
0
    {
118
0
        block_t *p_drained = packetizer_PacketizeBlock( p_pack, NULL );
119
0
        if( p_drained )
120
0
            return p_drained;
121
122
0
        p_pack->i_state = STATE_NOSYNC;
123
0
        block_BytestreamEmpty( &p_pack->bytestream );
124
0
        p_pack->i_offset = 0;
125
0
        p_pack->pf_reset( p_pack->p_private, false );
126
0
    }
127
128
1.39k
    if( p_block )
129
773
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
1.39k
    for( ;; )
132
16.2k
    {
133
16.2k
        bool b_used_ts;
134
16.2k
        block_t *p_pic;
135
136
16.2k
        switch( p_pack->i_state )
137
16.2k
        {
138
15.6k
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
15.6k
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
15.6k
                                                p_pack->p_startcode, p_pack->i_startcode,
142
15.6k
                                                p_pack->pf_startcode_helper, NULL ) )
143
14.9k
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
15.6k
            if( p_pack->i_offset )
146
756
            {
147
756
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
756
                p_pack->i_offset = 0;
149
756
                block_BytestreamFlush( &p_pack->bytestream );
150
756
            }
151
152
15.6k
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
761
                return NULL; /* Need more data */
154
155
14.9k
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
15.5k
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
15.5k
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
15.5k
                                               p_pack->p_startcode, p_pack->i_startcode,
162
15.5k
                                               p_pack->pf_startcode_helper, NULL ) )
163
1.21k
            {
164
1.21k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
607
                    return NULL; /* Need more data */
166
167
                /* When flushing and we don't find a startcode, suppose that
168
                 * the data extend up to the end */
169
607
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
607
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
607
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
26
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
26
                    return NULL;
176
607
            }
177
178
14.8k
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
14.8k
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
14.8k
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
14.8k
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
14.8k
            p_pic->i_pts = p_block_bytestream->i_pts;
190
14.8k
            p_pic->i_dts = p_block_bytestream->i_dts;
191
192
            /* Do not wait for next sync code if notified block ends AU */
193
14.8k
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
0
                 p_block_bytestream->i_buffer == p_pack->i_offset )
195
0
            {
196
0
                p_pic->i_flags |= BLOCK_FLAG_AU_END;
197
0
            }
198
199
14.8k
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
14.8k
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
14.8k
            if( p_pack->i_au_prepend > 0 )
202
0
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
14.8k
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
14.8k
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
2.12k
            {
209
2.12k
                block_Release( p_pic );
210
2.12k
                p_pic = NULL;
211
2.12k
            }
212
12.7k
            else
213
12.7k
            {
214
12.7k
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
12.7k
                if( b_used_ts )
216
6.48k
                {
217
6.48k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
6.48k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
6.48k
                }
220
12.7k
            }
221
222
14.8k
            if( !p_pic )
223
13.6k
            {
224
13.6k
                p_pack->i_state = STATE_NOSYNC;
225
13.6k
                break;
226
13.6k
            }
227
1.23k
            if( p_pack->pf_validate( p_pack->p_private, p_pic ) )
228
1.23k
            {
229
1.23k
                p_pack->i_state = STATE_NOSYNC;
230
1.23k
                block_Release( p_pic );
231
1.23k
                break;
232
1.23k
            }
233
234
            /* So p_block doesn't get re-added several times */
235
0
            if( pp_block )
236
0
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
0
            p_pack->i_state = STATE_NOSYNC;
239
240
0
            return p_pic;
241
16.2k
        }
242
16.2k
    }
243
1.39k
}
244
245
static block_t *packetizer_Packetize( packetizer_t *p_pack, block_t **pp_block )
246
1.05M
{
247
1.05M
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
1.05M
    if( p_out )
249
925k
        return p_out;
250
    /* handle caller drain */
251
130k
    if( pp_block == NULL && p_pack->pf_drain )
252
29.1k
    {
253
29.1k
        p_out = p_pack->pf_drain( p_pack->p_private );
254
29.1k
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
75
        {
256
75
            block_Release( p_out );
257
75
            p_out = NULL;
258
75
        }
259
29.1k
    }
260
130k
    return p_out;
261
1.05M
}
Unexecuted instantiation: a52.c:packetizer_Packetize
Unexecuted instantiation: dts.c:packetizer_Packetize
Unexecuted instantiation: flac.c:packetizer_Packetize
h264.c:packetizer_Packetize
Line
Count
Source
246
272k
{
247
272k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
272k
    if( p_out )
249
211k
        return p_out;
250
    /* handle caller drain */
251
61.2k
    if( pp_block == NULL && p_pack->pf_drain )
252
16.3k
    {
253
16.3k
        p_out = p_pack->pf_drain( p_pack->p_private );
254
16.3k
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
0
        {
256
0
            block_Release( p_out );
257
            p_out = NULL;
258
0
        }
259
16.3k
    }
260
61.2k
    return p_out;
261
272k
}
hevc.c:packetizer_Packetize
Line
Count
Source
246
782k
{
247
782k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
782k
    if( p_out )
249
714k
        return p_out;
250
    /* handle caller drain */
251
68.0k
    if( pp_block == NULL && p_pack->pf_drain )
252
12.0k
    {
253
12.0k
        p_out = p_pack->pf_drain( p_pack->p_private );
254
12.0k
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
0
        {
256
0
            block_Release( p_out );
257
            p_out = NULL;
258
0
        }
259
12.0k
    }
260
68.0k
    return p_out;
261
782k
}
Unexecuted instantiation: mlp.c:packetizer_Packetize
Unexecuted instantiation: mpeg4audio.c:packetizer_Packetize
Unexecuted instantiation: mpeg4video.c:packetizer_Packetize
Unexecuted instantiation: mpegaudio.c:packetizer_Packetize
Unexecuted instantiation: mpegvideo.c:packetizer_Packetize
vc1.c:packetizer_Packetize
Line
Count
Source
246
1.54k
{
247
1.54k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
1.54k
    if( p_out )
249
0
        return p_out;
250
    /* handle caller drain */
251
1.54k
    if( pp_block == NULL && p_pack->pf_drain )
252
773
    {
253
773
        p_out = p_pack->pf_drain( p_pack->p_private );
254
773
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
75
        {
256
75
            block_Release( p_out );
257
            p_out = NULL;
258
75
        }
259
773
    }
260
1.54k
    return p_out;
261
1.54k
}
262
263
static inline void packetizer_Header( packetizer_t *p_pack,
264
                                      const uint8_t *p_header, int i_header )
265
8.99k
{
266
8.99k
    block_t *p_init = block_Alloc( i_header );
267
8.99k
    if( !p_init )
268
0
        return;
269
270
8.99k
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
8.99k
    block_t *p_pic;
273
19.6k
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
10.6k
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
9.47k
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
476
        block_Release( p_pic );
277
278
8.99k
    p_pack->i_state = STATE_NOSYNC;
279
8.99k
    block_BytestreamEmpty( &p_pack->bytestream );
280
8.99k
    p_pack->i_offset = 0;
281
8.99k
}
Unexecuted instantiation: a52.c:packetizer_Header
Unexecuted instantiation: dts.c:packetizer_Header
Unexecuted instantiation: flac.c:packetizer_Header
h264.c:packetizer_Header
Line
Count
Source
265
4.65k
{
266
4.65k
    block_t *p_init = block_Alloc( i_header );
267
4.65k
    if( !p_init )
268
0
        return;
269
270
4.65k
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
4.65k
    block_t *p_pic;
273
14.1k
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
9.52k
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
5.07k
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
413
        block_Release( p_pic );
277
278
4.65k
    p_pack->i_state = STATE_NOSYNC;
279
4.65k
    block_BytestreamEmpty( &p_pack->bytestream );
280
4.65k
    p_pack->i_offset = 0;
281
4.65k
}
hevc.c:packetizer_Header
Line
Count
Source
265
3.56k
{
266
3.56k
    block_t *p_init = block_Alloc( i_header );
267
3.56k
    if( !p_init )
268
0
        return;
269
270
3.56k
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
3.56k
    block_t *p_pic;
273
4.66k
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
1.10k
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
3.62k
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
63
        block_Release( p_pic );
277
278
3.56k
    p_pack->i_state = STATE_NOSYNC;
279
3.56k
    block_BytestreamEmpty( &p_pack->bytestream );
280
3.56k
    p_pack->i_offset = 0;
281
3.56k
}
Unexecuted instantiation: mlp.c:packetizer_Header
Unexecuted instantiation: mpeg4audio.c:packetizer_Header
Unexecuted instantiation: mpeg4video.c:packetizer_Header
Unexecuted instantiation: mpegaudio.c:packetizer_Header
Unexecuted instantiation: mpegvideo.c:packetizer_Header
vc1.c:packetizer_Header
Line
Count
Source
265
773
{
266
773
    block_t *p_init = block_Alloc( i_header );
267
773
    if( !p_init )
268
0
        return;
269
270
773
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
773
    block_t *p_pic;
273
773
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
0
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
773
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
0
        block_Release( p_pic );
277
278
773
    p_pack->i_state = STATE_NOSYNC;
279
773
    block_BytestreamEmpty( &p_pack->bytestream );
280
773
    p_pack->i_offset = 0;
281
773
}
282
283
#endif
284