00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "bitstream.h"
00024 #include "riff.h"
00025
00026
00027 #define DUMMY_FILE_SIZE (100 * 1024 * 1024)
00028 #define DUMMY_DURATION 600
00029
00030 #define TAG_END 0
00031 #define TAG_SHOWFRAME 1
00032 #define TAG_DEFINESHAPE 2
00033 #define TAG_FREECHARACTER 3
00034 #define TAG_PLACEOBJECT 4
00035 #define TAG_REMOVEOBJECT 5
00036 #define TAG_STREAMHEAD 18
00037 #define TAG_STREAMBLOCK 19
00038 #define TAG_JPEG2 21
00039 #define TAG_PLACEOBJECT2 26
00040 #define TAG_STREAMHEAD2 45
00041 #define TAG_VIDEOSTREAM 60
00042 #define TAG_VIDEOFRAME 61
00043 #define TAG_FILEATTRIBUTES 69
00044
00045 #define TAG_LONG 0x100
00046
00047
00048 #define FLAG_MOVETO 0x01
00049 #define FLAG_SETFILL0 0x02
00050 #define FLAG_SETFILL1 0x04
00051
00052 #define AUDIO_FIFO_SIZE 65536
00053
00054
00055 #define BITMAP_ID 0
00056 #define VIDEO_ID 0
00057 #define SHAPE_ID 1
00058
00059 #undef NDEBUG
00060 #include <assert.h>
00061
00062 typedef struct {
00063 int audio_stream_index;
00064 offset_t duration_pos;
00065 offset_t tag_pos;
00066
00067 int samples_per_frame;
00068 int sound_samples;
00069 int swf_frame_number;
00070 int video_frame_number;
00071 int frame_rate;
00072 int tag;
00073
00074 uint8_t audio_fifo[AUDIO_FIFO_SIZE];
00075 int audio_in_pos;
00076
00077 int video_type;
00078 int audio_type;
00079 } SWFContext;
00080
00081 static const AVCodecTag swf_codec_tags[] = {
00082 {CODEC_ID_FLV1, 0x02},
00083 {CODEC_ID_VP6F, 0x04},
00084 {0, 0},
00085 };
00086
00087 static const AVCodecTag swf_audio_codec_tags[] = {
00088 {CODEC_ID_PCM_S16LE, 0x00},
00089 {CODEC_ID_ADPCM_SWF, 0x01},
00090 {CODEC_ID_MP3, 0x02},
00091 {CODEC_ID_PCM_S16LE, 0x03},
00092
00093 {0, 0},
00094 };
00095
00096 #ifdef CONFIG_MUXERS
00097 static void put_swf_tag(AVFormatContext *s, int tag)
00098 {
00099 SWFContext *swf = s->priv_data;
00100 ByteIOContext *pb = s->pb;
00101
00102 swf->tag_pos = url_ftell(pb);
00103 swf->tag = tag;
00104
00105 if (tag & TAG_LONG) {
00106 put_le16(pb, 0);
00107 put_le32(pb, 0);
00108 } else {
00109 put_le16(pb, 0);
00110 }
00111 }
00112
00113 static void put_swf_end_tag(AVFormatContext *s)
00114 {
00115 SWFContext *swf = s->priv_data;
00116 ByteIOContext *pb = s->pb;
00117 offset_t pos;
00118 int tag_len, tag;
00119
00120 pos = url_ftell(pb);
00121 tag_len = pos - swf->tag_pos - 2;
00122 tag = swf->tag;
00123 url_fseek(pb, swf->tag_pos, SEEK_SET);
00124 if (tag & TAG_LONG) {
00125 tag &= ~TAG_LONG;
00126 put_le16(pb, (tag << 6) | 0x3f);
00127 put_le32(pb, tag_len - 4);
00128 } else {
00129 assert(tag_len < 0x3f);
00130 put_le16(pb, (tag << 6) | tag_len);
00131 }
00132 url_fseek(pb, pos, SEEK_SET);
00133 }
00134
00135 static inline void max_nbits(int *nbits_ptr, int val)
00136 {
00137 int n;
00138
00139 if (val == 0)
00140 return;
00141 val = abs(val);
00142 n = 1;
00143 while (val != 0) {
00144 n++;
00145 val >>= 1;
00146 }
00147 if (n > *nbits_ptr)
00148 *nbits_ptr = n;
00149 }
00150
00151 static void put_swf_rect(ByteIOContext *pb,
00152 int xmin, int xmax, int ymin, int ymax)
00153 {
00154 PutBitContext p;
00155 uint8_t buf[256];
00156 int nbits, mask;
00157
00158 init_put_bits(&p, buf, sizeof(buf));
00159
00160 nbits = 0;
00161 max_nbits(&nbits, xmin);
00162 max_nbits(&nbits, xmax);
00163 max_nbits(&nbits, ymin);
00164 max_nbits(&nbits, ymax);
00165 mask = (1 << nbits) - 1;
00166
00167
00168 put_bits(&p, 5, nbits);
00169 put_bits(&p, nbits, xmin & mask);
00170 put_bits(&p, nbits, xmax & mask);
00171 put_bits(&p, nbits, ymin & mask);
00172 put_bits(&p, nbits, ymax & mask);
00173
00174 flush_put_bits(&p);
00175 put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
00176 }
00177
00178 static void put_swf_line_edge(PutBitContext *pb, int dx, int dy)
00179 {
00180 int nbits, mask;
00181
00182 put_bits(pb, 1, 1);
00183 put_bits(pb, 1, 1);
00184 nbits = 2;
00185 max_nbits(&nbits, dx);
00186 max_nbits(&nbits, dy);
00187
00188 mask = (1 << nbits) - 1;
00189 put_bits(pb, 4, nbits - 2);
00190 if (dx == 0) {
00191 put_bits(pb, 1, 0);
00192 put_bits(pb, 1, 1);
00193 put_bits(pb, nbits, dy & mask);
00194 } else if (dy == 0) {
00195 put_bits(pb, 1, 0);
00196 put_bits(pb, 1, 0);
00197 put_bits(pb, nbits, dx & mask);
00198 } else {
00199 put_bits(pb, 1, 1);
00200 put_bits(pb, nbits, dx & mask);
00201 put_bits(pb, nbits, dy & mask);
00202 }
00203 }
00204
00205 #define FRAC_BITS 16
00206
00207
00208 static void put_swf_matrix(ByteIOContext *pb,
00209 int a, int b, int c, int d, int tx, int ty)
00210 {
00211 PutBitContext p;
00212 uint8_t buf[256];
00213 int nbits;
00214
00215 init_put_bits(&p, buf, sizeof(buf));
00216
00217 put_bits(&p, 1, 1);
00218 nbits = 1;
00219 max_nbits(&nbits, a);
00220 max_nbits(&nbits, d);
00221 put_bits(&p, 5, nbits);
00222 put_bits(&p, nbits, a);
00223 put_bits(&p, nbits, d);
00224
00225 put_bits(&p, 1, 1);
00226 nbits = 1;
00227 max_nbits(&nbits, c);
00228 max_nbits(&nbits, b);
00229 put_bits(&p, 5, nbits);
00230 put_bits(&p, nbits, c);
00231 put_bits(&p, nbits, b);
00232
00233 nbits = 1;
00234 max_nbits(&nbits, tx);
00235 max_nbits(&nbits, ty);
00236 put_bits(&p, 5, nbits);
00237 put_bits(&p, nbits, tx);
00238 put_bits(&p, nbits, ty);
00239
00240 flush_put_bits(&p);
00241 put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
00242 }
00243
00244
00245 static int swf_write_header(AVFormatContext *s)
00246 {
00247 SWFContext *swf = s->priv_data;
00248 ByteIOContext *pb = s->pb;
00249 AVCodecContext *enc, *audio_enc, *video_enc;
00250 PutBitContext p;
00251 uint8_t buf1[256];
00252 int i, width, height, rate, rate_base;
00253 int is_avm2;
00254
00255 swf->audio_in_pos = 0;
00256 swf->sound_samples = 0;
00257 swf->swf_frame_number = 0;
00258 swf->video_frame_number = 0;
00259
00260 video_enc = NULL;
00261 audio_enc = NULL;
00262 for(i=0;i<s->nb_streams;i++) {
00263 enc = s->streams[i]->codec;
00264 if (enc->codec_type == CODEC_TYPE_AUDIO) {
00265 if (enc->codec_id == CODEC_ID_MP3) {
00266 if (!enc->frame_size) {
00267 av_log(s, AV_LOG_ERROR, "audio frame size not set\n");
00268 return -1;
00269 }
00270 audio_enc = enc;
00271 } else {
00272 av_log(s, AV_LOG_ERROR, "SWF muxer only supports MP3\n");
00273 return -1;
00274 }
00275 } else {
00276 if (enc->codec_id == CODEC_ID_VP6F ||
00277 enc->codec_id == CODEC_ID_FLV1 ||
00278 enc->codec_id == CODEC_ID_MJPEG) {
00279 video_enc = enc;
00280 } else {
00281 av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
00282 return -1;
00283 }
00284 }
00285 }
00286
00287 if (!video_enc) {
00288
00289 swf->video_type = 0;
00290 width = 320;
00291 height = 200;
00292 rate = 10;
00293 rate_base= 1;
00294 } else {
00295 swf->video_type = video_enc->codec_id;
00296 width = video_enc->width;
00297 height = video_enc->height;
00298 rate = video_enc->time_base.den;
00299 rate_base = video_enc->time_base.num;
00300 }
00301
00302 if (!audio_enc) {
00303 swf->audio_type = 0;
00304 swf->samples_per_frame = (44100. * rate_base) / rate;
00305 } else {
00306 swf->audio_type = audio_enc->codec_id;
00307 swf->samples_per_frame = (audio_enc->sample_rate * rate_base) / rate;
00308 }
00309
00310 is_avm2 = !strcmp("avm2", s->oformat->name);
00311
00312 put_tag(pb, "FWS");
00313 if (is_avm2) {
00314 put_byte(pb, 9);
00315 } else if (video_enc && video_enc->codec_id == CODEC_ID_VP6F) {
00316 put_byte(pb, 8);
00317 } else if (video_enc && video_enc->codec_id == CODEC_ID_FLV1) {
00318 put_byte(pb, 6);
00319 } else {
00320 put_byte(pb, 4);
00321 }
00322 put_le32(pb, DUMMY_FILE_SIZE);
00323
00324
00325 put_swf_rect(pb, 0, width * 20, 0, height * 20);
00326 put_le16(pb, (rate * 256) / rate_base);
00327 swf->duration_pos = url_ftell(pb);
00328 put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base));
00329
00330
00331 if (is_avm2) {
00332 put_swf_tag(s, TAG_FILEATTRIBUTES);
00333 put_le32(pb, 1<<3);
00334 put_swf_end_tag(s);
00335 }
00336
00337
00338 if (video_enc && (video_enc->codec_id == CODEC_ID_VP6F ||
00339 video_enc->codec_id == CODEC_ID_FLV1)) {
00340 } else if (video_enc && video_enc->codec_id == CODEC_ID_MJPEG) {
00341 put_swf_tag(s, TAG_DEFINESHAPE);
00342
00343 put_le16(pb, SHAPE_ID);
00344
00345 put_swf_rect(pb, 0, width, 0, height);
00346
00347 put_byte(pb, 1);
00348 put_byte(pb, 0x41);
00349 put_le16(pb, BITMAP_ID);
00350
00351 put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0,
00352 0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
00353 put_byte(pb, 0);
00354
00355
00356 init_put_bits(&p, buf1, sizeof(buf1));
00357 put_bits(&p, 4, 1);
00358 put_bits(&p, 4, 0);
00359
00360 put_bits(&p, 1, 0);
00361 put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
00362 put_bits(&p, 5, 1);
00363 put_bits(&p, 1, 0);
00364 put_bits(&p, 1, 0);
00365 put_bits(&p, 1, 1);
00366
00367
00368 put_swf_line_edge(&p, width, 0);
00369 put_swf_line_edge(&p, 0, height);
00370 put_swf_line_edge(&p, -width, 0);
00371 put_swf_line_edge(&p, 0, -height);
00372
00373
00374 put_bits(&p, 1, 0);
00375 put_bits(&p, 5, 0);
00376
00377 flush_put_bits(&p);
00378 put_buffer(pb, buf1, pbBufPtr(&p) - p.buf);
00379
00380 put_swf_end_tag(s);
00381 }
00382
00383 if (audio_enc && audio_enc->codec_id == CODEC_ID_MP3) {
00384 int v;
00385
00386
00387 put_swf_tag(s, TAG_STREAMHEAD2);
00388
00389 v = 0;
00390 switch(audio_enc->sample_rate) {
00391 case 11025:
00392 v |= 1 << 2;
00393 break;
00394 case 22050:
00395 v |= 2 << 2;
00396 break;
00397 case 44100:
00398 v |= 3 << 2;
00399 break;
00400 default:
00401
00402 av_log(s, AV_LOG_ERROR, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n");
00403 return -1;
00404 }
00405 v |= 0x02;
00406 if (audio_enc->channels == 2)
00407 v |= 0x01;
00408 put_byte(s->pb, v);
00409 v |= 0x20;
00410 put_byte(s->pb, v);
00411 put_le16(s->pb, swf->samples_per_frame);
00412 put_le16(s->pb, 0);
00413
00414 put_swf_end_tag(s);
00415 }
00416
00417 put_flush_packet(s->pb);
00418 return 0;
00419 }
00420
00421 static int swf_write_video(AVFormatContext *s,
00422 AVCodecContext *enc, const uint8_t *buf, int size)
00423 {
00424 SWFContext *swf = s->priv_data;
00425 ByteIOContext *pb = s->pb;
00426
00427
00428 if (swf->swf_frame_number == 16000) {
00429 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
00430 }
00431
00432 if (swf->video_type == CODEC_ID_VP6F ||
00433 swf->video_type == CODEC_ID_FLV1) {
00434 if (swf->video_frame_number == 0) {
00435
00436 put_swf_tag(s, TAG_VIDEOSTREAM);
00437 put_le16(pb, VIDEO_ID);
00438 put_le16(pb, 15000);
00439 put_le16(pb, enc->width);
00440 put_le16(pb, enc->height);
00441 put_byte(pb, 0);
00442 put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type));
00443 put_swf_end_tag(s);
00444
00445
00446 put_swf_tag(s, TAG_PLACEOBJECT2);
00447 put_byte(pb, 0x36);
00448 put_le16(pb, 1);
00449 put_le16(pb, VIDEO_ID);
00450 put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
00451 put_le16(pb, swf->video_frame_number);
00452 put_byte(pb, 'v');
00453 put_byte(pb, 'i');
00454 put_byte(pb, 'd');
00455 put_byte(pb, 'e');
00456 put_byte(pb, 'o');
00457 put_byte(pb, 0x00);
00458 put_swf_end_tag(s);
00459 } else {
00460
00461 put_swf_tag(s, TAG_PLACEOBJECT2);
00462 put_byte(pb, 0x11);
00463 put_le16(pb, 1);
00464 put_le16(pb, swf->video_frame_number);
00465 put_swf_end_tag(s);
00466 }
00467
00468
00469 put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
00470 put_le16(pb, VIDEO_ID);
00471 put_le16(pb, swf->video_frame_number++);
00472 put_buffer(pb, buf, size);
00473 put_swf_end_tag(s);
00474 } else if (swf->video_type == CODEC_ID_MJPEG) {
00475 if (swf->swf_frame_number > 0) {
00476
00477 put_swf_tag(s, TAG_REMOVEOBJECT);
00478 put_le16(pb, SHAPE_ID);
00479 put_le16(pb, 1);
00480 put_swf_end_tag(s);
00481
00482
00483 put_swf_tag(s, TAG_FREECHARACTER);
00484 put_le16(pb, BITMAP_ID);
00485 put_swf_end_tag(s);
00486 }
00487
00488 put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
00489
00490 put_le16(pb, BITMAP_ID);
00491
00492
00493 put_byte(pb, 0xff);
00494 put_byte(pb, 0xd8);
00495 put_byte(pb, 0xff);
00496 put_byte(pb, 0xd9);
00497
00498 put_buffer(pb, buf, size);
00499
00500 put_swf_end_tag(s);
00501
00502
00503
00504 put_swf_tag(s, TAG_PLACEOBJECT);
00505 put_le16(pb, SHAPE_ID);
00506 put_le16(pb, 1);
00507 put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
00508 put_swf_end_tag(s);
00509 } else {
00510
00511 }
00512
00513 swf->swf_frame_number ++;
00514
00515
00516 if (swf->audio_type && swf->audio_in_pos) {
00517 put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
00518 put_le16(pb, swf->sound_samples);
00519 put_le16(pb, 0);
00520 put_buffer(pb, swf->audio_fifo, swf->audio_in_pos);
00521 put_swf_end_tag(s);
00522
00523
00524 swf->sound_samples = 0;
00525 swf->audio_in_pos = 0;
00526 }
00527
00528
00529 put_swf_tag(s, TAG_SHOWFRAME);
00530 put_swf_end_tag(s);
00531
00532 put_flush_packet(s->pb);
00533
00534 return 0;
00535 }
00536
00537 static int swf_write_audio(AVFormatContext *s,
00538 AVCodecContext *enc, const uint8_t *buf, int size)
00539 {
00540 SWFContext *swf = s->priv_data;
00541
00542
00543 if (swf->swf_frame_number == 16000) {
00544 av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
00545 }
00546
00547 if (swf->audio_in_pos + size >= AUDIO_FIFO_SIZE) {
00548 av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n");
00549 return -1;
00550 }
00551
00552 memcpy(swf->audio_fifo + swf->audio_in_pos, buf, size);
00553 swf->audio_in_pos += size;
00554 swf->sound_samples += enc->frame_size;
00555
00556
00557 if (swf->video_type == 0) {
00558 swf_write_video(s, enc, 0, 0);
00559 }
00560
00561 return 0;
00562 }
00563
00564 static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
00565 {
00566 AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
00567 if (codec->codec_type == CODEC_TYPE_AUDIO)
00568 return swf_write_audio(s, codec, pkt->data, pkt->size);
00569 else
00570 return swf_write_video(s, codec, pkt->data, pkt->size);
00571 }
00572
00573 static int swf_write_trailer(AVFormatContext *s)
00574 {
00575 SWFContext *swf = s->priv_data;
00576 ByteIOContext *pb = s->pb;
00577 AVCodecContext *enc, *video_enc;
00578 int file_size, i;
00579
00580 video_enc = NULL;
00581 for(i=0;i<s->nb_streams;i++) {
00582 enc = s->streams[i]->codec;
00583 if (enc->codec_type == CODEC_TYPE_VIDEO)
00584 video_enc = enc;
00585 }
00586
00587 put_swf_tag(s, TAG_END);
00588 put_swf_end_tag(s);
00589
00590 put_flush_packet(s->pb);
00591
00592
00593 if (!url_is_streamed(s->pb) && video_enc) {
00594 file_size = url_ftell(pb);
00595 url_fseek(pb, 4, SEEK_SET);
00596 put_le32(pb, file_size);
00597 url_fseek(pb, swf->duration_pos, SEEK_SET);
00598 put_le16(pb, video_enc->frame_number);
00599 url_fseek(pb, file_size, SEEK_SET);
00600 }
00601 return 0;
00602 }
00603 #endif //CONFIG_MUXERS
00604
00605
00606
00607
00608
00609
00610
00611
00612 static int get_swf_tag(ByteIOContext *pb, int *len_ptr)
00613 {
00614 int tag, len;
00615
00616 if (url_feof(pb))
00617 return -1;
00618
00619 tag = get_le16(pb);
00620 len = tag & 0x3f;
00621 tag = tag >> 6;
00622 if (len == 0x3f) {
00623 len = get_le32(pb);
00624 }
00625
00626 *len_ptr = len;
00627 return tag;
00628 }
00629
00630
00631 static int swf_probe(AVProbeData *p)
00632 {
00633
00634 if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&
00635 p->buf[2] == 'S')
00636 return AVPROBE_SCORE_MAX;
00637 else
00638 return 0;
00639 }
00640
00641 static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
00642 {
00643 SWFContext *swf = s->priv_data;
00644 ByteIOContext *pb = s->pb;
00645 int nbits, len, tag;
00646
00647 tag = get_be32(pb) & 0xffffff00;
00648
00649 if (tag == MKBETAG('C', 'W', 'S', 0)) {
00650 av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");
00651 return AVERROR(EIO);
00652 }
00653 if (tag != MKBETAG('F', 'W', 'S', 0))
00654 return AVERROR(EIO);
00655 get_le32(pb);
00656
00657 nbits = get_byte(pb) >> 3;
00658 len = (4 * nbits - 3 + 7) / 8;
00659 url_fskip(pb, len);
00660 swf->frame_rate = get_le16(pb);
00661 get_le16(pb);
00662
00663 swf->samples_per_frame = 0;
00664 s->ctx_flags |= AVFMTCTX_NOHEADER;
00665 return 0;
00666 }
00667
00668 static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
00669 {
00670 SWFContext *swf = s->priv_data;
00671 ByteIOContext *pb = s->pb;
00672 AVStream *vst = NULL, *ast = NULL, *st = 0;
00673 int tag, len, i, frame, v;
00674
00675 for(;;) {
00676 tag = get_swf_tag(pb, &len);
00677 if (tag < 0)
00678 return AVERROR(EIO);
00679 if (tag == TAG_VIDEOSTREAM && !vst) {
00680 int ch_id = get_le16(pb);
00681 get_le16(pb);
00682 get_le16(pb);
00683 get_le16(pb);
00684 get_byte(pb);
00685
00686 vst = av_new_stream(s, ch_id);
00687 if (!vst)
00688 return -1;
00689 vst->codec->codec_type = CODEC_TYPE_VIDEO;
00690 vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
00691 av_set_pts_info(vst, 64, 256, swf->frame_rate);
00692 vst->codec->time_base = (AVRational){ 256, swf->frame_rate };
00693 len -= 10;
00694 } else if ((tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) && !ast) {
00695
00696 int sample_rate_code;
00697 get_byte(pb);
00698 v = get_byte(pb);
00699 swf->samples_per_frame = get_le16(pb);
00700 ast = av_new_stream(s, -1);
00701 if (!ast)
00702 return -1;
00703 swf->audio_stream_index = ast->index;
00704 ast->codec->channels = 1 + (v&1);
00705 ast->codec->codec_type = CODEC_TYPE_AUDIO;
00706 ast->codec->codec_id = codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
00707 ast->need_parsing = AVSTREAM_PARSE_FULL;
00708 sample_rate_code= (v>>2) & 3;
00709 if (!sample_rate_code)
00710 return AVERROR(EIO);
00711 ast->codec->sample_rate = 11025 << (sample_rate_code-1);
00712 av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
00713 len -= 4;
00714 } else if (tag == TAG_VIDEOFRAME) {
00715 int ch_id = get_le16(pb);
00716 len -= 2;
00717 for(i=0; i<s->nb_streams; i++) {
00718 st = s->streams[i];
00719 if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) {
00720 frame = get_le16(pb);
00721 av_get_packet(pb, pkt, len-2);
00722 pkt->pts = frame;
00723 pkt->stream_index = st->index;
00724 return pkt->size;
00725 }
00726 }
00727 } else if (tag == TAG_STREAMBLOCK) {
00728 st = s->streams[swf->audio_stream_index];
00729 if (st->codec->codec_id == CODEC_ID_MP3) {
00730 url_fskip(pb, 4);
00731 av_get_packet(pb, pkt, len-4);
00732 } else {
00733 av_get_packet(pb, pkt, len);
00734 }
00735 pkt->stream_index = st->index;
00736 return pkt->size;
00737 } else if (tag == TAG_JPEG2) {
00738 for (i=0; i<s->nb_streams; i++) {
00739 st = s->streams[i];
00740 if (st->id == -2)
00741 break;
00742 }
00743 if (i == s->nb_streams) {
00744 vst = av_new_stream(s, -2);
00745 if (!vst)
00746 return -1;
00747 vst->codec->codec_type = CODEC_TYPE_VIDEO;
00748 vst->codec->codec_id = CODEC_ID_MJPEG;
00749 av_set_pts_info(vst, 64, 256, swf->frame_rate);
00750 vst->codec->time_base = (AVRational){ 256, swf->frame_rate };
00751 st = vst;
00752 }
00753 get_le16(pb);
00754 av_new_packet(pkt, len-2);
00755 get_buffer(pb, pkt->data, 4);
00756 if (AV_RB32(pkt->data) == 0xffd8ffd9 ||
00757 AV_RB32(pkt->data) == 0xffd9ffd8) {
00758
00759
00760 pkt->size -= 4;
00761 get_buffer(pb, pkt->data, pkt->size);
00762 } else {
00763 get_buffer(pb, pkt->data + 4, pkt->size - 4);
00764 }
00765 pkt->stream_index = st->index;
00766 return pkt->size;
00767 }
00768 url_fskip(pb, len);
00769 }
00770 return 0;
00771 }
00772
00773 static int swf_read_close(AVFormatContext *s)
00774 {
00775 return 0;
00776 }
00777
00778 #ifdef CONFIG_SWF_DEMUXER
00779 AVInputFormat swf_demuxer = {
00780 "swf",
00781 "Flash format",
00782 sizeof(SWFContext),
00783 swf_probe,
00784 swf_read_header,
00785 swf_read_packet,
00786 swf_read_close,
00787 };
00788 #endif
00789 #ifdef CONFIG_SWF_MUXER
00790 AVOutputFormat swf_muxer = {
00791 "swf",
00792 "Flash format",
00793 "application/x-shockwave-flash",
00794 "swf",
00795 sizeof(SWFContext),
00796 CODEC_ID_MP3,
00797 CODEC_ID_FLV1,
00798 swf_write_header,
00799 swf_write_packet,
00800 swf_write_trailer,
00801 };
00802 #endif
00803 #ifdef CONFIG_AVM2_MUXER
00804 AVOutputFormat avm2_muxer = {
00805 "avm2",
00806 "Flash 9 (AVM2) format",
00807 "application/x-shockwave-flash",
00808 NULL,
00809 sizeof(SWFContext),
00810 CODEC_ID_MP3,
00811 CODEC_ID_FLV1,
00812 swf_write_header,
00813 swf_write_packet,
00814 swf_write_trailer,
00815 };
00816 #endif