1 /*
2 * "Real" compatible muxer.
3 * Copyright (c) 2000, 2001 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
25
26 typedef struct {
30 /* codec related output */
38
42 int data_pos;
/* position of the data after the header */
44
45 /* in ms */
46 #define BUFFER_DURATION 0
47
48
50 {
52 while (*tag) {
54 }
55 }
56
58 {
60 while (*tag) {
62 }
63 }
64
66 int data_size, int index_pos)
67 {
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;
76
78
84
88 packet_max_size = 0;
89 packet_total_size = 0;
90 nb_packets = 0;
91 bit_rate = 0;
92 duration = 0;
100 /* select maximum duration */
102 if (v > duration)
104 }
105 avio_wb32(s, bit_rate);
/* max bit rate */
106 avio_wb32(s, bit_rate);
/* avg bit rate */
107 avio_wb32(s, packet_max_size);
/* max packet size */
108 if (nb_packets > 0)
109 packet_avg_size = packet_total_size / nb_packets;
110 else
111 packet_avg_size = 0;
112 avio_wb32(s, packet_avg_size);
/* avg packet size */
113 avio_wb32(s, nb_packets);
/* num packets */
116 avio_wb32(s, index_pos);
/* index offset */
117 /* computation of data the data offset */
119 avio_wb32(s, 0);
/* data offset : will be patched after */
121 flags = 1 | 2; /* save allowed & perfect play */
123 flags |= 4; /* live broadcast */
125
126 /* comments */
127
129 size = 4 * 2 + 10;
132 if(tag) size += strlen(tag->
value);
133 }
139 }
140
142 int codec_data_size;
143
145
147 desc = "The Audio Stream";
148 mimetype = "audio/x-pn-realaudio";
149 codec_data_size = 73;
150 } else {
151 desc = "The Video Stream";
152 mimetype = "video/x-pn-realvideo";
153 codec_data_size = 34;
154 }
155
157 size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size;
160
168 else
169 packet_avg_size = 0;
170 avio_wb32(s, packet_avg_size);
/* avg packet size */
173 /* duration */
176 else
181
187 /* audio codec info */
192 avio_wb32(s, 0x01b53530);
/* stream length */
195
196 switch(sample_rate) {
197 case 48000:
198 case 24000:
199 case 12000:
200 fscode = 1;
201 break;
202 default:
203 case 44100:
204 case 22050:
205 case 11025:
206 fscode = 2;
207 break;
208 case 32000:
209 case 16000:
210 case 8000:
211 fscode = 3;
212 }
213 avio_wb16(s, fscode);
/* codec additional info, for AC-3, seems
214 to be a frequency code */
215 /* special hack to compensate rounding errors... */
216 if (coded_frame_size == 557)
217 coded_frame_size--;
218 avio_wb32(s, coded_frame_size);
/* frame length */
223 /* frame length : seems to be very important */
229 put_str8(s,
"Int0");
/* codec name */
231 avio_w8(s, 4);
/* tag length */
233 } else {
235 return -1;
236 }
240 avio_w8(s, 0);
/* end of header */
241 } else {
242 /* video codec info */
247 else
256 /* Seems to be the codec version: only use basic H263. The next
257 versions seems to add a diffential DC coding as in
258 MPEG... nothing new under the sun */
261 else
263 //avio_wb32(s,0x10003000);
264 }
265 }
266
267 /* patch data offset field */
268 data_pos = s->
buf_ptr - start_ptr;
270 data_offset_ptr[0] = data_pos >> 24;
271 data_offset_ptr[1] = data_pos >> 16;
272 data_offset_ptr[2] = data_pos >> 8;
273 data_offset_ptr[3] = data_pos;
274
275 /* data stream */
279
280 avio_wb32(s, nb_packets);
/* number of packets */
282 return 0;
283 }
284
286 int length,
int key_frame)
287 {
288 int timestamp;
290
295
302 avio_w8(s, key_frame ? 2 : 0);
/* flags */
303 }
304
306 {
311
313 av_log(s,
AV_LOG_ERROR,
"At most 2 streams are currently supported for muxing in RM\n");
315 }
316
325
330 /* XXX: dummy values */
334 break;
338 /* XXX: dummy values */
342 break;
343 default:
344 return -1;
345 }
346 }
347
351 return 0;
352 }
353
355 {
360 int i;
361
362 /* XXX: suppress this malloc */
364
366
368 /* for AC-3, the words seem to be reversed */
369 for(i=0;i<
size;i+=2) {
370 buf1[i] = buf[i+1];
371 buf1[i+1] = buf[i];
372 }
374 } else {
376 }
379 return 0;
380 }
381
383 {
388
389 /* XXX: this is incorrect: should be a parameter */
390
391 /* Well, I spent some time finding the meaning of these bits. I am
392 not sure I understood everything, but it works !! */
393 #if 1
395 /* bit 7: '1' if final packet of a frame converted in several packets */
397 /* bit 7: '1' if I frame. bits 6..0 : sequence number in current
398 frame starting from 1 */
399 if (key_frame) {
401 } else {
403 }
404 if(size >= 0x4000){
405 avio_wb32(pb, size);
/* total frame size */
406 avio_wb32(pb, size);
/* offset from the start or the end */
407 }else{
408 avio_wb16(pb, 0x4000 | size);
/* total frame size */
409 avio_wb16(pb, 0x4000 | size);
/* offset from the start or the end */
410 }
411 #else
412 /* full frame */
415 avio_wb16(pb, 0x4000 + size);
/* total frame size */
416 avio_wb16(pb, 0x4000 + packet_number * 126);
/* position in stream */
417 #endif
419
421
423 return 0;
424 }
425
427 {
431 else
433 }
434
436 {
438 int data_size, index_pos, i;
440
442 /* end of file: finish to write header */
444 data_size = index_pos - rm->
data_pos;
445
446 /* FIXME: write index */
447
448 /* undocumented end header */
451
456 } else {
457 /* undocumented end header */
460 }
461
462 return 0;
463 }
464
465
469 .mime_type = "application/vnd.rn-realmedia",
470 .extensions = "rm,ra",
478 };