00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "libavcodec/bitstream.h"
00024 #include "avformat.h"
00025 #include "swf.h"
00026
00027 static void put_swf_tag(AVFormatContext *s, int tag)
00028 {
00029 SWFContext *swf = s->priv_data;
00030 ByteIOContext *pb = s->pb;
00031
00032 swf->tag_pos = url_ftell(pb);
00033 swf->tag = tag;
00034
00035 if (tag & TAG_LONG) {
00036 put_le16(pb, 0);
00037 put_le32(pb, 0);
00038 } else {
00039 put_le16(pb, 0);
00040 }
00041 }
00042
00043 static void put_swf_end_tag(AVFormatContext *s)
00044 {
00045 SWFContext *swf = s->priv_data;
00046 ByteIOContext *pb = s->pb;
00047 int64_t pos;
00048 int tag_len, tag;
00049
00050 pos = url_ftell(pb);
00051 tag_len = pos - swf->tag_pos - 2;
00052 tag = swf->tag;
00053 url_fseek(pb, swf->tag_pos, SEEK_SET);
00054 if (tag & TAG_LONG) {
00055 tag &= ~TAG_LONG;
00056 put_le16(pb, (tag << 6) | 0x3f);
00057 put_le32(pb, tag_len - 4);
00058 } else {
00059 assert(tag_len < 0x3f);
00060 put_le16(pb, (tag << 6) | tag_len);
00061 }
00062 url_fseek(pb, pos, SEEK_SET);
00063 }
00064
00065 static inline void max_nbits(int *nbits_ptr, int val)
00066 {
00067 int n;
00068
00069 if (val == 0)
00070 return;
00071 val = abs(val);
00072 n = 1;
00073 while (val != 0) {
00074 n++;
00075 val >>= 1;
00076 }
00077 if (n > *nbits_ptr)
00078 *nbits_ptr = n;
00079 }
00080
00081 static void put_swf_rect(ByteIOContext *pb,
00082 int xmin, int xmax, int ymin, int ymax)
00083 {
00084 PutBitContext p;
00085 uint8_t buf[256];
00086 int nbits, mask;
00087
00088 init_put_bits(&p, buf, sizeof(buf));
00089
00090 nbits = 0;
00091 max_nbits(&nbits, xmin);
00092 max_nbits(&nbits, xmax);
00093 max_nbits(&nbits, ymin);
00094 max_nbits(&nbits, ymax);
00095 mask = (1 << nbits) - 1;
00096
00097
00098 put_bits(&p, 5, nbits);
00099 put_bits(&p, nbits, xmin & mask);
00100 put_bits(&p, nbits, xmax & mask);
00101 put_bits(&p, nbits, ymin & mask);
00102 put_bits(&p, nbits, ymax & mask);
00103
00104 flush_put_bits(&p);
00105 put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
00106 }
00107
00108 static void put_swf_line_edge(PutBitContext *pb, int dx, int dy)
00109 {
00110 int nbits, mask;
00111
00112 put_bits(pb, 1, 1);
00113 put_bits(pb, 1, 1);
00114 nbits = 2;
00115 max_nbits(&nbits, dx);
00116 max_nbits(&nbits, dy);
00117
00118 mask = (1 << nbits) - 1;
00119 put_bits(pb, 4, nbits - 2);
00120 if (dx == 0) {
00121 put_bits(pb, 1, 0);
00122 put_bits(pb, 1, 1);
00123 put_bits(pb, nbits, dy & mask);
00124 } else if (dy == 0) {
00125 put_bits(pb, 1, 0);
00126 put_bits(pb, 1, 0);
00127 put_bits(pb, nbits, dx & mask);
00128 } else {
00129 put_bits(pb, 1, 1);
00130 put_bits(pb, nbits, dx & mask);
00131 put_bits(pb, nbits, dy & mask);
00132 }
00133 }
00134
00135 #define FRAC_BITS 16
00136
00137 static void put_swf_matrix(ByteIOContext *pb,
00138 int a, int b, int c, int d, int tx, int ty)
00139 {
00140 PutBitContext p;
00141 uint8_t buf[256];
00142 int nbits;
00143
00144 init_put_bits(&p, buf, sizeof(buf));
00145
00146 put_bits(&p, 1, 1);
00147 nbits = 1;
00148 max_nbits(&nbits, a);
00149 max_nbits(&nbits, d);
00150 put_bits(&p, 5, nbits);
00151 put_bits(&p, nbits, a);
00152 put_bits(&p, nbits, d);
00153
00154 put_bits(&p, 1, 1);
00155 nbits = 1;
00156 max_nbits(&nbits, c);
00157 max_nbits(&nbits, b);
00158 put_bits(&p, 5, nbits);
00159 put_bits(&p, nbits, c);
00160 put_bits(&p, nbits, b);
00161
00162 nbits = 1;
00163 max_nbits(&nbits, tx);
00164 max_nbits(&nbits, ty);
00165 put_bits(&p, 5, nbits);
00166 put_bits(&p, nbits, tx);
00167 put_bits(&p, nbits, ty);
00168
00169 flush_put_bits(&p);
00170 put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
00171 }
00172
00173 static int swf_write_header(AVFormatContext *s)
00174 {
00175 SWFContext *swf = s->priv_data;
00176 ByteIOContext *pb = s->pb;
00177 PutBitContext p;
00178 uint8_t buf1[256];
00179 int i, width, height, rate, rate_base;
00180 int version;
00181
00182 swf->sound_samples = 0;
00183 swf->swf_frame_number = 0;
00184 swf->video_frame_number = 0;
00185
00186 for(i=0;i<s->nb_streams;i++) {
00187 AVCodecContext *enc = s->streams[i]->codec;
00188 if (enc->codec_type == CODEC_TYPE_AUDIO) {
00189 if (enc->codec_id == CODEC_ID_MP3) {
00190 if (!enc->frame_size) {
00191 av_log(s, AV_LOG_ERROR, "audio frame size not set\n");
00192 return -1;
00193 }
00194 swf->audio_enc = enc;
00195 av_fifo_init(&swf->audio_fifo, AUDIO_FIFO_SIZE);
00196 } else {
00197 av_log(s, AV_LOG_ERROR, "SWF muxer only supports MP3\n");
00198 return -1;
00199 }
00200 } else {
00201 if (enc->codec_id == CODEC_ID_VP6F ||
00202 enc->codec_id == CODEC_ID_FLV1 ||
00203 enc->codec_id == CODEC_ID_MJPEG) {
00204 swf->video_enc = enc;
00205 } else {
00206 av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
00207 return -1;
00208 }
00209 }
00210 }
00211
00212 if (!swf->video_enc) {
00213
00214 width = 320;
00215 height = 200;
00216 rate = 10;
00217 rate_base= 1;
00218 } else {
00219 width = swf->video_enc->width;
00220 height = swf->video_enc->height;
00221 rate = swf->video_enc->time_base.den;
00222 rate_base = swf->video_enc->time_base.num;
00223 }
00224
00225 if (!swf->audio_enc)
00226 swf->samples_per_frame = (44100. * rate_base) / rate;
00227 else
00228 swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate;
00229
00230 put_tag(pb, "FWS");
00231
00232 if (!strcmp("avm2", s->oformat->name))
00233 version = 9;
00234 else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_VP6F)
00235 version = 8;
00236 else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_FLV1)
00237 version = 6;
00238 else
00239 version = 4;
00240 put_byte(pb, version);
00241
00242 put_le32(pb, DUMMY_FILE_SIZE);
00243
00244
00245 put_swf_rect(pb, 0, width * 20, 0, height * 20);
00246 put_le16(pb, (rate * 256) / rate_base);
00247 swf->duration_pos = url_ftell(pb);
00248 put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base));
00249
00250
00251 if (version == 9) {
00252 put_swf_tag(s, TAG_FILEATTRIBUTES);
00253 put_le32(pb, 1<<3);
00254 put_swf_end_tag(s);
00255 }
00256
00257
00258 if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_MJPEG) {
00259 put_swf_tag(s, TAG_DEFINESHAPE);
00260
00261 put_le16(pb, SHAPE_ID);
00262
00263 put_swf_rect(pb, 0, width, 0, height);
00264
00265 put_byte(pb, 1);
00266 put_byte(pb, 0x41);
00267 put_le16(pb, BITMAP_ID);
00268
00269 put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0,
00270 0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
00271 put_byte(pb, 0);
00272
00273
00274 init_put_bits(&p, buf1, sizeof(buf1));
00275 put_bits(&p, 4, 1);
00276 put_bits(&p, 4, 0);
00277
00278 put_bits(&p, 1, 0);
00279 put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
00280 put_bits(&p, 5, 1);
00281 put_bits(&p, 1, 0);
00282 put_bits(&p, 1, 0);
00283 put_bits(&p, 1, 1);
00284
00285
00286 put_swf_line_edge(&p, width, 0);
00287 put_swf_line_edge(&p, 0, height);
00288 put_swf_line_edge(&p, -width, 0);
00289 put_swf_line_edge(&p, 0, -height);
00290
00291
00292 put_bits(&p, 1, 0);
00293 put_bits(&p, 5, 0);
00294
00295 flush_put_bits(&p);
00296 put_buffer(pb, buf1, pbBufPtr(&p) - p.buf);
00297
00298 put_swf_end_tag(s);
00299 }
00300
00301 if (swf->audio_enc && swf->audio_enc->codec_id == CODEC_ID_MP3) {
00302 int v = 0;
00303
00304
00305 put_swf_tag(s, TAG_STREAMHEAD2);
00306 switch(swf->audio_enc->sample_rate) {
00307 case 11025: v |= 1 << 2; break;
00308 case 22050: v |= 2 << 2; break;
00309 case 44100: v |= 3 << 2; break;
00310 default:
00311
00312 av_log(s, AV_LOG_ERROR, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n");
00313 return -1;
00314 }
00315 v |= 0x02;
00316 if (swf->audio_enc->channels == 2)
00317 v |= 0x01;
00318 put_byte(s->pb, v);
00319 v |= 0x20;
00320 put_byte(s->pb, v);
00321 put_le16(s->pb, swf->samples_per_frame);
00322 put_le16(s->pb, 0);
00323
00324 put_swf_end_tag(s);
00325 }
00326
00327 put_flush_packet(s->pb);
00328 return 0;
00329 }
00330
00331 static int swf_write_video(AVFormatContext *s,
00332 AVCodecContext *enc, const uint8_t *buf, int size)
00333 {
00334 SWFContext *swf = s->priv_data;
00335 ByteIOContext *pb = s->pb;
00336
00337
00338 if (swf->swf_frame_number == 16000)
00339 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
00340
00341 if (enc->codec_id == CODEC_ID_VP6F ||
00342 enc->codec_id == CODEC_ID_FLV1) {
00343 if (swf->video_frame_number == 0) {
00344
00345 put_swf_tag(s, TAG_VIDEOSTREAM);
00346 put_le16(pb, VIDEO_ID);
00347 swf->vframes_pos = url_ftell(pb);
00348 put_le16(pb, 15000);
00349 put_le16(pb, enc->width);
00350 put_le16(pb, enc->height);
00351 put_byte(pb, 0);
00352 put_byte(pb,codec_get_tag(swf_codec_tags,enc->codec_id));
00353 put_swf_end_tag(s);
00354
00355
00356 put_swf_tag(s, TAG_PLACEOBJECT2);
00357 put_byte(pb, 0x36);
00358 put_le16(pb, 1);
00359 put_le16(pb, VIDEO_ID);
00360 put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
00361 put_le16(pb, swf->video_frame_number);
00362 put_tag(pb, "video");
00363 put_byte(pb, 0x00);
00364 put_swf_end_tag(s);
00365 } else {
00366
00367 put_swf_tag(s, TAG_PLACEOBJECT2);
00368 put_byte(pb, 0x11);
00369 put_le16(pb, 1);
00370 put_le16(pb, swf->video_frame_number);
00371 put_swf_end_tag(s);
00372 }
00373
00374
00375 put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
00376 put_le16(pb, VIDEO_ID);
00377 put_le16(pb, swf->video_frame_number++);
00378 put_buffer(pb, buf, size);
00379 put_swf_end_tag(s);
00380 } else if (enc->codec_id == CODEC_ID_MJPEG) {
00381 if (swf->swf_frame_number > 0) {
00382
00383 put_swf_tag(s, TAG_REMOVEOBJECT);
00384 put_le16(pb, SHAPE_ID);
00385 put_le16(pb, 1);
00386 put_swf_end_tag(s);
00387
00388
00389 put_swf_tag(s, TAG_FREECHARACTER);
00390 put_le16(pb, BITMAP_ID);
00391 put_swf_end_tag(s);
00392 }
00393
00394 put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
00395
00396 put_le16(pb, BITMAP_ID);
00397
00398
00399 put_be32(pb, 0xffd8ffd9);
00400
00401 put_buffer(pb, buf, size);
00402
00403 put_swf_end_tag(s);
00404
00405
00406
00407 put_swf_tag(s, TAG_PLACEOBJECT);
00408 put_le16(pb, SHAPE_ID);
00409 put_le16(pb, 1);
00410 put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
00411 put_swf_end_tag(s);
00412 }
00413
00414 swf->swf_frame_number++;
00415
00416
00417 if (swf->audio_enc && av_fifo_size(&swf->audio_fifo)) {
00418 int frame_size = av_fifo_size(&swf->audio_fifo);
00419 put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
00420 put_le16(pb, swf->sound_samples);
00421 put_le16(pb, 0);
00422 av_fifo_generic_read(&swf->audio_fifo, frame_size, &put_buffer, pb);
00423 put_swf_end_tag(s);
00424
00425
00426 swf->sound_samples = 0;
00427 }
00428
00429
00430 put_swf_tag(s, TAG_SHOWFRAME);
00431 put_swf_end_tag(s);
00432
00433 put_flush_packet(s->pb);
00434
00435 return 0;
00436 }
00437
00438 static int swf_write_audio(AVFormatContext *s,
00439 AVCodecContext *enc, uint8_t *buf, int size)
00440 {
00441 SWFContext *swf = s->priv_data;
00442
00443
00444 if (swf->swf_frame_number == 16000)
00445 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
00446
00447 if (av_fifo_size(&swf->audio_fifo) + size > AUDIO_FIFO_SIZE) {
00448 av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n");
00449 return -1;
00450 }
00451
00452 av_fifo_generic_write(&swf->audio_fifo, buf, size, NULL);
00453 swf->sound_samples += enc->frame_size;
00454
00455
00456 if (!swf->video_enc)
00457 swf_write_video(s, enc, 0, 0);
00458
00459 return 0;
00460 }
00461
00462 static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
00463 {
00464 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
00465 if (codec->codec_type == CODEC_TYPE_AUDIO)
00466 return swf_write_audio(s, codec, pkt->data, pkt->size);
00467 else
00468 return swf_write_video(s, codec, pkt->data, pkt->size);
00469 }
00470
00471 static int swf_write_trailer(AVFormatContext *s)
00472 {
00473 SWFContext *swf = s->priv_data;
00474 ByteIOContext *pb = s->pb;
00475 AVCodecContext *enc, *video_enc;
00476 int file_size, i;
00477
00478 video_enc = NULL;
00479 for(i=0;i<s->nb_streams;i++) {
00480 enc = s->streams[i]->codec;
00481 if (enc->codec_type == CODEC_TYPE_VIDEO)
00482 video_enc = enc;
00483 else
00484 av_fifo_free(&swf->audio_fifo);
00485 }
00486
00487 put_swf_tag(s, TAG_END);
00488 put_swf_end_tag(s);
00489
00490 put_flush_packet(s->pb);
00491
00492
00493 if (!url_is_streamed(s->pb) && video_enc) {
00494 file_size = url_ftell(pb);
00495 url_fseek(pb, 4, SEEK_SET);
00496 put_le32(pb, file_size);
00497 url_fseek(pb, swf->duration_pos, SEEK_SET);
00498 put_le16(pb, swf->video_frame_number);
00499 if (swf->vframes_pos) {
00500 url_fseek(pb, swf->vframes_pos, SEEK_SET);
00501 put_le16(pb, swf->video_frame_number);
00502 }
00503 url_fseek(pb, file_size, SEEK_SET);
00504 }
00505 return 0;
00506 }
00507
00508 #if CONFIG_SWF_MUXER
00509 AVOutputFormat swf_muxer = {
00510 "swf",
00511 NULL_IF_CONFIG_SMALL("Flash format"),
00512 "application/x-shockwave-flash",
00513 "swf",
00514 sizeof(SWFContext),
00515 CODEC_ID_MP3,
00516 CODEC_ID_FLV1,
00517 swf_write_header,
00518 swf_write_packet,
00519 swf_write_trailer,
00520 };
00521 #endif
00522 #if CONFIG_AVM2_MUXER
00523 AVOutputFormat avm2_muxer = {
00524 "avm2",
00525 NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"),
00526 "application/x-shockwave-flash",
00527 NULL,
00528 sizeof(SWFContext),
00529 CODEC_ID_MP3,
00530 CODEC_ID_FLV1,
00531 swf_write_header,
00532 swf_write_packet,
00533 swf_write_trailer,
00534 };
00535 #endif