caching of timestamps for mpeg-ps so seeking is faster
[libav.git] / libavformat / mpeg.c
CommitLineData
de6d9b64 1/*
fb7566d0 2 * MPEG1/2 mux/demux
19720f15 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
de6d9b64 4 *
19720f15
FB
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.
de6d9b64 9 *
19720f15 10 * This library is distributed in the hope that it will be useful,
de6d9b64 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
de6d9b64 14 *
19720f15
FB
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
de6d9b64 18 */
de6d9b64
FB
19#include "avformat.h"
20
21#define MAX_PAYLOAD_SIZE 4096
27f388aa 22//#define DEBUG_SEEK
de6d9b64 23
b754978a
MN
24#undef NDEBUG
25#include <assert.h>
26
de6d9b64 27typedef struct {
0c1a9eda 28 uint8_t buffer[MAX_PAYLOAD_SIZE];
de6d9b64 29 int buffer_ptr;
0dbb48d9
FB
30 int nb_frames; /* number of starting frame encountered (AC3) */
31 int frame_start_offset; /* starting offset of the frame + 1 (0 if none) */
0c1a9eda 32 uint8_t id;
de6d9b64
FB
33 int max_buffer_size; /* in bytes */
34 int packet_number;
0c1a9eda 35 int64_t start_pts;
27a206e0 36 int64_t start_dts;
044007c2
FB
37 uint8_t lpcm_header[3];
38 int lpcm_align;
de6d9b64
FB
39} StreamInfo;
40
41typedef struct {
42 int packet_size; /* required packet size */
de6d9b64
FB
43 int packet_number;
44 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */
45 int system_header_freq;
0dbb48d9 46 int system_header_size;
de6d9b64
FB
47 int mux_rate; /* bitrate in units of 50 bytes/s */
48 /* stream info */
49 int audio_bound;
50 int video_bound;
fb7566d0
FB
51 int is_mpeg2;
52 int is_vcd;
27a206e0
MB
53 int scr_stream_index; /* stream from which the system clock is
54 computed (VBR case) */
55 int64_t last_scr; /* current system clock */
de6d9b64
FB
56} MpegMuxContext;
57
58#define PACK_START_CODE ((unsigned int)0x000001ba)
59#define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb)
92b3e125 60#define SEQUENCE_END_CODE ((unsigned int)0x000001b7)
de6d9b64
FB
61#define PACKET_START_CODE_MASK ((unsigned int)0xffffff00)
62#define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100)
63#define ISO_11172_END_CODE ((unsigned int)0x000001b9)
64
65/* mpeg2 */
66#define PROGRAM_STREAM_MAP 0x1bc
67#define PRIVATE_STREAM_1 0x1bd
68#define PADDING_STREAM 0x1be
69#define PRIVATE_STREAM_2 0x1bf
70
71
72#define AUDIO_ID 0xc0
73#define VIDEO_ID 0xe0
044007c2
FB
74#define AC3_ID 0x80
75#define LPCM_ID 0xa0
de6d9b64 76
764ef400 77#ifdef CONFIG_ENCODERS
fb7566d0
FB
78extern AVOutputFormat mpeg1system_mux;
79extern AVOutputFormat mpeg1vcd_mux;
80extern AVOutputFormat mpeg2vob_mux;
81
044007c2
FB
82static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
83
de6d9b64 84static int put_pack_header(AVFormatContext *ctx,
0c1a9eda 85 uint8_t *buf, int64_t timestamp)
de6d9b64
FB
86{
87 MpegMuxContext *s = ctx->priv_data;
88 PutBitContext pb;
89
117a5490 90 init_put_bits(&pb, buf, 128);
de6d9b64
FB
91
92 put_bits(&pb, 32, PACK_START_CODE);
b2cac184 93 if (s->is_mpeg2) {
8683e4a0 94 put_bits(&pb, 2, 0x1);
b2cac184
FB
95 } else {
96 put_bits(&pb, 4, 0x2);
97 }
0c1a9eda 98 put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07));
de6d9b64 99 put_bits(&pb, 1, 1);
0c1a9eda 100 put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff));
de6d9b64 101 put_bits(&pb, 1, 1);
0c1a9eda 102 put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff));
de6d9b64 103 put_bits(&pb, 1, 1);
b2cac184
FB
104 if (s->is_mpeg2) {
105 /* clock extension */
106 put_bits(&pb, 9, 0);
107 put_bits(&pb, 1, 1);
108 }
de6d9b64
FB
109 put_bits(&pb, 1, 1);
110 put_bits(&pb, 22, s->mux_rate);
111 put_bits(&pb, 1, 1);
b2cac184
FB
112 if (s->is_mpeg2) {
113 put_bits(&pb, 5, 0x1f); /* reserved */
114 put_bits(&pb, 3, 0); /* stuffing length */
115 }
de6d9b64 116 flush_put_bits(&pb);
17592475 117 return pbBufPtr(&pb) - pb.buf;
de6d9b64
FB
118}
119
0c1a9eda 120static int put_system_header(AVFormatContext *ctx, uint8_t *buf)
de6d9b64
FB
121{
122 MpegMuxContext *s = ctx->priv_data;
123 int size, rate_bound, i, private_stream_coded, id;
124 PutBitContext pb;
125
117a5490 126 init_put_bits(&pb, buf, 128);
de6d9b64
FB
127
128 put_bits(&pb, 32, SYSTEM_HEADER_START_CODE);
129 put_bits(&pb, 16, 0);
130 put_bits(&pb, 1, 1);
131
132 rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */
133 put_bits(&pb, 22, rate_bound);
134 put_bits(&pb, 1, 1); /* marker */
135 put_bits(&pb, 6, s->audio_bound);
136
137 put_bits(&pb, 1, 1); /* variable bitrate */
138 put_bits(&pb, 1, 1); /* non constrainted bit stream */
139
140 put_bits(&pb, 1, 0); /* audio locked */
141 put_bits(&pb, 1, 0); /* video locked */
142 put_bits(&pb, 1, 1); /* marker */
143
144 put_bits(&pb, 5, s->video_bound);
145 put_bits(&pb, 8, 0xff); /* reserved byte */
146
147 /* audio stream info */
148 private_stream_coded = 0;
149 for(i=0;i<ctx->nb_streams;i++) {
150 StreamInfo *stream = ctx->streams[i]->priv_data;
151 id = stream->id;
152 if (id < 0xc0) {
153 /* special case for private streams (AC3 use that) */
154 if (private_stream_coded)
155 continue;
156 private_stream_coded = 1;
157 id = 0xbd;
158 }
159 put_bits(&pb, 8, id); /* stream ID */
160 put_bits(&pb, 2, 3);
161 if (id < 0xe0) {
162 /* audio */
163 put_bits(&pb, 1, 0);
164 put_bits(&pb, 13, stream->max_buffer_size / 128);
165 } else {
166 /* video */
167 put_bits(&pb, 1, 1);
168 put_bits(&pb, 13, stream->max_buffer_size / 1024);
169 }
170 }
171 flush_put_bits(&pb);
17592475 172 size = pbBufPtr(&pb) - pb.buf;
de6d9b64
FB
173 /* patch packet size */
174 buf[4] = (size - 6) >> 8;
175 buf[5] = (size - 6) & 0xff;
176
177 return size;
178}
179
0dbb48d9
FB
180static int get_system_header_size(AVFormatContext *ctx)
181{
182 int buf_index, i, private_stream_coded;
183 StreamInfo *stream;
184
185 buf_index = 12;
186 private_stream_coded = 0;
187 for(i=0;i<ctx->nb_streams;i++) {
188 stream = ctx->streams[i]->priv_data;
189 if (stream->id < 0xc0) {
190 if (private_stream_coded)
191 continue;
192 private_stream_coded = 1;
193 }
194 buf_index += 3;
195 }
196 return buf_index;
197}
198
de6d9b64
FB
199static int mpeg_mux_init(AVFormatContext *ctx)
200{
db7f1f95 201 MpegMuxContext *s = ctx->priv_data;
044007c2 202 int bitrate, i, mpa_id, mpv_id, ac3_id, lpcm_id, j;
de6d9b64
FB
203 AVStream *st;
204 StreamInfo *stream;
205
de6d9b64 206 s->packet_number = 0;
fb7566d0
FB
207 s->is_vcd = (ctx->oformat == &mpeg1vcd_mux);
208 s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux);
209
210 if (s->is_vcd)
92b3e125
J
211 s->packet_size = 2324; /* VCD packet size */
212 else
213 s->packet_size = 2048;
214
de6d9b64
FB
215 s->audio_bound = 0;
216 s->video_bound = 0;
217 mpa_id = AUDIO_ID;
044007c2 218 ac3_id = AC3_ID;
de6d9b64 219 mpv_id = VIDEO_ID;
044007c2 220 lpcm_id = LPCM_ID;
27a206e0 221 s->scr_stream_index = -1;
de6d9b64
FB
222 for(i=0;i<ctx->nb_streams;i++) {
223 st = ctx->streams[i];
224 stream = av_mallocz(sizeof(StreamInfo));
225 if (!stream)
226 goto fail;
227 st->priv_data = stream;
228
229 switch(st->codec.codec_type) {
230 case CODEC_TYPE_AUDIO:
044007c2 231 if (st->codec.codec_id == CODEC_ID_AC3) {
de6d9b64 232 stream->id = ac3_id++;
044007c2
FB
233 } else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) {
234 stream->id = lpcm_id++;
235 for(j = 0; j < 4; j++) {
236 if (lpcm_freq_tab[j] == st->codec.sample_rate)
237 break;
238 }
239 if (j == 4)
240 goto fail;
241 if (st->codec.channels > 8)
242 return -1;
243 stream->lpcm_header[0] = 0x0c;
244 stream->lpcm_header[1] = (st->codec.channels - 1) | (j << 4);
245 stream->lpcm_header[2] = 0x80;
246 stream->lpcm_align = st->codec.channels * 2;
247 } else {
de6d9b64 248 stream->id = mpa_id++;
044007c2 249 }
de6d9b64
FB
250 stream->max_buffer_size = 4 * 1024;
251 s->audio_bound++;
252 break;
253 case CODEC_TYPE_VIDEO:
27a206e0
MB
254 /* by default, video is used for the SCR computation */
255 if (s->scr_stream_index == -1)
256 s->scr_stream_index = i;
de6d9b64
FB
257 stream->id = mpv_id++;
258 stream->max_buffer_size = 46 * 1024;
259 s->video_bound++;
260 break;
ac5e6a5b 261 default:
42343f7e 262 av_abort();
de6d9b64
FB
263 }
264 }
27a206e0
MB
265 /* if no SCR, use first stream (audio) */
266 if (s->scr_stream_index == -1)
267 s->scr_stream_index = 0;
de6d9b64
FB
268
269 /* we increase slightly the bitrate to take into account the
270 headers. XXX: compute it exactly */
271 bitrate = 2000;
272 for(i=0;i<ctx->nb_streams;i++) {
273 st = ctx->streams[i];
274 bitrate += st->codec.bit_rate;
275 }
276 s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
92b3e125 277
fb7566d0 278 if (s->is_vcd || s->is_mpeg2)
92b3e125
J
279 /* every packet */
280 s->pack_header_freq = 1;
281 else
282 /* every 2 seconds */
283 s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
b623bbcb
MN
284
285 /* the above seems to make pack_header_freq zero sometimes */
286 if (s->pack_header_freq == 0)
287 s->pack_header_freq = 1;
92b3e125 288
b2cac184
FB
289 if (s->is_mpeg2)
290 /* every 200 packets. Need to look at the spec. */
291 s->system_header_freq = s->pack_header_freq * 40;
292 else if (s->is_vcd)
92b3e125
J
293 /* every 40 packets, this is my invention */
294 s->system_header_freq = s->pack_header_freq * 40;
295 else
92b3e125
J
296 s->system_header_freq = s->pack_header_freq * 5;
297
de6d9b64
FB
298 for(i=0;i<ctx->nb_streams;i++) {
299 stream = ctx->streams[i]->priv_data;
300 stream->buffer_ptr = 0;
301 stream->packet_number = 0;
27a206e0
MB
302 stream->start_pts = AV_NOPTS_VALUE;
303 stream->start_dts = AV_NOPTS_VALUE;
de6d9b64 304 }
0dbb48d9 305 s->system_header_size = get_system_header_size(ctx);
27a206e0 306 s->last_scr = 0;
de6d9b64
FB
307 return 0;
308 fail:
309 for(i=0;i<ctx->nb_streams;i++) {
1ea4f593 310 av_free(ctx->streams[i]->priv_data);
de6d9b64 311 }
de6d9b64
FB
312 return -ENOMEM;
313}
314
27a206e0
MB
315static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp)
316{
317 put_byte(pb,
318 (id << 4) |
319 (((timestamp >> 30) & 0x07) << 1) |
320 1);
321 put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1));
322 put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1));
323}
324
0dbb48d9
FB
325
326/* return the exact available payload size for the next packet for
327 stream 'stream_index'. 'pts' and 'dts' are only used to know if
328 timestamps are needed in the packet header. */
329static int get_packet_payload_size(AVFormatContext *ctx, int stream_index,
330 int64_t pts, int64_t dts)
331{
332 MpegMuxContext *s = ctx->priv_data;
333 int buf_index;
334 StreamInfo *stream;
335
336 buf_index = 0;
337 if (((s->packet_number % s->pack_header_freq) == 0)) {
338 /* pack header size */
339 if (s->is_mpeg2)
340 buf_index += 14;
341 else
342 buf_index += 12;
343 if ((s->packet_number % s->system_header_freq) == 0)
344 buf_index += s->system_header_size;
345 }
346
347 /* packet header size */
348 buf_index += 6;
349 if (s->is_mpeg2)
350 buf_index += 3;
351 if (pts != AV_NOPTS_VALUE) {
e45f1943 352 if (dts != pts)
0dbb48d9
FB
353 buf_index += 5 + 5;
354 else
355 buf_index += 5;
356 } else {
357 if (!s->is_mpeg2)
358 buf_index++;
359 }
360
361 stream = ctx->streams[stream_index]->priv_data;
362 if (stream->id < 0xc0) {
044007c2 363 /* AC3/LPCM private data header */
0dbb48d9 364 buf_index += 4;
044007c2
FB
365 if (stream->id >= 0xa0) {
366 int n;
367 buf_index += 3;
368 /* NOTE: we round the payload size to an integer number of
369 LPCM samples */
370 n = (s->packet_size - buf_index) % stream->lpcm_align;
371 if (n)
372 buf_index += (stream->lpcm_align - n);
373 }
0dbb48d9
FB
374 }
375 return s->packet_size - buf_index;
376}
377
de6d9b64 378/* flush the packet on stream stream_index */
27a206e0
MB
379static void flush_packet(AVFormatContext *ctx, int stream_index,
380 int64_t pts, int64_t dts, int64_t scr)
de6d9b64
FB
381{
382 MpegMuxContext *s = ctx->priv_data;
383 StreamInfo *stream = ctx->streams[stream_index]->priv_data;
0c1a9eda 384 uint8_t *buf_ptr;
0dbb48d9
FB
385 int size, payload_size, startcode, id, stuffing_size, i, header_len;
386 int packet_size;
0c1a9eda 387 uint8_t buffer[128];
92b3e125 388
de6d9b64 389 id = stream->id;
27a206e0 390
de6d9b64
FB
391#if 0
392 printf("packet ID=%2x PTS=%0.3f\n",
27a206e0 393 id, pts / 90000.0);
de6d9b64
FB
394#endif
395
396 buf_ptr = buffer;
92b3e125 397 if (((s->packet_number % s->pack_header_freq) == 0)) {
de6d9b64 398 /* output pack and systems header if needed */
27a206e0 399 size = put_pack_header(ctx, buf_ptr, scr);
de6d9b64
FB
400 buf_ptr += size;
401 if ((s->packet_number % s->system_header_freq) == 0) {
402 size = put_system_header(ctx, buf_ptr);
403 buf_ptr += size;
404 }
405 }
406 size = buf_ptr - buffer;
407 put_buffer(&ctx->pb, buffer, size);
408
409 /* packet header */
fb7566d0 410 if (s->is_mpeg2) {
27a206e0 411 header_len = 3;
fb7566d0 412 } else {
27a206e0 413 header_len = 0;
fb7566d0 414 }
27a206e0 415 if (pts != AV_NOPTS_VALUE) {
e45f1943 416 if (dts != pts)
27a206e0
MB
417 header_len += 5 + 5;
418 else
419 header_len += 5;
420 } else {
421 if (!s->is_mpeg2)
422 header_len++;
423 }
424
0dbb48d9
FB
425 packet_size = s->packet_size - (size + 6);
426 payload_size = packet_size - header_len;
de6d9b64
FB
427 if (id < 0xc0) {
428 startcode = PRIVATE_STREAM_1;
429 payload_size -= 4;
044007c2
FB
430 if (id >= 0xa0)
431 payload_size -= 3;
de6d9b64
FB
432 } else {
433 startcode = 0x100 + id;
434 }
0dbb48d9 435
de6d9b64
FB
436 stuffing_size = payload_size - stream->buffer_ptr;
437 if (stuffing_size < 0)
438 stuffing_size = 0;
de6d9b64
FB
439 put_be32(&ctx->pb, startcode);
440
0dbb48d9 441 put_be16(&ctx->pb, packet_size);
de6d9b64
FB
442 /* stuffing */
443 for(i=0;i<stuffing_size;i++)
444 put_byte(&ctx->pb, 0xff);
fb7566d0
FB
445
446 if (s->is_mpeg2) {
447 put_byte(&ctx->pb, 0x80); /* mpeg2 id */
27a206e0
MB
448
449 if (pts != AV_NOPTS_VALUE) {
e45f1943 450 if (dts != pts) {
27a206e0
MB
451 put_byte(&ctx->pb, 0xc0); /* flags */
452 put_byte(&ctx->pb, header_len - 3);
453 put_timestamp(&ctx->pb, 0x03, pts);
454 put_timestamp(&ctx->pb, 0x01, dts);
455 } else {
456 put_byte(&ctx->pb, 0x80); /* flags */
457 put_byte(&ctx->pb, header_len - 3);
458 put_timestamp(&ctx->pb, 0x02, pts);
459 }
460 } else {
461 put_byte(&ctx->pb, 0x00); /* flags */
462 put_byte(&ctx->pb, header_len - 3);
463 }
464 } else {
465 if (pts != AV_NOPTS_VALUE) {
e45f1943 466 if (dts != pts) {
27a206e0
MB
467 put_timestamp(&ctx->pb, 0x03, pts);
468 put_timestamp(&ctx->pb, 0x01, dts);
469 } else {
470 put_timestamp(&ctx->pb, 0x02, pts);
471 }
472 } else {
473 put_byte(&ctx->pb, 0x0f);
474 }
fb7566d0 475 }
de6d9b64
FB
476
477 if (startcode == PRIVATE_STREAM_1) {
478 put_byte(&ctx->pb, id);
044007c2
FB
479 if (id >= 0xa0) {
480 /* LPCM (XXX: check nb_frames) */
481 put_byte(&ctx->pb, 7);
482 put_be16(&ctx->pb, 4); /* skip 3 header bytes */
483 put_byte(&ctx->pb, stream->lpcm_header[0]);
484 put_byte(&ctx->pb, stream->lpcm_header[1]);
485 put_byte(&ctx->pb, stream->lpcm_header[2]);
486 } else {
487 /* AC3 */
0dbb48d9
FB
488 put_byte(&ctx->pb, stream->nb_frames);
489 put_be16(&ctx->pb, stream->frame_start_offset);
de6d9b64
FB
490 }
491 }
492
493 /* output data */
494 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size);
495 put_flush_packet(&ctx->pb);
496
de6d9b64
FB
497 s->packet_number++;
498 stream->packet_number++;
0dbb48d9
FB
499 stream->nb_frames = 0;
500 stream->frame_start_offset = 0;
de6d9b64
FB
501}
502
e45f1943
FB
503/* XXX: move that to upper layer */
504/* XXX: we assume that there are always 'max_b_frames' between
505 reference frames. A better solution would be to use the AVFrame pts
506 field */
507static void compute_pts_dts(AVStream *st, int64_t *ppts, int64_t *pdts,
508 int64_t timestamp)
509{
510 int frame_delay;
511 int64_t pts, dts;
512
513 if (st->codec.codec_type == CODEC_TYPE_VIDEO &&
514 st->codec.max_b_frames != 0) {
515 frame_delay = (st->codec.frame_rate_base * 90000LL) /
516 st->codec.frame_rate;
517 if (timestamp == 0) {
518 /* specific case for first frame : DTS just before */
519 pts = timestamp;
520 dts = timestamp - frame_delay;
521 } else {
522 timestamp -= frame_delay;
523 if (st->codec.coded_frame->pict_type == FF_B_TYPE) {
524 /* B frames has identical pts/dts */
525 pts = timestamp;
526 dts = timestamp;
527 } else {
528 /* a reference frame has a pts equal to the dts of the
529 _next_ one */
530 dts = timestamp;
531 pts = timestamp + (st->codec.max_b_frames + 1) * frame_delay;
532 }
533 }
534#if 1
535 printf("pts=%0.3f dts=%0.3f pict_type=%c\n",
536 pts / 90000.0, dts / 90000.0,
537 av_get_pict_type_char(st->codec.coded_frame->pict_type));
538#endif
539 } else {
540 pts = timestamp;
541 dts = timestamp;
542 }
543 *ppts = pts & ((1LL << 33) - 1);
544 *pdts = dts & ((1LL << 33) - 1);
545}
546
10bb7023 547static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
e45f1943
FB
548 const uint8_t *buf, int size,
549 int64_t timestamp)
de6d9b64
FB
550{
551 MpegMuxContext *s = ctx->priv_data;
552 AVStream *st = ctx->streams[stream_index];
553 StreamInfo *stream = st->priv_data;
e45f1943 554 int64_t pts, dts, new_start_pts, new_start_dts;
0dbb48d9 555 int len, avail_size;
27a206e0 556
e45f1943
FB
557 compute_pts_dts(st, &pts, &dts, timestamp);
558
27a206e0
MB
559 /* XXX: system clock should be computed precisely, especially for
560 CBR case. The current mode gives at least something coherent */
561 if (stream_index == s->scr_stream_index)
562 s->last_scr = pts;
10bb7023 563
27a206e0 564#if 0
e45f1943
FB
565 printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n",
566 stream_index,
567 pts / 90000.0,
568 dts / 90000.0,
569 s->last_scr / 90000.0);
27a206e0
MB
570#endif
571
27a206e0 572 /* we assume here that pts != AV_NOPTS_VALUE */
0dbb48d9
FB
573 new_start_pts = stream->start_pts;
574 new_start_dts = stream->start_dts;
575
27a206e0 576 if (stream->start_pts == AV_NOPTS_VALUE) {
0dbb48d9
FB
577 new_start_pts = pts;
578 new_start_dts = dts;
579 }
580 avail_size = get_packet_payload_size(ctx, stream_index,
581 new_start_pts,
582 new_start_dts);
583 if (stream->buffer_ptr >= avail_size) {
584 /* unlikely case: outputing the pts or dts increase the packet
585 size so that we cannot write the start of the next
586 packet. In this case, we must flush the current packet with
587 padding */
588 flush_packet(ctx, stream_index,
589 stream->start_pts, stream->start_dts, s->last_scr);
590 stream->buffer_ptr = 0;
27a206e0 591 }
0dbb48d9
FB
592 stream->start_pts = new_start_pts;
593 stream->start_dts = new_start_dts;
594 stream->nb_frames++;
595 if (stream->frame_start_offset == 0)
596 stream->frame_start_offset = stream->buffer_ptr;
de6d9b64 597 while (size > 0) {
0dbb48d9
FB
598 avail_size = get_packet_payload_size(ctx, stream_index,
599 stream->start_pts,
600 stream->start_dts);
601 len = avail_size - stream->buffer_ptr;
de6d9b64
FB
602 if (len > size)
603 len = size;
604 memcpy(stream->buffer + stream->buffer_ptr, buf, len);
605 stream->buffer_ptr += len;
606 buf += len;
607 size -= len;
0dbb48d9
FB
608 if (stream->buffer_ptr >= avail_size) {
609 /* if packet full, we send it now */
27a206e0
MB
610 flush_packet(ctx, stream_index,
611 stream->start_pts, stream->start_dts, s->last_scr);
0dbb48d9 612 stream->buffer_ptr = 0;
27a206e0
MB
613 /* Make sure only the FIRST pes packet for this frame has
614 a timestamp */
615 stream->start_pts = AV_NOPTS_VALUE;
616 stream->start_dts = AV_NOPTS_VALUE;
de6d9b64
FB
617 }
618 }
0dbb48d9 619
de6d9b64
FB
620 return 0;
621}
622
623static int mpeg_mux_end(AVFormatContext *ctx)
624{
27a206e0 625 MpegMuxContext *s = ctx->priv_data;
de6d9b64
FB
626 StreamInfo *stream;
627 int i;
628
629 /* flush each packet */
630 for(i=0;i<ctx->nb_streams;i++) {
631 stream = ctx->streams[i]->priv_data;
0dbb48d9
FB
632 if (stream->buffer_ptr > 0) {
633 /* NOTE: we can always write the remaining data as it was
634 tested before in mpeg_mux_write_packet() */
635 flush_packet(ctx, i, stream->start_pts, stream->start_dts,
636 s->last_scr);
92b3e125 637 }
de6d9b64
FB
638 }
639
fa0f62c3
FB
640 /* End header according to MPEG1 systems standard. We do not write
641 it as it is usually not needed by decoders and because it
642 complicates MPEG stream concatenation. */
92b3e125
J
643 //put_be32(&ctx->pb, ISO_11172_END_CODE);
644 //put_flush_packet(&ctx->pb);
9d90c37f
MN
645
646 for(i=0;i<ctx->nb_streams;i++)
647 av_freep(&ctx->streams[i]->priv_data);
648
de6d9b64
FB
649 return 0;
650}
764ef400 651#endif //CONFIG_ENCODERS
de6d9b64
FB
652
653/*********************************************/
654/* demux code */
655
656#define MAX_SYNC_SIZE 100000
657
db7f1f95
FB
658static int mpegps_probe(AVProbeData *p)
659{
ec23a472 660 int code, c, i;
db7f1f95 661
ec23a472 662 code = 0xff;
db7f1f95
FB
663 /* we search the first start code. If it is a packet start code,
664 then we decide it is mpeg ps. We do not send highest value to
665 give a chance to mpegts */
fa777321
FB
666 /* NOTE: the search range was restricted to avoid too many false
667 detections */
668
669 if (p->buf_size < 6)
670 return 0;
ec23a472
IR
671
672 for (i = 0; i < 20; i++) {
673 c = p->buf[i];
674 code = (code << 8) | c;
675 if ((code & 0xffffff00) == 0x100) {
676 if (code == PACK_START_CODE ||
677 code == SYSTEM_HEADER_START_CODE ||
678 (code >= 0x1e0 && code <= 0x1ef) ||
679 (code >= 0x1c0 && code <= 0x1df) ||
680 code == PRIVATE_STREAM_2 ||
681 code == PROGRAM_STREAM_MAP ||
682 code == PRIVATE_STREAM_1 ||
683 code == PADDING_STREAM)
149f7c02 684 return AVPROBE_SCORE_MAX - 2;
ec23a472
IR
685 else
686 return 0;
687 }
db7f1f95
FB
688 }
689 return 0;
690}
691
692
de6d9b64
FB
693typedef struct MpegDemuxContext {
694 int header_state;
de6d9b64
FB
695} MpegDemuxContext;
696
27f388aa
FB
697static int mpegps_read_header(AVFormatContext *s,
698 AVFormatParameters *ap)
699{
700 MpegDemuxContext *m = s->priv_data;
701 m->header_state = 0xff;
702 s->ctx_flags |= AVFMTCTX_NOHEADER;
703
704 /* no need to do more */
705 return 0;
706}
707
708static int64_t get_pts(ByteIOContext *pb, int c)
709{
710 int64_t pts;
711 int val;
712
713 if (c < 0)
714 c = get_byte(pb);
715 pts = (int64_t)((c >> 1) & 0x07) << 30;
716 val = get_be16(pb);
717 pts |= (int64_t)(val >> 1) << 15;
718 val = get_be16(pb);
719 pts |= (int64_t)(val >> 1);
720 return pts;
721}
722
723static int find_next_start_code(ByteIOContext *pb, int *size_ptr,
724 uint32_t *header_state)
de6d9b64
FB
725{
726 unsigned int state, v;
727 int val, n;
728
729 state = *header_state;
730 n = *size_ptr;
731 while (n > 0) {
732 if (url_feof(pb))
733 break;
734 v = get_byte(pb);
735 n--;
736 if (state == 0x000001) {
737 state = ((state << 8) | v) & 0xffffff;
738 val = state;
739 goto found;
740 }
741 state = ((state << 8) | v) & 0xffffff;
742 }
743 val = -1;
744 found:
745 *header_state = state;
746 *size_ptr = n;
747 return val;
748}
749
27f388aa
FB
750/* XXX: optimize */
751static int find_prev_start_code(ByteIOContext *pb, int *size_ptr)
de6d9b64 752{
27f388aa
FB
753 int64_t pos, pos_start;
754 int max_size, start_code;
da24c5e3 755
27f388aa
FB
756 max_size = *size_ptr;
757 pos_start = url_ftell(pb);
de6d9b64 758
27f388aa
FB
759 /* in order to go faster, we fill the buffer */
760 pos = pos_start - 16386;
761 if (pos < 0)
762 pos = 0;
763 url_fseek(pb, pos, SEEK_SET);
764 get_byte(pb);
de6d9b64 765
27f388aa
FB
766 pos = pos_start;
767 for(;;) {
768 pos--;
769 if (pos < 0 || (pos_start - pos) >= max_size) {
770 start_code = -1;
771 goto the_end;
772 }
773 url_fseek(pb, pos, SEEK_SET);
774 start_code = get_be32(pb);
775 if ((start_code & 0xffffff00) == 0x100)
776 break;
777 }
778 the_end:
779 *size_ptr = pos_start - pos;
780 return start_code;
de6d9b64
FB
781}
782
27f388aa
FB
783/* read the next (or previous) PES header. Return its position in ppos
784 (if not NULL), and its start code, pts and dts.
785 */
786static int mpegps_read_pes_header(AVFormatContext *s,
787 int64_t *ppos, int *pstart_code,
788 int64_t *ppts, int64_t *pdts, int find_next)
de6d9b64
FB
789{
790 MpegDemuxContext *m = s->priv_data;
27f388aa
FB
791 int len, size, startcode, c, flags, header_len;
792 int64_t pts, dts, last_pos;
de6d9b64 793
27f388aa 794 last_pos = -1;
de6d9b64 795 redo:
27f388aa
FB
796 if (find_next) {
797 /* next start code (should be immediately after) */
798 m->header_state = 0xff;
799 size = MAX_SYNC_SIZE;
800 startcode = find_next_start_code(&s->pb, &size, &m->header_state);
801 } else {
802 if (last_pos >= 0)
803 url_fseek(&s->pb, last_pos, SEEK_SET);
804 size = MAX_SYNC_SIZE;
805 startcode = find_prev_start_code(&s->pb, &size);
806 last_pos = url_ftell(&s->pb) - 4;
807 }
001e3f55 808 //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
de6d9b64
FB
809 if (startcode < 0)
810 return -EIO;
811 if (startcode == PACK_START_CODE)
812 goto redo;
813 if (startcode == SYSTEM_HEADER_START_CODE)
814 goto redo;
815 if (startcode == PADDING_STREAM ||
816 startcode == PRIVATE_STREAM_2) {
817 /* skip them */
818 len = get_be16(&s->pb);
819 url_fskip(&s->pb, len);
820 goto redo;
821 }
822 /* find matching stream */
823 if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
824 (startcode >= 0x1e0 && startcode <= 0x1ef) ||
825 (startcode == 0x1bd)))
826 goto redo;
27f388aa
FB
827 if (ppos) {
828 *ppos = url_ftell(&s->pb) - 4;
829 }
de6d9b64 830 len = get_be16(&s->pb);
b2cac184
FB
831 pts = AV_NOPTS_VALUE;
832 dts = AV_NOPTS_VALUE;
de6d9b64
FB
833 /* stuffing */
834 for(;;) {
27f388aa
FB
835 if (len < 1)
836 goto redo;
de6d9b64
FB
837 c = get_byte(&s->pb);
838 len--;
839 /* XXX: for mpeg1, should test only bit 7 */
840 if (c != 0xff)
841 break;
842 }
843 if ((c & 0xc0) == 0x40) {
844 /* buffer scale & size */
27f388aa
FB
845 if (len < 2)
846 goto redo;
de6d9b64
FB
847 get_byte(&s->pb);
848 c = get_byte(&s->pb);
849 len -= 2;
850 }
851 if ((c & 0xf0) == 0x20) {
27f388aa
FB
852 if (len < 4)
853 goto redo;
854 dts = pts = get_pts(&s->pb, c);
de6d9b64 855 len -= 4;
de6d9b64 856 } else if ((c & 0xf0) == 0x30) {
27f388aa
FB
857 if (len < 9)
858 goto redo;
de6d9b64
FB
859 pts = get_pts(&s->pb, c);
860 dts = get_pts(&s->pb, -1);
861 len -= 9;
862 } else if ((c & 0xc0) == 0x80) {
863 /* mpeg 2 PES */
864 if ((c & 0x30) != 0) {
27f388aa
FB
865 /* Encrypted multiplex not handled */
866 goto redo;
de6d9b64
FB
867 }
868 flags = get_byte(&s->pb);
869 header_len = get_byte(&s->pb);
870 len -= 2;
871 if (header_len > len)
872 goto redo;
1e5c667c 873 if ((flags & 0xc0) == 0x80) {
27f388aa
FB
874 dts = pts = get_pts(&s->pb, -1);
875 if (header_len < 5)
876 goto redo;
de6d9b64
FB
877 header_len -= 5;
878 len -= 5;
879 } if ((flags & 0xc0) == 0xc0) {
880 pts = get_pts(&s->pb, -1);
881 dts = get_pts(&s->pb, -1);
27f388aa
FB
882 if (header_len < 10)
883 goto redo;
de6d9b64
FB
884 header_len -= 10;
885 len -= 10;
886 }
887 len -= header_len;
888 while (header_len > 0) {
889 get_byte(&s->pb);
890 header_len--;
891 }
892 }
893 if (startcode == 0x1bd) {
27f388aa
FB
894 if (len < 1)
895 goto redo;
de6d9b64
FB
896 startcode = get_byte(&s->pb);
897 len--;
898 if (startcode >= 0x80 && startcode <= 0xbf) {
899 /* audio: skip header */
27f388aa
FB
900 if (len < 3)
901 goto redo;
de6d9b64
FB
902 get_byte(&s->pb);
903 get_byte(&s->pb);
904 get_byte(&s->pb);
905 len -= 3;
906 }
907 }
b754978a
MN
908 if(dts != AV_NOPTS_VALUE && ppos){
909 int i;
910 for(i=0; i<s->nb_streams; i++){
911 if(startcode == s->streams[i]->id) {
912 av_add_index_entry(s->streams[i], *ppos, dts, 0 /* FIXME keyframe? */);
913 }
914 }
915 }
916
27f388aa
FB
917 *pstart_code = startcode;
918 *ppts = pts;
919 *pdts = dts;
920 return len;
921}
922
923static int mpegps_read_packet(AVFormatContext *s,
924 AVPacket *pkt)
925{
926 AVStream *st;
927 int len, startcode, i, type, codec_id;
b754978a 928 int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
27f388aa
FB
929
930 redo:
b754978a 931 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts, 1);
27f388aa
FB
932 if (len < 0)
933 return len;
27a206e0 934
de6d9b64
FB
935 /* now find stream */
936 for(i=0;i<s->nb_streams;i++) {
937 st = s->streams[i];
938 if (st->id == startcode)
939 goto found;
940 }
db7f1f95
FB
941 if (startcode >= 0x1e0 && startcode <= 0x1ef) {
942 type = CODEC_TYPE_VIDEO;
0dbb48d9 943 codec_id = CODEC_ID_MPEG2VIDEO;
db7f1f95
FB
944 } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
945 type = CODEC_TYPE_AUDIO;
946 codec_id = CODEC_ID_MP2;
947 } else if (startcode >= 0x80 && startcode <= 0x9f) {
948 type = CODEC_TYPE_AUDIO;
949 codec_id = CODEC_ID_AC3;
9ec05e36
FB
950 } else if (startcode >= 0xa0 && startcode <= 0xbf) {
951 type = CODEC_TYPE_AUDIO;
952 codec_id = CODEC_ID_PCM_S16BE;
db7f1f95
FB
953 } else {
954 skip:
955 /* skip packet */
956 url_fskip(&s->pb, len);
957 goto redo;
958 }
1e5c667c
FB
959 /* no stream found: add a new stream */
960 st = av_new_stream(s, startcode);
961 if (!st)
962 goto skip;
db7f1f95
FB
963 st->codec.codec_type = type;
964 st->codec.codec_id = codec_id;
27f388aa
FB
965 if (codec_id != CODEC_ID_PCM_S16BE)
966 st->need_parsing = 1;
de6d9b64 967 found:
9ec05e36
FB
968 if (startcode >= 0xa0 && startcode <= 0xbf) {
969 int b1, freq;
9ec05e36
FB
970
971 /* for LPCM, we just skip the header and consider it is raw
972 audio data */
973 if (len <= 3)
974 goto skip;
975 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */
976 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */
977 get_byte(&s->pb); /* dynamic range control (0x80 = off) */
978 len -= 3;
979 freq = (b1 >> 4) & 3;
980 st->codec.sample_rate = lpcm_freq_tab[freq];
981 st->codec.channels = 1 + (b1 & 7);
982 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2;
983 }
de6d9b64
FB
984 av_new_packet(pkt, len);
985 get_buffer(&s->pb, pkt->data, pkt->size);
986 pkt->pts = pts;
27f388aa 987 pkt->dts = dts;
db7f1f95 988 pkt->stream_index = st->index;
27a206e0
MB
989#if 0
990 printf("%d: pts=%0.3f dts=%0.3f\n",
991 pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0);
992#endif
de6d9b64
FB
993 return 0;
994}
995
db7f1f95 996static int mpegps_read_close(AVFormatContext *s)
de6d9b64 997{
de6d9b64
FB
998 return 0;
999}
1000
27f388aa
FB
1001static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
1002 int64_t *ppos, int find_next)
1003{
1004 int len, startcode;
1005 int64_t pos, pts, dts;
1006
1007 pos = *ppos;
1008#ifdef DEBUG_SEEK
1009 printf("read_dts: pos=0x%llx next=%d -> ", pos, find_next);
1010#endif
1011 url_fseek(&s->pb, pos, SEEK_SET);
1012 for(;;) {
1013 len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts, find_next);
1014 if (len < 0) {
1015#ifdef DEBUG_SEEK
1016 printf("none (ret=%d)\n", len);
1017#endif
1018 return AV_NOPTS_VALUE;
1019 }
1020 if (startcode == s->streams[stream_index]->id &&
1021 dts != AV_NOPTS_VALUE) {
1022 break;
1023 }
1024 if (find_next) {
1025 url_fskip(&s->pb, len);
1026 } else {
1027 url_fseek(&s->pb, pos, SEEK_SET);
1028 }
1029 }
1030#ifdef DEBUG_SEEK
1031 printf("pos=0x%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0);
1032#endif
1033 *ppos = pos;
1034 return dts;
1035}
1036
27f388aa
FB
1037static int mpegps_read_seek(AVFormatContext *s,
1038 int stream_index, int64_t timestamp)
1039{
1040 int64_t pos_min, pos_max, pos;
1041 int64_t dts_min, dts_max, dts;
b754978a
MN
1042 int index;
1043 AVStream *st;
27f388aa
FB
1044
1045 timestamp = (timestamp * 90000) / AV_TIME_BASE;
1046
1047#ifdef DEBUG_SEEK
1048 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0);
1049#endif
1050
1051 /* XXX: find stream_index by looking at the first PES packet found */
1052 if (stream_index < 0) {
b754978a 1053 stream_index = av_find_default_stream_index(s);
27f388aa
FB
1054 if (stream_index < 0)
1055 return -1;
1056 }
b754978a
MN
1057
1058 dts_max=
1059 dts_min= AV_NOPTS_VALUE;
1060
1061 st= s->streams[stream_index];
1062 if(st->index_entries){
1063 AVIndexEntry *e;
1064
1065 index= av_index_search_timestamp(st, timestamp);
1066 e= &st->index_entries[index];
1067 if(e->timestamp <= timestamp){
1068 pos_min= e->pos;
1069 dts_min= e->timestamp;
1070#ifdef DEBUG_SEEK
1071 printf("unsing cached pos_min=0x%llx dts_min=%0.3f\n",
1072 pos_min,dts_min / 90000.0);
1073#endif
1074 }else{
1075 assert(index==0);
1076 }
1077 index++;
1078 if(index < st->nb_index_entries){
1079 e= &st->index_entries[index];
1080 assert(e->timestamp >= timestamp);
1081 pos_max= e->pos;
1082 dts_max= e->timestamp;
1083#ifdef DEBUG_SEEK
1084 printf("unsing cached pos_max=0x%llx dts_max=%0.3f\n",
1085 pos_max,dts_max / 90000.0);
1086#endif
1087 }
1088 }
1089
1090 if(dts_min == AV_NOPTS_VALUE){
1091 pos_min = 0;
1092 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1);
1093 if (dts_min == AV_NOPTS_VALUE) {
1094 /* we can reach this case only if no PTS are present in
1095 the whole stream */
1096 return -1;
1097 }
1098 }
1099 if(dts_max == AV_NOPTS_VALUE){
1100 pos_max = url_filesize(url_fileno(&s->pb)) - 1;
1101 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0);
27f388aa 1102 }
27f388aa
FB
1103
1104 while (pos_min <= pos_max) {
1105#ifdef DEBUG_SEEK
1106 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n",
1107 pos_min, pos_max,
1108 dts_min / 90000.0, dts_max / 90000.0);
1109#endif
1110 if (timestamp <= dts_min) {
1111 pos = pos_min;
1112 goto found;
1113 } else if (timestamp >= dts_max) {
1114 pos = pos_max;
1115 goto found;
1116 } else {
1117 /* interpolate position (better than dichotomy) */
1118 pos = (int64_t)((double)(pos_max - pos_min) *
1119 (double)(timestamp - dts_min) /
1120 (double)(dts_max - dts_min)) + pos_min;
1121 }
1122#ifdef DEBUG_SEEK
1123 printf("pos=0x%llx\n", pos);
1124#endif
1125 /* read the next timestamp */
1126 dts = mpegps_read_dts(s, stream_index, &pos, 1);
1127 /* check if we are lucky */
1128 if (dts == AV_NOPTS_VALUE) {
1129 /* should never happen */
1130 pos = pos_min;
1131 goto found;
1132 } else if (timestamp == dts) {
1133 goto found;
1134 } else if (timestamp < dts) {
1135 pos_max = pos;
1136 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0);
1137 if (dts_max == AV_NOPTS_VALUE) {
1138 /* should never happen */
1139 break;
1140 } else if (timestamp >= dts_max) {
1141 pos = pos_max;
1142 goto found;
1143 }
1144 } else {
1145 pos_min = pos + 1;
1146 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1);
1147 if (dts_min == AV_NOPTS_VALUE) {
1148 /* should never happen */
1149 goto found;
1150 } else if (timestamp <= dts_min) {
1151 goto found;
1152 }
1153 }
1154 }
1155 pos = pos_min;
1156 found:
1157#ifdef DEBUG_SEEK
1158 pos_min = pos;
1159 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1);
1160 pos_min++;
1161 dts_max = mpegps_read_dts(s, stream_index, &pos_min, 1);
1162 printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n",
1163 pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0);
1164#endif
1165 /* do the seek */
1166 url_fseek(&s->pb, pos, SEEK_SET);
1167 return 0;
1168}
1169
764ef400 1170#ifdef CONFIG_ENCODERS
fb7566d0 1171static AVOutputFormat mpeg1system_mux = {
de6d9b64 1172 "mpeg",
fb7566d0 1173 "MPEG1 System format",
c6c11cb6 1174 "video/mpeg",
fb7566d0
FB
1175 "mpg,mpeg",
1176 sizeof(MpegMuxContext),
1177 CODEC_ID_MP2,
1178 CODEC_ID_MPEG1VIDEO,
1179 mpeg_mux_init,
1180 mpeg_mux_write_packet,
1181 mpeg_mux_end,
1182};
1183
1184static AVOutputFormat mpeg1vcd_mux = {
1185 "vcd",
1186 "MPEG1 System format (VCD)",
c6c11cb6 1187 "video/mpeg",
fb7566d0
FB
1188 NULL,
1189 sizeof(MpegMuxContext),
1190 CODEC_ID_MP2,
1191 CODEC_ID_MPEG1VIDEO,
1192 mpeg_mux_init,
1193 mpeg_mux_write_packet,
1194 mpeg_mux_end,
1195};
1196
1197static AVOutputFormat mpeg2vob_mux = {
1198 "vob",
1199 "MPEG2 PS format (VOB)",
c6c11cb6 1200 "video/mpeg",
fb7566d0 1201 "vob",
db7f1f95 1202 sizeof(MpegMuxContext),
de6d9b64 1203 CODEC_ID_MP2,
0dbb48d9 1204 CODEC_ID_MPEG2VIDEO,
de6d9b64
FB
1205 mpeg_mux_init,
1206 mpeg_mux_write_packet,
1207 mpeg_mux_end,
db7f1f95 1208};
764ef400 1209#endif //CONFIG_ENCODERS
de6d9b64 1210
32f38cb4 1211AVInputFormat mpegps_demux = {
db7f1f95
FB
1212 "mpeg",
1213 "MPEG PS format",
1214 sizeof(MpegDemuxContext),
1215 mpegps_probe,
1216 mpegps_read_header,
1217 mpegps_read_packet,
1218 mpegps_read_close,
27f388aa 1219 mpegps_read_seek,
de6d9b64 1220};
db7f1f95
FB
1221
1222int mpegps_init(void)
1223{
764ef400 1224#ifdef CONFIG_ENCODERS
fb7566d0
FB
1225 av_register_output_format(&mpeg1system_mux);
1226 av_register_output_format(&mpeg1vcd_mux);
1227 av_register_output_format(&mpeg2vob_mux);
764ef400 1228#endif //CONFIG_ENCODERS
db7f1f95
FB
1229 av_register_input_format(&mpegps_demux);
1230 return 0;
1231}