Mercurial > libavformat.hg
annotate mpeg.c @ 2694:bb2ba011f1e1 libavformat
remove useless initialization to 0 of adx context
author | aurel |
---|---|
date | Thu, 01 Nov 2007 17:50:05 +0000 |
parents | a8122196ad95 |
children | b89af3f21df6 |
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 | |
0 | 47 static int mpegps_probe(AVProbeData *p) |
48 { | |
936 | 49 uint32_t code= -1; |
1138
36ce24677f96
detect MPEG PES streams as MPEG PS; the PS demuxer will cope
mru
parents:
1126
diff
changeset
|
50 int sys=0, pspack=0, priv1=0, vid=0, audio=0; |
539 | 51 int i; |
1257 | 52 int score=0; |
49 | 53 |
1284 | 54 score = cdxa_probe(p); |
55 if (score > 0) return score; | |
56 | |
57 /* Search for MPEG stream */ | |
936 | 58 for(i=0; i<p->buf_size; i++){ |
59 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
|
60 if ((code & 0xffffff00) == 0x100) { |
1140
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
61 if(code == SYSTEM_HEADER_START_CODE) sys++; |
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
62 else if(code == PRIVATE_STREAM_1) priv1++; |
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
63 else if(code == PACK_START_CODE) pspack++; |
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
64 else if((code & 0xf0) == VIDEO_ID) vid++; |
2cfb5e02b299
detect audio-only program streams and broken files made by VDR
mru
parents:
1138
diff
changeset
|
65 else if((code & 0xe0) == AUDIO_ID) audio++; |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
66 } |
0 | 67 } |
1257 | 68 |
69 if(vid || audio) /* invalid VDR files nd short PES streams */ | |
70 score= AVPROBE_SCORE_MAX/4; | |
71 | |
2311 | 72 //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, p->buf_size); |
936 | 73 if(sys && sys*9 <= pspack*10) |
74 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
|
75 if((priv1 || vid || audio) && (priv1+vid+audio)*9 <= pspack*10) |
940 | 76 return AVPROBE_SCORE_MAX/2+2; // +1 for .mpg |
2312 | 77 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
|
78 return AVPROBE_SCORE_MAX/2+2; |
1257 | 79 |
80 //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1 | |
81 return score; | |
0 | 82 } |
83 | |
84 | |
85 typedef struct MpegDemuxContext { | |
1332 | 86 int32_t header_state; |
722 | 87 unsigned char psm_es_type[256]; |
2694 | 88 int sofdec; |
0 | 89 } MpegDemuxContext; |
90 | |
310 | 91 static int mpegps_read_header(AVFormatContext *s, |
92 AVFormatParameters *ap) | |
93 { | |
94 MpegDemuxContext *m = s->priv_data; | |
2694 | 95 uint8_t buffer[8192]; |
96 char *p; | |
97 | |
310 | 98 m->header_state = 0xff; |
99 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
100 | |
2694 | 101 get_buffer(&s->pb, buffer, sizeof(buffer)); |
102 if ((p=memchr(buffer, 'S', sizeof(buffer)))) | |
103 if (!memcmp(p, "Sofdec", 6)) | |
104 m->sofdec = 1; | |
105 url_fseek(&s->pb, -sizeof(buffer), SEEK_CUR); | |
106 | |
310 | 107 /* no need to do more */ |
108 return 0; | |
109 } | |
110 | |
111 static int64_t get_pts(ByteIOContext *pb, int c) | |
112 { | |
113 int64_t pts; | |
114 int val; | |
115 | |
116 if (c < 0) | |
117 c = get_byte(pb); | |
118 pts = (int64_t)((c >> 1) & 0x07) << 30; | |
119 val = get_be16(pb); | |
120 pts |= (int64_t)(val >> 1) << 15; | |
121 val = get_be16(pb); | |
122 pts |= (int64_t)(val >> 1); | |
123 return pts; | |
124 } | |
125 | |
885 | 126 static int find_next_start_code(ByteIOContext *pb, int *size_ptr, |
1332 | 127 int32_t *header_state) |
0 | 128 { |
129 unsigned int state, v; | |
130 int val, n; | |
131 | |
132 state = *header_state; | |
133 n = *size_ptr; | |
134 while (n > 0) { | |
135 if (url_feof(pb)) | |
136 break; | |
137 v = get_byte(pb); | |
138 n--; | |
139 if (state == 0x000001) { | |
140 state = ((state << 8) | v) & 0xffffff; | |
141 val = state; | |
142 goto found; | |
143 } | |
144 state = ((state << 8) | v) & 0xffffff; | |
145 } | |
146 val = -1; | |
147 found: | |
148 *header_state = state; | |
149 *size_ptr = n; | |
150 return val; | |
151 } | |
152 | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
674
diff
changeset
|
153 #if 0 /* unused, remove? */ |
310 | 154 /* XXX: optimize */ |
155 static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) | |
0 | 156 { |
310 | 157 int64_t pos, pos_start; |
158 int max_size, start_code; | |
159 | |
160 max_size = *size_ptr; | |
161 pos_start = url_ftell(pb); | |
162 | |
163 /* in order to go faster, we fill the buffer */ | |
164 pos = pos_start - 16386; | |
165 if (pos < 0) | |
166 pos = 0; | |
167 url_fseek(pb, pos, SEEK_SET); | |
168 get_byte(pb); | |
293
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
169 |
310 | 170 pos = pos_start; |
171 for(;;) { | |
172 pos--; | |
173 if (pos < 0 || (pos_start - pos) >= max_size) { | |
174 start_code = -1; | |
175 goto the_end; | |
176 } | |
177 url_fseek(pb, pos, SEEK_SET); | |
178 start_code = get_be32(pb); | |
179 if ((start_code & 0xffffff00) == 0x100) | |
180 break; | |
181 } | |
182 the_end: | |
183 *size_ptr = pos_start - pos; | |
184 return start_code; | |
0 | 185 } |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
674
diff
changeset
|
186 #endif |
0 | 187 |
722 | 188 /** |
189 * Extracts stream types from a program stream map | |
190 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35 | |
885 | 191 * |
722 | 192 * @return number of bytes occupied by PSM in the bitstream |
193 */ | |
194 static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb) | |
195 { | |
196 int psm_length, ps_info_length, es_map_length; | |
197 | |
198 psm_length = get_be16(pb); | |
199 get_byte(pb); | |
200 get_byte(pb); | |
201 ps_info_length = get_be16(pb); | |
202 | |
203 /* skip program_stream_info */ | |
204 url_fskip(pb, ps_info_length); | |
205 es_map_length = get_be16(pb); | |
206 | |
207 /* at least one es available? */ | |
208 while (es_map_length >= 4){ | |
209 unsigned char type = get_byte(pb); | |
210 unsigned char es_id = get_byte(pb); | |
211 uint16_t es_info_length = get_be16(pb); | |
212 /* remember mapping from stream id to stream type */ | |
213 m->psm_es_type[es_id] = type; | |
214 /* skip program_stream_info */ | |
215 url_fskip(pb, es_info_length); | |
216 es_map_length -= 4 + es_info_length; | |
217 } | |
218 get_be32(pb); /* crc32 */ | |
219 return 2 + psm_length; | |
220 } | |
221 | |
885 | 222 /* read the next PES header. Return its position in ppos |
310 | 223 (if not NULL), and its start code, pts and dts. |
224 */ | |
225 static int mpegps_read_pes_header(AVFormatContext *s, | |
885 | 226 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
|
227 int64_t *ppts, int64_t *pdts) |
0 | 228 { |
229 MpegDemuxContext *m = s->priv_data; | |
310 | 230 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
|
231 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
|
232 int64_t pts, dts; |
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
233 int64_t last_sync= url_ftell(&s->pb); |
0 | 234 |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
235 error_redo: |
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
236 url_fseek(&s->pb, last_sync, SEEK_SET); |
0 | 237 redo: |
310 | 238 /* next start code (should be immediately after) */ |
239 m->header_state = 0xff; | |
240 size = MAX_SYNC_SIZE; | |
241 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
|
242 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
|
243 //printf("startcode=%x pos=0x%"PRIx64"\n", startcode, url_ftell(&s->pb)); |
0 | 244 if (startcode < 0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2177
diff
changeset
|
245 return AVERROR(EIO); |
0 | 246 if (startcode == PACK_START_CODE) |
247 goto redo; | |
248 if (startcode == SYSTEM_HEADER_START_CODE) | |
249 goto redo; | |
250 if (startcode == PADDING_STREAM || | |
251 startcode == PRIVATE_STREAM_2) { | |
252 /* skip them */ | |
253 len = get_be16(&s->pb); | |
254 url_fskip(&s->pb, len); | |
255 goto redo; | |
256 } | |
722 | 257 if (startcode == PROGRAM_STREAM_MAP) { |
258 mpegps_psm_parse(m, &s->pb); | |
259 goto redo; | |
260 } | |
885 | 261 |
0 | 262 /* find matching stream */ |
263 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
264 (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
|
265 (startcode == 0x1bd) || (startcode == 0x1fd))) |
0 | 266 goto redo; |
310 | 267 if (ppos) { |
268 *ppos = url_ftell(&s->pb) - 4; | |
269 } | |
0 | 270 len = get_be16(&s->pb); |
1666 | 271 pts = |
0 | 272 dts = AV_NOPTS_VALUE; |
273 /* stuffing */ | |
274 for(;;) { | |
310 | 275 if (len < 1) |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
276 goto error_redo; |
0 | 277 c = get_byte(&s->pb); |
278 len--; | |
279 /* XXX: for mpeg1, should test only bit 7 */ | |
885 | 280 if (c != 0xff) |
0 | 281 break; |
282 } | |
283 if ((c & 0xc0) == 0x40) { | |
284 /* buffer scale & size */ | |
285 get_byte(&s->pb); | |
286 c = get_byte(&s->pb); | |
287 len -= 2; | |
288 } | |
1667 | 289 if ((c & 0xe0) == 0x20) { |
310 | 290 dts = pts = get_pts(&s->pb, c); |
0 | 291 len -= 4; |
1667 | 292 if (c & 0x10){ |
293 dts = get_pts(&s->pb, -1); | |
294 len -= 5; | |
295 } | |
0 | 296 } else if ((c & 0xc0) == 0x80) { |
297 /* mpeg 2 PES */ | |
1126 | 298 #if 0 /* some streams have this field set for no apparent reason */ |
0 | 299 if ((c & 0x30) != 0) { |
310 | 300 /* Encrypted multiplex not handled */ |
301 goto redo; | |
0 | 302 } |
1126 | 303 #endif |
0 | 304 flags = get_byte(&s->pb); |
305 header_len = get_byte(&s->pb); | |
306 len -= 2; | |
307 if (header_len > len) | |
1664
5e7460a2f209
seperate redo (we dont handle this possibly valid packet) from
michael
parents:
1443
diff
changeset
|
308 goto error_redo; |
1668 | 309 len -= header_len; |
1667 | 310 if (flags & 0x80) { |
310 | 311 dts = pts = get_pts(&s->pb, -1); |
0 | 312 header_len -= 5; |
1667 | 313 if (flags & 0x40) { |
314 dts = get_pts(&s->pb, -1); | |
315 header_len -= 5; | |
316 } | |
0 | 317 } |
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
|
318 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
|
319 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
|
320 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
|
321 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
|
322 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
|
323 } |
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
|
324 /* 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
|
325 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
|
326 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
|
327 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
|
328 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
|
329 |
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
|
330 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
|
331 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
|
332 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
|
333 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
|
334 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
|
335 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
|
336 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
|
337 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
|
338 } |
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
|
339 } |
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 } |
1668 | 341 if(header_len < 0) |
342 goto error_redo; | |
343 url_fskip(&s->pb, header_len); | |
0 | 344 } |
447
94aa265c18b9
Mpeg start codes patch by ("Dmitry Borisov" <jbors at mail dot ru>)
michael
parents:
437
diff
changeset
|
345 else if( c!= 0xf ) |
94aa265c18b9
Mpeg start codes patch by ("Dmitry Borisov" <jbors at mail dot ru>)
michael
parents:
437
diff
changeset
|
346 goto redo; |
94aa265c18b9
Mpeg start codes patch by ("Dmitry Borisov" <jbors at mail dot ru>)
michael
parents:
437
diff
changeset
|
347 |
722 | 348 if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) { |
0 | 349 startcode = get_byte(&s->pb); |
350 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
|
351 if (startcode >= 0x80 && startcode <= 0xcf) { |
0 | 352 /* audio: skip header */ |
353 get_byte(&s->pb); | |
354 get_byte(&s->pb); | |
355 get_byte(&s->pb); | |
356 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
|
357 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
|
358 /* 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
|
359 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
|
360 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
|
361 } |
0 | 362 } |
363 } | |
1665 | 364 if(len<0) |
365 goto error_redo; | |
346
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
366 if(dts != AV_NOPTS_VALUE && ppos){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
367 int i; |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
368 for(i=0; i<s->nb_streams; i++){ |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
369 if(startcode == s->streams[i]->id) { |
979 | 370 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
|
371 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
372 } |
e154eb1b7149
caching of timestamps for mpeg-ps so seeking is faster
michael
parents:
337
diff
changeset
|
373 } |
885 | 374 |
310 | 375 *pstart_code = startcode; |
376 *ppts = pts; | |
377 *pdts = dts; | |
378 return len; | |
379 } | |
380 | |
381 static int mpegps_read_packet(AVFormatContext *s, | |
382 AVPacket *pkt) | |
383 { | |
722 | 384 MpegDemuxContext *m = s->priv_data; |
310 | 385 AVStream *st; |
722 | 386 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
|
387 int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work |
310 | 388 |
389 redo: | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
390 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); |
310 | 391 if (len < 0) |
392 return len; | |
885 | 393 |
0 | 394 /* now find stream */ |
395 for(i=0;i<s->nb_streams;i++) { | |
396 st = s->streams[i]; | |
397 if (st->id == startcode) | |
398 goto found; | |
399 } | |
722 | 400 |
401 es_type = m->psm_es_type[startcode & 0xff]; | |
402 if(es_type > 0){ | |
403 if(es_type == STREAM_TYPE_VIDEO_MPEG1){ | |
404 codec_id = CODEC_ID_MPEG2VIDEO; | |
405 type = CODEC_TYPE_VIDEO; | |
406 } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){ | |
407 codec_id = CODEC_ID_MPEG2VIDEO; | |
408 type = CODEC_TYPE_VIDEO; | |
409 } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 || | |
410 es_type == STREAM_TYPE_AUDIO_MPEG2){ | |
411 codec_id = CODEC_ID_MP3; | |
412 type = CODEC_TYPE_AUDIO; | |
413 } else if(es_type == STREAM_TYPE_AUDIO_AAC){ | |
414 codec_id = CODEC_ID_AAC; | |
415 type = CODEC_TYPE_AUDIO; | |
416 } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){ | |
417 codec_id = CODEC_ID_MPEG4; | |
418 type = CODEC_TYPE_VIDEO; | |
419 } else if(es_type == STREAM_TYPE_VIDEO_H264){ | |
420 codec_id = CODEC_ID_H264; | |
421 type = CODEC_TYPE_VIDEO; | |
422 } else if(es_type == STREAM_TYPE_AUDIO_AC3){ | |
423 codec_id = CODEC_ID_AC3; | |
424 type = CODEC_TYPE_AUDIO; | |
425 } else { | |
426 goto skip; | |
427 } | |
428 } else if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
1146 | 429 static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; |
430 unsigned char buf[8]; | |
431 get_buffer(&s->pb, buf, 8); | |
432 url_fseek(&s->pb, -8, SEEK_CUR); | |
433 if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) | |
434 codec_id = CODEC_ID_CAVS; | |
435 else | |
436 codec_id = CODEC_ID_MPEG2VIDEO; | |
0 | 437 type = CODEC_TYPE_VIDEO; |
438 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { | |
439 type = CODEC_TYPE_AUDIO; | |
2694 | 440 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
|
441 } else if (startcode >= 0x80 && startcode <= 0x87) { |
0 | 442 type = CODEC_TYPE_AUDIO; |
443 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
|
444 } 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
|
445 ||( 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
|
446 /* 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
|
447 type = CODEC_TYPE_AUDIO; |
112057e05179
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
483
diff
changeset
|
448 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
|
449 } else if (startcode >= 0xa0 && startcode <= 0xaf) { |
41 | 450 type = CODEC_TYPE_AUDIO; |
451 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
|
452 } 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
|
453 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
|
454 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
|
455 } 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
|
456 /* 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
|
457 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
|
458 codec_id = CODEC_ID_AC3; |
783
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
459 } else if (startcode >= 0x20 && startcode <= 0x3f) { |
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
460 type = CODEC_TYPE_SUBTITLE; |
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
461 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
|
462 } 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
|
463 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
|
464 codec_id = CODEC_ID_VC1; |
0 | 465 } else { |
466 skip: | |
467 /* skip packet */ | |
468 url_fskip(&s->pb, len); | |
469 goto redo; | |
470 } | |
471 /* no stream found: add a new stream */ | |
472 st = av_new_stream(s, startcode); | |
885 | 473 if (!st) |
0 | 474 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
|
475 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
|
476 st->codec->codec_id = codec_id; |
310 | 477 if (codec_id != CODEC_ID_PCM_S16BE) |
2023 | 478 st->need_parsing = AVSTREAM_PARSE_FULL; |
0 | 479 found: |
708 | 480 if(st->discard >= AVDISCARD_ALL) |
652 | 481 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
|
482 if (startcode >= 0xa0 && startcode <= 0xaf) { |
41 | 483 int b1, freq; |
484 | |
485 /* for LPCM, we just skip the header and consider it is raw | |
486 audio data */ | |
487 if (len <= 3) | |
488 goto skip; | |
489 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
490 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
491 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
492 len -= 3; | |
493 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
|
494 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
|
495 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
|
496 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 2; |
41 | 497 } |
0 | 498 av_new_packet(pkt, len); |
499 get_buffer(&s->pb, pkt->data, pkt->size); | |
500 pkt->pts = pts; | |
310 | 501 pkt->dts = dts; |
0 | 502 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
|
503 #if 0 |
652 | 504 av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", |
505 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
|
506 #endif |
482 | 507 |
0 | 508 return 0; |
509 } | |
510 | |
511 static int mpegps_read_close(AVFormatContext *s) | |
512 { | |
513 return 0; | |
514 } | |
515 | |
885 | 516 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
|
517 int64_t *ppos, int64_t pos_limit) |
310 | 518 { |
519 int len, startcode; | |
520 int64_t pos, pts, dts; | |
521 | |
522 pos = *ppos; | |
523 #ifdef DEBUG_SEEK | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
524 printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next); |
310 | 525 #endif |
526 url_fseek(&s->pb, pos, SEEK_SET); | |
527 for(;;) { | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
528 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); |
310 | 529 if (len < 0) { |
530 #ifdef DEBUG_SEEK | |
531 printf("none (ret=%d)\n", len); | |
532 #endif | |
533 return AV_NOPTS_VALUE; | |
534 } | |
885 | 535 if (startcode == s->streams[stream_index]->id && |
310 | 536 dts != AV_NOPTS_VALUE) { |
537 break; | |
538 } | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
539 url_fskip(&s->pb, len); |
310 | 540 } |
541 #ifdef DEBUG_SEEK | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
542 printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0); |
310 | 543 #endif |
544 *ppos = pos; | |
463
696f41bc8784
store index for seeking in the native timebase of each stream
michael
parents:
452
diff
changeset
|
545 return dts; |
310 | 546 } |
547 | |
1167 | 548 AVInputFormat mpegps_demuxer = { |
0 | 549 "mpeg", |
550 "MPEG PS format", | |
551 sizeof(MpegDemuxContext), | |
552 mpegps_probe, | |
553 mpegps_read_header, | |
554 mpegps_read_packet, | |
555 mpegps_read_close, | |
437
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
556 NULL, //mpegps_read_seek, |
50bae308f71e
moving nearly identical binary search code from nut/mpeg/asf to utils.c
michael
parents:
396
diff
changeset
|
557 mpegps_read_dts, |
783
2e8b5a7d7e02
DVD subtitle parsing - show mpeg component IDs by default
bellard
parents:
767
diff
changeset
|
558 .flags = AVFMT_SHOW_IDS, |
0 | 559 }; |