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 */ 21#include "avformat.h" 22#include "avio_internal.h" 23#include "rm.h" 24#include "libavutil/dict.h" 25 26typedef struct StreamInfo { 27 int nb_packets; 28 int packet_total_size; 29 int packet_max_size; 30 /* codec related output */ 31 int bit_rate; 32 AVRational frame_rate; 33 int nb_frames; /* current frame number */ 34 int total_frames; /* total number of frames */ 35 int num; 36 AVCodecParameters *par; 37} StreamInfo; 38 39typedef struct RMMuxContext { 40 StreamInfo streams[2]; 41 StreamInfo *audio_stream, *video_stream; 42 int data_pos; /* position of the data after the header */ 43} RMMuxContext; 44 45/* in ms */ 46#define BUFFER_DURATION 0 47/* the header needs at most 7 + 4 + 12 B */ 48#define MAX_HEADER_SIZE (7 + 4 + 12) 49/* UINT16_MAX is the maximal chunk size */ 50#define MAX_PACKET_SIZE (UINT16_MAX - MAX_HEADER_SIZE) 51 52 53static void put_str(AVIOContext *s, const char *tag) 54{ 55 avio_wb16(s,strlen(tag)); 56 while (*tag) { 57 avio_w8(s, *tag++); 58 } 59} 60 61static void put_str8(AVIOContext *s, const char *tag) 62{ 63 avio_w8(s, strlen(tag)); 64 while (*tag) { 65 avio_w8(s, *tag++); 66 } 67} 68 69static int rv10_write_header(AVFormatContext *ctx, 70 int data_size, int index_pos) 71{ 72 RMMuxContext *rm = ctx->priv_data; 73 AVIOContext *s = ctx->pb; 74 StreamInfo *stream; 75 const char *desc, *mimetype; 76 int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i; 77 int bit_rate, v, duration, flags; 78 int data_offset; 79 AVDictionaryEntry *tag; 80 81 ffio_wfourcc(s, ".RMF"); 82 avio_wb32(s,18); /* header size */ 83 avio_wb16(s,0); 84 avio_wb32(s,0); 85 avio_wb32(s,4 + ctx->nb_streams); /* num headers */ 86 87 ffio_wfourcc(s,"PROP"); 88 avio_wb32(s, 50); 89 avio_wb16(s, 0); 90 packet_max_size = 0; 91 packet_total_size = 0; 92 nb_packets = 0; 93 bit_rate = 0; 94 duration = 0; 95 for(i=0;i<ctx->nb_streams;i++) { 96 StreamInfo *stream = &rm->streams[i]; 97 bit_rate += stream->bit_rate; 98 if (stream->packet_max_size > packet_max_size) 99 packet_max_size = stream->packet_max_size; 100 nb_packets += stream->nb_packets; 101 packet_total_size += stream->packet_total_size; 102 /* select maximum duration */ 103 v = av_rescale_q_rnd(stream->total_frames, (AVRational){1000, 1}, stream->frame_rate, AV_ROUND_ZERO); 104 if (v > duration) 105 duration = v; 106 } 107 avio_wb32(s, bit_rate); /* max bit rate */ 108 avio_wb32(s, bit_rate); /* avg bit rate */ 109 avio_wb32(s, packet_max_size); /* max packet size */ 110 if (nb_packets > 0) 111 packet_avg_size = packet_total_size / nb_packets; 112 else 113 packet_avg_size = 0; 114 avio_wb32(s, packet_avg_size); /* avg packet size */ 115 avio_wb32(s, nb_packets); /* num packets */ 116 avio_wb32(s, duration); /* duration */ 117 avio_wb32(s, BUFFER_DURATION); /* preroll */ 118 avio_wb32(s, index_pos); /* index offset */ 119 /* computation of data the data offset */ 120 data_offset = avio_tell(s); 121 avio_wb32(s, 0); /* data offset : will be patched after */ 122 avio_wb16(s, ctx->nb_streams); /* num streams */ 123 flags = 1 | 2; /* save allowed & perfect play */ 124 if (!(s->seekable & AVIO_SEEKABLE_NORMAL)) 125 flags |= 4; /* live broadcast */ 126 avio_wb16(s, flags); 127 128 /* comments */ 129 130 ffio_wfourcc(s,"CONT"); 131 size = 4 * 2 + 10; 132 for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) { 133 tag = av_dict_get(ctx->metadata, ff_rm_metadata[i], NULL, 0); 134 if(tag) size += strlen(tag->value); 135 } 136 avio_wb32(s,size); 137 avio_wb16(s,0); 138 for(i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) { 139 tag = av_dict_get(ctx->metadata, ff_rm_metadata[i], NULL, 0); 140 put_str(s, tag ? tag->value : ""); 141 } 142 143 for(i=0;i<ctx->nb_streams;i++) { 144 int codec_data_size; 145 146 stream = &rm->streams[i]; 147 148 if (stream->par->codec_type == AVMEDIA_TYPE_AUDIO) { 149 desc = "The Audio Stream"; 150 mimetype = "audio/x-pn-realaudio"; 151 codec_data_size = 73; 152 } else { 153 desc = "The Video Stream"; 154 mimetype = "video/x-pn-realvideo"; 155 codec_data_size = 34; 156 } 157 158 ffio_wfourcc(s,"MDPR"); 159 size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size; 160 avio_wb32(s, size); 161 avio_wb16(s, 0); 162 163 avio_wb16(s, i); /* stream number */ 164 avio_wb32(s, stream->bit_rate); /* max bit rate */ 165 avio_wb32(s, stream->bit_rate); /* avg bit rate */ 166 avio_wb32(s, stream->packet_max_size); /* max packet size */ 167 if (stream->nb_packets > 0) 168 packet_avg_size = stream->packet_total_size / 169 stream->nb_packets; 170 else 171 packet_avg_size = 0; 172 avio_wb32(s, packet_avg_size); /* avg packet size */ 173 avio_wb32(s, 0); /* start time */ 174 avio_wb32(s, BUFFER_DURATION); /* preroll */ 175 /* duration */ 176 if (!(s->seekable & AVIO_SEEKABLE_NORMAL) || !stream->total_frames) 177 avio_wb32(s, (int)(3600 * 1000)); 178 else 179 avio_wb32(s, av_rescale_q_rnd(stream->total_frames, (AVRational){1000, 1}, stream->frame_rate, AV_ROUND_ZERO)); 180 put_str8(s, desc); 181 put_str8(s, mimetype); 182 avio_wb32(s, codec_data_size); 183 184 if (stream->par->codec_type == AVMEDIA_TYPE_AUDIO) { 185 int coded_frame_size, fscode, sample_rate; 186 int frame_size = av_get_audio_frame_duration2(stream->par, 0); 187 sample_rate = stream->par->sample_rate; 188 coded_frame_size = (stream->par->bit_rate * 189 frame_size) / (8 * sample_rate); 190 /* audio codec info */ 191 avio_write(s, ".ra", 3); 192 avio_w8(s, 0xfd); 193 avio_wb32(s, 0x00040000); /* version */ 194 ffio_wfourcc(s, ".ra4"); 195 avio_wb32(s, 0x01b53530); /* stream length */ 196 avio_wb16(s, 4); /* unknown */ 197 avio_wb32(s, 0x39); /* header size */ 198 199 switch(sample_rate) { 200 case 48000: 201 case 24000: 202 case 12000: 203 fscode = 1; 204 break; 205 default: 206 case 44100: 207 case 22050: 208 case 11025: 209 fscode = 2; 210 break; 211 case 32000: 212 case 16000: 213 case 8000: 214 fscode = 3; 215 } 216 avio_wb16(s, fscode); /* codec additional info, for AC-3, seems 217 to be a frequency code */ 218 /* special hack to compensate rounding errors... */ 219 if (coded_frame_size == 557) 220 coded_frame_size--; 221 avio_wb32(s, coded_frame_size); /* frame length */ 222 avio_wb32(s, 0x51540); /* unknown */ 223 avio_wb32(s, stream->par->bit_rate / 8 * 60); /* bytes per minute */ 224 avio_wb32(s, stream->par->bit_rate / 8 * 60); /* bytes per minute */ 225 avio_wb16(s, 0x01); 226 /* frame length : seems to be very important */ 227 avio_wb16(s, coded_frame_size); 228 avio_wb32(s, 0); /* unknown */ 229 avio_wb16(s, stream->par->sample_rate); /* sample rate */ 230 avio_wb32(s, 0x10); /* unknown */ 231 avio_wb16(s, stream->par->ch_layout.nb_channels); 232 put_str8(s, "Int0"); /* codec name */ 233 if (stream->par->codec_tag) { 234 avio_w8(s, 4); /* tag length */ 235 avio_wl32(s, stream->par->codec_tag); 236 } else { 237 av_log(ctx, AV_LOG_ERROR, "Invalid codec tag\n"); 238 return -1; 239 } 240 avio_wb16(s, 0); /* title length */ 241 avio_wb16(s, 0); /* author length */ 242 avio_wb16(s, 0); /* copyright length */ 243 avio_w8(s, 0); /* end of header */ 244 } else { 245 /* video codec info */ 246 avio_wb32(s,34); /* size */ 247 ffio_wfourcc(s, "VIDO"); 248 if(stream->par->codec_id == AV_CODEC_ID_RV10) 249 ffio_wfourcc(s,"RV10"); 250 else 251 ffio_wfourcc(s,"RV20"); 252 avio_wb16(s, stream->par->width); 253 avio_wb16(s, stream->par->height); 254 255 if (stream->frame_rate.num / stream->frame_rate.den > 65535) { 256 av_log(s, AV_LOG_ERROR, "Frame rate %d is too high\n", stream->frame_rate.num / stream->frame_rate.den); 257 return AVERROR(EINVAL); 258 } 259 260 avio_wb16(s, stream->frame_rate.num / stream->frame_rate.den); /* frames per seconds ? */ 261 avio_wb32(s,0); /* unknown meaning */ 262 avio_wb16(s, stream->frame_rate.num / stream->frame_rate.den); /* unknown meaning */ 263 avio_wb32(s,0); /* unknown meaning */ 264 avio_wb16(s, 8); /* unknown meaning */ 265 /* Seems to be the codec version: only use basic H.263. The next 266 versions seems to add a differential DC coding as in 267 MPEG... nothing new under the sun. */ 268 if(stream->par->codec_id == AV_CODEC_ID_RV10) 269 avio_wb32(s,0x10000000); 270 else 271 avio_wb32(s,0x20103001); 272 //avio_wb32(s,0x10003000); 273 } 274 } 275 276 /* patch data offset field */ 277 rm->data_pos = avio_tell(s); 278 if (avio_seek(s, data_offset, SEEK_SET) >= 0) { 279 avio_wb32(s, rm->data_pos); 280 avio_seek(s, rm->data_pos, SEEK_SET); 281 } 282 283 /* data stream */ 284 ffio_wfourcc(s, "DATA"); 285 avio_wb32(s,data_size + 10 + 8); 286 avio_wb16(s,0); 287 288 avio_wb32(s, nb_packets); /* number of packets */ 289 avio_wb32(s,0); /* next data header */ 290 return 0; 291} 292 293static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream, 294 int length, int key_frame) 295{ 296 int timestamp; 297 AVIOContext *s = ctx->pb; 298 299 stream->nb_packets++; 300 stream->packet_total_size += length; 301 if (length > stream->packet_max_size) 302 stream->packet_max_size = length; 303 304 avio_wb16(s,0); /* version */ 305 avio_wb16(s,length + 12); 306 avio_wb16(s, stream->num); /* stream number */ 307 timestamp = av_rescale_q_rnd(stream->nb_frames, (AVRational){1000, 1}, stream->frame_rate, AV_ROUND_ZERO); 308 avio_wb32(s, timestamp); /* timestamp */ 309 avio_w8(s, 0); /* reserved */ 310 avio_w8(s, key_frame ? 2 : 0); /* flags */ 311} 312 313static int rm_write_header(AVFormatContext *s) 314{ 315 RMMuxContext *rm = s->priv_data; 316 StreamInfo *stream; 317 int n; 318 AVCodecParameters *par; 319 320 if (s->nb_streams > 2) { 321 av_log(s, AV_LOG_ERROR, "At most 2 streams are currently supported for muxing in RM\n"); 322 return AVERROR_PATCHWELCOME; 323 } 324 325 for(n=0;n<s->nb_streams;n++) { 326 AVStream *st = s->streams[n]; 327 int frame_size; 328 329 s->streams[n]->id = n; 330 par = s->streams[n]->codecpar; 331 stream = &rm->streams[n]; 332 memset(stream, 0, sizeof(StreamInfo)); 333 stream->num = n; 334 stream->bit_rate = par->bit_rate; 335 stream->par = par; 336 337 switch (par->codec_type) { 338 case AVMEDIA_TYPE_AUDIO: 339 rm->audio_stream = stream; 340 frame_size = av_get_audio_frame_duration2(par, 0); 341 stream->frame_rate = (AVRational){par->sample_rate, frame_size}; 342 /* XXX: dummy values */ 343 stream->packet_max_size = 1024; 344 stream->nb_packets = 0; 345 stream->total_frames = stream->nb_packets; 346 break; 347 case AVMEDIA_TYPE_VIDEO: 348 rm->video_stream = stream; 349 // TODO: should be avg_frame_rate 350 stream->frame_rate = av_inv_q(st->time_base); 351 /* XXX: dummy values */ 352 stream->packet_max_size = 4096; 353 stream->nb_packets = 0; 354 stream->total_frames = stream->nb_packets; 355 break; 356 default: 357 return -1; 358 } 359 } 360 361 if (rv10_write_header(s, 0, 0)) 362 return AVERROR_INVALIDDATA; 363 return 0; 364} 365 366static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int flags) 367{ 368 RMMuxContext *rm = s->priv_data; 369 AVIOContext *pb = s->pb; 370 StreamInfo *stream = rm->audio_stream; 371 int i; 372 373 write_packet_header(s, stream, size, !!(flags & AV_PKT_FLAG_KEY)); 374 375 if (stream->par->codec_id == AV_CODEC_ID_AC3) { 376 /* for AC-3, the words seem to be reversed */ 377 for (i = 0; i < size; i += 2) { 378 avio_w8(pb, buf[i + 1]); 379 avio_w8(pb, buf[i]); 380 } 381 } else { 382 avio_write(pb, buf, size); 383 } 384 stream->nb_frames++; 385 return 0; 386} 387 388static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags) 389{ 390 RMMuxContext *rm = s->priv_data; 391 AVIOContext *pb = s->pb; 392 StreamInfo *stream = rm->video_stream; 393 int key_frame = !!(flags & AV_PKT_FLAG_KEY); 394 395 /* XXX: this is incorrect: should be a parameter */ 396 397 /* Well, I spent some time finding the meaning of these bits. I am 398 not sure I understood everything, but it works !! */ 399 if (size > MAX_PACKET_SIZE) { 400 av_log(s, AV_LOG_ERROR, "Muxing packets larger than 64 kB (%d) is not supported\n", size); 401 return AVERROR_PATCHWELCOME; 402 } 403 write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame); 404 /* bit 7: '1' if final packet of a frame converted in several packets */ 405 avio_w8(pb, 0x81); 406 /* bit 7: '1' if I-frame. bits 6..0 : sequence number in current 407 frame starting from 1 */ 408 if (key_frame) { 409 avio_w8(pb, 0x81); 410 } else { 411 avio_w8(pb, 0x01); 412 } 413 if(size >= 0x4000){ 414 avio_wb32(pb, size); /* total frame size */ 415 avio_wb32(pb, size); /* offset from the start or the end */ 416 }else{ 417 avio_wb16(pb, 0x4000 | size); /* total frame size */ 418 avio_wb16(pb, 0x4000 | size); /* offset from the start or the end */ 419 } 420 avio_w8(pb, stream->nb_frames & 0xff); 421 422 avio_write(pb, buf, size); 423 424 stream->nb_frames++; 425 return 0; 426} 427 428static int rm_write_packet(AVFormatContext *s, AVPacket *pkt) 429{ 430 if (s->streams[pkt->stream_index]->codecpar->codec_type == 431 AVMEDIA_TYPE_AUDIO) 432 return rm_write_audio(s, pkt->data, pkt->size, pkt->flags); 433 else 434 return rm_write_video(s, pkt->data, pkt->size, pkt->flags); 435} 436 437static int rm_write_trailer(AVFormatContext *s) 438{ 439 RMMuxContext *rm = s->priv_data; 440 int data_size, index_pos, i; 441 AVIOContext *pb = s->pb; 442 443 if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) { 444 /* end of file: finish to write header */ 445 index_pos = avio_tell(pb); 446 data_size = index_pos - rm->data_pos; 447 448 /* FIXME: write index */ 449 450 /* undocumented end header */ 451 avio_wb32(pb, 0); 452 avio_wb32(pb, 0); 453 454 avio_seek(pb, 0, SEEK_SET); 455 for(i=0;i<s->nb_streams;i++) 456 rm->streams[i].total_frames = rm->streams[i].nb_frames; 457 rv10_write_header(s, data_size, 0); 458 } else { 459 /* undocumented end header */ 460 avio_wb32(pb, 0); 461 avio_wb32(pb, 0); 462 } 463 464 return 0; 465} 466 467 468const AVOutputFormat ff_rm_muxer = { 469 .name = "rm", 470 .long_name = NULL_IF_CONFIG_SMALL("RealMedia"), 471 .mime_type = "application/vnd.rn-realmedia", 472 .extensions = "rm,ra", 473 .priv_data_size = sizeof(RMMuxContext), 474 .audio_codec = AV_CODEC_ID_AC3, 475 .video_codec = AV_CODEC_ID_RV10, 476 .write_header = rm_write_header, 477 .write_packet = rm_write_packet, 478 .write_trailer = rm_write_trailer, 479 .codec_tag = (const AVCodecTag* const []){ ff_rm_codec_tags, 0 }, 480}; 481