Initial revision
[libav.git] / libav / mpeg.c
CommitLineData
de6d9b64
FB
1/*
2 * Output a MPEG1 multiplexed video/audio stream
3 * Copyright (c) 2000 Gerard Lantau.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <errno.h>
24#include <sys/time.h>
25
26#include "avformat.h"
27
28#define MAX_PAYLOAD_SIZE 4096
29#define NB_STREAMS 2
30
31typedef struct {
32 UINT8 buffer[MAX_PAYLOAD_SIZE];
33 int buffer_ptr;
34 UINT8 id;
35 int max_buffer_size; /* in bytes */
36 int packet_number;
37 float pts;
38 INT64 start_pts;
39} StreamInfo;
40
41typedef struct {
42 int packet_size; /* required packet size */
43 int packet_data_max_size; /* maximum data size inside a packet */
44 int packet_number;
45 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */
46 int system_header_freq;
47 int mux_rate; /* bitrate in units of 50 bytes/s */
48 /* stream info */
49 int audio_bound;
50 int video_bound;
51} MpegMuxContext;
52
53#define PACK_START_CODE ((unsigned int)0x000001ba)
54#define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb)
55#define PACKET_START_CODE_MASK ((unsigned int)0xffffff00)
56#define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100)
57#define ISO_11172_END_CODE ((unsigned int)0x000001b9)
58
59/* mpeg2 */
60#define PROGRAM_STREAM_MAP 0x1bc
61#define PRIVATE_STREAM_1 0x1bd
62#define PADDING_STREAM 0x1be
63#define PRIVATE_STREAM_2 0x1bf
64
65
66#define AUDIO_ID 0xc0
67#define VIDEO_ID 0xe0
68
69static int put_pack_header(AVFormatContext *ctx,
70 UINT8 *buf, long long timestamp)
71{
72 MpegMuxContext *s = ctx->priv_data;
73 PutBitContext pb;
74
75 init_put_bits(&pb, buf, 128, NULL, NULL);
76
77 put_bits(&pb, 32, PACK_START_CODE);
78 put_bits(&pb, 4, 0x2);
79 put_bits(&pb, 3, (timestamp >> 30) & 0x07);
80 put_bits(&pb, 1, 1);
81 put_bits(&pb, 15, (timestamp >> 15) & 0x7fff);
82 put_bits(&pb, 1, 1);
83 put_bits(&pb, 15, (timestamp) & 0x7fff);
84 put_bits(&pb, 1, 1);
85 put_bits(&pb, 1, 1);
86 put_bits(&pb, 22, s->mux_rate);
87 put_bits(&pb, 1, 1);
88
89 flush_put_bits(&pb);
90 return pb.buf_ptr - pb.buf;
91}
92
93static int put_system_header(AVFormatContext *ctx, UINT8 *buf)
94{
95 MpegMuxContext *s = ctx->priv_data;
96 int size, rate_bound, i, private_stream_coded, id;
97 PutBitContext pb;
98
99 init_put_bits(&pb, buf, 128, NULL, NULL);
100
101 put_bits(&pb, 32, SYSTEM_HEADER_START_CODE);
102 put_bits(&pb, 16, 0);
103 put_bits(&pb, 1, 1);
104
105 rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */
106 put_bits(&pb, 22, rate_bound);
107 put_bits(&pb, 1, 1); /* marker */
108 put_bits(&pb, 6, s->audio_bound);
109
110 put_bits(&pb, 1, 1); /* variable bitrate */
111 put_bits(&pb, 1, 1); /* non constrainted bit stream */
112
113 put_bits(&pb, 1, 0); /* audio locked */
114 put_bits(&pb, 1, 0); /* video locked */
115 put_bits(&pb, 1, 1); /* marker */
116
117 put_bits(&pb, 5, s->video_bound);
118 put_bits(&pb, 8, 0xff); /* reserved byte */
119
120 /* audio stream info */
121 private_stream_coded = 0;
122 for(i=0;i<ctx->nb_streams;i++) {
123 StreamInfo *stream = ctx->streams[i]->priv_data;
124 id = stream->id;
125 if (id < 0xc0) {
126 /* special case for private streams (AC3 use that) */
127 if (private_stream_coded)
128 continue;
129 private_stream_coded = 1;
130 id = 0xbd;
131 }
132 put_bits(&pb, 8, id); /* stream ID */
133 put_bits(&pb, 2, 3);
134 if (id < 0xe0) {
135 /* audio */
136 put_bits(&pb, 1, 0);
137 put_bits(&pb, 13, stream->max_buffer_size / 128);
138 } else {
139 /* video */
140 put_bits(&pb, 1, 1);
141 put_bits(&pb, 13, stream->max_buffer_size / 1024);
142 }
143 }
144 flush_put_bits(&pb);
145 size = pb.buf_ptr - pb.buf;
146 /* patch packet size */
147 buf[4] = (size - 6) >> 8;
148 buf[5] = (size - 6) & 0xff;
149
150 return size;
151}
152
153static int mpeg_mux_init(AVFormatContext *ctx)
154{
155 MpegMuxContext *s;
156 int bitrate, i, mpa_id, mpv_id, ac3_id;
157 AVStream *st;
158 StreamInfo *stream;
159
160 s = malloc(sizeof(MpegMuxContext));
161 if (!s)
162 return -1;
163 memset(s, 0, sizeof(MpegMuxContext));
164 ctx->priv_data = s;
165 s->packet_number = 0;
166
167 /* XXX: hardcoded */
168 s->packet_size = 2048;
169 /* startcode(4) + length(2) + flags(1) */
170 s->packet_data_max_size = s->packet_size - 7;
171 s->audio_bound = 0;
172 s->video_bound = 0;
173 mpa_id = AUDIO_ID;
174 ac3_id = 0x80;
175 mpv_id = VIDEO_ID;
176 for(i=0;i<ctx->nb_streams;i++) {
177 st = ctx->streams[i];
178 stream = av_mallocz(sizeof(StreamInfo));
179 if (!stream)
180 goto fail;
181 st->priv_data = stream;
182
183 switch(st->codec.codec_type) {
184 case CODEC_TYPE_AUDIO:
185 if (st->codec.codec_id == CODEC_ID_AC3)
186 stream->id = ac3_id++;
187 else
188 stream->id = mpa_id++;
189 stream->max_buffer_size = 4 * 1024;
190 s->audio_bound++;
191 break;
192 case CODEC_TYPE_VIDEO:
193 stream->id = mpv_id++;
194 stream->max_buffer_size = 46 * 1024;
195 s->video_bound++;
196 break;
197 }
198 }
199
200 /* we increase slightly the bitrate to take into account the
201 headers. XXX: compute it exactly */
202 bitrate = 2000;
203 for(i=0;i<ctx->nb_streams;i++) {
204 st = ctx->streams[i];
205 bitrate += st->codec.bit_rate;
206 }
207 s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
208 /* every 2 seconds */
209 s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
210 /* every 10 seconds */
211 s->system_header_freq = s->pack_header_freq * 5;
212
213 for(i=0;i<ctx->nb_streams;i++) {
214 stream = ctx->streams[i]->priv_data;
215 stream->buffer_ptr = 0;
216 stream->packet_number = 0;
217 stream->pts = 0;
218 stream->start_pts = -1;
219 }
220 return 0;
221 fail:
222 for(i=0;i<ctx->nb_streams;i++) {
223 free(ctx->streams[i]->priv_data);
224 }
225 free(s);
226 return -ENOMEM;
227}
228
229/* flush the packet on stream stream_index */
230static void flush_packet(AVFormatContext *ctx, int stream_index)
231{
232 MpegMuxContext *s = ctx->priv_data;
233 StreamInfo *stream = ctx->streams[stream_index]->priv_data;
234 UINT8 *buf_ptr;
235 int size, payload_size, startcode, id, len, stuffing_size, i;
236 INT64 timestamp;
237 UINT8 buffer[128];
238
239 id = stream->id;
240 timestamp = stream->start_pts;
241
242#if 0
243 printf("packet ID=%2x PTS=%0.3f\n",
244 id, timestamp / 90000.0);
245#endif
246
247 buf_ptr = buffer;
248 if ((s->packet_number % s->pack_header_freq) == 0) {
249 /* output pack and systems header if needed */
250 size = put_pack_header(ctx, buf_ptr, timestamp);
251 buf_ptr += size;
252 if ((s->packet_number % s->system_header_freq) == 0) {
253 size = put_system_header(ctx, buf_ptr);
254 buf_ptr += size;
255 }
256 }
257 size = buf_ptr - buffer;
258 put_buffer(&ctx->pb, buffer, size);
259
260 /* packet header */
261 payload_size = s->packet_size - (size + 6 + 5);
262 if (id < 0xc0) {
263 startcode = PRIVATE_STREAM_1;
264 payload_size -= 4;
265 } else {
266 startcode = 0x100 + id;
267 }
268 stuffing_size = payload_size - stream->buffer_ptr;
269 if (stuffing_size < 0)
270 stuffing_size = 0;
271
272 put_be32(&ctx->pb, startcode);
273
274 put_be16(&ctx->pb, payload_size + 5);
275 /* stuffing */
276 for(i=0;i<stuffing_size;i++)
277 put_byte(&ctx->pb, 0xff);
278
279 /* presentation time stamp */
280 put_byte(&ctx->pb,
281 (0x02 << 4) |
282 (((timestamp >> 30) & 0x07) << 1) |
283 1);
284 put_be16(&ctx->pb, (((timestamp >> 15) & 0x7fff) << 1) | 1);
285 put_be16(&ctx->pb, (((timestamp) & 0x7fff) << 1) | 1);
286
287 if (startcode == PRIVATE_STREAM_1) {
288 put_byte(&ctx->pb, id);
289 if (id >= 0x80 && id <= 0xbf) {
290 /* XXX: need to check AC3 spec */
291 put_byte(&ctx->pb, 1);
292 put_byte(&ctx->pb, 0);
293 put_byte(&ctx->pb, 2);
294 }
295 }
296
297 /* output data */
298 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size);
299 put_flush_packet(&ctx->pb);
300
301 /* preserve remaining data */
302 len = stream->buffer_ptr - payload_size;
303 if (len < 0)
304 len = 0;
305 memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len);
306 stream->buffer_ptr = len;
307
308 s->packet_number++;
309 stream->packet_number++;
310 stream->start_pts = -1;
311}
312
313static int mpeg_mux_write_packet(AVFormatContext *ctx,
314 int stream_index, UINT8 *buf, int size)
315{
316 MpegMuxContext *s = ctx->priv_data;
317 AVStream *st = ctx->streams[stream_index];
318 StreamInfo *stream = st->priv_data;
319 int len;
320
321 while (size > 0) {
322 /* set pts */
323 if (stream->start_pts == -1)
324 stream->start_pts = stream->pts * 90000.0;
325 len = s->packet_data_max_size - stream->buffer_ptr;
326 if (len > size)
327 len = size;
328 memcpy(stream->buffer + stream->buffer_ptr, buf, len);
329 stream->buffer_ptr += len;
330 buf += len;
331 size -= len;
332 while (stream->buffer_ptr >= s->packet_data_max_size) {
333 /* output the packet */
334 if (stream->start_pts == -1)
335 stream->start_pts = stream->pts * 90000.0;
336 flush_packet(ctx, stream_index);
337 }
338 }
339
340 if (st->codec.codec_type == CODEC_TYPE_AUDIO) {
341 stream->pts += (float)st->codec.frame_size / st->codec.sample_rate;
342 } else {
343 stream->pts += FRAME_RATE_BASE / (float)st->codec.frame_rate;
344 }
345 return 0;
346}
347
348static int mpeg_mux_end(AVFormatContext *ctx)
349{
350 StreamInfo *stream;
351 int i;
352
353 /* flush each packet */
354 for(i=0;i<ctx->nb_streams;i++) {
355 stream = ctx->streams[i]->priv_data;
356 if (stream->buffer_ptr > 0)
357 flush_packet(ctx, i);
358 }
359
360 /* write the end header */
361 put_be32(&ctx->pb, ISO_11172_END_CODE);
362 put_flush_packet(&ctx->pb);
363 return 0;
364}
365
366/*********************************************/
367/* demux code */
368
369#define MAX_SYNC_SIZE 100000
370
371typedef struct MpegDemuxContext {
372 int header_state;
373 int mux_rate; /* 50 byte/s unit */
374} MpegDemuxContext;
375
376static int find_start_code(ByteIOContext *pb, int *size_ptr,
377 UINT32 *header_state)
378{
379 unsigned int state, v;
380 int val, n;
381
382 state = *header_state;
383 n = *size_ptr;
384 while (n > 0) {
385 if (url_feof(pb))
386 break;
387 v = get_byte(pb);
388 n--;
389 if (state == 0x000001) {
390 state = ((state << 8) | v) & 0xffffff;
391 val = state;
392 goto found;
393 }
394 state = ((state << 8) | v) & 0xffffff;
395 }
396 val = -1;
397 found:
398 *header_state = state;
399 *size_ptr = n;
400 return val;
401}
402
403static int mpeg_mux_read_header(AVFormatContext *s,
404 AVFormatParameters *ap)
405{
406 MpegDemuxContext *m;
407 int size, startcode, c, rate_bound, audio_bound, video_bound, mux_rate, val;
408 int codec_id, n, i, type;
409 AVStream *st;
410
411 m = av_mallocz(sizeof(MpegDemuxContext));
412 if (!m)
413 return -ENOMEM;
414 s->priv_data = m;
415
416 /* search first pack header */
417 m->header_state = 0xff;
418 size = MAX_SYNC_SIZE;
419 for(;;) {
420 while (size > 0) {
421 startcode = find_start_code(&s->pb, &size, &m->header_state);
422 if (startcode == PACK_START_CODE)
423 goto found;
424 }
425 return -ENODATA;
426 found:
427 /* search system header just after pack header */
428 /* parse pack header */
429 get_byte(&s->pb); /* ts1 */
430 get_be16(&s->pb); /* ts2 */
431 get_be16(&s->pb); /* ts3 */
432
433 mux_rate = get_byte(&s->pb) << 16;
434 mux_rate |= get_byte(&s->pb) << 8;
435 mux_rate |= get_byte(&s->pb);
436 mux_rate &= (1 << 22) - 1;
437 m->mux_rate = mux_rate;
438
439 startcode = find_start_code(&s->pb, &size, &m->header_state);
440 if (startcode == SYSTEM_HEADER_START_CODE)
441 break;
442 }
443 size = get_be16(&s->pb);
444 rate_bound = get_byte(&s->pb) << 16;
445 rate_bound |= get_byte(&s->pb) << 8;
446 rate_bound |= get_byte(&s->pb);
447 rate_bound = (rate_bound >> 1) & ((1 << 22) - 1);
448 audio_bound = get_byte(&s->pb) >> 2;
449 video_bound = get_byte(&s->pb) & 0x1f;
450 get_byte(&s->pb); /* reserved byte */
451#if 0
452 printf("mux_rate=%d kbit/s\n", (m->mux_rate * 50 * 8) / 1000);
453 printf("rate_bound=%d\n", rate_bound);
454 printf("audio_bound=%d\n", audio_bound);
455 printf("video_bound=%d\n", video_bound);
456#endif
457 size -= 6;
458 s->nb_streams = 0;
459 while (size > 0) {
460 c = get_byte(&s->pb);
461 size--;
462 if ((c & 0x80) == 0)
463 break;
464 val = get_be16(&s->pb);
465 size -= 2;
466 if (c >= 0xc0 && c <= 0xdf) {
467 /* mpeg audio stream */
468 type = CODEC_TYPE_AUDIO;
469 codec_id = CODEC_ID_MP2;
470 n = 1;
471 c = c | 0x100;
472 } else if (c >= 0xe0 && c <= 0xef) {
473 type = CODEC_TYPE_VIDEO;
474 codec_id = CODEC_ID_MPEG1VIDEO;
475 n = 1;
476 c = c | 0x100;
477 } else if (c == 0xb8) {
478 /* all audio streams */
479 /* XXX: hack for DVD: we force AC3, although we do not
480 know that this codec will be used */
481 type = CODEC_TYPE_AUDIO;
482 codec_id = CODEC_ID_AC3;
483 n = audio_bound;
484 c = 0x80;
485 /* c = 0x1c0; */
486 } else if (c == 0xb9) {
487 /* all video streams */
488 type = CODEC_TYPE_VIDEO;
489 codec_id = CODEC_ID_MPEG1VIDEO;
490 n = video_bound;
491 c = 0x1e0;
492 } else {
493 type = 0;
494 codec_id = 0;
495 n = 0;
496 }
497
498 for(i=0;i<n;i++) {
499 st = av_mallocz(sizeof(AVStream));
500 if (!st)
501 return -ENOMEM;
502 s->streams[s->nb_streams++] = st;
503 st->id = c + i;
504 st->codec.codec_type = type;
505 st->codec.codec_id = codec_id;
506 }
507 }
508
509 return 0;
510}
511
512static INT64 get_pts(ByteIOContext *pb, int c)
513{
514 INT64 pts;
515 int val;
516
517 if (c < 0)
518 c = get_byte(pb);
519 pts = (INT64)((c >> 1) & 0x07) << 30;
520 val = get_be16(pb);
521 pts |= (INT64)(val >> 1) << 15;
522 val = get_be16(pb);
523 pts |= (INT64)(val >> 1);
524 return pts;
525}
526
527static int mpeg_mux_read_packet(AVFormatContext *s,
528 AVPacket *pkt)
529{
530 MpegDemuxContext *m = s->priv_data;
531 AVStream *st;
532 int len, size, startcode, i, c, flags, header_len;
533 INT64 pts, dts;
534
535 /* next start code (should be immediately after */
536 redo:
537 m->header_state = 0xff;
538 size = MAX_SYNC_SIZE;
539 startcode = find_start_code(&s->pb, &size, &m->header_state);
540 // printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
541 if (startcode < 0)
542 return -EIO;
543 if (startcode == PACK_START_CODE)
544 goto redo;
545 if (startcode == SYSTEM_HEADER_START_CODE)
546 goto redo;
547 if (startcode == PADDING_STREAM ||
548 startcode == PRIVATE_STREAM_2) {
549 /* skip them */
550 len = get_be16(&s->pb);
551 url_fskip(&s->pb, len);
552 goto redo;
553 }
554 /* find matching stream */
555 if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
556 (startcode >= 0x1e0 && startcode <= 0x1ef) ||
557 (startcode == 0x1bd)))
558 goto redo;
559
560 len = get_be16(&s->pb);
561 pts = 0;
562 dts = 0;
563 /* stuffing */
564 for(;;) {
565 c = get_byte(&s->pb);
566 len--;
567 /* XXX: for mpeg1, should test only bit 7 */
568 if (c != 0xff)
569 break;
570 }
571 if ((c & 0xc0) == 0x40) {
572 /* buffer scale & size */
573 get_byte(&s->pb);
574 c = get_byte(&s->pb);
575 len -= 2;
576 }
577 if ((c & 0xf0) == 0x20) {
578 pts = get_pts(&s->pb, c);
579 len -= 4;
580 dts = pts;
581 } else if ((c & 0xf0) == 0x30) {
582 pts = get_pts(&s->pb, c);
583 dts = get_pts(&s->pb, -1);
584 len -= 9;
585 } else if ((c & 0xc0) == 0x80) {
586 /* mpeg 2 PES */
587 if ((c & 0x30) != 0) {
588 fprintf(stderr, "Encrypted multiplex not handled\n");
589 return -EIO;
590 }
591 flags = get_byte(&s->pb);
592 header_len = get_byte(&s->pb);
593 len -= 2;
594 if (header_len > len)
595 goto redo;
596 if ((flags & 0xc0) == 0x40) {
597 pts = get_pts(&s->pb, -1);
598 dts = pts;
599 header_len -= 5;
600 len -= 5;
601 } if ((flags & 0xc0) == 0xc0) {
602 pts = get_pts(&s->pb, -1);
603 dts = get_pts(&s->pb, -1);
604 header_len -= 10;
605 len -= 10;
606 }
607 len -= header_len;
608 while (header_len > 0) {
609 get_byte(&s->pb);
610 header_len--;
611 }
612 }
613 if (startcode == 0x1bd) {
614 startcode = get_byte(&s->pb);
615 len--;
616 if (startcode >= 0x80 && startcode <= 0xbf) {
617 /* audio: skip header */
618 get_byte(&s->pb);
619 get_byte(&s->pb);
620 get_byte(&s->pb);
621 len -= 3;
622 }
623 }
624
625 /* now find stream */
626 for(i=0;i<s->nb_streams;i++) {
627 st = s->streams[i];
628 if (st->id == startcode)
629 goto found;
630 }
631 /* skip packet */
632 url_fskip(&s->pb, len);
633 goto redo;
634 found:
635 av_new_packet(pkt, len);
636 get_buffer(&s->pb, pkt->data, pkt->size);
637 pkt->pts = pts;
638 pkt->stream_index = i;
639 return 0;
640}
641
642static int mpeg_mux_read_close(AVFormatContext *s)
643{
644 MpegDemuxContext *m = s->priv_data;
645 free(m);
646 return 0;
647}
648
649AVFormat mpeg_mux_format = {
650 "mpeg",
651 "MPEG multiplex format",
652 "video/x-mpeg",
653 "mpg,mpeg,vob",
654 CODEC_ID_MP2,
655 CODEC_ID_MPEG1VIDEO,
656 mpeg_mux_init,
657 mpeg_mux_write_packet,
658 mpeg_mux_end,
659
660 mpeg_mux_read_header,
661 mpeg_mux_read_packet,
662 mpeg_mux_read_close,
663};