Mercurial > libavformat.hg
annotate mpeg.c @ 309:6c9fddf8458c libavformat
seeking support - fixed some ADPCM decoding cases
author | bellard |
---|---|
date | Mon, 10 Nov 2003 18:44:27 +0000 |
parents | 62cec412a186 |
children | 944c8edaf609 |
rev | line source |
---|---|
0 | 1 /* |
2 * MPEG1/2 mux/demux | |
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 #include "avformat.h" | |
20 | |
21 #define MAX_PAYLOAD_SIZE 4096 | |
22 #define NB_STREAMS 2 | |
23 | |
24 typedef struct { | |
65 | 25 uint8_t buffer[MAX_PAYLOAD_SIZE]; |
0 | 26 int buffer_ptr; |
65 | 27 uint8_t id; |
0 | 28 int max_buffer_size; /* in bytes */ |
29 int packet_number; | |
65 | 30 int64_t start_pts; |
0 | 31 } StreamInfo; |
32 | |
33 typedef struct { | |
34 int packet_size; /* required packet size */ | |
35 int packet_data_max_size; /* maximum data size inside a packet */ | |
36 int packet_number; | |
37 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | |
38 int system_header_freq; | |
39 int mux_rate; /* bitrate in units of 50 bytes/s */ | |
40 /* stream info */ | |
41 int audio_bound; | |
42 int video_bound; | |
43 int is_mpeg2; | |
44 int is_vcd; | |
45 } MpegMuxContext; | |
46 | |
47 #define PACK_START_CODE ((unsigned int)0x000001ba) | |
48 #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) | |
49 #define SEQUENCE_END_CODE ((unsigned int)0x000001b7) | |
50 #define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) | |
51 #define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) | |
52 #define ISO_11172_END_CODE ((unsigned int)0x000001b9) | |
53 | |
54 /* mpeg2 */ | |
55 #define PROGRAM_STREAM_MAP 0x1bc | |
56 #define PRIVATE_STREAM_1 0x1bd | |
57 #define PADDING_STREAM 0x1be | |
58 #define PRIVATE_STREAM_2 0x1bf | |
59 | |
60 | |
61 #define AUDIO_ID 0xc0 | |
62 #define VIDEO_ID 0xe0 | |
63 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
64 #ifdef CONFIG_ENCODERS |
0 | 65 extern AVOutputFormat mpeg1system_mux; |
66 extern AVOutputFormat mpeg1vcd_mux; | |
67 extern AVOutputFormat mpeg2vob_mux; | |
68 | |
69 static int put_pack_header(AVFormatContext *ctx, | |
65 | 70 uint8_t *buf, int64_t timestamp) |
0 | 71 { |
72 MpegMuxContext *s = ctx->priv_data; | |
73 PutBitContext pb; | |
74 | |
276 | 75 init_put_bits(&pb, buf, 128); |
0 | 76 |
77 put_bits(&pb, 32, PACK_START_CODE); | |
78 if (s->is_mpeg2) { | |
174
7d56e9f83fdb
Write correct MPEG2-PS streams patch by (mru at users dot sourceforge dot net (Mns Rullgrd))
michaelni
parents:
165
diff
changeset
|
79 put_bits(&pb, 2, 0x1); |
0 | 80 } else { |
81 put_bits(&pb, 4, 0x2); | |
82 } | |
65 | 83 put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); |
0 | 84 put_bits(&pb, 1, 1); |
65 | 85 put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); |
0 | 86 put_bits(&pb, 1, 1); |
65 | 87 put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); |
0 | 88 put_bits(&pb, 1, 1); |
89 if (s->is_mpeg2) { | |
90 /* clock extension */ | |
91 put_bits(&pb, 9, 0); | |
92 put_bits(&pb, 1, 1); | |
93 } | |
94 put_bits(&pb, 1, 1); | |
95 put_bits(&pb, 22, s->mux_rate); | |
96 put_bits(&pb, 1, 1); | |
97 if (s->is_mpeg2) { | |
98 put_bits(&pb, 5, 0x1f); /* reserved */ | |
99 put_bits(&pb, 3, 0); /* stuffing length */ | |
100 } | |
101 flush_put_bits(&pb); | |
102 return pbBufPtr(&pb) - pb.buf; | |
103 } | |
104 | |
65 | 105 static int put_system_header(AVFormatContext *ctx, uint8_t *buf) |
0 | 106 { |
107 MpegMuxContext *s = ctx->priv_data; | |
108 int size, rate_bound, i, private_stream_coded, id; | |
109 PutBitContext pb; | |
110 | |
276 | 111 init_put_bits(&pb, buf, 128); |
0 | 112 |
113 put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); | |
114 put_bits(&pb, 16, 0); | |
115 put_bits(&pb, 1, 1); | |
116 | |
117 rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */ | |
118 put_bits(&pb, 22, rate_bound); | |
119 put_bits(&pb, 1, 1); /* marker */ | |
120 put_bits(&pb, 6, s->audio_bound); | |
121 | |
122 put_bits(&pb, 1, 1); /* variable bitrate */ | |
123 put_bits(&pb, 1, 1); /* non constrainted bit stream */ | |
124 | |
125 put_bits(&pb, 1, 0); /* audio locked */ | |
126 put_bits(&pb, 1, 0); /* video locked */ | |
127 put_bits(&pb, 1, 1); /* marker */ | |
128 | |
129 put_bits(&pb, 5, s->video_bound); | |
130 put_bits(&pb, 8, 0xff); /* reserved byte */ | |
131 | |
132 /* audio stream info */ | |
133 private_stream_coded = 0; | |
134 for(i=0;i<ctx->nb_streams;i++) { | |
135 StreamInfo *stream = ctx->streams[i]->priv_data; | |
136 id = stream->id; | |
137 if (id < 0xc0) { | |
138 /* special case for private streams (AC3 use that) */ | |
139 if (private_stream_coded) | |
140 continue; | |
141 private_stream_coded = 1; | |
142 id = 0xbd; | |
143 } | |
144 put_bits(&pb, 8, id); /* stream ID */ | |
145 put_bits(&pb, 2, 3); | |
146 if (id < 0xe0) { | |
147 /* audio */ | |
148 put_bits(&pb, 1, 0); | |
149 put_bits(&pb, 13, stream->max_buffer_size / 128); | |
150 } else { | |
151 /* video */ | |
152 put_bits(&pb, 1, 1); | |
153 put_bits(&pb, 13, stream->max_buffer_size / 1024); | |
154 } | |
155 } | |
156 flush_put_bits(&pb); | |
157 size = pbBufPtr(&pb) - pb.buf; | |
158 /* patch packet size */ | |
159 buf[4] = (size - 6) >> 8; | |
160 buf[5] = (size - 6) & 0xff; | |
161 | |
162 return size; | |
163 } | |
164 | |
165 static int mpeg_mux_init(AVFormatContext *ctx) | |
166 { | |
167 MpegMuxContext *s = ctx->priv_data; | |
168 int bitrate, i, mpa_id, mpv_id, ac3_id; | |
169 AVStream *st; | |
170 StreamInfo *stream; | |
171 | |
172 s->packet_number = 0; | |
173 s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); | |
174 s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux); | |
175 | |
176 if (s->is_vcd) | |
177 s->packet_size = 2324; /* VCD packet size */ | |
178 else | |
179 s->packet_size = 2048; | |
180 | |
181 /* startcode(4) + length(2) + flags(1) */ | |
182 s->packet_data_max_size = s->packet_size - 7; | |
183 s->audio_bound = 0; | |
184 s->video_bound = 0; | |
185 mpa_id = AUDIO_ID; | |
186 ac3_id = 0x80; | |
187 mpv_id = VIDEO_ID; | |
188 for(i=0;i<ctx->nb_streams;i++) { | |
189 st = ctx->streams[i]; | |
190 stream = av_mallocz(sizeof(StreamInfo)); | |
191 if (!stream) | |
192 goto fail; | |
193 st->priv_data = stream; | |
194 | |
195 switch(st->codec.codec_type) { | |
196 case CODEC_TYPE_AUDIO: | |
197 if (st->codec.codec_id == CODEC_ID_AC3) | |
198 stream->id = ac3_id++; | |
199 else | |
200 stream->id = mpa_id++; | |
201 stream->max_buffer_size = 4 * 1024; | |
202 s->audio_bound++; | |
203 break; | |
204 case CODEC_TYPE_VIDEO: | |
205 stream->id = mpv_id++; | |
206 stream->max_buffer_size = 46 * 1024; | |
207 s->video_bound++; | |
208 break; | |
209 default: | |
210 av_abort(); | |
211 } | |
212 } | |
213 | |
214 /* we increase slightly the bitrate to take into account the | |
215 headers. XXX: compute it exactly */ | |
216 bitrate = 2000; | |
217 for(i=0;i<ctx->nb_streams;i++) { | |
218 st = ctx->streams[i]; | |
219 bitrate += st->codec.bit_rate; | |
220 } | |
221 s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); | |
222 | |
223 if (s->is_vcd || s->is_mpeg2) | |
224 /* every packet */ | |
225 s->pack_header_freq = 1; | |
226 else | |
227 /* every 2 seconds */ | |
228 s->pack_header_freq = 2 * bitrate / s->packet_size / 8; | |
291
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
229 |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
230 /* the above seems to make pack_header_freq zero sometimes */ |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
231 if (s->pack_header_freq == 0) |
b19f70a6d60f
1/0 fix by (Tim Allen <tim at proximity dot com dot au>)
michael
parents:
277
diff
changeset
|
232 s->pack_header_freq = 1; |
0 | 233 |
234 if (s->is_mpeg2) | |
235 /* every 200 packets. Need to look at the spec. */ | |
236 s->system_header_freq = s->pack_header_freq * 40; | |
237 else if (s->is_vcd) | |
238 /* every 40 packets, this is my invention */ | |
239 s->system_header_freq = s->pack_header_freq * 40; | |
240 else | |
241 s->system_header_freq = s->pack_header_freq * 5; | |
242 | |
243 for(i=0;i<ctx->nb_streams;i++) { | |
244 stream = ctx->streams[i]->priv_data; | |
245 stream->buffer_ptr = 0; | |
246 stream->packet_number = 0; | |
247 stream->start_pts = -1; | |
248 } | |
249 return 0; | |
250 fail: | |
251 for(i=0;i<ctx->nb_streams;i++) { | |
252 av_free(ctx->streams[i]->priv_data); | |
253 } | |
254 return -ENOMEM; | |
255 } | |
256 | |
257 /* flush the packet on stream stream_index */ | |
242 | 258 static void flush_packet(AVFormatContext *ctx, int stream_index) |
0 | 259 { |
260 MpegMuxContext *s = ctx->priv_data; | |
261 StreamInfo *stream = ctx->streams[stream_index]->priv_data; | |
65 | 262 uint8_t *buf_ptr; |
0 | 263 int size, payload_size, startcode, id, len, stuffing_size, i, header_len; |
65 | 264 int64_t timestamp; |
265 uint8_t buffer[128]; | |
0 | 266 |
267 id = stream->id; | |
268 timestamp = stream->start_pts; | |
269 | |
270 #if 0 | |
271 printf("packet ID=%2x PTS=%0.3f\n", | |
272 id, timestamp / 90000.0); | |
273 #endif | |
274 | |
275 buf_ptr = buffer; | |
276 if (((s->packet_number % s->pack_header_freq) == 0)) { | |
277 /* output pack and systems header if needed */ | |
278 size = put_pack_header(ctx, buf_ptr, timestamp); | |
279 buf_ptr += size; | |
280 if ((s->packet_number % s->system_header_freq) == 0) { | |
281 size = put_system_header(ctx, buf_ptr); | |
282 buf_ptr += size; | |
283 } | |
284 } | |
285 size = buf_ptr - buffer; | |
286 put_buffer(&ctx->pb, buffer, size); | |
287 | |
288 /* packet header */ | |
289 if (s->is_mpeg2) { | |
290 header_len = 8; | |
291 } else { | |
292 header_len = 5; | |
293 } | |
242 | 294 payload_size = s->packet_size - (size + 6 + header_len); |
0 | 295 if (id < 0xc0) { |
296 startcode = PRIVATE_STREAM_1; | |
297 payload_size -= 4; | |
298 } else { | |
299 startcode = 0x100 + id; | |
300 } | |
301 stuffing_size = payload_size - stream->buffer_ptr; | |
302 if (stuffing_size < 0) | |
303 stuffing_size = 0; | |
304 | |
305 put_be32(&ctx->pb, startcode); | |
306 | |
307 put_be16(&ctx->pb, payload_size + header_len); | |
308 /* stuffing */ | |
309 for(i=0;i<stuffing_size;i++) | |
310 put_byte(&ctx->pb, 0xff); | |
311 | |
312 if (s->is_mpeg2) { | |
313 put_byte(&ctx->pb, 0x80); /* mpeg2 id */ | |
314 put_byte(&ctx->pb, 0x80); /* flags */ | |
315 put_byte(&ctx->pb, 0x05); /* header len (only pts is included) */ | |
316 } | |
317 put_byte(&ctx->pb, | |
318 (0x02 << 4) | | |
319 (((timestamp >> 30) & 0x07) << 1) | | |
320 1); | |
65 | 321 put_be16(&ctx->pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); |
322 put_be16(&ctx->pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); | |
0 | 323 |
324 if (startcode == PRIVATE_STREAM_1) { | |
325 put_byte(&ctx->pb, id); | |
326 if (id >= 0x80 && id <= 0xbf) { | |
327 /* XXX: need to check AC3 spec */ | |
328 put_byte(&ctx->pb, 1); | |
329 put_byte(&ctx->pb, 0); | |
330 put_byte(&ctx->pb, 2); | |
331 } | |
332 } | |
333 | |
334 /* output data */ | |
335 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); | |
336 put_flush_packet(&ctx->pb); | |
337 | |
338 /* preserve remaining data */ | |
339 len = stream->buffer_ptr - payload_size; | |
340 if (len < 0) | |
341 len = 0; | |
342 memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len); | |
343 stream->buffer_ptr = len; | |
344 | |
345 s->packet_number++; | |
346 stream->packet_number++; | |
347 stream->start_pts = -1; | |
348 } | |
349 | |
350 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, | |
241 | 351 const uint8_t *buf, int size, int64_t pts) |
0 | 352 { |
353 MpegMuxContext *s = ctx->priv_data; | |
354 AVStream *st = ctx->streams[stream_index]; | |
355 StreamInfo *stream = st->priv_data; | |
356 int len; | |
357 | |
358 while (size > 0) { | |
359 /* set pts */ | |
360 if (stream->start_pts == -1) { | |
361 stream->start_pts = pts; | |
362 } | |
363 len = s->packet_data_max_size - stream->buffer_ptr; | |
364 if (len > size) | |
365 len = size; | |
366 memcpy(stream->buffer + stream->buffer_ptr, buf, len); | |
367 stream->buffer_ptr += len; | |
368 buf += len; | |
369 size -= len; | |
370 while (stream->buffer_ptr >= s->packet_data_max_size) { | |
371 /* output the packet */ | |
372 if (stream->start_pts == -1) | |
373 stream->start_pts = pts; | |
242 | 374 flush_packet(ctx, stream_index); |
0 | 375 } |
376 } | |
377 return 0; | |
378 } | |
379 | |
380 static int mpeg_mux_end(AVFormatContext *ctx) | |
381 { | |
382 StreamInfo *stream; | |
383 int i; | |
384 | |
385 /* flush each packet */ | |
386 for(i=0;i<ctx->nb_streams;i++) { | |
387 stream = ctx->streams[i]->priv_data; | |
388 if (stream->buffer_ptr > 0) { | |
242 | 389 flush_packet(ctx, i); |
0 | 390 } |
391 } | |
392 | |
242 | 393 /* End header according to MPEG1 systems standard. We do not write |
394 it as it is usually not needed by decoders and because it | |
395 complicates MPEG stream concatenation. */ | |
0 | 396 //put_be32(&ctx->pb, ISO_11172_END_CODE); |
397 //put_flush_packet(&ctx->pb); | |
237
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
398 |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
399 for(i=0;i<ctx->nb_streams;i++) |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
400 av_freep(&ctx->streams[i]->priv_data); |
35231c0be8e5
memleak fix by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michaelni
parents:
210
diff
changeset
|
401 |
0 | 402 return 0; |
403 } | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
404 #endif //CONFIG_ENCODERS |
0 | 405 |
406 /*********************************************/ | |
407 /* demux code */ | |
408 | |
409 #define MAX_SYNC_SIZE 100000 | |
410 | |
411 static int mpegps_probe(AVProbeData *p) | |
412 { | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
413 int code, c, i; |
0 | 414 |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
415 code = 0xff; |
0 | 416 /* we search the first start code. If it is a packet start code, |
417 then we decide it is mpeg ps. We do not send highest value to | |
418 give a chance to mpegts */ | |
49 | 419 /* NOTE: the search range was restricted to avoid too many false |
420 detections */ | |
421 | |
422 if (p->buf_size < 6) | |
423 return 0; | |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
424 |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
425 for (i = 0; i < 20; i++) { |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
426 c = p->buf[i]; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
427 code = (code << 8) | c; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
428 if ((code & 0xffffff00) == 0x100) { |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
429 if (code == PACK_START_CODE || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
430 code == SYSTEM_HEADER_START_CODE || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
431 (code >= 0x1e0 && code <= 0x1ef) || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
432 (code >= 0x1c0 && code <= 0x1df) || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
433 code == PRIVATE_STREAM_2 || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
434 code == PROGRAM_STREAM_MAP || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
435 code == PRIVATE_STREAM_1 || |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
436 code == PADDING_STREAM) |
210 | 437 return AVPROBE_SCORE_MAX - 2; |
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
438 else |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
439 return 0; |
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
440 } |
0 | 441 } |
442 return 0; | |
443 } | |
444 | |
445 | |
446 typedef struct MpegDemuxContext { | |
447 int header_state; | |
448 } MpegDemuxContext; | |
449 | |
450 static int find_start_code(ByteIOContext *pb, int *size_ptr, | |
65 | 451 uint32_t *header_state) |
0 | 452 { |
453 unsigned int state, v; | |
454 int val, n; | |
455 | |
456 state = *header_state; | |
457 n = *size_ptr; | |
458 while (n > 0) { | |
459 if (url_feof(pb)) | |
460 break; | |
461 v = get_byte(pb); | |
462 n--; | |
463 if (state == 0x000001) { | |
464 state = ((state << 8) | v) & 0xffffff; | |
465 val = state; | |
466 goto found; | |
467 } | |
468 state = ((state << 8) | v) & 0xffffff; | |
469 } | |
470 val = -1; | |
471 found: | |
472 *header_state = state; | |
473 *size_ptr = n; | |
474 return val; | |
475 } | |
476 | |
477 static int mpegps_read_header(AVFormatContext *s, | |
478 AVFormatParameters *ap) | |
479 { | |
480 MpegDemuxContext *m = s->priv_data; | |
481 m->header_state = 0xff; | |
293
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
482 s->ctx_flags |= AVFMTCTX_NOHEADER; |
62cec412a186
make AVFMT_NOHEADER flag dynamic - added av_open_input_stream()
bellard
parents:
291
diff
changeset
|
483 |
0 | 484 /* no need to do more */ |
485 return 0; | |
486 } | |
487 | |
65 | 488 static int64_t get_pts(ByteIOContext *pb, int c) |
0 | 489 { |
65 | 490 int64_t pts; |
0 | 491 int val; |
492 | |
493 if (c < 0) | |
494 c = get_byte(pb); | |
65 | 495 pts = (int64_t)((c >> 1) & 0x07) << 30; |
0 | 496 val = get_be16(pb); |
65 | 497 pts |= (int64_t)(val >> 1) << 15; |
0 | 498 val = get_be16(pb); |
65 | 499 pts |= (int64_t)(val >> 1); |
0 | 500 return pts; |
501 } | |
502 | |
503 static int mpegps_read_packet(AVFormatContext *s, | |
504 AVPacket *pkt) | |
505 { | |
506 MpegDemuxContext *m = s->priv_data; | |
507 AVStream *st; | |
508 int len, size, startcode, i, c, flags, header_len, type, codec_id; | |
65 | 509 int64_t pts, dts; |
0 | 510 |
511 /* next start code (should be immediately after) */ | |
512 redo: | |
513 m->header_state = 0xff; | |
514 size = MAX_SYNC_SIZE; | |
515 startcode = find_start_code(&s->pb, &size, &m->header_state); | |
516 //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); | |
517 if (startcode < 0) | |
518 return -EIO; | |
519 if (startcode == PACK_START_CODE) | |
520 goto redo; | |
521 if (startcode == SYSTEM_HEADER_START_CODE) | |
522 goto redo; | |
523 if (startcode == PADDING_STREAM || | |
524 startcode == PRIVATE_STREAM_2) { | |
525 /* skip them */ | |
526 len = get_be16(&s->pb); | |
527 url_fskip(&s->pb, len); | |
528 goto redo; | |
529 } | |
530 /* find matching stream */ | |
531 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
532 (startcode >= 0x1e0 && startcode <= 0x1ef) || | |
533 (startcode == 0x1bd))) | |
534 goto redo; | |
535 | |
536 len = get_be16(&s->pb); | |
537 pts = AV_NOPTS_VALUE; | |
538 dts = AV_NOPTS_VALUE; | |
539 /* stuffing */ | |
540 for(;;) { | |
541 c = get_byte(&s->pb); | |
542 len--; | |
543 /* XXX: for mpeg1, should test only bit 7 */ | |
544 if (c != 0xff) | |
545 break; | |
546 } | |
547 if ((c & 0xc0) == 0x40) { | |
548 /* buffer scale & size */ | |
549 get_byte(&s->pb); | |
550 c = get_byte(&s->pb); | |
551 len -= 2; | |
552 } | |
553 if ((c & 0xf0) == 0x20) { | |
554 pts = get_pts(&s->pb, c); | |
555 len -= 4; | |
556 } else if ((c & 0xf0) == 0x30) { | |
557 pts = get_pts(&s->pb, c); | |
558 dts = get_pts(&s->pb, -1); | |
559 len -= 9; | |
560 } else if ((c & 0xc0) == 0x80) { | |
561 /* mpeg 2 PES */ | |
562 if ((c & 0x30) != 0) { | |
563 fprintf(stderr, "Encrypted multiplex not handled\n"); | |
564 return -EIO; | |
565 } | |
566 flags = get_byte(&s->pb); | |
567 header_len = get_byte(&s->pb); | |
568 len -= 2; | |
569 if (header_len > len) | |
570 goto redo; | |
571 if ((flags & 0xc0) == 0x80) { | |
572 pts = get_pts(&s->pb, -1); | |
573 header_len -= 5; | |
574 len -= 5; | |
575 } if ((flags & 0xc0) == 0xc0) { | |
576 pts = get_pts(&s->pb, -1); | |
577 dts = get_pts(&s->pb, -1); | |
578 header_len -= 10; | |
579 len -= 10; | |
580 } | |
581 len -= header_len; | |
582 while (header_len > 0) { | |
583 get_byte(&s->pb); | |
584 header_len--; | |
585 } | |
586 } | |
587 if (startcode == 0x1bd) { | |
588 startcode = get_byte(&s->pb); | |
589 len--; | |
590 if (startcode >= 0x80 && startcode <= 0xbf) { | |
591 /* audio: skip header */ | |
592 get_byte(&s->pb); | |
593 get_byte(&s->pb); | |
594 get_byte(&s->pb); | |
595 len -= 3; | |
596 } | |
597 } | |
598 | |
599 /* now find stream */ | |
600 for(i=0;i<s->nb_streams;i++) { | |
601 st = s->streams[i]; | |
602 if (st->id == startcode) | |
603 goto found; | |
604 } | |
605 if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
606 type = CODEC_TYPE_VIDEO; | |
607 codec_id = CODEC_ID_MPEG1VIDEO; | |
608 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { | |
609 type = CODEC_TYPE_AUDIO; | |
610 codec_id = CODEC_ID_MP2; | |
611 } else if (startcode >= 0x80 && startcode <= 0x9f) { | |
612 type = CODEC_TYPE_AUDIO; | |
613 codec_id = CODEC_ID_AC3; | |
41 | 614 } else if (startcode >= 0xa0 && startcode <= 0xbf) { |
615 type = CODEC_TYPE_AUDIO; | |
616 codec_id = CODEC_ID_PCM_S16BE; | |
0 | 617 } else { |
618 skip: | |
619 /* skip packet */ | |
620 url_fskip(&s->pb, len); | |
621 goto redo; | |
622 } | |
623 /* no stream found: add a new stream */ | |
624 st = av_new_stream(s, startcode); | |
625 if (!st) | |
626 goto skip; | |
627 st->codec.codec_type = type; | |
628 st->codec.codec_id = codec_id; | |
629 found: | |
41 | 630 if (startcode >= 0xa0 && startcode <= 0xbf) { |
631 int b1, freq; | |
632 static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; | |
633 | |
634 /* for LPCM, we just skip the header and consider it is raw | |
635 audio data */ | |
636 if (len <= 3) | |
637 goto skip; | |
638 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
639 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
640 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
641 len -= 3; | |
642 freq = (b1 >> 4) & 3; | |
643 st->codec.sample_rate = lpcm_freq_tab[freq]; | |
644 st->codec.channels = 1 + (b1 & 7); | |
645 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; | |
646 } | |
0 | 647 av_new_packet(pkt, len); |
648 //printf("\nRead Packet ID: %x PTS: %f Size: %d", startcode, | |
649 // (float)pts/90000, len); | |
650 get_buffer(&s->pb, pkt->data, pkt->size); | |
651 pkt->pts = pts; | |
652 pkt->stream_index = st->index; | |
653 return 0; | |
654 } | |
655 | |
656 static int mpegps_read_close(AVFormatContext *s) | |
657 { | |
658 return 0; | |
659 } | |
660 | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
661 #ifdef CONFIG_ENCODERS |
0 | 662 static AVOutputFormat mpeg1system_mux = { |
663 "mpeg", | |
664 "MPEG1 System format", | |
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
665 "video/mpeg", |
0 | 666 "mpg,mpeg", |
667 sizeof(MpegMuxContext), | |
668 CODEC_ID_MP2, | |
669 CODEC_ID_MPEG1VIDEO, | |
670 mpeg_mux_init, | |
671 mpeg_mux_write_packet, | |
672 mpeg_mux_end, | |
673 }; | |
674 | |
675 static AVOutputFormat mpeg1vcd_mux = { | |
676 "vcd", | |
677 "MPEG1 System format (VCD)", | |
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
678 "video/mpeg", |
0 | 679 NULL, |
680 sizeof(MpegMuxContext), | |
681 CODEC_ID_MP2, | |
682 CODEC_ID_MPEG1VIDEO, | |
683 mpeg_mux_init, | |
684 mpeg_mux_write_packet, | |
685 mpeg_mux_end, | |
686 }; | |
687 | |
688 static AVOutputFormat mpeg2vob_mux = { | |
689 "vob", | |
690 "MPEG2 PS format (VOB)", | |
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
691 "video/mpeg", |
0 | 692 "vob", |
693 sizeof(MpegMuxContext), | |
694 CODEC_ID_MP2, | |
695 CODEC_ID_MPEG1VIDEO, | |
696 mpeg_mux_init, | |
697 mpeg_mux_write_packet, | |
698 mpeg_mux_end, | |
699 }; | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
700 #endif //CONFIG_ENCODERS |
0 | 701 |
190 | 702 AVInputFormat mpegps_demux = { |
0 | 703 "mpeg", |
704 "MPEG PS format", | |
705 sizeof(MpegDemuxContext), | |
706 mpegps_probe, | |
707 mpegps_read_header, | |
708 mpegps_read_packet, | |
709 mpegps_read_close, | |
710 }; | |
711 | |
712 int mpegps_init(void) | |
713 { | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
714 #ifdef CONFIG_ENCODERS |
0 | 715 av_register_output_format(&mpeg1system_mux); |
716 av_register_output_format(&mpeg1vcd_mux); | |
717 av_register_output_format(&mpeg2vob_mux); | |
277
a313e1080322
disable encoders where appropriate (patch courtesy of BERO
melanson
parents:
276
diff
changeset
|
718 #endif //CONFIG_ENCODERS |
0 | 719 av_register_input_format(&mpegps_demux); |
720 return 0; | |
721 } |