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