/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 | 102k | #define STREAM_ID_PROGRAM_STREAM_MAP 0xBC |
26 | 413k | #define STREAM_ID_PRIVATE_STREAM_1 0xBD |
27 | 8.14k | #define STREAM_ID_PADDING 0xBE |
28 | 1.30k | #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.79k | #define STREAM_ID_ECM 0xF0 |
32 | 1.89k | #define STREAM_ID_EMM 0xF1 |
33 | 4.57k | #define STREAM_ID_DSM_CC 0xF2 |
34 | 5.55k | #define STREAM_ID_H222_1_TYPE_E 0xF8 |
35 | | #define STREAM_ID_METADATA_STREAM 0xFC |
36 | 331k | #define STREAM_ID_EXTENDED_STREAM_ID 0xFD |
37 | 52.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 | 394k | { |
42 | | /* prefixed by 4 bits 0010 or 0011 */ |
43 | 394k | return ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)| |
44 | 394k | (ts_90khz_t)(p_data[1] << 22)| |
45 | 394k | ((ts_90khz_t)(p_data[2]&0xfe) << 14)| |
46 | 394k | (ts_90khz_t)(p_data[3] << 7)| |
47 | 394k | (ts_90khz_t)(p_data[4] >> 1); |
48 | 394k | } Line | Count | Source | 41 | 151k | { | 42 | | /* prefixed by 4 bits 0010 or 0011 */ | 43 | 151k | return ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)| | 44 | 151k | (ts_90khz_t)(p_data[1] << 22)| | 45 | 151k | ((ts_90khz_t)(p_data[2]&0xfe) << 14)| | 46 | 151k | (ts_90khz_t)(p_data[3] << 7)| | 47 | 151k | (ts_90khz_t)(p_data[4] >> 1); | 48 | 151k | } |
Line | Count | Source | 41 | 144k | { | 42 | | /* prefixed by 4 bits 0010 or 0011 */ | 43 | 144k | return ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)| | 44 | 144k | (ts_90khz_t)(p_data[1] << 22)| | 45 | 144k | ((ts_90khz_t)(p_data[2]&0xfe) << 14)| | 46 | 144k | (ts_90khz_t)(p_data[3] << 7)| | 47 | 144k | (ts_90khz_t)(p_data[4] >> 1); | 48 | 144k | } |
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 Line | Count | Source | 41 | 70.4k | { | 42 | | /* prefixed by 4 bits 0010 or 0011 */ | 43 | 70.4k | return ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)| | 44 | 70.4k | (ts_90khz_t)(p_data[1] << 22)| | 45 | 70.4k | ((ts_90khz_t)(p_data[2]&0xfe) << 14)| | 46 | 70.4k | (ts_90khz_t)(p_data[3] << 7)| | 47 | 70.4k | (ts_90khz_t)(p_data[4] >> 1); | 48 | 70.4k | } |
ts_hotfixes.c:GetPESTimestamp Line | Count | Source | 41 | 6.54k | { | 42 | | /* prefixed by 4 bits 0010 or 0011 */ | 43 | 6.54k | return ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)| | 44 | 6.54k | (ts_90khz_t)(p_data[1] << 22)| | 45 | 6.54k | ((ts_90khz_t)(p_data[2]&0xfe) << 14)| | 46 | 6.54k | (ts_90khz_t)(p_data[3] << 7)| | 47 | 6.54k | (ts_90khz_t)(p_data[4] >> 1); | 48 | 6.54k | } |
|
49 | | |
50 | | static inline bool ExtractPESTimestamp( const uint8_t *p_data, uint8_t i_flags, ts_90khz_t *ret ) |
51 | 432k | { |
52 | | /* !warn broken muxers set incorrect flags. see #17773 and #19140 */ |
53 | | /* check marker bits, and i_flags = b 0010, 0011 or 0001 */ |
54 | 432k | if((p_data[0] & 0xC1) != 0x01 || |
55 | 291k | (p_data[2] & 0x01) != 0x01 || |
56 | 267k | (p_data[4] & 0x01) != 0x01 || |
57 | 252k | (p_data[0] & 0x30) == 0 || /* at least needs one bit */ |
58 | 228k | (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */ |
59 | 204k | return false; |
60 | | |
61 | | |
62 | 228k | *ret = GetPESTimestamp( p_data ); |
63 | 228k | return true; |
64 | 432k | } Line | Count | Source | 51 | 303k | { | 52 | | /* !warn broken muxers set incorrect flags. see #17773 and #19140 */ | 53 | | /* check marker bits, and i_flags = b 0010, 0011 or 0001 */ | 54 | 303k | if((p_data[0] & 0xC1) != 0x01 || | 55 | 206k | (p_data[2] & 0x01) != 0x01 || | 56 | 185k | (p_data[4] & 0x01) != 0x01 || | 57 | 175k | (p_data[0] & 0x30) == 0 || /* at least needs one bit */ | 58 | 151k | (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */ | 59 | 152k | return false; | 60 | | | 61 | | | 62 | 151k | *ret = GetPESTimestamp( p_data ); | 63 | | return true; | 64 | 303k | } |
Unexecuted instantiation: pva.c:ExtractPESTimestamp Unexecuted instantiation: ty.c:ExtractPESTimestamp Unexecuted instantiation: vobsub.c:ExtractPESTimestamp Line | Count | Source | 51 | 114k | { | 52 | | /* !warn broken muxers set incorrect flags. see #17773 and #19140 */ | 53 | | /* check marker bits, and i_flags = b 0010, 0011 or 0001 */ | 54 | 114k | if((p_data[0] & 0xC1) != 0x01 || | 55 | 78.0k | (p_data[2] & 0x01) != 0x01 || | 56 | 75.5k | (p_data[4] & 0x01) != 0x01 || | 57 | 70.5k | (p_data[0] & 0x30) == 0 || /* at least needs one bit */ | 58 | 70.4k | (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */ | 59 | 44.0k | return false; | 60 | | | 61 | | | 62 | 70.4k | *ret = GetPESTimestamp( p_data ); | 63 | | return true; | 64 | 114k | } |
ts_hotfixes.c:ExtractPESTimestamp Line | Count | Source | 51 | 14.2k | { | 52 | | /* !warn broken muxers set incorrect flags. see #17773 and #19140 */ | 53 | | /* check marker bits, and i_flags = b 0010, 0011 or 0001 */ | 54 | 14.2k | if((p_data[0] & 0xC1) != 0x01 || | 55 | 7.27k | (p_data[2] & 0x01) != 0x01 || | 56 | 6.91k | (p_data[4] & 0x01) != 0x01 || | 57 | 6.58k | (p_data[0] & 0x30) == 0 || /* at least needs one bit */ | 58 | 6.54k | (p_data[0] >> 5) > i_flags ) /* needs flags 1x => 1x or flags 01 => 01 */ | 59 | 7.72k | return false; | 60 | | | 61 | | | 62 | 6.54k | *ret = GetPESTimestamp( p_data ); | 63 | | return true; | 64 | 14.2k | } |
|
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 | 112 | { |
69 | | /* prefixed by 2 bits 01 */ |
70 | 112 | return ((ts_90khz_t)(p_data[0]&0x38 ) << 27)| |
71 | 112 | ((ts_90khz_t)(p_data[0]&0x03 ) << 28)| |
72 | 112 | (ts_90khz_t)(p_data[1] << 20)| |
73 | 112 | ((ts_90khz_t)(p_data[2]&0xf8 ) << 12)| |
74 | 112 | ((ts_90khz_t)(p_data[2]&0x03 ) << 13)| |
75 | 112 | (ts_90khz_t)(p_data[3] << 5) | |
76 | 112 | (ts_90khz_t)(p_data[4] >> 3); |
77 | 112 | } ps.c:ExtractPackHeaderTimestamp Line | Count | Source | 68 | 112 | { | 69 | | /* prefixed by 2 bits 01 */ | 70 | 112 | return ((ts_90khz_t)(p_data[0]&0x38 ) << 27)| | 71 | 112 | ((ts_90khz_t)(p_data[0]&0x03 ) << 28)| | 72 | 112 | (ts_90khz_t)(p_data[1] << 20)| | 73 | 112 | ((ts_90khz_t)(p_data[2]&0xf8 ) << 12)| | 74 | 112 | ((ts_90khz_t)(p_data[2]&0x03 ) << 13)| | 75 | 112 | (ts_90khz_t)(p_data[3] << 5) | | 76 | 112 | (ts_90khz_t)(p_data[4] >> 3); | 77 | 112 | } |
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 | 902k | { |
90 | 902k | h->i_dts = TS_90KHZ_INVALID; |
91 | 902k | h->i_pts = TS_90KHZ_INVALID; |
92 | 902k | h->i_stream_id = 0; |
93 | 902k | h->b_scrambling = false; |
94 | 902k | h->i_size = 0; |
95 | 902k | } Line | Count | Source | 89 | 234k | { | 90 | 234k | h->i_dts = TS_90KHZ_INVALID; | 91 | 234k | h->i_pts = TS_90KHZ_INVALID; | 92 | 234k | h->i_stream_id = 0; | 93 | | h->b_scrambling = false; | 94 | 234k | h->i_size = 0; | 95 | 234k | } |
Unexecuted instantiation: pva.c:ts_pes_header_init Unexecuted instantiation: ty.c:ts_pes_header_init Unexecuted instantiation: vobsub.c:ts_pes_header_init Line | Count | Source | 89 | 615k | { | 90 | 615k | h->i_dts = TS_90KHZ_INVALID; | 91 | 615k | h->i_pts = TS_90KHZ_INVALID; | 92 | 615k | h->i_stream_id = 0; | 93 | | h->b_scrambling = false; | 94 | 615k | h->i_size = 0; | 95 | 615k | } |
ts_hotfixes.c:ts_pes_header_init Line | Count | Source | 89 | 52.6k | { | 90 | 52.6k | h->i_dts = TS_90KHZ_INVALID; | 91 | 52.6k | h->i_pts = TS_90KHZ_INVALID; | 92 | 52.6k | h->i_stream_id = 0; | 93 | | h->b_scrambling = false; | 94 | 52.6k | h->i_size = 0; | 95 | 52.6k | } |
|
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 | 902k | { |
101 | 902k | unsigned i_skip; |
102 | | |
103 | 902k | if ( i_header < 9 ) |
104 | 7.88k | return VLC_EGENERIC; |
105 | | |
106 | 895k | if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 ) |
107 | 13.4k | return VLC_EGENERIC; |
108 | | |
109 | 881k | h->i_stream_id = p_header[3]; |
110 | | |
111 | 881k | switch( p_header[3] ) |
112 | 881k | { |
113 | 1.12k | case STREAM_ID_PROGRAM_STREAM_MAP: |
114 | 1.25k | case STREAM_ID_PADDING: |
115 | 1.30k | case STREAM_ID_PRIVATE_STREAM_2: |
116 | 1.79k | case STREAM_ID_ECM: |
117 | 1.89k | case STREAM_ID_EMM: |
118 | 4.16k | case STREAM_ID_PROGRAM_STREAM_DIRECTORY: |
119 | 4.57k | case STREAM_ID_DSM_CC: |
120 | 5.55k | case STREAM_ID_H222_1_TYPE_E: |
121 | 5.55k | i_skip = 6; |
122 | 5.55k | h->b_scrambling = false; |
123 | 5.55k | break; |
124 | 876k | default: |
125 | 876k | if( ( p_header[6]&0xC0 ) == 0x80 ) |
126 | 607k | { |
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 | 607k | i_skip = p_header[8] + 9; |
131 | | |
132 | 607k | h->b_scrambling = p_header[6]&0x30; |
133 | | |
134 | 607k | if( p_header[7]&0x80 ) /* has pts */ |
135 | 61.1k | { |
136 | 61.1k | if( i_header >= 9 + 5 ) |
137 | 61.1k | (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts ); |
138 | | |
139 | 61.1k | if( ( p_header[7]&0x40 ) && /* has dts */ |
140 | 5.93k | i_header >= 14 + 5 ) |
141 | 5.65k | (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts ); |
142 | 61.1k | } |
143 | 607k | } |
144 | 268k | else |
145 | 268k | { |
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 | 268k | i_skip = 6; |
151 | | |
152 | 268k | h->b_scrambling = false; |
153 | | |
154 | 452k | while( i_skip < 23 && p_header[i_skip] == 0xff ) |
155 | 184k | { |
156 | 184k | i_skip++; |
157 | 184k | if( i_header < i_skip + 1 ) |
158 | 319 | return VLC_EGENERIC; |
159 | 184k | } |
160 | 268k | if( i_skip == 23 ) |
161 | 1.54k | { |
162 | 1.54k | vlc_error( p_logger, "too much MPEG-1 stuffing" ); |
163 | 1.54k | return VLC_EGENERIC; |
164 | 1.54k | } |
165 | | /* Skip STD buffer size */ |
166 | 266k | if( ( p_header[i_skip] & 0xC0 ) == 0x40 ) |
167 | 34.1k | { |
168 | 34.1k | i_skip += 2; |
169 | 34.1k | } |
170 | | |
171 | 266k | if( i_header < i_skip + 1 ) |
172 | 81 | return VLC_EGENERIC; |
173 | | |
174 | 266k | if( p_header[i_skip]&0x20 ) |
175 | 220k | { |
176 | 220k | if( i_header >= i_skip + 5 ) |
177 | 214k | (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts ); |
178 | | |
179 | 220k | if( ( p_header[i_skip]&0x10 ) && /* has dts */ |
180 | 180k | i_header >= i_skip + 10 ) |
181 | 150k | { |
182 | 150k | (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts ); |
183 | 150k | i_skip += 10; |
184 | 150k | } |
185 | 69.6k | else |
186 | 69.6k | { |
187 | 69.6k | i_skip += 5; |
188 | 69.6k | } |
189 | 220k | } |
190 | 46.7k | else |
191 | 46.7k | { |
192 | 46.7k | if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */ |
193 | 46.5k | return VLC_EGENERIC; |
194 | 183 | i_skip += 1; |
195 | 183 | } |
196 | 266k | } |
197 | 827k | break; |
198 | 881k | } |
199 | | |
200 | 833k | h->i_size = i_skip; |
201 | 833k | return VLC_SUCCESS; |
202 | 881k | } Line | Count | Source | 100 | 234k | { | 101 | 234k | unsigned i_skip; | 102 | | | 103 | 234k | if ( i_header < 9 ) | 104 | 7.44k | return VLC_EGENERIC; | 105 | | | 106 | 227k | if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 ) | 107 | 0 | return VLC_EGENERIC; | 108 | | | 109 | 227k | h->i_stream_id = p_header[3]; | 110 | | | 111 | 227k | switch( p_header[3] ) | 112 | 227k | { | 113 | 0 | case STREAM_ID_PROGRAM_STREAM_MAP: | 114 | 0 | case STREAM_ID_PADDING: | 115 | 0 | case STREAM_ID_PRIVATE_STREAM_2: | 116 | 10 | case STREAM_ID_ECM: | 117 | 42 | case STREAM_ID_EMM: | 118 | 146 | case STREAM_ID_PROGRAM_STREAM_DIRECTORY: | 119 | 274 | case STREAM_ID_DSM_CC: | 120 | 376 | case STREAM_ID_H222_1_TYPE_E: | 121 | 376 | i_skip = 6; | 122 | 376 | h->b_scrambling = false; | 123 | 376 | break; | 124 | 226k | default: | 125 | 226k | if( ( p_header[6]&0xC0 ) == 0x80 ) | 126 | 12.5k | { | 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 | 12.5k | i_skip = p_header[8] + 9; | 131 | | | 132 | 12.5k | h->b_scrambling = p_header[6]&0x30; | 133 | | | 134 | 12.5k | if( p_header[7]&0x80 ) /* has pts */ | 135 | 5.60k | { | 136 | 5.60k | if( i_header >= 9 + 5 ) | 137 | 5.59k | (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts ); | 138 | | | 139 | 5.60k | if( ( p_header[7]&0x40 ) && /* has dts */ | 140 | 2.82k | i_header >= 14 + 5 ) | 141 | 2.55k | (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts ); | 142 | 5.60k | } | 143 | 12.5k | } | 144 | 214k | else | 145 | 214k | { | 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 | 214k | i_skip = 6; | 151 | | | 152 | 214k | h->b_scrambling = false; | 153 | | | 154 | 264k | while( i_skip < 23 && p_header[i_skip] == 0xff ) | 155 | 50.3k | { | 156 | 50.3k | i_skip++; | 157 | 50.3k | if( i_header < i_skip + 1 ) | 158 | 312 | return VLC_EGENERIC; | 159 | 50.3k | } | 160 | 213k | if( i_skip == 23 ) | 161 | 1.24k | { | 162 | 1.24k | vlc_error( p_logger, "too much MPEG-1 stuffing" ); | 163 | 1.24k | return VLC_EGENERIC; | 164 | 1.24k | } | 165 | | /* Skip STD buffer size */ | 166 | 212k | if( ( p_header[i_skip] & 0xC0 ) == 0x40 ) | 167 | 18.1k | { | 168 | 18.1k | i_skip += 2; | 169 | 18.1k | } | 170 | | | 171 | 212k | if( i_header < i_skip + 1 ) | 172 | 9 | return VLC_EGENERIC; | 173 | | | 174 | 212k | if( p_header[i_skip]&0x20 ) | 175 | 176k | { | 176 | 176k | if( i_header >= i_skip + 5 ) | 177 | 171k | (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts ); | 178 | | | 179 | 176k | if( ( p_header[i_skip]&0x10 ) && /* has dts */ | 180 | 153k | i_header >= i_skip + 10 ) | 181 | 124k | { | 182 | 124k | (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts ); | 183 | 124k | i_skip += 10; | 184 | 124k | } | 185 | 52.2k | else | 186 | 52.2k | { | 187 | 52.2k | i_skip += 5; | 188 | 52.2k | } | 189 | 176k | } | 190 | 36.3k | else | 191 | 36.3k | { | 192 | 36.3k | if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */ | 193 | 36.3k | return VLC_EGENERIC; | 194 | 53 | i_skip += 1; | 195 | 53 | } | 196 | 212k | } | 197 | 188k | break; | 198 | 227k | } | 199 | | | 200 | 189k | h->i_size = i_skip; | 201 | 189k | return VLC_SUCCESS; | 202 | 227k | } |
Unexecuted instantiation: pva.c:ParsePESHeader Unexecuted instantiation: ty.c:ParsePESHeader Unexecuted instantiation: vobsub.c:ParsePESHeader Line | Count | Source | 100 | 615k | { | 101 | 615k | unsigned i_skip; | 102 | | | 103 | 615k | if ( i_header < 9 ) | 104 | 347 | return VLC_EGENERIC; | 105 | | | 106 | 615k | if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 ) | 107 | 6.06k | return VLC_EGENERIC; | 108 | | | 109 | 609k | h->i_stream_id = p_header[3]; | 110 | | | 111 | 609k | switch( p_header[3] ) | 112 | 609k | { | 113 | 980 | case STREAM_ID_PROGRAM_STREAM_MAP: | 114 | 1.06k | case STREAM_ID_PADDING: | 115 | 1.10k | case STREAM_ID_PRIVATE_STREAM_2: | 116 | 1.50k | case STREAM_ID_ECM: | 117 | 1.55k | case STREAM_ID_EMM: | 118 | 2.51k | case STREAM_ID_PROGRAM_STREAM_DIRECTORY: | 119 | 2.70k | case STREAM_ID_DSM_CC: | 120 | 3.49k | case STREAM_ID_H222_1_TYPE_E: | 121 | 3.49k | i_skip = 6; | 122 | 3.49k | h->b_scrambling = false; | 123 | 3.49k | break; | 124 | 605k | default: | 125 | 605k | if( ( p_header[6]&0xC0 ) == 0x80 ) | 126 | 559k | { | 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 | 559k | i_skip = p_header[8] + 9; | 131 | | | 132 | 559k | h->b_scrambling = p_header[6]&0x30; | 133 | | | 134 | 559k | if( p_header[7]&0x80 ) /* has pts */ | 135 | 52.9k | { | 136 | 52.9k | if( i_header >= 9 + 5 ) | 137 | 52.9k | (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts ); | 138 | | | 139 | 52.9k | if( ( p_header[7]&0x40 ) && /* has dts */ | 140 | 2.57k | i_header >= 14 + 5 ) | 141 | 2.57k | (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts ); | 142 | 52.9k | } | 143 | 559k | } | 144 | 46.7k | else | 145 | 46.7k | { | 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 | 46.7k | i_skip = 6; | 151 | | | 152 | 46.7k | h->b_scrambling = false; | 153 | | | 154 | 173k | while( i_skip < 23 && p_header[i_skip] == 0xff ) | 155 | 126k | { | 156 | 126k | i_skip++; | 157 | 126k | if( i_header < i_skip + 1 ) | 158 | 1 | return VLC_EGENERIC; | 159 | 126k | } | 160 | 46.7k | if( i_skip == 23 ) | 161 | 266 | { | 162 | 266 | vlc_error( p_logger, "too much MPEG-1 stuffing" ); | 163 | 266 | return VLC_EGENERIC; | 164 | 266 | } | 165 | | /* Skip STD buffer size */ | 166 | 46.4k | if( ( p_header[i_skip] & 0xC0 ) == 0x40 ) | 167 | 14.3k | { | 168 | 14.3k | i_skip += 2; | 169 | 14.3k | } | 170 | | | 171 | 46.4k | if( i_header < i_skip + 1 ) | 172 | 60 | return VLC_EGENERIC; | 173 | | | 174 | 46.4k | if( p_header[i_skip]&0x20 ) | 175 | 37.3k | { | 176 | 37.3k | if( i_header >= i_skip + 5 ) | 177 | 37.3k | (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts ); | 178 | | | 179 | 37.3k | if( ( p_header[i_skip]&0x10 ) && /* has dts */ | 180 | 21.7k | i_header >= i_skip + 10 ) | 181 | 21.7k | { | 182 | 21.7k | (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts ); | 183 | 21.7k | i_skip += 10; | 184 | 21.7k | } | 185 | 15.6k | else | 186 | 15.6k | { | 187 | 15.6k | i_skip += 5; | 188 | 15.6k | } | 189 | 37.3k | } | 190 | 9.01k | else | 191 | 9.01k | { | 192 | 9.01k | if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */ | 193 | 8.92k | return VLC_EGENERIC; | 194 | 90 | i_skip += 1; | 195 | 90 | } | 196 | 46.4k | } | 197 | 596k | break; | 198 | 609k | } | 199 | | | 200 | 600k | h->i_size = i_skip; | 201 | 600k | return VLC_SUCCESS; | 202 | 609k | } |
ts_hotfixes.c:ParsePESHeader Line | Count | Source | 100 | 52.6k | { | 101 | 52.6k | unsigned i_skip; | 102 | | | 103 | 52.6k | if ( i_header < 9 ) | 104 | 94 | return VLC_EGENERIC; | 105 | | | 106 | 52.5k | if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 ) | 107 | 7.34k | return VLC_EGENERIC; | 108 | | | 109 | 45.1k | h->i_stream_id = p_header[3]; | 110 | | | 111 | 45.1k | switch( p_header[3] ) | 112 | 45.1k | { | 113 | 141 | case STREAM_ID_PROGRAM_STREAM_MAP: | 114 | 182 | case STREAM_ID_PADDING: | 115 | 202 | case STREAM_ID_PRIVATE_STREAM_2: | 116 | 278 | case STREAM_ID_ECM: | 117 | 295 | case STREAM_ID_EMM: | 118 | 1.50k | case STREAM_ID_PROGRAM_STREAM_DIRECTORY: | 119 | 1.59k | case STREAM_ID_DSM_CC: | 120 | 1.68k | case STREAM_ID_H222_1_TYPE_E: | 121 | 1.68k | i_skip = 6; | 122 | 1.68k | h->b_scrambling = false; | 123 | 1.68k | break; | 124 | 43.4k | default: | 125 | 43.4k | if( ( p_header[6]&0xC0 ) == 0x80 ) | 126 | 35.6k | { | 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 | 35.6k | i_skip = p_header[8] + 9; | 131 | | | 132 | 35.6k | h->b_scrambling = p_header[6]&0x30; | 133 | | | 134 | 35.6k | if( p_header[7]&0x80 ) /* has pts */ | 135 | 2.65k | { | 136 | 2.65k | if( i_header >= 9 + 5 ) | 137 | 2.65k | (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts ); | 138 | | | 139 | 2.65k | if( ( p_header[7]&0x40 ) && /* has dts */ | 140 | 531 | i_header >= 14 + 5 ) | 141 | 525 | (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts ); | 142 | 2.65k | } | 143 | 35.6k | } | 144 | 7.80k | else | 145 | 7.80k | { | 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 | 7.80k | i_skip = 6; | 151 | | | 152 | 7.80k | h->b_scrambling = false; | 153 | | | 154 | 14.8k | while( i_skip < 23 && p_header[i_skip] == 0xff ) | 155 | 7.06k | { | 156 | 7.06k | i_skip++; | 157 | 7.06k | if( i_header < i_skip + 1 ) | 158 | 6 | return VLC_EGENERIC; | 159 | 7.06k | } | 160 | 7.80k | if( i_skip == 23 ) | 161 | 34 | { | 162 | 34 | vlc_error( p_logger, "too much MPEG-1 stuffing" ); | 163 | 34 | return VLC_EGENERIC; | 164 | 34 | } | 165 | | /* Skip STD buffer size */ | 166 | 7.76k | if( ( p_header[i_skip] & 0xC0 ) == 0x40 ) | 167 | 1.73k | { | 168 | 1.73k | i_skip += 2; | 169 | 1.73k | } | 170 | | | 171 | 7.76k | if( i_header < i_skip + 1 ) | 172 | 12 | return VLC_EGENERIC; | 173 | | | 174 | 7.75k | if( p_header[i_skip]&0x20 ) | 175 | 6.45k | { | 176 | 6.45k | if( i_header >= i_skip + 5 ) | 177 | 6.43k | (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts ); | 178 | | | 179 | 6.45k | if( ( p_header[i_skip]&0x10 ) && /* has dts */ | 180 | 4.69k | i_header >= i_skip + 10 ) | 181 | 4.65k | { | 182 | 4.65k | (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts ); | 183 | 4.65k | i_skip += 10; | 184 | 4.65k | } | 185 | 1.80k | else | 186 | 1.80k | { | 187 | 1.80k | i_skip += 5; | 188 | 1.80k | } | 189 | 6.45k | } | 190 | 1.30k | else | 191 | 1.30k | { | 192 | 1.30k | if( (p_header[i_skip] & 0xFF) != 0x0F ) /* No pts/dts, lowest bits set to 0x0F */ | 193 | 1.26k | return VLC_EGENERIC; | 194 | 40 | i_skip += 1; | 195 | 40 | } | 196 | 7.75k | } | 197 | 42.1k | break; | 198 | 45.1k | } | 199 | | | 200 | 43.8k | h->i_size = i_skip; | 201 | 43.8k | return VLC_SUCCESS; | 202 | 45.1k | } |
|
203 | | |
204 | | #endif |