Coverage Report

Created: 2025-07-23 07:11

/src/vlc/modules/packetizer/packetizer_helper.h
Line
Count
Source (jump to first uncovered line)
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
26.0k
{
78
26.0k
    p_pack->i_state = STATE_NOSYNC;
79
26.0k
    block_BytestreamInit( &p_pack->bytestream );
80
26.0k
    p_pack->i_offset = 0;
81
82
26.0k
    p_pack->i_au_prepend = i_au_prepend;
83
26.0k
    p_pack->p_au_prepend = p_au_prepend;
84
26.0k
    p_pack->i_au_min_size = i_au_min_size;
85
86
26.0k
    p_pack->i_startcode = i_startcode;
87
26.0k
    p_pack->p_startcode = p_startcode;
88
26.0k
    p_pack->pf_startcode_helper = pf_start_helper;
89
26.0k
    p_pack->pf_reset = pf_reset;
90
26.0k
    p_pack->pf_parse = pf_parse;
91
26.0k
    p_pack->pf_validate = pf_validate;
92
26.0k
    p_pack->pf_drain = pf_drain;
93
26.0k
    p_pack->p_private = p_private;
94
26.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
13.6k
{
78
13.6k
    p_pack->i_state = STATE_NOSYNC;
79
13.6k
    block_BytestreamInit( &p_pack->bytestream );
80
13.6k
    p_pack->i_offset = 0;
81
82
13.6k
    p_pack->i_au_prepend = i_au_prepend;
83
13.6k
    p_pack->p_au_prepend = p_au_prepend;
84
13.6k
    p_pack->i_au_min_size = i_au_min_size;
85
86
13.6k
    p_pack->i_startcode = i_startcode;
87
13.6k
    p_pack->p_startcode = p_startcode;
88
13.6k
    p_pack->pf_startcode_helper = pf_start_helper;
89
13.6k
    p_pack->pf_reset = pf_reset;
90
13.6k
    p_pack->pf_parse = pf_parse;
91
13.6k
    p_pack->pf_validate = pf_validate;
92
13.6k
    p_pack->pf_drain = pf_drain;
93
13.6k
    p_pack->p_private = p_private;
94
13.6k
}
hevc.c:packetizer_Init
Line
Count
Source
77
10.2k
{
78
10.2k
    p_pack->i_state = STATE_NOSYNC;
79
10.2k
    block_BytestreamInit( &p_pack->bytestream );
80
10.2k
    p_pack->i_offset = 0;
81
82
10.2k
    p_pack->i_au_prepend = i_au_prepend;
83
10.2k
    p_pack->p_au_prepend = p_au_prepend;
84
10.2k
    p_pack->i_au_min_size = i_au_min_size;
85
86
10.2k
    p_pack->i_startcode = i_startcode;
87
10.2k
    p_pack->p_startcode = p_startcode;
88
10.2k
    p_pack->pf_startcode_helper = pf_start_helper;
89
10.2k
    p_pack->pf_reset = pf_reset;
90
10.2k
    p_pack->pf_parse = pf_parse;
91
10.2k
    p_pack->pf_validate = pf_validate;
92
10.2k
    p_pack->pf_drain = pf_drain;
93
10.2k
    p_pack->p_private = p_private;
94
10.2k
}
Unexecuted instantiation: mlp.c:packetizer_Init
Unexecuted instantiation: mpeg4audio.c:packetizer_Init
mpeg4video.c:packetizer_Init
Line
Count
Source
77
175
{
78
175
    p_pack->i_state = STATE_NOSYNC;
79
175
    block_BytestreamInit( &p_pack->bytestream );
80
175
    p_pack->i_offset = 0;
81
82
175
    p_pack->i_au_prepend = i_au_prepend;
83
175
    p_pack->p_au_prepend = p_au_prepend;
84
175
    p_pack->i_au_min_size = i_au_min_size;
85
86
175
    p_pack->i_startcode = i_startcode;
87
175
    p_pack->p_startcode = p_startcode;
88
175
    p_pack->pf_startcode_helper = pf_start_helper;
89
175
    p_pack->pf_reset = pf_reset;
90
175
    p_pack->pf_parse = pf_parse;
91
175
    p_pack->pf_validate = pf_validate;
92
175
    p_pack->pf_drain = pf_drain;
93
175
    p_pack->p_private = p_private;
94
175
}
Unexecuted instantiation: mpegaudio.c:packetizer_Init
mpegvideo.c:packetizer_Init
Line
Count
Source
77
1.41k
{
78
1.41k
    p_pack->i_state = STATE_NOSYNC;
79
1.41k
    block_BytestreamInit( &p_pack->bytestream );
80
1.41k
    p_pack->i_offset = 0;
81
82
1.41k
    p_pack->i_au_prepend = i_au_prepend;
83
1.41k
    p_pack->p_au_prepend = p_au_prepend;
84
1.41k
    p_pack->i_au_min_size = i_au_min_size;
85
86
1.41k
    p_pack->i_startcode = i_startcode;
87
1.41k
    p_pack->p_startcode = p_startcode;
88
1.41k
    p_pack->pf_startcode_helper = pf_start_helper;
89
1.41k
    p_pack->pf_reset = pf_reset;
90
1.41k
    p_pack->pf_parse = pf_parse;
91
1.41k
    p_pack->pf_validate = pf_validate;
92
1.41k
    p_pack->pf_drain = pf_drain;
93
1.41k
    p_pack->p_private = p_private;
94
1.41k
}
vc1.c:packetizer_Init
Line
Count
Source
77
590
{
78
590
    p_pack->i_state = STATE_NOSYNC;
79
590
    block_BytestreamInit( &p_pack->bytestream );
80
590
    p_pack->i_offset = 0;
81
82
590
    p_pack->i_au_prepend = i_au_prepend;
83
590
    p_pack->p_au_prepend = p_au_prepend;
84
590
    p_pack->i_au_min_size = i_au_min_size;
85
86
590
    p_pack->i_startcode = i_startcode;
87
590
    p_pack->p_startcode = p_startcode;
88
590
    p_pack->pf_startcode_helper = pf_start_helper;
89
590
    p_pack->pf_reset = pf_reset;
90
590
    p_pack->pf_parse = pf_parse;
91
590
    p_pack->pf_validate = pf_validate;
92
590
    p_pack->pf_drain = pf_drain;
93
590
    p_pack->p_private = p_private;
94
590
}
95
96
static inline void packetizer_Clean( packetizer_t *p_pack )
97
26.0k
{
98
26.0k
    block_BytestreamRelease( &p_pack->bytestream );
99
26.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
13.6k
{
98
13.6k
    block_BytestreamRelease( &p_pack->bytestream );
99
13.6k
}
hevc.c:packetizer_Clean
Line
Count
Source
97
10.2k
{
98
10.2k
    block_BytestreamRelease( &p_pack->bytestream );
99
10.2k
}
Unexecuted instantiation: mlp.c:packetizer_Clean
Unexecuted instantiation: mpeg4audio.c:packetizer_Clean
mpeg4video.c:packetizer_Clean
Line
Count
Source
97
175
{
98
175
    block_BytestreamRelease( &p_pack->bytestream );
99
175
}
Unexecuted instantiation: mpegaudio.c:packetizer_Clean
mpegvideo.c:packetizer_Clean
Line
Count
Source
97
1.41k
{
98
1.41k
    block_BytestreamRelease( &p_pack->bytestream );
99
1.41k
}
vc1.c:packetizer_Clean
Line
Count
Source
97
590
{
98
590
    block_BytestreamRelease( &p_pack->bytestream );
99
590
}
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
694k
{
111
694k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
694k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
269
        return NULL;
115
116
693k
    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
693k
    if( p_block )
129
665k
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
693k
    for( ;; )
132
2.32M
    {
133
2.32M
        bool b_used_ts;
134
2.32M
        block_t *p_pic;
135
136
2.32M
        switch( p_pack->i_state )
137
2.32M
        {
138
2.21M
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
2.21M
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
2.21M
                                                p_pack->p_startcode, p_pack->i_startcode,
142
2.21M
                                                p_pack->pf_startcode_helper, NULL ) )
143
2.18M
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
2.21M
            if( p_pack->i_offset )
146
25.6k
            {
147
25.6k
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
25.6k
                p_pack->i_offset = 0;
149
25.6k
                block_BytestreamFlush( &p_pack->bytestream );
150
25.6k
            }
151
152
2.21M
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
32.0k
                return NULL; /* Need more data */
154
155
2.18M
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
2.28M
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
2.28M
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
2.28M
                                               p_pack->p_startcode, p_pack->i_startcode,
162
2.28M
                                               p_pack->pf_startcode_helper, NULL ) )
163
125k
            {
164
125k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
101k
                    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
23.8k
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
23.8k
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
23.8k
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
23.8k
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
562
                    return NULL;
176
23.8k
            }
177
178
2.18M
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
2.18M
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
2.18M
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
2.18M
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
2.18M
            p_pic->i_pts = p_block_bytestream->i_pts;
190
2.18M
            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.18M
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
2.18M
                 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.18M
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
2.18M
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
2.18M
            if( p_pack->i_au_prepend > 0 )
202
2.17M
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
2.18M
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
2.18M
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
27.3k
            {
209
27.3k
                block_Release( p_pic );
210
27.3k
                p_pic = NULL;
211
27.3k
            }
212
2.15M
            else
213
2.15M
            {
214
2.15M
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
2.15M
                if( b_used_ts )
216
794k
                {
217
794k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
794k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
794k
                }
220
2.15M
            }
221
222
2.18M
            if( !p_pic )
223
1.62M
            {
224
1.62M
                p_pack->i_state = STATE_NOSYNC;
225
1.62M
                break;
226
1.62M
            }
227
560k
            if( p_pack->pf_validate( p_pack->p_private, p_pic ) )
228
711
            {
229
711
                p_pack->i_state = STATE_NOSYNC;
230
711
                block_Release( p_pic );
231
711
                break;
232
711
            }
233
234
            /* So p_block doesn't get re-added several times */
235
559k
            if( pp_block )
236
558k
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
559k
            p_pack->i_state = STATE_NOSYNC;
239
240
559k
            return p_pic;
241
2.32M
        }
242
2.32M
    }
243
693k
}
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
288k
{
111
288k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
288k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
119
        return NULL;
115
116
288k
    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
288k
    if( p_block )
129
271k
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
288k
    for( ;; )
132
1.04M
    {
133
1.04M
        bool b_used_ts;
134
1.04M
        block_t *p_pic;
135
136
1.04M
        switch( p_pack->i_state )
137
1.04M
        {
138
998k
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
998k
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
998k
                                                p_pack->p_startcode, p_pack->i_startcode,
142
998k
                                                p_pack->pf_startcode_helper, NULL ) )
143
980k
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
998k
            if( p_pack->i_offset )
146
13.7k
            {
147
13.7k
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
13.7k
                p_pack->i_offset = 0;
149
13.7k
                block_BytestreamFlush( &p_pack->bytestream );
150
13.7k
            }
151
152
998k
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
17.9k
                return NULL; /* Need more data */
154
155
980k
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
1.02M
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
1.02M
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
1.02M
                                               p_pack->p_startcode, p_pack->i_startcode,
162
1.02M
                                               p_pack->pf_startcode_helper, NULL ) )
163
55.4k
            {
164
55.4k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
41.9k
                    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.4k
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
13.4k
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
13.4k
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
13.4k
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
274
                    return NULL;
176
13.4k
            }
177
178
980k
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
980k
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
980k
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
980k
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
980k
            p_pic->i_pts = p_block_bytestream->i_pts;
190
980k
            p_pic->i_dts = p_block_bytestream->i_dts;
191
192
            /* Do not wait for next sync code if notified block ends AU */
193
980k
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
980k
                 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
980k
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
980k
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
980k
            if( p_pack->i_au_prepend > 0 )
202
980k
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
980k
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
980k
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
9.55k
            {
209
9.55k
                block_Release( p_pic );
210
9.55k
                p_pic = NULL;
211
9.55k
            }
212
970k
            else
213
970k
            {
214
970k
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
970k
                if( b_used_ts )
216
408k
                {
217
408k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
408k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
408k
                }
220
970k
            }
221
222
980k
            if( !p_pic )
223
751k
            {
224
751k
                p_pack->i_state = STATE_NOSYNC;
225
751k
                break;
226
751k
            }
227
228k
            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
228k
            if( pp_block )
236
227k
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
228k
            p_pack->i_state = STATE_NOSYNC;
239
240
228k
            return p_pic;
241
1.04M
        }
242
1.04M
    }
243
288k
}
hevc.c:packetizer_PacketizeBlock
Line
Count
Source
110
404k
{
111
404k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
404k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
123
        return NULL;
115
116
404k
    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
404k
    if( p_block )
129
393k
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
404k
    for( ;; )
132
1.26M
    {
133
1.26M
        bool b_used_ts;
134
1.26M
        block_t *p_pic;
135
136
1.26M
        switch( p_pack->i_state )
137
1.26M
        {
138
1.20M
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
1.20M
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
1.20M
                                                p_pack->p_startcode, p_pack->i_startcode,
142
1.20M
                                                p_pack->pf_startcode_helper, NULL ) )
143
1.19M
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
1.20M
            if( p_pack->i_offset )
146
11.3k
            {
147
11.3k
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
11.3k
                p_pack->i_offset = 0;
149
11.3k
                block_BytestreamFlush( &p_pack->bytestream );
150
11.3k
            }
151
152
1.20M
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
13.5k
                return NULL; /* Need more data */
154
155
1.19M
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
1.25M
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
1.25M
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
1.25M
                                               p_pack->p_startcode, p_pack->i_startcode,
162
1.25M
                                               p_pack->pf_startcode_helper, NULL ) )
163
68.8k
            {
164
68.8k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
59.0k
                    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
9.78k
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
9.78k
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
9.78k
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
9.78k
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
257
                    return NULL;
176
9.78k
            }
177
178
1.19M
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
1.19M
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
1.19M
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
1.19M
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
1.19M
            p_pic->i_pts = p_block_bytestream->i_pts;
190
1.19M
            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.19M
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
1.19M
                 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.19M
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
1.19M
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
1.19M
            if( p_pack->i_au_prepend > 0 )
202
1.19M
                memcpy( p_pic->p_buffer, p_pack->p_au_prepend, p_pack->i_au_prepend );
203
204
1.19M
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
1.19M
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
17.1k
            {
209
17.1k
                block_Release( p_pic );
210
17.1k
                p_pic = NULL;
211
17.1k
            }
212
1.17M
            else
213
1.17M
            {
214
1.17M
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
1.17M
                if( b_used_ts )
216
380k
                {
217
380k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
380k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
380k
                }
220
1.17M
            }
221
222
1.19M
            if( !p_pic )
223
864k
            {
224
864k
                p_pack->i_state = STATE_NOSYNC;
225
864k
                break;
226
864k
            }
227
331k
            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
331k
            if( pp_block )
236
331k
                *pp_block = block_BytestreamPop( &p_pack->bytestream );
237
238
331k
            p_pack->i_state = STATE_NOSYNC;
239
240
331k
            return p_pic;
241
1.26M
        }
242
1.26M
    }
243
404k
}
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.17k
{
111
1.17k
    block_t *p_block = ( pp_block ) ? *pp_block : NULL;
112
113
1.17k
    if( p_block == NULL && p_pack->bytestream.p_block == NULL )
114
27
        return NULL;
115
116
1.14k
    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.14k
    if( p_block )
129
588
        block_BytestreamPush( &p_pack->bytestream, p_block );
130
131
1.14k
    for( ;; )
132
11.6k
    {
133
11.6k
        bool b_used_ts;
134
11.6k
        block_t *p_pic;
135
136
11.6k
        switch( p_pack->i_state )
137
11.6k
        {
138
11.0k
        case STATE_NOSYNC:
139
            /* Find a startcode */
140
11.0k
            if( !block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
141
11.0k
                                                p_pack->p_startcode, p_pack->i_startcode,
142
11.0k
                                                p_pack->pf_startcode_helper, NULL ) )
143
10.5k
                p_pack->i_state = STATE_NEXT_SYNC;
144
145
11.0k
            if( p_pack->i_offset )
146
580
            {
147
580
                block_SkipBytes( &p_pack->bytestream, p_pack->i_offset );
148
580
                p_pack->i_offset = 0;
149
580
                block_BytestreamFlush( &p_pack->bytestream );
150
580
            }
151
152
11.0k
            if( p_pack->i_state != STATE_NEXT_SYNC )
153
568
                return NULL; /* Need more data */
154
155
10.5k
            p_pack->i_offset = 1; /* To find next startcode */
156
            /* fallthrough */
157
158
11.0k
        case STATE_NEXT_SYNC:
159
            /* Find the next startcode */
160
11.0k
            if( block_FindStartcodeFromOffset( &p_pack->bytestream, &p_pack->i_offset,
161
11.0k
                                               p_pack->p_startcode, p_pack->i_startcode,
162
11.0k
                                               p_pack->pf_startcode_helper, NULL ) )
163
1.10k
            {
164
1.10k
                if( pp_block /* not flushing */ || !p_pack->bytestream.p_chain )
165
550
                    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
550
                p_pack->i_offset = block_BytestreamRemaining(&p_pack->bytestream);
170
550
                if( p_pack->i_offset == 0 )
171
0
                    return NULL;
172
173
550
                if( p_pack->i_offset <= (size_t)p_pack->i_startcode &&
174
550
                    (p_pack->bytestream.p_block->i_flags & BLOCK_FLAG_AU_END) == 0 )
175
31
                    return NULL;
176
550
            }
177
178
10.4k
            block_BytestreamFlush( &p_pack->bytestream );
179
180
            /* Get the new fragment and set the pts/dts */
181
10.4k
            block_t *p_block_bytestream = p_pack->bytestream.p_block;
182
183
10.4k
            p_pic = block_Alloc( p_pack->i_offset + p_pack->i_au_prepend );
184
10.4k
            if( p_pic == NULL )
185
0
            {
186
0
                p_pack->i_state = STATE_NOSYNC;
187
0
                return NULL;
188
0
            }
189
10.4k
            p_pic->i_pts = p_block_bytestream->i_pts;
190
10.4k
            p_pic->i_dts = p_block_bytestream->i_dts;
191
192
            /* Do not wait for next sync code if notified block ends AU */
193
10.4k
            if( (p_block_bytestream->i_flags & BLOCK_FLAG_AU_END) &&
194
10.4k
                 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
10.4k
            block_GetBytes( &p_pack->bytestream, &p_pic->p_buffer[p_pack->i_au_prepend],
200
10.4k
                            p_pic->i_buffer - p_pack->i_au_prepend );
201
10.4k
            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
10.4k
            p_pack->i_offset = 0;
205
206
            /* Parse the NAL */
207
10.4k
            if( p_pic->i_buffer < p_pack->i_au_min_size )
208
596
            {
209
596
                block_Release( p_pic );
210
596
                p_pic = NULL;
211
596
            }
212
9.89k
            else
213
9.89k
            {
214
9.89k
                p_pic = p_pack->pf_parse( p_pack->p_private, &b_used_ts, p_pic );
215
9.89k
                if( b_used_ts )
216
5.25k
                {
217
5.25k
                    p_block_bytestream->i_dts = VLC_TICK_INVALID;
218
5.25k
                    p_block_bytestream->i_pts = VLC_TICK_INVALID;
219
5.25k
                }
220
9.89k
            }
221
222
10.4k
            if( !p_pic )
223
9.78k
            {
224
9.78k
                p_pack->i_state = STATE_NOSYNC;
225
9.78k
                break;
226
9.78k
            }
227
711
            if( p_pack->pf_validate( p_pack->p_private, p_pic ) )
228
711
            {
229
711
                p_pack->i_state = STATE_NOSYNC;
230
711
                block_Release( p_pic );
231
711
                break;
232
711
            }
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
11.6k
        }
242
11.6k
    }
243
1.14k
}
244
245
static block_t *packetizer_Packetize( packetizer_t *p_pack, block_t **pp_block )
246
694k
{
247
694k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
694k
    if( p_out )
249
559k
        return p_out;
250
    /* handle caller drain */
251
134k
    if( pp_block == NULL && p_pack->pf_drain )
252
27.0k
    {
253
27.0k
        p_out = p_pack->pf_drain( p_pack->p_private );
254
27.0k
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
53
        {
256
53
            block_Release( p_out );
257
53
            p_out = NULL;
258
53
        }
259
27.0k
    }
260
134k
    return p_out;
261
694k
}
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
288k
{
247
288k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
288k
    if( p_out )
249
228k
        return p_out;
250
    /* handle caller drain */
251
60.2k
    if( pp_block == NULL && p_pack->pf_drain )
252
16.0k
    {
253
16.0k
        p_out = p_pack->pf_drain( p_pack->p_private );
254
16.0k
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
0
        {
256
0
            block_Release( p_out );
257
0
            p_out = NULL;
258
0
        }
259
16.0k
    }
260
60.2k
    return p_out;
261
288k
}
hevc.c:packetizer_Packetize
Line
Count
Source
246
404k
{
247
404k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
404k
    if( p_out )
249
331k
        return p_out;
250
    /* handle caller drain */
251
72.9k
    if( pp_block == NULL && p_pack->pf_drain )
252
10.4k
    {
253
10.4k
        p_out = p_pack->pf_drain( p_pack->p_private );
254
10.4k
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
0
        {
256
0
            block_Release( p_out );
257
0
            p_out = NULL;
258
0
        }
259
10.4k
    }
260
72.9k
    return p_out;
261
404k
}
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.17k
{
247
1.17k
    block_t *p_out = packetizer_PacketizeBlock( p_pack, pp_block );
248
1.17k
    if( p_out )
249
0
        return p_out;
250
    /* handle caller drain */
251
1.17k
    if( pp_block == NULL && p_pack->pf_drain )
252
588
    {
253
588
        p_out = p_pack->pf_drain( p_pack->p_private );
254
588
        if( p_out && p_pack->pf_validate( p_pack->p_private, p_out ) )
255
53
        {
256
53
            block_Release( p_out );
257
53
            p_out = NULL;
258
53
        }
259
588
    }
260
1.17k
    return p_out;
261
1.17k
}
262
263
static inline void packetizer_Header( packetizer_t *p_pack,
264
                                      const uint8_t *p_header, int i_header )
265
9.32k
{
266
9.32k
    block_t *p_init = block_Alloc( i_header );
267
9.32k
    if( !p_init )
268
0
        return;
269
270
9.32k
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
9.32k
    block_t *p_pic;
273
17.5k
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
8.26k
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
10.2k
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
882
        block_Release( p_pic );
277
278
9.32k
    p_pack->i_state = STATE_NOSYNC;
279
9.32k
    block_BytestreamEmpty( &p_pack->bytestream );
280
9.32k
    p_pack->i_offset = 0;
281
9.32k
}
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
5.82k
{
266
5.82k
    block_t *p_init = block_Alloc( i_header );
267
5.82k
    if( !p_init )
268
0
        return;
269
270
5.82k
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
5.82k
    block_t *p_pic;
273
13.7k
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
7.93k
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
6.65k
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
824
        block_Release( p_pic );
277
278
5.82k
    p_pack->i_state = STATE_NOSYNC;
279
5.82k
    block_BytestreamEmpty( &p_pack->bytestream );
280
5.82k
    p_pack->i_offset = 0;
281
5.82k
}
hevc.c:packetizer_Header
Line
Count
Source
265
2.90k
{
266
2.90k
    block_t *p_init = block_Alloc( i_header );
267
2.90k
    if( !p_init )
268
0
        return;
269
270
2.90k
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
2.90k
    block_t *p_pic;
273
3.23k
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
330
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
2.96k
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
58
        block_Release( p_pic );
277
278
2.90k
    p_pack->i_state = STATE_NOSYNC;
279
2.90k
    block_BytestreamEmpty( &p_pack->bytestream );
280
2.90k
    p_pack->i_offset = 0;
281
2.90k
}
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
588
{
266
588
    block_t *p_init = block_Alloc( i_header );
267
588
    if( !p_init )
268
0
        return;
269
270
588
    memcpy( p_init->p_buffer, p_header, i_header );
271
272
588
    block_t *p_pic;
273
588
    while( ( p_pic = packetizer_Packetize( p_pack, &p_init ) ) )
274
0
        block_Release( p_pic ); /* Should not happen (only sequence header) */
275
588
    while( ( p_pic = packetizer_Packetize( p_pack, NULL ) ) )
276
0
        block_Release( p_pic );
277
278
588
    p_pack->i_state = STATE_NOSYNC;
279
588
    block_BytestreamEmpty( &p_pack->bytestream );
280
588
    p_pack->i_offset = 0;
281
588
}
282
283
#endif
284