merge
[libav.git] / libav / rm.c
CommitLineData
de6d9b64
FB
1/*
2 * "Real" compatible mux and demux.
3 * Copyright (c) 2000, 2001 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#include <stdlib.h>
20#include <string.h>
21#include <stdio.h>
22#include <errno.h>
23
24#include "avformat.h"
25
26/* in ms */
27#define BUFFER_DURATION 0
28
29typedef struct {
30 int nb_packets;
31 int packet_total_size;
32 int packet_max_size;
33 /* codec related output */
34 int bit_rate;
35 float frame_rate;
36 int nb_frames; /* current frame number */
37 int total_frames; /* total number of frames */
38 int num;
39 AVCodecContext *enc;
40} StreamInfo;
41
42typedef struct {
43 StreamInfo streams[2];
44 StreamInfo *audio_stream, *video_stream;
45 int data_pos; /* position of the data after the header */
46 int nb_packets;
47} RMContext;
48
49static void put_str(ByteIOContext *s, const char *tag)
50{
51 put_be16(s,strlen(tag));
52 while (*tag) {
53 put_byte(s, *tag++);
54 }
55}
56
57static void put_str8(ByteIOContext *s, const char *tag)
58{
59 put_byte(s, strlen(tag));
60 while (*tag) {
61 put_byte(s, *tag++);
62 }
63}
64
65static void rv10_write_header(AVFormatContext *ctx,
66 int data_size, int index_pos)
67{
68 RMContext *rm = ctx->priv_data;
69 ByteIOContext *s = &ctx->pb;
70 StreamInfo *stream;
71 unsigned char *data_offset_ptr, *start_ptr;
72 const char *desc, *mimetype;
73 int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i;
74 int bit_rate, v, duration, flags, data_pos;
75
76 start_ptr = s->buf_ptr;
77
78 put_tag(s, ".RMF");
79 put_be32(s,18); /* header size */
80 put_be16(s,0);
81 put_be32(s,0);
82 put_be32(s,4 + ctx->nb_streams); /* num headers */
83
84 put_tag(s,"PROP");
85 put_be32(s, 50);
86 put_be16(s, 0);
87 packet_max_size = 0;
88 packet_total_size = 0;
89 nb_packets = 0;
90 bit_rate = 0;
91 duration = 0;
92 for(i=0;i<ctx->nb_streams;i++) {
93 StreamInfo *stream = &rm->streams[i];
94 bit_rate += stream->bit_rate;
95 if (stream->packet_max_size > packet_max_size)
96 packet_max_size = stream->packet_max_size;
97 nb_packets += stream->nb_packets;
98 packet_total_size += stream->packet_total_size;
99 /* select maximum duration */
100 v = (int) (1000.0 * (float)stream->total_frames / stream->frame_rate);
101 if (v > duration)
102 duration = v;
103 }
104 put_be32(s, bit_rate); /* max bit rate */
105 put_be32(s, bit_rate); /* avg bit rate */
106 put_be32(s, packet_max_size); /* max packet size */
107 if (nb_packets > 0)
108 packet_avg_size = packet_total_size / nb_packets;
109 else
110 packet_avg_size = 0;
111 put_be32(s, packet_avg_size); /* avg packet size */
112 put_be32(s, nb_packets); /* num packets */
113 put_be32(s, duration); /* duration */
114 put_be32(s, BUFFER_DURATION); /* preroll */
115 put_be32(s, index_pos); /* index offset */
116 /* computation of data the data offset */
117 data_offset_ptr = s->buf_ptr;
118 put_be32(s, 0); /* data offset : will be patched after */
119 put_be16(s, ctx->nb_streams); /* num streams */
120 flags = 1 | 2; /* save allowed & perfect play */
121 if (url_is_streamed(s))
122 flags |= 4; /* live broadcast */
123 put_be16(s, flags);
124
125 /* comments */
126
127 put_tag(s,"CONT");
128 size = strlen(ctx->title) + strlen(ctx->author) + strlen(ctx->copyright) +
129 strlen(ctx->comment) + 4 * 2 + 10;
130 put_be32(s,size);
131 put_be16(s,0);
132 put_str(s, ctx->title);
133 put_str(s, ctx->author);
134 put_str(s, ctx->copyright);
135 put_str(s, ctx->comment);
136
137 for(i=0;i<ctx->nb_streams;i++) {
138 int codec_data_size;
139
140 stream = &rm->streams[i];
141
142 if (stream->enc->codec_type == CODEC_TYPE_AUDIO) {
143 desc = "The Audio Stream";
144 mimetype = "audio/x-pn-realaudio";
145 codec_data_size = 73;
146 } else {
147 desc = "The Video Stream";
148 mimetype = "video/x-pn-realvideo";
149 codec_data_size = 34;
150 }
151
152 put_tag(s,"MDPR");
153 size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size;
154 put_be32(s, size);
155 put_be16(s, 0);
156
157 put_be16(s, i); /* stream number */
158 put_be32(s, stream->bit_rate); /* max bit rate */
159 put_be32(s, stream->bit_rate); /* avg bit rate */
160 put_be32(s, stream->packet_max_size); /* max packet size */
161 if (stream->nb_packets > 0)
162 packet_avg_size = stream->packet_total_size /
163 stream->nb_packets;
164 else
165 packet_avg_size = 0;
166 put_be32(s, packet_avg_size); /* avg packet size */
167 put_be32(s, 0); /* start time */
168 put_be32(s, BUFFER_DURATION); /* preroll */
169 /* duration */
170 put_be32(s, (int)(stream->total_frames * 1000 / stream->frame_rate));
171 put_str8(s, desc);
172 put_str8(s, mimetype);
173 put_be32(s, codec_data_size);
174
175 if (stream->enc->codec_type == CODEC_TYPE_AUDIO) {
176 int coded_frame_size, fscode, sample_rate;
177 sample_rate = stream->enc->sample_rate;
178 coded_frame_size = (stream->enc->bit_rate *
179 stream->enc->frame_size) / (8 * sample_rate);
180 /* audio codec info */
181 put_tag(s, ".ra");
182 put_byte(s, 0xfd);
183 put_be32(s, 0x00040000); /* version */
184 put_tag(s, ".ra4");
185 put_be32(s, 0x01b53530); /* stream length */
186 put_be16(s, 4); /* unknown */
187 put_be32(s, 0x39); /* header size */
188
189 switch(sample_rate) {
190 case 48000:
191 case 24000:
192 case 12000:
193 fscode = 1;
194 break;
195 default:
196 case 44100:
197 case 22050:
198 case 11025:
199 fscode = 2;
200 break;
201 case 32000:
202 case 16000:
203 case 8000:
204 fscode = 3;
205 }
206 put_be16(s, fscode); /* codec additional info, for AC3, seems
207 to be a frequency code */
208 /* special hack to compensate rounding errors... */
209 if (coded_frame_size == 557)
210 coded_frame_size--;
211 put_be32(s, coded_frame_size); /* frame length */
212 put_be32(s, 0x51540); /* unknown */
213 put_be32(s, 0x249f0); /* unknown */
214 put_be32(s, 0x249f0); /* unknown */
215 put_be16(s, 0x01);
216 /* frame length : seems to be very important */
217 put_be16(s, coded_frame_size);
218 put_be32(s, 0); /* unknown */
219 put_be16(s, stream->enc->sample_rate); /* sample rate */
220 put_be32(s, 0x10); /* unknown */
221 put_be16(s, stream->enc->channels);
222 put_str8(s, "Int0"); /* codec name */
223 put_str8(s, "dnet"); /* codec name */
224 put_be16(s, 0); /* title length */
225 put_be16(s, 0); /* author length */
226 put_be16(s, 0); /* copyright length */
227 put_byte(s, 0); /* end of header */
228 } else {
229 /* video codec info */
230 put_be32(s,34); /* size */
231 put_tag(s,"VIDORV10");
232 put_be16(s, stream->enc->width);
233 put_be16(s, stream->enc->height);
234 put_be16(s, 24); /* frames per seconds ? */
235 put_be32(s,0); /* unknown meaning */
236 put_be16(s, 12); /* unknown meaning */
237 put_be32(s,0); /* unknown meaning */
238 put_be16(s, 8); /* unknown meaning */
239 /* Seems to be the codec version: only use basic H263. The next
240 versions seems to add a diffential DC coding as in
241 MPEG... nothing new under the sun */
242 put_be32(s,0x10000000);
243 //put_be32(s,0x10003000);
244 }
245 }
246
247 /* patch data offset field */
248 data_pos = s->buf_ptr - start_ptr;
249 rm->data_pos = data_pos;
250 data_offset_ptr[0] = data_pos >> 24;
251 data_offset_ptr[1] = data_pos >> 16;
252 data_offset_ptr[2] = data_pos >> 8;
253 data_offset_ptr[3] = data_pos;
254
255 /* data stream */
256 put_tag(s,"DATA");
257 put_be32(s,data_size + 10 + 8);
258 put_be16(s,0);
259
260 put_be32(s, nb_packets); /* number of packets */
261 put_be32(s,0); /* next data header */
262}
263
264static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream,
265 int length, int key_frame)
266{
267 int timestamp;
268 ByteIOContext *s = &ctx->pb;
269
270 stream->nb_packets++;
271 stream->packet_total_size += length;
272 if (length > stream->packet_max_size)
273 stream->packet_max_size = length;
274
275 put_be16(s,0); /* version */
276 put_be16(s,length + 12);
277 put_be16(s, stream->num); /* stream number */
278 timestamp = (1000 * (float)stream->nb_frames) / stream->frame_rate;
279 put_be32(s, timestamp); /* timestamp */
280 put_byte(s, 0); /* reserved */
281 put_byte(s, key_frame ? 2 : 0); /* flags */
282}
283
284static int rm_write_header(AVFormatContext *s)
285{
286 StreamInfo *stream;
287 RMContext *rm;
288 int n;
289 AVCodecContext *codec;
290
291 rm = malloc(sizeof(RMContext));
292 if (!rm)
293 return -1;
294 memset(rm, 0, sizeof(RMContext));
295 s->priv_data = rm;
296
297 for(n=0;n<s->nb_streams;n++) {
298 s->streams[n]->id = n;
299 codec = &s->streams[n]->codec;
300 stream = &rm->streams[n];
301 memset(stream, 0, sizeof(StreamInfo));
302 stream->num = n;
303 stream->bit_rate = codec->bit_rate;
304 stream->enc = codec;
305
306 switch(codec->codec_type) {
307 case CODEC_TYPE_AUDIO:
308 rm->audio_stream = stream;
309 stream->frame_rate = (float)codec->sample_rate / (float)codec->frame_size;
310 /* XXX: dummy values */
311 stream->packet_max_size = 1024;
312 stream->nb_packets = 0;
313 stream->total_frames = stream->nb_packets;
314 break;
315 case CODEC_TYPE_VIDEO:
316 rm->video_stream = stream;
317 stream->frame_rate = (float)codec->frame_rate / (float)FRAME_RATE_BASE;
318 /* XXX: dummy values */
319 stream->packet_max_size = 4096;
320 stream->nb_packets = 0;
321 stream->total_frames = stream->nb_packets;
322 break;
323 }
324 }
325
326 rv10_write_header(s, 0, 0);
327 put_flush_packet(&s->pb);
328 return 0;
329}
330
331static int rm_write_audio(AVFormatContext *s, UINT8 *buf, int size)
332{
333 UINT8 buf1[size];
334 RMContext *rm = s->priv_data;
335 ByteIOContext *pb = &s->pb;
336 StreamInfo *stream = rm->audio_stream;
337 int i;
338
339 write_packet_header(s, stream, size, stream->enc->key_frame);
340
341 /* for AC3, the words seems to be reversed */
342 for(i=0;i<size;i+=2) {
343 buf1[i] = buf[i+1];
344 buf1[i+1] = buf[i];
345 }
346 put_buffer(pb, buf1, size);
347 put_flush_packet(pb);
348 stream->nb_frames++;
349 return 0;
350}
351
352static int rm_write_video(AVFormatContext *s, UINT8 *buf, int size)
353{
354 RMContext *rm = s->priv_data;
355 ByteIOContext *pb = &s->pb;
356 StreamInfo *stream = rm->video_stream;
357 int key_frame = stream->enc->key_frame;
358
359 /* XXX: this is incorrect: should be a parameter */
360
361 /* Well, I spent some time finding the meaning of these bits. I am
362 not sure I understood everything, but it works !! */
363#if 1
364 write_packet_header(s, stream, size + 7, key_frame);
365 /* bit 7: '1' if final packet of a frame converted in several packets */
366 put_byte(pb, 0x81);
367 /* bit 7: '1' if I frame. bits 6..0 : sequence number in current
368 frame starting from 1 */
369 if (key_frame) {
370 put_byte(pb, 0x81);
371 } else {
372 put_byte(pb, 0x01);
373 }
374 put_be16(pb, 0x4000 | (size)); /* total frame size */
375 put_be16(pb, 0x4000 | (size)); /* offset from the start or the end */
376#else
377 /* full frame */
378 write_packet_header(s, size + 6);
379 put_byte(pb, 0xc0);
380 put_be16(pb, 0x4000 | size); /* total frame size */
381 put_be16(pb, 0x4000 + packet_number * 126); /* position in stream */
382#endif
383 put_byte(pb, stream->nb_frames & 0xff);
384
385 put_buffer(pb, buf, size);
386 put_flush_packet(pb);
387
388 stream->nb_frames++;
389 return 0;
390}
391
392static int rm_write_packet(AVFormatContext *s, int stream_index,
393 UINT8 *buf, int size)
394{
395 if (s->streams[stream_index]->codec.codec_type ==
396 CODEC_TYPE_AUDIO)
397 return rm_write_audio(s, buf, size);
398 else
399 return rm_write_video(s, buf, size);
400}
401
402static int rm_write_trailer(AVFormatContext *s)
403{
404 RMContext *rm = s->priv_data;
405 int data_size, index_pos, i;
406 ByteIOContext *pb = &s->pb;
407
408 if (!url_is_streamed(&s->pb)) {
409 /* end of file: finish to write header */
410 index_pos = url_fseek(pb, 0, SEEK_CUR);
411 data_size = index_pos - rm->data_pos;
412
413 /* index */
414 put_tag(pb, "INDX");
415 put_be32(pb, 10 + 10 * s->nb_streams);
416 put_be16(pb, 0);
417
418 for(i=0;i<s->nb_streams;i++) {
419 put_be32(pb, 0); /* zero indices */
420 put_be16(pb, i); /* stream number */
421 put_be32(pb, 0); /* next index */
422 }
423 /* undocumented end header */
424 put_be32(pb, 0);
425 put_be32(pb, 0);
426
427 url_fseek(pb, 0, SEEK_SET);
428 for(i=0;i<s->nb_streams;i++)
429 rm->streams[i].total_frames = rm->streams[i].nb_frames;
430 rv10_write_header(s, data_size, index_pos);
431 } else {
432 /* undocumented end header */
433 put_be32(pb, 0);
434 put_be32(pb, 0);
435 }
436 put_flush_packet(pb);
437
438 free(rm);
439 return 0;
440}
441
442/***************************************************/
443
444static void get_str(ByteIOContext *pb, char *buf, int buf_size)
445{
446 int len, i;
447 char *q;
448
449 len = get_be16(pb);
450 q = buf;
451 for(i=0;i<len;i++) {
452 if (i < buf_size - 1)
453 *q++ = get_byte(pb);
454 }
455 *q = '\0';
456}
457
458static void get_str8(ByteIOContext *pb, char *buf, int buf_size)
459{
460 int len, i;
461 char *q;
462
463 len = get_byte(pb);
464 q = buf;
465 for(i=0;i<len;i++) {
466 if (i < buf_size - 1)
467 *q++ = get_byte(pb);
468 }
469 *q = '\0';
470}
471
472static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
473{
474 RMContext *rm;
475 AVStream *st;
476 ByteIOContext *pb = &s->pb;
477 unsigned int tag, v;
478 int tag_size, size, codec_data_size, i;
479 INT64 codec_pos;
480 unsigned int h263_hack_version;
481 char buf[128];
482
483 if (get_le32(pb) != MKTAG('.', 'R', 'M', 'F'))
484 return -EIO;
485 rm = av_mallocz(sizeof(RMContext));
486 if (!rm)
487 return -ENOMEM;
488 s->priv_data = rm;
489
490 get_be32(pb); /* header size */
491 get_be16(pb);
492 get_be32(pb);
493 get_be32(pb); /* number of headers */
494
495 for(;;) {
496 if (url_feof(pb))
497 goto fail;
498 tag = get_le32(pb);
499 tag_size = get_be32(pb);
500 get_be16(pb);
501#if 0
502 printf("tag=%c%c%c%c (%08x) size=%d\n",
503 (tag) & 0xff,
504 (tag >> 8) & 0xff,
505 (tag >> 16) & 0xff,
506 (tag >> 24) & 0xff,
507 tag,
508 tag_size);
509#endif
510 if (tag_size < 10)
511 goto fail;
512 switch(tag) {
513 case MKTAG('P', 'R', 'O', 'P'):
514 /* file header */
515 get_be32(pb); /* max bit rate */
516 get_be32(pb); /* avg bit rate */
517 get_be32(pb); /* max packet size */
518 get_be32(pb); /* avg packet size */
519 get_be32(pb); /* nb packets */
520 get_be32(pb); /* duration */
521 get_be32(pb); /* preroll */
522 get_be32(pb); /* index offset */
523 get_be32(pb); /* data offset */
524 get_be16(pb); /* nb streams */
525 get_be16(pb); /* flags */
526 break;
527 case MKTAG('C', 'O', 'N', 'T'):
528 get_str(pb, s->title, sizeof(s->title));
529 get_str(pb, s->author, sizeof(s->author));
530 get_str(pb, s->copyright, sizeof(s->copyright));
531 get_str(pb, s->comment, sizeof(s->comment));
532 break;
533 case MKTAG('M', 'D', 'P', 'R'):
534 st = av_mallocz(sizeof(AVStream));
535 if (!st)
536 goto fail;
537 s->streams[s->nb_streams++] = st;
538 st->id = get_be16(pb);
539 get_be32(pb); /* max bit rate */
540 st->codec.bit_rate = get_be32(pb); /* bit rate */
541 get_be32(pb); /* max packet size */
542 get_be32(pb); /* avg packet size */
543 get_be32(pb); /* start time */
544 get_be32(pb); /* preroll */
545 get_be32(pb); /* duration */
546 get_str8(pb, buf, sizeof(buf)); /* desc */
547 get_str8(pb, buf, sizeof(buf)); /* mimetype */
548 codec_data_size = get_be32(pb);
549 codec_pos = url_ftell(pb);
550
551 v = get_be32(pb);
552 if (v == MKTAG(0xfd, 'a', 'r', '.')) {
553 /* ra type header */
554 get_be32(pb); /* version */
555 get_be32(pb); /* .ra4 */
556 get_be32(pb);
557 get_be16(pb);
558 get_be32(pb); /* header size */
559 get_be16(pb); /* add codec info */
560 get_be32(pb); /* coded frame size */
561 get_be32(pb); /* ??? */
562 get_be32(pb); /* ??? */
563 get_be32(pb); /* ??? */
564 get_be16(pb); /* 1 */
565 get_be16(pb); /* coded frame size */
566 get_be32(pb);
567 st->codec.sample_rate = get_be16(pb);
568 get_be32(pb);
569 st->codec.channels = get_be16(pb);
570 get_str8(pb, buf, sizeof(buf)); /* desc */
571 get_str8(pb, buf, sizeof(buf)); /* desc */
572 st->codec.codec_type = CODEC_TYPE_AUDIO;
573 if (!strcmp(buf, "dnet")) {
574 st->codec.codec_id = CODEC_ID_AC3;
575 } else {
576 st->codec.codec_id = CODEC_ID_NONE;
577 nstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name),
578 buf);
579 }
580 } else {
581 if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) {
582 fail1:
583 fprintf(stderr, "Unsupported video codec\n");
584 goto fail;
585 }
586 st->codec.codec_tag = get_le32(pb);
587 if (st->codec.codec_tag != MKTAG('R', 'V', '1', '0'))
588 goto fail1;
589 st->codec.width = get_be16(pb);
590 st->codec.height = get_be16(pb);
591 st->codec.frame_rate = get_be16(pb) * FRAME_RATE_BASE;
592 st->codec.codec_type = CODEC_TYPE_VIDEO;
593 get_be32(pb);
594 get_be16(pb);
595 get_be32(pb);
596 get_be16(pb);
597 /* modification of h263 codec version (!) */
598 h263_hack_version = get_be32(pb);
599 switch(h263_hack_version) {
600 case 0x10000000:
601 st->codec.sub_id = 0;
602 st->codec.codec_id = CODEC_ID_RV10;
603 break;
604 case 0x10003000:
605 case 0x10003001:
606 st->codec.sub_id = 3;
607 st->codec.codec_id = CODEC_ID_RV10;
608 break;
609 default:
610 /* not handled */
611 st->codec.codec_id = CODEC_ID_NONE;
612 break;
613 }
614 }
615 /* skip codec info */
616 size = url_ftell(pb) - codec_pos;
617 url_fskip(pb, codec_data_size - size);
618 break;
619 case MKTAG('D', 'A', 'T', 'A'):
620 goto header_end;
621 default:
622 /* unknown tag: skip it */
623 url_fskip(pb, tag_size - 10);
624 break;
625 }
626 }
627 header_end:
628 rm->nb_packets = get_be32(pb); /* number of packets */
629 get_be32(pb); /* next data header */
630 return 0;
631
632 fail:
633 for(i=0;i<s->nb_streams;i++) {
634 free(s->streams[i]);
635 }
636 return -EIO;
637}
638
639static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
640{
641 RMContext *rm = s->priv_data;
642 ByteIOContext *pb = &s->pb;
643 AVStream *st;
644 int len, num, timestamp, i, tmp, j;
645 UINT8 *ptr;
646
647 redo:
648 if (rm->nb_packets == 0)
649 return -EIO;
650 get_be16(pb);
651 len = get_be16(pb);
652 if (len < 12)
653 return -EIO;
654 num = get_be16(pb);
655 timestamp = get_be32(pb);
656 get_byte(pb); /* reserved */
657 get_byte(pb); /* flags */
658 rm->nb_packets--;
659 len -= 12;
660
661 st = NULL;
662 for(i=0;i<s->nb_streams;i++) {
663 st = s->streams[i];
664 if (num == st->id)
665 break;
666 }
667 if (i == s->nb_streams) {
668 /* skip packet if unknown number */
669 url_fskip(pb, len);
670 goto redo;
671 }
672
673 av_new_packet(pkt, len);
674 pkt->stream_index = i;
675 get_buffer(pb, pkt->data, len);
676 /* for AC3, needs to swap bytes */
677 if (st->codec.codec_id == CODEC_ID_AC3) {
678 ptr = pkt->data;
679 for(j=0;j<len;j+=2) {
680 tmp = ptr[0];
681 ptr[0] = ptr[1];
682 ptr[1] = tmp;
683 ptr += 2;
684 }
685 }
686 return 0;
687}
688
689static int rm_read_close(AVFormatContext *s)
690{
691 RMContext *rm = s->priv_data;
692 free(rm);
693 return 0;
694}
695
696AVFormat rm_format = {
697 "rm",
698 "rm format",
699 "audio/x-pn-realaudio",
700 "rm,ra",
701 CODEC_ID_AC3,
702 CODEC_ID_RV10,
703 rm_write_header,
704 rm_write_packet,
705 rm_write_trailer,
706
707 rm_read_header,
708 rm_read_packet,
709 rm_read_close,
710};