Mercurial > libavformat.hg
annotate mpeg.c @ 2727:a21454bf80b8 libavformat
fix potential buffer over-read
author | aurel |
---|---|
date | Thu, 08 Nov 2007 20:53:06 +0000 |
parents | 5dbc1dfc1300 |
children | e00622d9d3c9 |
rev | line source |
---|---|
0 | 1 /* |
2176
50322a49fa2b
split mpeg ps and variants muxer and demuxer, I'll clean more in a few minutes, lpcm freq tab is left static const in mpeg.h for now until we have more code in common
bcoudurier
parents:
2164
diff
changeset
|
2 * MPEG1/2 demuxer |
0 | 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
2176
50322a49fa2b
split mpeg ps and variants muxer and demuxer, I'll clean more in a few minutes, lpcm freq tab is left static const in mpeg.h for now until we have more code in common
bcoudurier
parents:
2164
diff
changeset
|
21 |
0 | 22 #include "avformat.h" |
2176
50322a49fa2b
split mpeg ps and variants muxer and demuxer, I'll clean more in a few minutes, lpcm freq tab is left static const in mpeg.h for now until we have more code in common
bcoudurier
parents:
2164
diff
changeset
|
23 #include "mpeg.h" |
0 | 24 |
310 | 25 //#define DEBUG_SEEK |
0 | 26 |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
27 #undef NDEBUG |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
28 #include <assert.h> |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
29 |
0 | 30 /*********************************************/ |
31 /* demux code */ | |
32 | |
33 #define MAX_SYNC_SIZE 100000 | |
34 | |
1284 | 35 static int cdxa_probe(AVProbeData *p) |
36 { | |
37 /* check file header */ | |
38 if (p->buf[0] == 'R' && p->buf[1] == 'I' && | |
39 p->buf[2] == 'F' && p->buf[3] == 'F' && | |
40 p->buf[8] == 'C' && p->buf[9] == 'D' && | |
41 p->buf[10] == 'X' && p->buf[11] == 'A') | |
42 return AVPROBE_SCORE_MAX; | |
43 else | |
44 return 0; | |
45 } | |
46 | |
2697
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
47 static int check_pes(uint8_t *p, uint8_t *end){ |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
48 int pes1; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
49 int pes2= (p[3] & 0xC0) == 0x80 |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
50 && (p[4] & 0xC0) != 0x40 |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
51 &&((p[4] & 0xC0) == 0x00 || (p[4]&0xC0)>>2 == (p[6]&0xF0)); |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
52 |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
53 for(p+=3; p<end && *p == 0xFF; p++); |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
54 if((*p&0xC0) == 0x40) p+=2; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
55 if((*p&0xF0) == 0x20){ |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
56 pes1= p[0]&p[2]&p[4]&1; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
57 p+=5; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
58 }else if((*p&0xF0) == 0x30){ |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
59 pes1= p[0]&p[2]&p[4]&p[5]&p[7]&p[9]&1; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
60 p+=10; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
61 }else |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
62 pes1 = *p == 0x0F; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
63 |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
64 return pes1||pes2; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
65 } |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
66 |
0 | 67 static int mpegps_probe(AVProbeData *p) |
68 { | |
936 | 69 uint32_t code= -1; |
1138
36ce24677f96
detect MPEG PES streams as MPEG PS; the PS demuxer will cope
mru
parents:
1126
diff
changeset
|
70 int sys=0, pspack=0, priv1=0, vid=0, audio=0; |
539 | 71 int i; |
1257 | 72 int score=0; |
49 | 73 |
1284 | 74 score = cdxa_probe(p); |
75 if (score > 0) return score; | |
76 | |
77 /* Search for MPEG stream */ | |
936 | 78 for(i=0; i<p->buf_size; i++){ |
79 code = (code<<8) + p->buf[i]; | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
80 if ((code & 0xffffff00) == 0x100) { |
2698 | 81 int pes= check_pes(p->buf+i, p->buf+p->buf_size); |
2697
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
82 |
1140
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
83 if(code == SYSTEM_HEADER_START_CODE) sys++; |
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
84 else if(code == PRIVATE_STREAM_1) priv1++; |
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
85 else if(code == PACK_START_CODE) pspack++; |
2697
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
86 else if((code & 0xf0) == VIDEO_ID && pes) vid++; |
afbdd52324e3
fix misdetection of mp3could_not_find_codec_parameters.mp3
michael
parents:
2695
diff
changeset
|
87 else if((code & 0xe0) == AUDIO_ID && pes) audio++; |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
88 } |
0 | 89 } |
1257 | 90 |
91 if(vid || audio) /* invalid VDR files nd short PES streams */ | |
92 score= AVPROBE_SCORE_MAX/4; | |
93 | |
2311 | 94 //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, p->buf_size); |
936 | 95 if(sys && sys*9 <= pspack*10) |
96 return AVPROBE_SCORE_MAX/2+2; // +1 for .mpg | |
1140
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
97 if((priv1 || vid || audio) && (priv1+vid+audio)*9 <= pspack*10) |
940 | 98 return AVPROBE_SCORE_MAX/2+2; // +1 for .mpg |
2312 | 99 if((!!vid ^ !!audio) && (audio+vid > 1) && !sys && !pspack && p->buf_size>2048) /* PES stream */ |
1140
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
100 return AVPROBE_SCORE_MAX/2+2; |
1257 | 101 |
102 //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1 | |
103 return score; | |
0 | 104 } |
105 | |
106 | |
107 typedef struct MpegDemuxContext { | |
1332 | 108 int32_t header_state; |
722 | 109 unsigned char psm_es_type[256]; |
2718
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
110 int sofdec; |
0 | 111 } MpegDemuxContext; |
112 | |
310 | 113 static int mpegps_read_header(AVFormatContext *s, |
114 AVFormatParameters *ap) | |
115 { | |
116 MpegDemuxContext *m = s->priv_data; | |
2718
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
117 uint8_t buffer[8192]; |
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
118 char *p; |
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
119 |
310 | 120 m->header_state = 0xff; |
121 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
122 | |
2718
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
123 get_buffer(&s->pb, buffer, sizeof(buffer)); |
2727 | 124 if ((p=memchr(buffer, 'S', sizeof(buffer)-5))) |
2718
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
125 if (!memcmp(p, "Sofdec", 6)) |
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
126 m->sofdec = 1; |
2726 | 127 url_fseek(&s->pb, -(offset_t)sizeof(buffer), SEEK_CUR); |
2718
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
128 |
310 | 129 /* no need to do more */ |
130 return 0; | |
131 } | |
132 | |
133 static int64_t get_pts(ByteIOContext *pb, int c) | |
134 { | |
135 int64_t pts; | |
136 int val; | |
137 | |
138 if (c < 0) | |
139 c = get_byte(pb); | |
140 pts = (int64_t)((c >> 1) & 0x07) << 30; | |
141 val = get_be16(pb); | |
142 pts |= (int64_t)(val >> 1) << 15; | |
143 val = get_be16(pb); | |
144 pts |= (int64_t)(val >> 1); | |
145 return pts; | |
146 } | |
147 | |
885 | 148 static int find_next_start_code(ByteIOContext *pb, int *size_ptr, |
1332 | 149 int32_t *header_state) |
0 | 150 { |
151 unsigned int state, v; | |
152 int val, n; | |
153 | |
154 state = *header_state; | |
155 n = *size_ptr; | |
156 while (n > 0) { | |
157 if (url_feof(pb)) | |
158 break; | |
159 v = get_byte(pb); | |
160 n--; | |
161 if (state == 0x000001) { | |
162 state = ((state << 8) | v) & 0xffffff; | |
163 val = state; | |
164 goto found; | |
165 } | |
166 state = ((state << 8) | v) & 0xffffff; | |
167 } | |
168 val = -1; | |
169 found: | |
170 *header_state = state; | |
171 *size_ptr = n; | |
172 return val; | |
173 } | |
174 | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
674
diff
changeset
|
175 #if 0 /* unused, remove? */ |
310 | 176 /* XXX: optimize */ |
177 static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) | |
0 | 178 { |
310 | 179 int64_t pos, pos_start; |
180 int max_size, start_code; | |
181 | |
182 max_size = *size_ptr; | |
183 pos_start = url_ftell(pb); | |
184 | |
185 /* in order to go faster, we fill the buffer */ | |
186 pos = pos_start - 16386; | |
187 if (pos < 0) | |
188 pos = 0; | |
189 url_fseek(pb, pos, SEEK_SET); | |
190 get_byte(pb); | |
293
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
191 |
310 | 192 pos = pos_start; |
193 for(;;) { | |
194 pos--; | |
195 if (pos < 0 || (pos_start - pos) >= max_size) { | |
196 start_code = -1; | |
197 goto the_end; | |
198 } | |
199 url_fseek(pb, pos, SEEK_SET); | |
200 start_code = get_be32(pb); | |
201 if ((start_code & 0xffffff00) == 0x100) | |
202 break; | |
203 } | |
204 the_end: | |
205 *size_ptr = pos_start - pos; | |
206 return start_code; | |
0 | 207 } |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
674
diff
changeset
|
208 #endif |
0 | 209 |
722 | 210 /** |
211 * Extracts stream types from a program stream map | |
212 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35 | |
885 | 213 * |
722 | 214 * @return number of bytes occupied by PSM in the bitstream |
215 */ | |
216 static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb) | |
217 { | |
218 int psm_length, ps_info_length, es_map_length; | |
219 | |
220 psm_length = get_be16(pb); | |
221 get_byte(pb); | |
222 get_byte(pb); | |
223 ps_info_length = get_be16(pb); | |
224 | |
225 /* skip program_stream_info */ | |
226 url_fskip(pb, ps_info_length); | |
227 es_map_length = get_be16(pb); | |
228 | |
229 /* at least one es available? */ | |
230 while (es_map_length >= 4){ | |
231 unsigned char type = get_byte(pb); | |
232 unsigned char es_id = get_byte(pb); | |
233 uint16_t es_info_length = get_be16(pb); | |
234 /* remember mapping from stream id to stream type */ | |
235 m->psm_es_type[es_id] = type; | |
236 /* skip program_stream_info */ | |
237 url_fskip(pb, es_info_length); | |
238 es_map_length -= 4 + es_info_length; | |
239 } | |
240 get_be32(pb); /* crc32 */ | |
241 return 2 + psm_length; | |
242 } | |
243 | |
885 | 244 /* read the next PES header. Return its position in ppos |
310 | 245 (if not NULL), and its start code, pts and dts. |
246 */ | |
247 static int mpegps_read_pes_header(AVFormatContext *s, | |
885 | 248 int64_t *ppos, int *pstart_code, |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
249 int64_t *ppts, int64_t *pdts) |
0 | 250 { |
251 MpegDemuxContext *m = s->priv_data; | |
310 | 252 int len, size, startcode, c, flags, header_len; |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
253 int pes_ext, ext2_len, id_ext, skip; |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
254 int64_t pts, dts; |
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
255 int64_t last_sync= url_ftell(&s->pb); |
0 | 256 |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
257 error_redo: |
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
258 url_fseek(&s->pb, last_sync, SEEK_SET); |
0 | 259 redo: |
310 | 260 /* next start code (should be immediately after) */ |
261 m->header_state = 0xff; | |
262 size = MAX_SYNC_SIZE; | |
263 startcode = find_next_start_code(&s->pb, &size, &m->header_state); | |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
264 last_sync = url_ftell(&s->pb); |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
265 //printf("startcode=%x pos=0x%"PRIx64"\n", startcode, url_ftell(&s->pb)); |
0 | 266 if (startcode < 0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2177
diff
changeset
|
267 return AVERROR(EIO); |
0 | 268 if (startcode == PACK_START_CODE) |
269 goto redo; | |
270 if (startcode == SYSTEM_HEADER_START_CODE) | |
271 goto redo; | |
272 if (startcode == PADDING_STREAM || | |
273 startcode == PRIVATE_STREAM_2) { | |
274 /* skip them */ | |
275 len = get_be16(&s->pb); | |
276 url_fskip(&s->pb, len); | |
277 goto redo; | |
278 } | |
722 | 279 if (startcode == PROGRAM_STREAM_MAP) { |
280 mpegps_psm_parse(m, &s->pb); | |
281 goto redo; | |
282 } | |
885 | 283 |
0 | 284 /* find matching stream */ |
285 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
286 (startcode >= 0x1e0 && startcode <= 0x1ef) || | |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
287 (startcode == 0x1bd) || (startcode == 0x1fd))) |
0 | 288 goto redo; |
310 | 289 if (ppos) { |
290 *ppos = url_ftell(&s->pb) - 4; | |
291 } | |
0 | 292 len = get_be16(&s->pb); |
1666 | 293 pts = |
0 | 294 dts = AV_NOPTS_VALUE; |
295 /* stuffing */ | |
296 for(;;) { | |
310 | 297 if (len < 1) |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
298 goto error_redo; |
0 | 299 c = get_byte(&s->pb); |
300 len--; | |
301 /* XXX: for mpeg1, should test only bit 7 */ | |
885 | 302 if (c != 0xff) |
0 | 303 break; |
304 } | |
305 if ((c & 0xc0) == 0x40) { | |
306 /* buffer scale & size */ | |
307 get_byte(&s->pb); | |
308 c = get_byte(&s->pb); | |
309 len -= 2; | |
310 } | |
1667 | 311 if ((c & 0xe0) == 0x20) { |
310 | 312 dts = pts = get_pts(&s->pb, c); |
0 | 313 len -= 4; |
1667 | 314 if (c & 0x10){ |
315 dts = get_pts(&s->pb, -1); | |
316 len -= 5; | |
317 } | |
0 | 318 } else if ((c & 0xc0) == 0x80) { |
319 /* mpeg 2 PES */ | |
1126 | 320 #if 0 /* some streams have this field set for no apparent reason */ |
0 | 321 if ((c & 0x30) != 0) { |
310 | 322 /* Encrypted multiplex not handled */ |
323 goto redo; | |
0 | 324 } |
1126 | 325 #endif |
0 | 326 flags = get_byte(&s->pb); |
327 header_len = get_byte(&s->pb); | |
328 len -= 2; | |
329 if (header_len > len) | |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
330 goto error_redo; |
1668 | 331 len -= header_len; |
1667 | 332 if (flags & 0x80) { |
310 | 333 dts = pts = get_pts(&s->pb, -1); |
0 | 334 header_len -= 5; |
1667 | 335 if (flags & 0x40) { |
336 dts = get_pts(&s->pb, -1); | |
337 header_len -= 5; | |
338 } | |
0 | 339 } |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
340 if (flags & 0x01) { /* PES extension */ |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
341 pes_ext = get_byte(&s->pb); |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
342 header_len--; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
343 if (pes_ext & 0x40) { /* pack header - should be zero in PS */ |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
344 goto error_redo; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
345 } |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
346 /* Skip PES private data, program packet sequence counter and P-STD buffer */ |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
347 skip = (pes_ext >> 4) & 0xb; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
348 skip += skip & 0x9; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
349 url_fskip(&s->pb, skip); |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
350 header_len -= skip; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
351 |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
352 if (pes_ext & 0x01) { /* PES extension 2 */ |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
353 ext2_len = get_byte(&s->pb); |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
354 header_len--; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
355 if ((ext2_len & 0x7f) > 0) { |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
356 id_ext = get_byte(&s->pb); |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
357 if ((id_ext & 0x80) == 0) |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
358 startcode = ((startcode & 0xff) << 8) | id_ext; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
359 header_len--; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
360 } |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
361 } |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
362 } |
1668 | 363 if(header_len < 0) |
364 goto error_redo; | |
365 url_fskip(&s->pb, header_len); | |
0 | 366 } |
447
94aa265c18b9
Mpeg start codes patch by ("Dmitry Borisov" <jbors at mail dot ru>)
michael
parents:
437
diff
changeset
|
367 else if( c!= 0xf ) |
94aa265c18b9
Mpeg start codes patch by ("Dmitry Borisov" <jbors at mail dot ru>)
michael
parents:
437
diff
changeset
|
368 goto redo; |
94aa265c18b9
Mpeg start codes patch by ("Dmitry Borisov" <jbors at mail dot ru>)
michael
parents:
437
diff
changeset
|
369 |
722 | 370 if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) { |
0 | 371 startcode = get_byte(&s->pb); |
372 len--; | |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
373 if (startcode >= 0x80 && startcode <= 0xcf) { |
0 | 374 /* audio: skip header */ |
375 get_byte(&s->pb); | |
376 get_byte(&s->pb); | |
377 get_byte(&s->pb); | |
378 len -= 3; | |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
379 if (startcode >= 0xb0 && startcode <= 0xbf) { |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
380 /* MLP/TrueHD audio has a 4-byte header */ |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
381 get_byte(&s->pb); |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
382 len--; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
383 } |
0 | 384 } |
385 } | |
1665 | 386 if(len<0) |
387 goto error_redo; | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
388 if(dts != AV_NOPTS_VALUE && ppos){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
389 int i; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
390 for(i=0; i<s->nb_streams; i++){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
391 if(startcode == s->streams[i]->id) { |
979 | 392 av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
393 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
394 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
395 } |
885 | 396 |
310 | 397 *pstart_code = startcode; |
398 *ppts = pts; | |
399 *pdts = dts; | |
400 return len; | |
401 } | |
402 | |
403 static int mpegps_read_packet(AVFormatContext *s, | |
404 AVPacket *pkt) | |
405 { | |
722 | 406 MpegDemuxContext *m = s->priv_data; |
310 | 407 AVStream *st; |
722 | 408 int len, startcode, i, type, codec_id = 0, es_type; |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
409 int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work |
310 | 410 |
411 redo: | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
412 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); |
310 | 413 if (len < 0) |
414 return len; | |
885 | 415 |
0 | 416 /* now find stream */ |
417 for(i=0;i<s->nb_streams;i++) { | |
418 st = s->streams[i]; | |
419 if (st->id == startcode) | |
420 goto found; | |
421 } | |
722 | 422 |
423 es_type = m->psm_es_type[startcode & 0xff]; | |
424 if(es_type > 0){ | |
425 if(es_type == STREAM_TYPE_VIDEO_MPEG1){ | |
426 codec_id = CODEC_ID_MPEG2VIDEO; | |
427 type = CODEC_TYPE_VIDEO; | |
428 } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){ | |
429 codec_id = CODEC_ID_MPEG2VIDEO; | |
430 type = CODEC_TYPE_VIDEO; | |
431 } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 || | |
432 es_type == STREAM_TYPE_AUDIO_MPEG2){ | |
433 codec_id = CODEC_ID_MP3; | |
434 type = CODEC_TYPE_AUDIO; | |
435 } else if(es_type == STREAM_TYPE_AUDIO_AAC){ | |
436 codec_id = CODEC_ID_AAC; | |
437 type = CODEC_TYPE_AUDIO; | |
438 } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){ | |
439 codec_id = CODEC_ID_MPEG4; | |
440 type = CODEC_TYPE_VIDEO; | |
441 } else if(es_type == STREAM_TYPE_VIDEO_H264){ | |
442 codec_id = CODEC_ID_H264; | |
443 type = CODEC_TYPE_VIDEO; | |
444 } else if(es_type == STREAM_TYPE_AUDIO_AC3){ | |
445 codec_id = CODEC_ID_AC3; | |
446 type = CODEC_TYPE_AUDIO; | |
447 } else { | |
448 goto skip; | |
449 } | |
450 } else if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
1146 | 451 static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; |
452 unsigned char buf[8]; | |
453 get_buffer(&s->pb, buf, 8); | |
454 url_fseek(&s->pb, -8, SEEK_CUR); | |
455 if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) | |
456 codec_id = CODEC_ID_CAVS; | |
457 else | |
458 codec_id = CODEC_ID_MPEG2VIDEO; | |
0 | 459 type = CODEC_TYPE_VIDEO; |
460 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { | |
461 type = CODEC_TYPE_AUDIO; | |
2718
1bbb4fa1cdcd
correctly set audio codec when demuxing sofdec files
aurel
parents:
2698
diff
changeset
|
462 codec_id = m->sofdec ? CODEC_ID_ADPCM_ADX : CODEC_ID_MP2; |
767
cbfea73709bd
fix ac3 and dts detection (patch by Joakim Plate <joakim.plate at ecce.se>)
mru
parents:
722
diff
changeset
|
463 } else if (startcode >= 0x80 && startcode <= 0x87) { |
0 | 464 type = CODEC_TYPE_AUDIO; |
465 codec_id = CODEC_ID_AC3; | |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
466 } else if ((startcode >= 0x88 && startcode <= 0x8f) |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
467 ||( startcode >= 0x98 && startcode <= 0x9f)) { |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
468 /* 0x90 - 0x97 is reserved for SDDS in DVD specs */ |
496
112057e05179
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
483
diff
changeset
|
469 type = CODEC_TYPE_AUDIO; |
112057e05179
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
483
diff
changeset
|
470 codec_id = CODEC_ID_DTS; |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
471 } else if (startcode >= 0xa0 && startcode <= 0xaf) { |
41 | 472 type = CODEC_TYPE_AUDIO; |
473 codec_id = CODEC_ID_PCM_S16BE; | |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
474 } else if (startcode >= 0xb0 && startcode <= 0xbf) { |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
475 type = CODEC_TYPE_AUDIO; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
476 codec_id = CODEC_ID_MLP; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
477 } else if (startcode >= 0xc0 && startcode <= 0xcf) { |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
478 /* Used for both AC-3 and E-AC-3 in EVOB files */ |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
479 type = CODEC_TYPE_AUDIO; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
480 codec_id = CODEC_ID_AC3; |
783
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
481 } else if (startcode >= 0x20 && startcode <= 0x3f) { |
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
482 type = CODEC_TYPE_SUBTITLE; |
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
483 codec_id = CODEC_ID_DVD_SUBTITLE; |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
484 } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) { |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
485 type = CODEC_TYPE_VIDEO; |
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
486 codec_id = CODEC_ID_VC1; |
0 | 487 } else { |
488 skip: | |
489 /* skip packet */ | |
490 url_fskip(&s->pb, len); | |
491 goto redo; | |
492 } | |
493 /* no stream found: add a new stream */ | |
494 st = av_new_stream(s, startcode); | |
885 | 495 if (!st) |
0 | 496 goto skip; |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
789
diff
changeset
|
497 st->codec->codec_type = type; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
789
diff
changeset
|
498 st->codec->codec_id = codec_id; |
310 | 499 if (codec_id != CODEC_ID_PCM_S16BE) |
2023 | 500 st->need_parsing = AVSTREAM_PARSE_FULL; |
0 | 501 found: |
708 | 502 if(st->discard >= AVDISCARD_ALL) |
652 | 503 goto skip; |
1759
9eaf71a70ac1
Revised patch for HD DVD .EVO demuxing by (Ian Caulfield <lowercase name seperated by . place at here gmail place a dot here com>)
michael
parents:
1668
diff
changeset
|
504 if (startcode >= 0xa0 && startcode <= 0xaf) { |
41 | 505 int b1, freq; |
506 | |
507 /* for LPCM, we just skip the header and consider it is raw | |
508 audio data */ | |
509 if (len <= 3) | |
510 goto skip; | |
511 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
512 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
513 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
514 len -= 3; | |
515 freq = (b1 >> 4) & 3; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
789
diff
changeset
|
516 st->codec->sample_rate = lpcm_freq_tab[freq]; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
789
diff
changeset
|
517 st->codec->channels = 1 + (b1 & 7); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
789
diff
changeset
|
518 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 2; |
41 | 519 } |
0 | 520 av_new_packet(pkt, len); |
521 get_buffer(&s->pb, pkt->data, pkt->size); | |
522 pkt->pts = pts; | |
310 | 523 pkt->dts = dts; |
0 | 524 pkt->stream_index = st->index; |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
525 #if 0 |
652 | 526 av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", |
527 pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size); | |
331
4530681af424
suppress PTS in packets when not needed (slightly smaller files), fixed PTS generation in some cases, added provision for DTS generation, slightly better SCR generation (initial patch by Michel Bardiaux)
bellard
parents:
310
diff
changeset
|
528 #endif |
482 | 529 |
0 | 530 return 0; |
531 } | |
532 | |
533 static int mpegps_read_close(AVFormatContext *s) | |
534 { | |
535 return 0; | |
536 } | |
537 | |
885 | 538 static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
539 int64_t *ppos, int64_t pos_limit) |
310 | 540 { |
541 int len, startcode; | |
542 int64_t pos, pts, dts; | |
543 | |
544 pos = *ppos; | |
545 #ifdef DEBUG_SEEK | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
546 printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next); |
310 | 547 #endif |
548 url_fseek(&s->pb, pos, SEEK_SET); | |
549 for(;;) { | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
550 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); |
310 | 551 if (len < 0) { |
552 #ifdef DEBUG_SEEK | |
553 printf("none (ret=%d)\n", len); | |
554 #endif | |
555 return AV_NOPTS_VALUE; | |
556 } | |
885 | 557 if (startcode == s->streams[stream_index]->id && |
310 | 558 dts != AV_NOPTS_VALUE) { |
559 break; | |
560 } | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
561 url_fskip(&s->pb, len); |
310 | 562 } |
563 #ifdef DEBUG_SEEK | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
564 printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0); |
310 | 565 #endif |
566 *ppos = pos; | |
463
696f41bc8784
store index for seeking in the native timebase of each stream
michael
parents:
452
diff
changeset
|
567 return dts; |
310 | 568 } |
569 | |
1167 | 570 AVInputFormat mpegps_demuxer = { |
0 | 571 "mpeg", |
572 "MPEG PS format", | |
573 sizeof(MpegDemuxContext), | |
574 mpegps_probe, | |
575 mpegps_read_header, | |
576 mpegps_read_packet, | |
577 mpegps_read_close, | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
578 NULL, //mpegps_read_seek, |
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
579 mpegps_read_dts, |
783
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
580 .flags = AVFMT_SHOW_IDS, |
0 | 581 }; |