1/* 2 * Flash Compatible Streaming Format muxer 3 * Copyright (c) 2000 Fabrice Bellard 4 * Copyright (c) 2003 Tinic Uro 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23#include "libavcodec/put_bits.h" 24#include "avformat.h" 25#include "swf.h" 26 27static void put_swf_tag(AVFormatContext *s, int tag) 28{ 29 SWFContext *swf = s->priv_data; 30 ByteIOContext *pb = s->pb; 31 32 swf->tag_pos = url_ftell(pb); 33 swf->tag = tag; 34 /* reserve some room for the tag */ 35 if (tag & TAG_LONG) { 36 put_le16(pb, 0); 37 put_le32(pb, 0); 38 } else { 39 put_le16(pb, 0); 40 } 41} 42 43static void put_swf_end_tag(AVFormatContext *s) 44{ 45 SWFContext *swf = s->priv_data; 46 ByteIOContext *pb = s->pb; 47 int64_t pos; 48 int tag_len, tag; 49 50 pos = url_ftell(pb); 51 tag_len = pos - swf->tag_pos - 2; 52 tag = swf->tag; 53 url_fseek(pb, swf->tag_pos, SEEK_SET); 54 if (tag & TAG_LONG) { 55 tag &= ~TAG_LONG; 56 put_le16(pb, (tag << 6) | 0x3f); 57 put_le32(pb, tag_len - 4); 58 } else { 59 assert(tag_len < 0x3f); 60 put_le16(pb, (tag << 6) | tag_len); 61 } 62 url_fseek(pb, pos, SEEK_SET); 63} 64 65static inline void max_nbits(int *nbits_ptr, int val) 66{ 67 int n; 68 69 if (val == 0) 70 return; 71 val = abs(val); 72 n = 1; 73 while (val != 0) { 74 n++; 75 val >>= 1; 76 } 77 if (n > *nbits_ptr) 78 *nbits_ptr = n; 79} 80 81static void put_swf_rect(ByteIOContext *pb, 82 int xmin, int xmax, int ymin, int ymax) 83{ 84 PutBitContext p; 85 uint8_t buf[256]; 86 int nbits, mask; 87 88 init_put_bits(&p, buf, sizeof(buf)); 89 90 nbits = 0; 91 max_nbits(&nbits, xmin); 92 max_nbits(&nbits, xmax); 93 max_nbits(&nbits, ymin); 94 max_nbits(&nbits, ymax); 95 mask = (1 << nbits) - 1; 96 97 /* rectangle info */ 98 put_bits(&p, 5, nbits); 99 put_bits(&p, nbits, xmin & mask); 100 put_bits(&p, nbits, xmax & mask); 101 put_bits(&p, nbits, ymin & mask); 102 put_bits(&p, nbits, ymax & mask); 103 104 flush_put_bits(&p); 105 put_buffer(pb, buf, put_bits_ptr(&p) - p.buf); 106} 107 108static void put_swf_line_edge(PutBitContext *pb, int dx, int dy) 109{ 110 int nbits, mask; 111 112 put_bits(pb, 1, 1); /* edge */ 113 put_bits(pb, 1, 1); /* line select */ 114 nbits = 2; 115 max_nbits(&nbits, dx); 116 max_nbits(&nbits, dy); 117 118 mask = (1 << nbits) - 1; 119 put_bits(pb, 4, nbits - 2); /* 16 bits precision */ 120 if (dx == 0) { 121 put_bits(pb, 1, 0); 122 put_bits(pb, 1, 1); 123 put_bits(pb, nbits, dy & mask); 124 } else if (dy == 0) { 125 put_bits(pb, 1, 0); 126 put_bits(pb, 1, 0); 127 put_bits(pb, nbits, dx & mask); 128 } else { 129 put_bits(pb, 1, 1); 130 put_bits(pb, nbits, dx & mask); 131 put_bits(pb, nbits, dy & mask); 132 } 133} 134 135#define FRAC_BITS 16 136 137static void put_swf_matrix(ByteIOContext *pb, 138 int a, int b, int c, int d, int tx, int ty) 139{ 140 PutBitContext p; 141 uint8_t buf[256]; 142 int nbits; 143 144 init_put_bits(&p, buf, sizeof(buf)); 145 146 put_bits(&p, 1, 1); /* a, d present */ 147 nbits = 1; 148 max_nbits(&nbits, a); 149 max_nbits(&nbits, d); 150 put_bits(&p, 5, nbits); /* nb bits */ 151 put_bits(&p, nbits, a); 152 put_bits(&p, nbits, d); 153 154 put_bits(&p, 1, 1); /* b, c present */ 155 nbits = 1; 156 max_nbits(&nbits, c); 157 max_nbits(&nbits, b); 158 put_bits(&p, 5, nbits); /* nb bits */ 159 put_bits(&p, nbits, c); 160 put_bits(&p, nbits, b); 161 162 nbits = 1; 163 max_nbits(&nbits, tx); 164 max_nbits(&nbits, ty); 165 put_bits(&p, 5, nbits); /* nb bits */ 166 put_bits(&p, nbits, tx); 167 put_bits(&p, nbits, ty); 168 169 flush_put_bits(&p); 170 put_buffer(pb, buf, put_bits_ptr(&p) - p.buf); 171} 172 173static int swf_write_header(AVFormatContext *s) 174{ 175 SWFContext *swf = s->priv_data; 176 ByteIOContext *pb = s->pb; 177 PutBitContext p; 178 uint8_t buf1[256]; 179 int i, width, height, rate, rate_base; 180 int version; 181 182 swf->sound_samples = 0; 183 swf->swf_frame_number = 0; 184 swf->video_frame_number = 0; 185 186 for(i=0;i<s->nb_streams;i++) { 187 AVCodecContext *enc = s->streams[i]->codec; 188 if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { 189 if (enc->codec_id == CODEC_ID_MP3) { 190 if (!enc->frame_size) { 191 av_log(s, AV_LOG_ERROR, "audio frame size not set\n"); 192 return -1; 193 } 194 swf->audio_enc = enc; 195 swf->audio_fifo= av_fifo_alloc(AUDIO_FIFO_SIZE); 196 if (!swf->audio_fifo) 197 return AVERROR(ENOMEM); 198 } else { 199 av_log(s, AV_LOG_ERROR, "SWF muxer only supports MP3\n"); 200 return -1; 201 } 202 } else { 203 if (enc->codec_id == CODEC_ID_VP6F || 204 enc->codec_id == CODEC_ID_FLV1 || 205 enc->codec_id == CODEC_ID_MJPEG) { 206 swf->video_enc = enc; 207 } else { 208 av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n"); 209 return -1; 210 } 211 } 212 } 213 214 if (!swf->video_enc) { 215 /* currently, cannot work correctly if audio only */ 216 width = 320; 217 height = 200; 218 rate = 10; 219 rate_base= 1; 220 } else { 221 width = swf->video_enc->width; 222 height = swf->video_enc->height; 223 rate = swf->video_enc->time_base.den; 224 rate_base = swf->video_enc->time_base.num; 225 } 226 227 if (!swf->audio_enc) 228 swf->samples_per_frame = (44100. * rate_base) / rate; 229 else 230 swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate; 231 232 put_tag(pb, "FWS"); 233 234 if (!strcmp("avm2", s->oformat->name)) 235 version = 9; 236 else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_VP6F) 237 version = 8; /* version 8 and above support VP6 codec */ 238 else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_FLV1) 239 version = 6; /* version 6 and above support FLV1 codec */ 240 else 241 version = 4; /* version 4 for mpeg audio support */ 242 put_byte(pb, version); 243 244 put_le32(pb, DUMMY_FILE_SIZE); /* dummy size 245 (will be patched if not streamed) */ 246 247 put_swf_rect(pb, 0, width * 20, 0, height * 20); 248 put_le16(pb, (rate * 256) / rate_base); /* frame rate */ 249 swf->duration_pos = url_ftell(pb); 250 put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */ 251 252 /* avm2/swf v9 (also v8?) files require a file attribute tag */ 253 if (version == 9) { 254 put_swf_tag(s, TAG_FILEATTRIBUTES); 255 put_le32(pb, 1<<3); /* set ActionScript v3/AVM2 flag */ 256 put_swf_end_tag(s); 257 } 258 259 /* define a shape with the jpeg inside */ 260 if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_MJPEG) { 261 put_swf_tag(s, TAG_DEFINESHAPE); 262 263 put_le16(pb, SHAPE_ID); /* ID of shape */ 264 /* bounding rectangle */ 265 put_swf_rect(pb, 0, width, 0, height); 266 /* style info */ 267 put_byte(pb, 1); /* one fill style */ 268 put_byte(pb, 0x41); /* clipped bitmap fill */ 269 put_le16(pb, BITMAP_ID); /* bitmap ID */ 270 /* position of the bitmap */ 271 put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0, 272 0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0); 273 put_byte(pb, 0); /* no line style */ 274 275 /* shape drawing */ 276 init_put_bits(&p, buf1, sizeof(buf1)); 277 put_bits(&p, 4, 1); /* one fill bit */ 278 put_bits(&p, 4, 0); /* zero line bit */ 279 280 put_bits(&p, 1, 0); /* not an edge */ 281 put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0); 282 put_bits(&p, 5, 1); /* nbits */ 283 put_bits(&p, 1, 0); /* X */ 284 put_bits(&p, 1, 0); /* Y */ 285 put_bits(&p, 1, 1); /* set fill style 1 */ 286 287 /* draw the rectangle ! */ 288 put_swf_line_edge(&p, width, 0); 289 put_swf_line_edge(&p, 0, height); 290 put_swf_line_edge(&p, -width, 0); 291 put_swf_line_edge(&p, 0, -height); 292 293 /* end of shape */ 294 put_bits(&p, 1, 0); /* not an edge */ 295 put_bits(&p, 5, 0); 296 297 flush_put_bits(&p); 298 put_buffer(pb, buf1, put_bits_ptr(&p) - p.buf); 299 300 put_swf_end_tag(s); 301 } 302 303 if (swf->audio_enc && swf->audio_enc->codec_id == CODEC_ID_MP3) { 304 int v = 0; 305 306 /* start sound */ 307 put_swf_tag(s, TAG_STREAMHEAD2); 308 switch(swf->audio_enc->sample_rate) { 309 case 11025: v |= 1 << 2; break; 310 case 22050: v |= 2 << 2; break; 311 case 44100: v |= 3 << 2; break; 312 default: 313 /* not supported */ 314 av_log(s, AV_LOG_ERROR, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n"); 315 return -1; 316 } 317 v |= 0x02; /* 16 bit playback */ 318 if (swf->audio_enc->channels == 2) 319 v |= 0x01; /* stereo playback */ 320 put_byte(s->pb, v); 321 v |= 0x20; /* mp3 compressed */ 322 put_byte(s->pb, v); 323 put_le16(s->pb, swf->samples_per_frame); /* avg samples per frame */ 324 put_le16(s->pb, 0); 325 326 put_swf_end_tag(s); 327 } 328 329 put_flush_packet(s->pb); 330 return 0; 331} 332 333static int swf_write_video(AVFormatContext *s, 334 AVCodecContext *enc, const uint8_t *buf, int size) 335{ 336 SWFContext *swf = s->priv_data; 337 ByteIOContext *pb = s->pb; 338 339 /* Flash Player limit */ 340 if (swf->swf_frame_number == 16000) 341 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n"); 342 343 if (enc->codec_id == CODEC_ID_VP6F || 344 enc->codec_id == CODEC_ID_FLV1) { 345 if (swf->video_frame_number == 0) { 346 /* create a new video object */ 347 put_swf_tag(s, TAG_VIDEOSTREAM); 348 put_le16(pb, VIDEO_ID); 349 swf->vframes_pos = url_ftell(pb); 350 put_le16(pb, 15000); /* hard flash player limit */ 351 put_le16(pb, enc->width); 352 put_le16(pb, enc->height); 353 put_byte(pb, 0); 354 put_byte(pb,ff_codec_get_tag(swf_codec_tags,enc->codec_id)); 355 put_swf_end_tag(s); 356 357 /* place the video object for the first time */ 358 put_swf_tag(s, TAG_PLACEOBJECT2); 359 put_byte(pb, 0x36); 360 put_le16(pb, 1); 361 put_le16(pb, VIDEO_ID); 362 put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0); 363 put_le16(pb, swf->video_frame_number); 364 put_tag(pb, "video"); 365 put_byte(pb, 0x00); 366 put_swf_end_tag(s); 367 } else { 368 /* mark the character for update */ 369 put_swf_tag(s, TAG_PLACEOBJECT2); 370 put_byte(pb, 0x11); 371 put_le16(pb, 1); 372 put_le16(pb, swf->video_frame_number); 373 put_swf_end_tag(s); 374 } 375 376 /* set video frame data */ 377 put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG); 378 put_le16(pb, VIDEO_ID); 379 put_le16(pb, swf->video_frame_number++); 380 put_buffer(pb, buf, size); 381 put_swf_end_tag(s); 382 } else if (enc->codec_id == CODEC_ID_MJPEG) { 383 if (swf->swf_frame_number > 0) { 384 /* remove the shape */ 385 put_swf_tag(s, TAG_REMOVEOBJECT); 386 put_le16(pb, SHAPE_ID); /* shape ID */ 387 put_le16(pb, 1); /* depth */ 388 put_swf_end_tag(s); 389 390 /* free the bitmap */ 391 put_swf_tag(s, TAG_FREECHARACTER); 392 put_le16(pb, BITMAP_ID); 393 put_swf_end_tag(s); 394 } 395 396 put_swf_tag(s, TAG_JPEG2 | TAG_LONG); 397 398 put_le16(pb, BITMAP_ID); /* ID of the image */ 399 400 /* a dummy jpeg header seems to be required */ 401 put_be32(pb, 0xffd8ffd9); 402 /* write the jpeg image */ 403 put_buffer(pb, buf, size); 404 405 put_swf_end_tag(s); 406 407 /* draw the shape */ 408 409 put_swf_tag(s, TAG_PLACEOBJECT); 410 put_le16(pb, SHAPE_ID); /* shape ID */ 411 put_le16(pb, 1); /* depth */ 412 put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0); 413 put_swf_end_tag(s); 414 } 415 416 swf->swf_frame_number++; 417 418 /* streaming sound always should be placed just before showframe tags */ 419 if (swf->audio_enc && av_fifo_size(swf->audio_fifo)) { 420 int frame_size = av_fifo_size(swf->audio_fifo); 421 put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG); 422 put_le16(pb, swf->sound_samples); 423 put_le16(pb, 0); // seek samples 424 av_fifo_generic_read(swf->audio_fifo, pb, frame_size, &put_buffer); 425 put_swf_end_tag(s); 426 427 /* update FIFO */ 428 swf->sound_samples = 0; 429 } 430 431 /* output the frame */ 432 put_swf_tag(s, TAG_SHOWFRAME); 433 put_swf_end_tag(s); 434 435 put_flush_packet(s->pb); 436 437 return 0; 438} 439 440static int swf_write_audio(AVFormatContext *s, 441 AVCodecContext *enc, uint8_t *buf, int size) 442{ 443 SWFContext *swf = s->priv_data; 444 445 /* Flash Player limit */ 446 if (swf->swf_frame_number == 16000) 447 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n"); 448 449 if (av_fifo_size(swf->audio_fifo) + size > AUDIO_FIFO_SIZE) { 450 av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n"); 451 return -1; 452 } 453 454 av_fifo_generic_write(swf->audio_fifo, buf, size, NULL); 455 swf->sound_samples += enc->frame_size; 456 457 /* if audio only stream make sure we add swf frames */ 458 if (!swf->video_enc) 459 swf_write_video(s, enc, 0, 0); 460 461 return 0; 462} 463 464static int swf_write_packet(AVFormatContext *s, AVPacket *pkt) 465{ 466 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; 467 if (codec->codec_type == AVMEDIA_TYPE_AUDIO) 468 return swf_write_audio(s, codec, pkt->data, pkt->size); 469 else 470 return swf_write_video(s, codec, pkt->data, pkt->size); 471} 472 473static int swf_write_trailer(AVFormatContext *s) 474{ 475 SWFContext *swf = s->priv_data; 476 ByteIOContext *pb = s->pb; 477 AVCodecContext *enc, *video_enc; 478 int file_size, i; 479 480 video_enc = NULL; 481 for(i=0;i<s->nb_streams;i++) { 482 enc = s->streams[i]->codec; 483 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) 484 video_enc = enc; 485 else 486 av_fifo_free(swf->audio_fifo); 487 } 488 489 put_swf_tag(s, TAG_END); 490 put_swf_end_tag(s); 491 492 put_flush_packet(s->pb); 493 494 /* patch file size and number of frames if not streamed */ 495 if (!url_is_streamed(s->pb) && video_enc) { 496 file_size = url_ftell(pb); 497 url_fseek(pb, 4, SEEK_SET); 498 put_le32(pb, file_size); 499 url_fseek(pb, swf->duration_pos, SEEK_SET); 500 put_le16(pb, swf->video_frame_number); 501 url_fseek(pb, swf->vframes_pos, SEEK_SET); 502 put_le16(pb, swf->video_frame_number); 503 url_fseek(pb, file_size, SEEK_SET); 504 } 505 return 0; 506} 507 508#if CONFIG_SWF_MUXER 509AVOutputFormat swf_muxer = { 510 "swf", 511 NULL_IF_CONFIG_SMALL("Flash format"), 512 "application/x-shockwave-flash", 513 "swf", 514 sizeof(SWFContext), 515 CODEC_ID_MP3, 516 CODEC_ID_FLV1, 517 swf_write_header, 518 swf_write_packet, 519 swf_write_trailer, 520}; 521#endif 522#if CONFIG_AVM2_MUXER 523AVOutputFormat avm2_muxer = { 524 "avm2", 525 NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"), 526 "application/x-shockwave-flash", 527 NULL, 528 sizeof(SWFContext), 529 CODEC_ID_MP3, 530 CODEC_ID_FLV1, 531 swf_write_header, 532 swf_write_packet, 533 swf_write_trailer, 534}; 535#endif 536