Coverage Report

Created: 2026-06-09 09:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/demux/mpeg/pes.h
Line
Count
Source
1
/*****************************************************************************
2
 * pes.h: PES Packet helpers
3
 *****************************************************************************
4
 * Copyright (C) 2004-2015 VLC authors and VideoLAN
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19
 *****************************************************************************/
20
#ifndef VLC_MPEG_PES_H
21
#define VLC_MPEG_PES_H
22
23
#include "timestamps.h"
24
25
48.1k
#define STREAM_ID_PROGRAM_STREAM_MAP         0xBC
26
224k
#define STREAM_ID_PRIVATE_STREAM_1           0xBD
27
3.11k
#define STREAM_ID_PADDING                    0xBE
28
1.18k
#define STREAM_ID_PRIVATE_STREAM_2           0xBF
29
#define STREAM_ID_AUDIO_STREAM_0             0xC0
30
#define STREAM_ID_VIDEO_STREAM_0             0xE0
31
1.55k
#define STREAM_ID_ECM                        0xF0
32
2.26k
#define STREAM_ID_EMM                        0xF1
33
6.60k
#define STREAM_ID_DSM_CC                     0xF2
34
7.15k
#define STREAM_ID_H222_1_TYPE_E              0xF8
35
#define STREAM_ID_METADATA_STREAM            0xFC
36
222k
#define STREAM_ID_EXTENDED_STREAM_ID         0xFD
37
29.2k
#define STREAM_ID_PROGRAM_STREAM_DIRECTORY   0xFF
38
39
/* MPEG-2 PTS/DTS */
40
static inline ts_90khz_t GetPESTimestamp( const uint8_t *p_data )
41
1.64M
{
42
    /* prefixed by 4 bits 0010 or 0011 */
43
1.64M
    return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
44
1.64M
             (ts_90khz_t)(p_data[1] << 22)|
45
1.64M
            ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
46
1.64M
             (ts_90khz_t)(p_data[3] << 7)|
47
1.64M
             (ts_90khz_t)(p_data[4] >> 1);
48
1.64M
}
ps.c:GetPESTimestamp
Line
Count
Source
41
74.0k
{
42
    /* prefixed by 4 bits 0010 or 0011 */
43
74.0k
    return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
44
74.0k
             (ts_90khz_t)(p_data[1] << 22)|
45
74.0k
            ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
46
74.0k
             (ts_90khz_t)(p_data[3] << 7)|
47
74.0k
             (ts_90khz_t)(p_data[4] >> 1);
48
74.0k
}
pva.c:GetPESTimestamp
Line
Count
Source
41
1.36M
{
42
    /* prefixed by 4 bits 0010 or 0011 */
43
1.36M
    return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
44
1.36M
             (ts_90khz_t)(p_data[1] << 22)|
45
1.36M
            ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
46
1.36M
             (ts_90khz_t)(p_data[3] << 7)|
47
1.36M
             (ts_90khz_t)(p_data[4] >> 1);
48
1.36M
}
ty.c:GetPESTimestamp
Line
Count
Source
41
21.7k
{
42
    /* prefixed by 4 bits 0010 or 0011 */
43
21.7k
    return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
44
21.7k
             (ts_90khz_t)(p_data[1] << 22)|
45
21.7k
            ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
46
21.7k
             (ts_90khz_t)(p_data[3] << 7)|
47
21.7k
             (ts_90khz_t)(p_data[4] >> 1);
48
21.7k
}
Unexecuted instantiation: vobsub.c:GetPESTimestamp
ts.c:GetPESTimestamp
Line
Count
Source
41
184k
{
42
    /* prefixed by 4 bits 0010 or 0011 */
43
184k
    return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
44
184k
             (ts_90khz_t)(p_data[1] << 22)|
45
184k
            ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
46
184k
             (ts_90khz_t)(p_data[3] << 7)|
47
184k
             (ts_90khz_t)(p_data[4] >> 1);
48
184k
}
ts_hotfixes.c:GetPESTimestamp
Line
Count
Source
41
8.59k
{
42
    /* prefixed by 4 bits 0010 or 0011 */
43
8.59k
    return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
44
8.59k
             (ts_90khz_t)(p_data[1] << 22)|
45
8.59k
            ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
46
8.59k
             (ts_90khz_t)(p_data[3] << 7)|
47
8.59k
             (ts_90khz_t)(p_data[4] >> 1);
48
8.59k
}
49
50
static inline bool ExtractPESTimestamp( const uint8_t *p_data, uint8_t i_flags, ts_90khz_t *ret )
51
475k
{
52
    /* !warn broken muxers set incorrect flags. see #17773 and #19140 */
53
    /* check marker bits, and i_flags = b 0010, 0011 or 0001 */
54
475k
    if((p_data[0] & 0xC1) != 0x01 ||
55
344k
       (p_data[2] & 0x01) != 0x01 ||
56
297k
       (p_data[4] & 0x01) != 0x01 ||
57
268k
       (p_data[0] & 0x30) == 0 || /* at least needs one bit */
58
266k
       (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */
59
208k
        return false;
60
61
62
266k
    *ret =  GetPESTimestamp( p_data );
63
266k
    return true;
64
475k
}
ps.c:ExtractPESTimestamp
Line
Count
Source
51
144k
{
52
    /* !warn broken muxers set incorrect flags. see #17773 and #19140 */
53
    /* check marker bits, and i_flags = b 0010, 0011 or 0001 */
54
144k
    if((p_data[0] & 0xC1) != 0x01 ||
55
93.9k
       (p_data[2] & 0x01) != 0x01 ||
56
87.0k
       (p_data[4] & 0x01) != 0x01 ||
57
75.2k
       (p_data[0] & 0x30) == 0 || /* at least needs one bit */
58
74.0k
       (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */
59
70.6k
        return false;
60
61
62
74.0k
    *ret =  GetPESTimestamp( p_data );
63
    return true;
64
144k
}
Unexecuted instantiation: pva.c:ExtractPESTimestamp
Unexecuted instantiation: ty.c:ExtractPESTimestamp
Unexecuted instantiation: vobsub.c:ExtractPESTimestamp
ts.c:ExtractPESTimestamp
Line
Count
Source
51
312k
{
52
    /* !warn broken muxers set incorrect flags. see #17773 and #19140 */
53
    /* check marker bits, and i_flags = b 0010, 0011 or 0001 */
54
312k
    if((p_data[0] & 0xC1) != 0x01 ||
55
239k
       (p_data[2] & 0x01) != 0x01 ||
56
200k
       (p_data[4] & 0x01) != 0x01 ||
57
184k
       (p_data[0] & 0x30) == 0 || /* at least needs one bit */
58
184k
       (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */
59
128k
        return false;
60
61
62
184k
    *ret =  GetPESTimestamp( p_data );
63
    return true;
64
312k
}
ts_hotfixes.c:ExtractPESTimestamp
Line
Count
Source
51
18.1k
{
52
    /* !warn broken muxers set incorrect flags. see #17773 and #19140 */
53
    /* check marker bits, and i_flags = b 0010, 0011 or 0001 */
54
18.1k
    if((p_data[0] & 0xC1) != 0x01 ||
55
10.9k
       (p_data[2] & 0x01) != 0x01 ||
56
9.58k
       (p_data[4] & 0x01) != 0x01 ||
57
8.83k
       (p_data[0] & 0x30) == 0 || /* at least needs one bit */
58
8.59k
       (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */
59
9.53k
        return false;
60
61
62
8.59k
    *ret =  GetPESTimestamp( p_data );
63
    return true;
64
18.1k
}
65
66
/* PS SCR timestamp as defined in H222 2.5.3.2 */
67
static inline ts_90khz_t ExtractPackHeaderTimestamp( const uint8_t *p_data )
68
1.15k
{
69
    /* prefixed by 2 bits 01 */
70
1.15k
    return  ((ts_90khz_t)(p_data[0]&0x38 ) << 27)|
71
1.15k
            ((ts_90khz_t)(p_data[0]&0x03 ) << 28)|
72
1.15k
             (ts_90khz_t)(p_data[1] << 20)|
73
1.15k
            ((ts_90khz_t)(p_data[2]&0xf8 ) << 12)|
74
1.15k
            ((ts_90khz_t)(p_data[2]&0x03 ) << 13)|
75
1.15k
             (ts_90khz_t)(p_data[3] << 5) |
76
1.15k
             (ts_90khz_t)(p_data[4] >> 3);
77
1.15k
}
ps.c:ExtractPackHeaderTimestamp
Line
Count
Source
68
1.15k
{
69
    /* prefixed by 2 bits 01 */
70
1.15k
    return  ((ts_90khz_t)(p_data[0]&0x38 ) << 27)|
71
1.15k
            ((ts_90khz_t)(p_data[0]&0x03 ) << 28)|
72
1.15k
             (ts_90khz_t)(p_data[1] << 20)|
73
1.15k
            ((ts_90khz_t)(p_data[2]&0xf8 ) << 12)|
74
1.15k
            ((ts_90khz_t)(p_data[2]&0x03 ) << 13)|
75
1.15k
             (ts_90khz_t)(p_data[3] << 5) |
76
1.15k
             (ts_90khz_t)(p_data[4] >> 3);
77
1.15k
}
Unexecuted instantiation: pva.c:ExtractPackHeaderTimestamp
Unexecuted instantiation: ty.c:ExtractPackHeaderTimestamp
Unexecuted instantiation: vobsub.c:ExtractPackHeaderTimestamp
Unexecuted instantiation: ts.c:ExtractPackHeaderTimestamp
Unexecuted instantiation: ts_hotfixes.c:ExtractPackHeaderTimestamp
78
79
typedef struct
80
{
81
    ts_90khz_t i_dts;
82
    ts_90khz_t i_pts;
83
    uint8_t i_stream_id;
84
    bool b_scrambling;
85
    unsigned i_size;
86
} ts_pes_header_t;
87
88
static inline void ts_pes_header_init(ts_pes_header_t *h)
89
1.16M
{
90
1.16M
    h->i_dts = TS_90KHZ_INVALID;
91
1.16M
    h->i_pts = TS_90KHZ_INVALID;
92
1.16M
    h->i_stream_id = 0;
93
1.16M
    h->b_scrambling = false;
94
1.16M
    h->i_size = 0;
95
1.16M
}
ps.c:ts_pes_header_init
Line
Count
Source
89
127k
{
90
127k
    h->i_dts = TS_90KHZ_INVALID;
91
127k
    h->i_pts = TS_90KHZ_INVALID;
92
127k
    h->i_stream_id = 0;
93
    h->b_scrambling = false;
94
127k
    h->i_size = 0;
95
127k
}
Unexecuted instantiation: pva.c:ts_pes_header_init
Unexecuted instantiation: ty.c:ts_pes_header_init
Unexecuted instantiation: vobsub.c:ts_pes_header_init
ts.c:ts_pes_header_init
Line
Count
Source
89
987k
{
90
987k
    h->i_dts = TS_90KHZ_INVALID;
91
987k
    h->i_pts = TS_90KHZ_INVALID;
92
987k
    h->i_stream_id = 0;
93
    h->b_scrambling = false;
94
987k
    h->i_size = 0;
95
987k
}
ts_hotfixes.c:ts_pes_header_init
Line
Count
Source
89
51.8k
{
90
51.8k
    h->i_dts = TS_90KHZ_INVALID;
91
51.8k
    h->i_pts = TS_90KHZ_INVALID;
92
51.8k
    h->i_stream_id = 0;
93
    h->b_scrambling = false;
94
51.8k
    h->i_size = 0;
95
51.8k
}
96
97
inline
98
static int ParsePESHeader( struct vlc_logger *p_logger, const uint8_t *p_header, size_t i_header,
99
                           ts_pes_header_t *h )
100
1.16M
{
101
1.16M
    unsigned i_skip;
102
103
1.16M
    if ( i_header < 9 )
104
5.09k
        return VLC_EGENERIC;
105
106
1.16M
    if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 )
107
18.0k
        return VLC_EGENERIC;
108
109
1.14M
    h->i_stream_id = p_header[3];
110
111
1.14M
    switch( p_header[3] )
112
1.14M
    {
113
442
    case STREAM_ID_PROGRAM_STREAM_MAP:
114
935
    case STREAM_ID_PADDING:
115
1.18k
    case STREAM_ID_PRIVATE_STREAM_2:
116
1.55k
    case STREAM_ID_ECM:
117
2.26k
    case STREAM_ID_EMM:
118
5.10k
    case STREAM_ID_PROGRAM_STREAM_DIRECTORY:
119
6.60k
    case STREAM_ID_DSM_CC:
120
7.15k
    case STREAM_ID_H222_1_TYPE_E:
121
7.15k
        i_skip = 6;
122
7.15k
        h->b_scrambling = false;
123
7.15k
        break;
124
1.13M
    default:
125
1.13M
        if( ( p_header[6]&0xC0 ) == 0x80 )
126
939k
        {
127
            /* mpeg2 PES */
128
            // 9 = syncword(3), stream ID(1), length(2), MPEG2 PES(1), flags(1), header_len(1)
129
            // p_header[8] = header_len(1)
130
939k
            i_skip = p_header[8] + 9;
131
132
939k
            h->b_scrambling = p_header[6]&0x30;
133
134
939k
            if( p_header[7]&0x80 )    /* has pts */
135
185k
            {
136
185k
                if( i_header >= 9 + 5 )
137
185k
                   (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts );
138
139
185k
                if( ( p_header[7]&0x40 ) &&    /* has dts */
140
22.7k
                    i_header >= 14 + 5 )
141
22.6k
                   (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts );
142
185k
            }
143
939k
        }
144
197k
        else
145
197k
        {
146
            /* FIXME?: WTH do we have undocumented MPEG1 packet stuff here ?
147
               This code path should not be valid, but seems some ppl did
148
               put MPEG1 packets into PS or TS.
149
               Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
150
197k
            i_skip = 6;
151
152
197k
            h->b_scrambling = false;
153
154
375k
            while( i_skip < 23 && p_header[i_skip] == 0xff )
155
180k
            {
156
180k
                i_skip++;
157
180k
                if( i_header < i_skip + 1 )
158
1.53k
                    return VLC_EGENERIC;
159
180k
            }
160
195k
            if( i_skip == 23 )
161
3.60k
            {
162
3.60k
                vlc_error( p_logger, "too much MPEG-1 stuffing" );
163
3.60k
                return VLC_EGENERIC;
164
3.60k
            }
165
            /* Skip STD buffer size */
166
192k
            if( ( p_header[i_skip] & 0xC0 ) == 0x40 )
167
24.2k
            {
168
24.2k
                i_skip += 2;
169
24.2k
            }
170
171
192k
            if( i_header < i_skip + 1 )
172
176
                return VLC_EGENERIC;
173
174
191k
            if(  p_header[i_skip]&0x20 )
175
151k
            {
176
151k
                if( i_header >= i_skip + 5 )
177
150k
                    (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts );
178
179
151k
                if( ( p_header[i_skip]&0x10 ) &&     /* has dts */
180
119k
                    i_header >= i_skip + 10 )
181
115k
                {
182
115k
                    (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts );
183
115k
                    i_skip += 10;
184
115k
                }
185
35.9k
                else
186
35.9k
                {
187
35.9k
                    i_skip += 5;
188
35.9k
                }
189
151k
            }
190
40.0k
            else
191
40.0k
            {
192
40.0k
                if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */
193
37.5k
                    return VLC_EGENERIC;
194
2.48k
                i_skip += 1;
195
2.48k
            }
196
191k
        }
197
1.09M
        break;
198
1.14M
    }
199
200
1.10M
    h->i_size = i_skip;
201
1.10M
    return VLC_SUCCESS;
202
1.14M
}
ps.c:ParsePESHeader
Line
Count
Source
100
127k
{
101
127k
    unsigned i_skip;
102
103
127k
    if ( i_header < 9 )
104
2.86k
        return VLC_EGENERIC;
105
106
124k
    if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 )
107
0
        return VLC_EGENERIC;
108
109
124k
    h->i_stream_id = p_header[3];
110
111
124k
    switch( p_header[3] )
112
124k
    {
113
0
    case STREAM_ID_PROGRAM_STREAM_MAP:
114
0
    case STREAM_ID_PADDING:
115
0
    case STREAM_ID_PRIVATE_STREAM_2:
116
38
    case STREAM_ID_ECM:
117
38
    case STREAM_ID_EMM:
118
217
    case STREAM_ID_PROGRAM_STREAM_DIRECTORY:
119
218
    case STREAM_ID_DSM_CC:
120
411
    case STREAM_ID_H222_1_TYPE_E:
121
411
        i_skip = 6;
122
411
        h->b_scrambling = false;
123
411
        break;
124
124k
    default:
125
124k
        if( ( p_header[6]&0xC0 ) == 0x80 )
126
26.0k
        {
127
            /* mpeg2 PES */
128
            // 9 = syncword(3), stream ID(1), length(2), MPEG2 PES(1), flags(1), header_len(1)
129
            // p_header[8] = header_len(1)
130
26.0k
            i_skip = p_header[8] + 9;
131
132
26.0k
            h->b_scrambling = p_header[6]&0x30;
133
134
26.0k
            if( p_header[7]&0x80 )    /* has pts */
135
21.6k
            {
136
21.6k
                if( i_header >= 9 + 5 )
137
21.5k
                   (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts );
138
139
21.6k
                if( ( p_header[7]&0x40 ) &&    /* has dts */
140
1.14k
                    i_header >= 14 + 5 )
141
1.10k
                   (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts );
142
21.6k
            }
143
26.0k
        }
144
98.4k
        else
145
98.4k
        {
146
            /* FIXME?: WTH do we have undocumented MPEG1 packet stuff here ?
147
               This code path should not be valid, but seems some ppl did
148
               put MPEG1 packets into PS or TS.
149
               Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
150
98.4k
            i_skip = 6;
151
152
98.4k
            h->b_scrambling = false;
153
154
141k
            while( i_skip < 23 && p_header[i_skip] == 0xff )
155
44.5k
            {
156
44.5k
                i_skip++;
157
44.5k
                if( i_header < i_skip + 1 )
158
1.06k
                    return VLC_EGENERIC;
159
44.5k
            }
160
97.3k
            if( i_skip == 23 )
161
75
            {
162
75
                vlc_error( p_logger, "too much MPEG-1 stuffing" );
163
75
                return VLC_EGENERIC;
164
75
            }
165
            /* Skip STD buffer size */
166
97.2k
            if( ( p_header[i_skip] & 0xC0 ) == 0x40 )
167
9.82k
            {
168
9.82k
                i_skip += 2;
169
9.82k
            }
170
171
97.2k
            if( i_header < i_skip + 1 )
172
54
                return VLC_EGENERIC;
173
174
97.2k
            if(  p_header[i_skip]&0x20 )
175
71.7k
            {
176
71.7k
                if( i_header >= i_skip + 5 )
177
71.4k
                    (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts );
178
179
71.7k
                if( ( p_header[i_skip]&0x10 ) &&     /* has dts */
180
51.7k
                    i_header >= i_skip + 10 )
181
49.8k
                {
182
49.8k
                    (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts );
183
49.8k
                    i_skip += 10;
184
49.8k
                }
185
21.9k
                else
186
21.9k
                {
187
21.9k
                    i_skip += 5;
188
21.9k
                }
189
71.7k
            }
190
25.4k
            else
191
25.4k
            {
192
25.4k
                if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */
193
25.4k
                    return VLC_EGENERIC;
194
54
                i_skip += 1;
195
54
            }
196
97.2k
        }
197
97.8k
        break;
198
124k
    }
199
200
98.2k
    h->i_size = i_skip;
201
98.2k
    return VLC_SUCCESS;
202
124k
}
Unexecuted instantiation: pva.c:ParsePESHeader
Unexecuted instantiation: ty.c:ParsePESHeader
Unexecuted instantiation: vobsub.c:ParsePESHeader
ts.c:ParsePESHeader
Line
Count
Source
100
987k
{
101
987k
    unsigned i_skip;
102
103
987k
    if ( i_header < 9 )
104
1.63k
        return VLC_EGENERIC;
105
106
985k
    if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 )
107
5.20k
        return VLC_EGENERIC;
108
109
980k
    h->i_stream_id = p_header[3];
110
111
980k
    switch( p_header[3] )
112
980k
    {
113
313
    case STREAM_ID_PROGRAM_STREAM_MAP:
114
686
    case STREAM_ID_PADDING:
115
833
    case STREAM_ID_PRIVATE_STREAM_2:
116
1.12k
    case STREAM_ID_ECM:
117
1.76k
    case STREAM_ID_EMM:
118
3.48k
    case STREAM_ID_PROGRAM_STREAM_DIRECTORY:
119
4.61k
    case STREAM_ID_DSM_CC:
120
4.89k
    case STREAM_ID_H222_1_TYPE_E:
121
4.89k
        i_skip = 6;
122
4.89k
        h->b_scrambling = false;
123
4.89k
        break;
124
975k
    default:
125
975k
        if( ( p_header[6]&0xC0 ) == 0x80 )
126
886k
        {
127
            /* mpeg2 PES */
128
            // 9 = syncword(3), stream ID(1), length(2), MPEG2 PES(1), flags(1), header_len(1)
129
            // p_header[8] = header_len(1)
130
886k
            i_skip = p_header[8] + 9;
131
132
886k
            h->b_scrambling = p_header[6]&0x30;
133
134
886k
            if( p_header[7]&0x80 )    /* has pts */
135
158k
            {
136
158k
                if( i_header >= 9 + 5 )
137
158k
                   (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts );
138
139
158k
                if( ( p_header[7]&0x40 ) &&    /* has dts */
140
18.8k
                    i_header >= 14 + 5 )
141
18.8k
                   (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts );
142
158k
            }
143
886k
        }
144
89.1k
        else
145
89.1k
        {
146
            /* FIXME?: WTH do we have undocumented MPEG1 packet stuff here ?
147
               This code path should not be valid, but seems some ppl did
148
               put MPEG1 packets into PS or TS.
149
               Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
150
89.1k
            i_skip = 6;
151
152
89.1k
            h->b_scrambling = false;
153
154
192k
            while( i_skip < 23 && p_header[i_skip] == 0xff )
155
103k
            {
156
103k
                i_skip++;
157
103k
                if( i_header < i_skip + 1 )
158
241
                    return VLC_EGENERIC;
159
103k
            }
160
88.9k
            if( i_skip == 23 )
161
2.30k
            {
162
2.30k
                vlc_error( p_logger, "too much MPEG-1 stuffing" );
163
2.30k
                return VLC_EGENERIC;
164
2.30k
            }
165
            /* Skip STD buffer size */
166
86.6k
            if( ( p_header[i_skip] & 0xC0 ) == 0x40 )
167
13.0k
            {
168
13.0k
                i_skip += 2;
169
13.0k
            }
170
171
86.6k
            if( i_header < i_skip + 1 )
172
102
                return VLC_EGENERIC;
173
174
86.5k
            if(  p_header[i_skip]&0x20 )
175
73.7k
            {
176
73.7k
                if( i_header >= i_skip + 5 )
177
72.9k
                    (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts );
178
179
73.7k
                if( ( p_header[i_skip]&0x10 ) &&     /* has dts */
180
62.8k
                    i_header >= i_skip + 10 )
181
61.9k
                {
182
61.9k
                    (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts );
183
61.9k
                    i_skip += 10;
184
61.9k
                }
185
11.7k
                else
186
11.7k
                {
187
11.7k
                    i_skip += 5;
188
11.7k
                }
189
73.7k
            }
190
12.7k
            else
191
12.7k
            {
192
12.7k
                if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */
193
10.8k
                    return VLC_EGENERIC;
194
1.92k
                i_skip += 1;
195
1.92k
            }
196
86.5k
        }
197
962k
        break;
198
980k
    }
199
200
967k
    h->i_size = i_skip;
201
967k
    return VLC_SUCCESS;
202
980k
}
ts_hotfixes.c:ParsePESHeader
Line
Count
Source
100
51.8k
{
101
51.8k
    unsigned i_skip;
102
103
51.8k
    if ( i_header < 9 )
104
593
        return VLC_EGENERIC;
105
106
51.2k
    if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 )
107
12.8k
        return VLC_EGENERIC;
108
109
38.4k
    h->i_stream_id = p_header[3];
110
111
38.4k
    switch( p_header[3] )
112
38.4k
    {
113
129
    case STREAM_ID_PROGRAM_STREAM_MAP:
114
249
    case STREAM_ID_PADDING:
115
350
    case STREAM_ID_PRIVATE_STREAM_2:
116
392
    case STREAM_ID_ECM:
117
466
    case STREAM_ID_EMM:
118
1.40k
    case STREAM_ID_PROGRAM_STREAM_DIRECTORY:
119
1.78k
    case STREAM_ID_DSM_CC:
120
1.85k
    case STREAM_ID_H222_1_TYPE_E:
121
1.85k
        i_skip = 6;
122
1.85k
        h->b_scrambling = false;
123
1.85k
        break;
124
36.6k
    default:
125
36.6k
        if( ( p_header[6]&0xC0 ) == 0x80 )
126
26.9k
        {
127
            /* mpeg2 PES */
128
            // 9 = syncword(3), stream ID(1), length(2), MPEG2 PES(1), flags(1), header_len(1)
129
            // p_header[8] = header_len(1)
130
26.9k
            i_skip = p_header[8] + 9;
131
132
26.9k
            h->b_scrambling = p_header[6]&0x30;
133
134
26.9k
            if( p_header[7]&0x80 )    /* has pts */
135
5.18k
            {
136
5.18k
                if( i_header >= 9 + 5 )
137
5.17k
                   (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts );
138
139
5.18k
                if( ( p_header[7]&0x40 ) &&    /* has dts */
140
2.75k
                    i_header >= 14 + 5 )
141
2.74k
                   (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts );
142
5.18k
            }
143
26.9k
        }
144
9.66k
        else
145
9.66k
        {
146
            /* FIXME?: WTH do we have undocumented MPEG1 packet stuff here ?
147
               This code path should not be valid, but seems some ppl did
148
               put MPEG1 packets into PS or TS.
149
               Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
150
9.66k
            i_skip = 6;
151
152
9.66k
            h->b_scrambling = false;
153
154
41.4k
            while( i_skip < 23 && p_header[i_skip] == 0xff )
155
32.0k
            {
156
32.0k
                i_skip++;
157
32.0k
                if( i_header < i_skip + 1 )
158
228
                    return VLC_EGENERIC;
159
32.0k
            }
160
9.43k
            if( i_skip == 23 )
161
1.22k
            {
162
1.22k
                vlc_error( p_logger, "too much MPEG-1 stuffing" );
163
1.22k
                return VLC_EGENERIC;
164
1.22k
            }
165
            /* Skip STD buffer size */
166
8.20k
            if( ( p_header[i_skip] & 0xC0 ) == 0x40 )
167
1.37k
            {
168
1.37k
                i_skip += 2;
169
1.37k
            }
170
171
8.20k
            if( i_header < i_skip + 1 )
172
20
                return VLC_EGENERIC;
173
174
8.18k
            if(  p_header[i_skip]&0x20 )
175
6.34k
            {
176
6.34k
                if( i_header >= i_skip + 5 )
177
6.01k
                    (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts );
178
179
6.34k
                if( ( p_header[i_skip]&0x10 ) &&     /* has dts */
180
4.51k
                    i_header >= i_skip + 10 )
181
4.19k
                {
182
4.19k
                    (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts );
183
4.19k
                    i_skip += 10;
184
4.19k
                }
185
2.15k
                else
186
2.15k
                {
187
2.15k
                    i_skip += 5;
188
2.15k
                }
189
6.34k
            }
190
1.84k
            else
191
1.84k
            {
192
1.84k
                if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */
193
1.34k
                    return VLC_EGENERIC;
194
503
                i_skip += 1;
195
503
            }
196
8.18k
        }
197
33.7k
        break;
198
38.4k
    }
199
200
35.6k
    h->i_size = i_skip;
201
35.6k
    return VLC_SUCCESS;
202
38.4k
}
203
204
#endif