]> git.sesse.net Git - ffmpeg/blob - libavformat/swf.c
cosmetics: fix indentation of the new matroska_parse_block() function
[ffmpeg] / libavformat / swf.c
1 /*
2  * Flash Compatible Streaming Format
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 #include "avformat.h"
23 #include "bitstream.h"
24 #include "riff.h"    /* for CodecTag */
25
26 /* should have a generic way to indicate probable size */
27 #define DUMMY_FILE_SIZE   (100 * 1024 * 1024)
28 #define DUMMY_DURATION    600 /* in seconds */
29
30 #define TAG_END           0
31 #define TAG_SHOWFRAME     1
32 #define TAG_DEFINESHAPE   2
33 #define TAG_FREECHARACTER 3
34 #define TAG_PLACEOBJECT   4
35 #define TAG_REMOVEOBJECT  5
36 #define TAG_STREAMHEAD    18
37 #define TAG_STREAMBLOCK   19
38 #define TAG_JPEG2         21
39 #define TAG_PLACEOBJECT2  26
40 #define TAG_STREAMHEAD2   45
41 #define TAG_VIDEOSTREAM   60
42 #define TAG_VIDEOFRAME    61
43
44 #define TAG_LONG         0x100
45
46 /* flags for shape definition */
47 #define FLAG_MOVETO      0x01
48 #define FLAG_SETFILL0    0x02
49 #define FLAG_SETFILL1    0x04
50
51 #define AUDIO_FIFO_SIZE 65536
52
53 /* character id used */
54 #define BITMAP_ID 0
55 #define VIDEO_ID 0
56 #define SHAPE_ID  1
57
58 #undef NDEBUG
59 #include <assert.h>
60
61 typedef struct {
62     int audio_stream_index;
63     offset_t duration_pos;
64     offset_t tag_pos;
65
66     int samples_per_frame;
67     int sound_samples;
68     int video_samples;
69     int swf_frame_number;
70     int video_frame_number;
71     int ms_per_frame;
72     int tag;
73
74     uint8_t *audio_fifo;
75     int audio_in_pos;
76     int audio_out_pos;
77     int audio_size;
78
79     int video_type;
80     int audio_type;
81 } SWFContext;
82
83 static const AVCodecTag swf_codec_tags[] = {
84     {CODEC_ID_FLV1, 0x02},
85     {CODEC_ID_VP6F, 0x04},
86     {0, 0},
87 };
88
89 static const int sSampleRates[3][4] = {
90     {44100, 48000, 32000, 0},
91     {22050, 24000, 16000, 0},
92     {11025, 12000,  8000, 0},
93 };
94
95 static const int sBitRates[2][3][15] = {
96     {   {  0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448},
97         {  0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384},
98         {  0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}
99     },
100     {   {  0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256},
101         {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160},
102         {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}
103     },
104 };
105
106 static const int sSamplesPerFrame[3][3] =
107 {
108     {  384,     1152,    1152 },
109     {  384,     1152,     576 },
110     {  384,     1152,     576 }
111 };
112
113 static const int sBitsPerSlot[3] = {
114     32,
115     8,
116     8
117 };
118
119 static int swf_mp3_info(void *data, int *byteSize, int *samplesPerFrame, int *sampleRate, int *isMono )
120 {
121     uint32_t header = AV_RB32(data);
122     int layerID = 3 - ((header >> 17) & 0x03);
123     int bitRateID = ((header >> 12) & 0x0f);
124     int sampleRateID = ((header >> 10) & 0x03);
125     int bitRate = 0;
126     int bitsPerSlot = sBitsPerSlot[layerID];
127     int isPadded = ((header >> 9) & 0x01);
128
129     if ( (( header >> 21 ) & 0x7ff) != 0x7ff ) {
130         return 0;
131     }
132
133     *isMono = ((header >>  6) & 0x03) == 0x03;
134
135     if ( (header >> 19 ) & 0x01 ) {
136         *sampleRate = sSampleRates[0][sampleRateID];
137         bitRate = sBitRates[0][layerID][bitRateID] * 1000;
138         *samplesPerFrame = sSamplesPerFrame[0][layerID];
139     } else {
140         if ( (header >> 20) & 0x01 ) {
141             *sampleRate = sSampleRates[1][sampleRateID];
142             bitRate = sBitRates[1][layerID][bitRateID] * 1000;
143             *samplesPerFrame = sSamplesPerFrame[1][layerID];
144         } else {
145             *sampleRate = sSampleRates[2][sampleRateID];
146             bitRate = sBitRates[1][layerID][bitRateID] * 1000;
147             *samplesPerFrame = sSamplesPerFrame[2][layerID];
148         }
149     }
150
151     *byteSize = ( ( ( ( *samplesPerFrame * (bitRate / bitsPerSlot) ) / *sampleRate ) + isPadded ) );
152
153     return 1;
154 }
155
156 #ifdef CONFIG_MUXERS
157 static void put_swf_tag(AVFormatContext *s, int tag)
158 {
159     SWFContext *swf = s->priv_data;
160     ByteIOContext *pb = &s->pb;
161
162     swf->tag_pos = url_ftell(pb);
163     swf->tag = tag;
164     /* reserve some room for the tag */
165     if (tag & TAG_LONG) {
166         put_le16(pb, 0);
167         put_le32(pb, 0);
168     } else {
169         put_le16(pb, 0);
170     }
171 }
172
173 static void put_swf_end_tag(AVFormatContext *s)
174 {
175     SWFContext *swf = s->priv_data;
176     ByteIOContext *pb = &s->pb;
177     offset_t pos;
178     int tag_len, tag;
179
180     pos = url_ftell(pb);
181     tag_len = pos - swf->tag_pos - 2;
182     tag = swf->tag;
183     url_fseek(pb, swf->tag_pos, SEEK_SET);
184     if (tag & TAG_LONG) {
185         tag &= ~TAG_LONG;
186         put_le16(pb, (tag << 6) | 0x3f);
187         put_le32(pb, tag_len - 4);
188     } else {
189         assert(tag_len < 0x3f);
190         put_le16(pb, (tag << 6) | tag_len);
191     }
192     url_fseek(pb, pos, SEEK_SET);
193 }
194
195 static inline void max_nbits(int *nbits_ptr, int val)
196 {
197     int n;
198
199     if (val == 0)
200         return;
201     val = abs(val);
202     n = 1;
203     while (val != 0) {
204         n++;
205         val >>= 1;
206     }
207     if (n > *nbits_ptr)
208         *nbits_ptr = n;
209 }
210
211 static void put_swf_rect(ByteIOContext *pb,
212                          int xmin, int xmax, int ymin, int ymax)
213 {
214     PutBitContext p;
215     uint8_t buf[256];
216     int nbits, mask;
217
218     init_put_bits(&p, buf, sizeof(buf));
219
220     nbits = 0;
221     max_nbits(&nbits, xmin);
222     max_nbits(&nbits, xmax);
223     max_nbits(&nbits, ymin);
224     max_nbits(&nbits, ymax);
225     mask = (1 << nbits) - 1;
226
227     /* rectangle info */
228     put_bits(&p, 5, nbits);
229     put_bits(&p, nbits, xmin & mask);
230     put_bits(&p, nbits, xmax & mask);
231     put_bits(&p, nbits, ymin & mask);
232     put_bits(&p, nbits, ymax & mask);
233
234     flush_put_bits(&p);
235     put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
236 }
237
238 static void put_swf_line_edge(PutBitContext *pb, int dx, int dy)
239 {
240     int nbits, mask;
241
242     put_bits(pb, 1, 1); /* edge */
243     put_bits(pb, 1, 1); /* line select */
244     nbits = 2;
245     max_nbits(&nbits, dx);
246     max_nbits(&nbits, dy);
247
248     mask = (1 << nbits) - 1;
249     put_bits(pb, 4, nbits - 2); /* 16 bits precision */
250     if (dx == 0) {
251       put_bits(pb, 1, 0);
252       put_bits(pb, 1, 1);
253       put_bits(pb, nbits, dy & mask);
254     } else if (dy == 0) {
255       put_bits(pb, 1, 0);
256       put_bits(pb, 1, 0);
257       put_bits(pb, nbits, dx & mask);
258     } else {
259       put_bits(pb, 1, 1);
260       put_bits(pb, nbits, dx & mask);
261       put_bits(pb, nbits, dy & mask);
262     }
263 }
264
265 #define FRAC_BITS 16
266
267 /* put matrix */
268 static void put_swf_matrix(ByteIOContext *pb,
269                            int a, int b, int c, int d, int tx, int ty)
270 {
271     PutBitContext p;
272     uint8_t buf[256];
273     int nbits;
274
275     init_put_bits(&p, buf, sizeof(buf));
276
277     put_bits(&p, 1, 1); /* a, d present */
278     nbits = 1;
279     max_nbits(&nbits, a);
280     max_nbits(&nbits, d);
281     put_bits(&p, 5, nbits); /* nb bits */
282     put_bits(&p, nbits, a);
283     put_bits(&p, nbits, d);
284
285     put_bits(&p, 1, 1); /* b, c present */
286     nbits = 1;
287     max_nbits(&nbits, c);
288     max_nbits(&nbits, b);
289     put_bits(&p, 5, nbits); /* nb bits */
290     put_bits(&p, nbits, c);
291     put_bits(&p, nbits, b);
292
293     nbits = 1;
294     max_nbits(&nbits, tx);
295     max_nbits(&nbits, ty);
296     put_bits(&p, 5, nbits); /* nb bits */
297     put_bits(&p, nbits, tx);
298     put_bits(&p, nbits, ty);
299
300     flush_put_bits(&p);
301     put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
302 }
303
304 /* */
305 static int swf_write_header(AVFormatContext *s)
306 {
307     SWFContext *swf = s->priv_data;
308     ByteIOContext *pb = &s->pb;
309     AVCodecContext *enc, *audio_enc, *video_enc;
310     PutBitContext p;
311     uint8_t buf1[256];
312     int i, width, height, rate, rate_base;
313
314     swf->audio_in_pos = 0;
315     swf->audio_out_pos = 0;
316     swf->audio_size = 0;
317     swf->audio_fifo = av_malloc(AUDIO_FIFO_SIZE);
318     swf->sound_samples = 0;
319     swf->video_samples = 0;
320     swf->swf_frame_number = 0;
321     swf->video_frame_number = 0;
322
323     video_enc = NULL;
324     audio_enc = NULL;
325     for(i=0;i<s->nb_streams;i++) {
326         enc = s->streams[i]->codec;
327         if (enc->codec_type == CODEC_TYPE_AUDIO)
328             audio_enc = enc;
329         else {
330             if ( enc->codec_id == CODEC_ID_VP6F ||
331                  enc->codec_id == CODEC_ID_FLV1 ||
332                  enc->codec_id == CODEC_ID_MJPEG ) {
333                 video_enc = enc;
334             } else {
335                 av_log(enc, AV_LOG_ERROR, "SWF only supports VP6, FLV1 and MJPEG\n");
336                 return -1;
337             }
338         }
339     }
340
341     if (!video_enc) {
342         /* currenty, cannot work correctly if audio only */
343         swf->video_type = 0;
344         width = 320;
345         height = 200;
346         rate = 10;
347         rate_base= 1;
348     } else {
349         swf->video_type = video_enc->codec_id;
350         width = video_enc->width;
351         height = video_enc->height;
352         rate = video_enc->time_base.den;
353         rate_base = video_enc->time_base.num;
354     }
355
356     if (!audio_enc ) {
357         swf->audio_type = 0;
358         swf->samples_per_frame = ( 44100. * rate_base ) / rate;
359     } else {
360         swf->audio_type = audio_enc->codec_id;
361         swf->samples_per_frame = ( ( audio_enc->sample_rate ) * rate_base ) / rate;
362     }
363
364     put_tag(pb, "FWS");
365     if ( video_enc && video_enc->codec_id == CODEC_ID_VP6F ) {
366         put_byte(pb, 8); /* version (version 8 and above support VP6 codec) */
367     } else if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
368         put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */
369     } else {
370         put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */
371     }
372     put_le32(pb, DUMMY_FILE_SIZE); /* dummy size
373                                       (will be patched if not streamed) */
374
375     put_swf_rect(pb, 0, width * 20, 0, height * 20);
376     put_le16(pb, (rate * 256) / rate_base); /* frame rate */
377     swf->duration_pos = url_ftell(pb);
378     put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
379
380     /* define a shape with the jpeg inside */
381     if ( video_enc && (video_enc->codec_id == CODEC_ID_VP6F ||
382                        video_enc->codec_id == CODEC_ID_FLV1 )) {
383     } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) {
384         put_swf_tag(s, TAG_DEFINESHAPE);
385
386         put_le16(pb, SHAPE_ID); /* ID of shape */
387         /* bounding rectangle */
388         put_swf_rect(pb, 0, width, 0, height);
389         /* style info */
390         put_byte(pb, 1); /* one fill style */
391         put_byte(pb, 0x41); /* clipped bitmap fill */
392         put_le16(pb, BITMAP_ID); /* bitmap ID */
393         /* position of the bitmap */
394         put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0,
395                         0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
396         put_byte(pb, 0); /* no line style */
397
398         /* shape drawing */
399         init_put_bits(&p, buf1, sizeof(buf1));
400         put_bits(&p, 4, 1); /* one fill bit */
401         put_bits(&p, 4, 0); /* zero line bit */
402
403         put_bits(&p, 1, 0); /* not an edge */
404         put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
405         put_bits(&p, 5, 1); /* nbits */
406         put_bits(&p, 1, 0); /* X */
407         put_bits(&p, 1, 0); /* Y */
408         put_bits(&p, 1, 1); /* set fill style 1 */
409
410         /* draw the rectangle ! */
411         put_swf_line_edge(&p, width, 0);
412         put_swf_line_edge(&p, 0, height);
413         put_swf_line_edge(&p, -width, 0);
414         put_swf_line_edge(&p, 0, -height);
415
416         /* end of shape */
417         put_bits(&p, 1, 0); /* not an edge */
418         put_bits(&p, 5, 0);
419
420         flush_put_bits(&p);
421         put_buffer(pb, buf1, pbBufPtr(&p) - p.buf);
422
423         put_swf_end_tag(s);
424     }
425
426     if (audio_enc && audio_enc->codec_id == CODEC_ID_MP3 ) {
427         int v;
428
429         /* start sound */
430         put_swf_tag(s, TAG_STREAMHEAD2);
431
432         v = 0;
433         switch(audio_enc->sample_rate) {
434         case 11025:
435             v |= 1 << 2;
436             break;
437         case 22050:
438             v |= 2 << 2;
439             break;
440         case 44100:
441             v |= 3 << 2;
442             break;
443         default:
444             /* not supported */
445             av_log(s, AV_LOG_ERROR, "swf doesnt support that sample rate, choose from (44100, 22050, 11025)\n");
446             av_free(swf->audio_fifo);
447             return -1;
448         }
449         v |= 0x02; /* 16 bit playback */
450         if (audio_enc->channels == 2)
451             v |= 0x01; /* stereo playback */
452         put_byte(&s->pb, v);
453         v |= 0x20; /* mp3 compressed */
454         put_byte(&s->pb, v);
455         put_le16(&s->pb, swf->samples_per_frame);  /* avg samples per frame */
456         put_le16(&s->pb, 0);
457
458         put_swf_end_tag(s);
459     }
460
461     put_flush_packet(&s->pb);
462     return 0;
463 }
464
465 static int swf_write_video(AVFormatContext *s,
466                            AVCodecContext *enc, const uint8_t *buf, int size)
467 {
468     SWFContext *swf = s->priv_data;
469     ByteIOContext *pb = &s->pb;
470     int c = 0;
471     int outSize = 0;
472     int outSamples = 0;
473
474     /* Flash Player limit */
475     if ( swf->swf_frame_number == 16000 ) {
476         av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
477     }
478
479     if ( swf->audio_type ) {
480         /* Prescan audio data for this swf frame */
481 retry_swf_audio_packet:
482         if ( ( swf->audio_size-outSize ) >= 4 ) {
483             int mp3FrameSize = 0;
484             int mp3SampleRate = 0;
485             int mp3IsMono = 0;
486             int mp3SamplesPerFrame = 0;
487
488             /* copy out mp3 header from ring buffer */
489             uint8_t header[4];
490             for (c=0; c<4; c++) {
491                 header[c] = swf->audio_fifo[(swf->audio_in_pos+outSize+c) % AUDIO_FIFO_SIZE];
492             }
493
494             if ( swf_mp3_info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) {
495                 if ( ( swf->audio_size-outSize ) >= mp3FrameSize ) {
496                     outSize += mp3FrameSize;
497                     outSamples += mp3SamplesPerFrame;
498                     if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
499                         goto retry_swf_audio_packet;
500                     }
501                 }
502             } else {
503                 /* invalid mp3 data, skip forward
504                 we need to do this since the Flash Player
505                 does not like custom headers */
506                 swf->audio_in_pos ++;
507                 swf->audio_size --;
508                 swf->audio_in_pos %= AUDIO_FIFO_SIZE;
509                 goto retry_swf_audio_packet;
510             }
511         }
512
513         /* audio stream is behind video stream, bail */
514         if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
515             return 0;
516         }
517     }
518
519             if ( swf->video_type == CODEC_ID_VP6F ||
520                  swf->video_type == CODEC_ID_FLV1 ) {
521                 if ( swf->video_frame_number == 0 ) {
522                     /* create a new video object */
523                     put_swf_tag(s, TAG_VIDEOSTREAM);
524                     put_le16(pb, VIDEO_ID);
525                     put_le16(pb, 15000 ); /* hard flash player limit */
526                     put_le16(pb, enc->width);
527                     put_le16(pb, enc->height);
528                     put_byte(pb, 0);
529                     put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type));
530                     put_swf_end_tag(s);
531
532                     /* place the video object for the first time */
533                     put_swf_tag(s, TAG_PLACEOBJECT2);
534                     put_byte(pb, 0x36);
535                     put_le16(pb, 1);
536                     put_le16(pb, VIDEO_ID);
537                     put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
538                     put_le16(pb, swf->video_frame_number );
539                     put_byte(pb, 'v');
540                     put_byte(pb, 'i');
541                     put_byte(pb, 'd');
542                     put_byte(pb, 'e');
543                     put_byte(pb, 'o');
544                     put_byte(pb, 0x00);
545                     put_swf_end_tag(s);
546                 } else {
547                     /* mark the character for update */
548                     put_swf_tag(s, TAG_PLACEOBJECT2);
549                     put_byte(pb, 0x11);
550                     put_le16(pb, 1);
551                     put_le16(pb, swf->video_frame_number );
552                     put_swf_end_tag(s);
553                 }
554
555                     /* set video frame data */
556                     put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
557                     put_le16(pb, VIDEO_ID);
558                     put_le16(pb, swf->video_frame_number++ );
559                     put_buffer(pb, buf, size);
560                     put_swf_end_tag(s);
561             } else if ( swf->video_type == CODEC_ID_MJPEG ) {
562                 if (swf->swf_frame_number > 0) {
563                     /* remove the shape */
564                     put_swf_tag(s, TAG_REMOVEOBJECT);
565                     put_le16(pb, SHAPE_ID); /* shape ID */
566                     put_le16(pb, 1); /* depth */
567                     put_swf_end_tag(s);
568
569                     /* free the bitmap */
570                     put_swf_tag(s, TAG_FREECHARACTER);
571                     put_le16(pb, BITMAP_ID);
572                     put_swf_end_tag(s);
573                 }
574
575                 put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
576
577                 put_le16(pb, BITMAP_ID); /* ID of the image */
578
579                 /* a dummy jpeg header seems to be required */
580                 put_byte(pb, 0xff);
581                 put_byte(pb, 0xd8);
582                 put_byte(pb, 0xff);
583                 put_byte(pb, 0xd9);
584                 /* write the jpeg image */
585                 put_buffer(pb, buf, size);
586
587                 put_swf_end_tag(s);
588
589                 /* draw the shape */
590
591                 put_swf_tag(s, TAG_PLACEOBJECT);
592                 put_le16(pb, SHAPE_ID); /* shape ID */
593                 put_le16(pb, 1); /* depth */
594                 put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
595                 put_swf_end_tag(s);
596             } else {
597                 /* invalid codec */
598             }
599
600             swf->swf_frame_number ++;
601
602     swf->video_samples += swf->samples_per_frame;
603
604     /* streaming sound always should be placed just before showframe tags */
605     if ( outSize > 0 ) {
606         put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
607         put_le16(pb, outSamples);
608         put_le16(pb, 0);
609         for (c=0; c<outSize; c++) {
610             put_byte(pb,swf->audio_fifo[(swf->audio_in_pos+c) % AUDIO_FIFO_SIZE]);
611         }
612         put_swf_end_tag(s);
613
614         /* update FIFO */
615         swf->sound_samples += outSamples;
616         swf->audio_in_pos += outSize;
617         swf->audio_size -= outSize;
618         swf->audio_in_pos %= AUDIO_FIFO_SIZE;
619     }
620
621     /* output the frame */
622     put_swf_tag(s, TAG_SHOWFRAME);
623     put_swf_end_tag(s);
624
625     put_flush_packet(&s->pb);
626
627     return 0;
628 }
629
630 static int swf_write_audio(AVFormatContext *s,
631                            AVCodecContext *enc, const uint8_t *buf, int size)
632 {
633     SWFContext *swf = s->priv_data;
634     int c = 0;
635
636     /* Flash Player limit */
637     if ( swf->swf_frame_number == 16000 ) {
638         av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
639     }
640
641     if (enc->codec_id == CODEC_ID_MP3 ) {
642         for (c=0; c<size; c++) {
643             swf->audio_fifo[(swf->audio_out_pos+c)%AUDIO_FIFO_SIZE] = buf[c];
644         }
645         swf->audio_size += size;
646         swf->audio_out_pos += size;
647         swf->audio_out_pos %= AUDIO_FIFO_SIZE;
648     }
649
650     /* if audio only stream make sure we add swf frames */
651     if ( swf->video_type == 0 ) {
652         swf_write_video(s, enc, 0, 0);
653     }
654
655     return 0;
656 }
657
658 static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
659 {
660     AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
661     if (codec->codec_type == CODEC_TYPE_AUDIO)
662         return swf_write_audio(s, codec, pkt->data, pkt->size);
663     else
664         return swf_write_video(s, codec, pkt->data, pkt->size);
665 }
666
667 static int swf_write_trailer(AVFormatContext *s)
668 {
669     SWFContext *swf = s->priv_data;
670     ByteIOContext *pb = &s->pb;
671     AVCodecContext *enc, *video_enc;
672     int file_size, i;
673
674     video_enc = NULL;
675     for(i=0;i<s->nb_streams;i++) {
676         enc = s->streams[i]->codec;
677         if (enc->codec_type == CODEC_TYPE_VIDEO)
678             video_enc = enc;
679     }
680
681     put_swf_tag(s, TAG_END);
682     put_swf_end_tag(s);
683
684     put_flush_packet(&s->pb);
685
686     /* patch file size and number of frames if not streamed */
687     if (!url_is_streamed(&s->pb) && video_enc) {
688         file_size = url_ftell(pb);
689         url_fseek(pb, 4, SEEK_SET);
690         put_le32(pb, file_size);
691         url_fseek(pb, swf->duration_pos, SEEK_SET);
692         put_le16(pb, video_enc->frame_number);
693         url_fseek(pb, file_size, SEEK_SET);
694     }
695
696     av_free(swf->audio_fifo);
697
698     return 0;
699 }
700 #endif //CONFIG_MUXERS
701
702 /*********************************************/
703 /* Extract FLV encoded frame and MP3 from swf
704    Note that the detection of the real frame
705    is inaccurate at this point as it can be
706    quite tricky to determine, you almost certainly
707    will get a bad audio/video sync */
708
709 static int get_swf_tag(ByteIOContext *pb, int *len_ptr)
710 {
711     int tag, len;
712
713     if (url_feof(pb))
714         return -1;
715
716     tag = get_le16(pb);
717     len = tag & 0x3f;
718     tag = tag >> 6;
719     if (len == 0x3f) {
720         len = get_le32(pb);
721     }
722 //    av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len);
723     *len_ptr = len;
724     return tag;
725 }
726
727
728 static int swf_probe(AVProbeData *p)
729 {
730     /* check file header */
731     if (p->buf_size <= 16)
732         return 0;
733     if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&
734         p->buf[2] == 'S')
735         return AVPROBE_SCORE_MAX;
736     else
737         return 0;
738 }
739
740 static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
741 {
742     SWFContext *swf = s->priv_data;
743     ByteIOContext *pb = &s->pb;
744     int nbits, len, frame_rate, tag, v;
745     offset_t frame_offset = -1;
746     AVStream *ast = 0;
747     AVStream *vst = 0;
748
749     tag = get_be32(pb) & 0xffffff00;
750
751     if (tag == MKBETAG('C', 'W', 'S', 0))
752     {
753         av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");
754         return AVERROR_IO;
755     }
756     if (tag != MKBETAG('F', 'W', 'S', 0))
757         return AVERROR_IO;
758     get_le32(pb);
759     /* skip rectangle size */
760     nbits = get_byte(pb) >> 3;
761     len = (4 * nbits - 3 + 7) / 8;
762     url_fskip(pb, len);
763     frame_rate = get_le16(pb);
764     get_le16(pb); /* frame count */
765
766     /* The Flash Player converts 8.8 frame rates
767        to milliseconds internally. Do the same to get
768        a correct framerate */
769     swf->ms_per_frame = ( 1000 * 256 ) / frame_rate;
770     swf->samples_per_frame = 0;
771
772     for(;;) {
773         offset_t tag_offset = url_ftell(pb);
774         tag = get_swf_tag(pb, &len);
775         if (tag < 0 || tag == TAG_VIDEOFRAME || tag == TAG_STREAMBLOCK) {
776             url_fseek(pb, frame_offset == -1 ? tag_offset : frame_offset, SEEK_SET);
777             break;
778         }
779         if ( tag == TAG_VIDEOSTREAM && !vst) {
780             int ch_id = get_le16(pb);
781             get_le16(pb);
782             get_le16(pb);
783             get_le16(pb);
784             get_byte(pb);
785             /* Check for FLV1 */
786             vst = av_new_stream(s, ch_id);
787             vst->codec->codec_type = CODEC_TYPE_VIDEO;
788             vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
789         } else if ( ( tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2 ) && !ast) {
790             /* streaming found */
791             int sample_rate_code;
792             get_byte(pb);
793             v = get_byte(pb);
794             swf->samples_per_frame = get_le16(pb);
795             ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */
796             av_set_pts_info(ast, 24, 1, 1000); /* 24 bit pts in ms */
797             swf->audio_stream_index = ast->index;
798             ast->codec->channels = 1 + (v&1);
799             ast->codec->codec_type = CODEC_TYPE_AUDIO;
800             if (v & 0x20)
801                 ast->codec->codec_id = CODEC_ID_MP3;
802             ast->need_parsing = 1;
803             sample_rate_code= (v>>2) & 3;
804             if (!sample_rate_code)
805                 return AVERROR_IO;
806             ast->codec->sample_rate = 11025 << (sample_rate_code-1);
807             if (len > 4)
808                 url_fskip(pb,len-4);
809
810         } else if (tag == TAG_JPEG2 && !vst) {
811             vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */
812             vst->codec->codec_type = CODEC_TYPE_VIDEO;
813             vst->codec->codec_id = CODEC_ID_MJPEG;
814             url_fskip(pb, len);
815             frame_offset = tag_offset;
816         } else {
817             url_fskip(pb, len);
818         }
819     }
820     if (vst) {
821         av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
822         if (swf->ms_per_frame) {
823             vst->codec->time_base.den = 1000. / swf->ms_per_frame;
824             vst->codec->time_base.num = 1;
825         }
826     }
827     return 0;
828 }
829
830 static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
831 {
832     SWFContext *swf = s->priv_data;
833     ByteIOContext *pb = &s->pb;
834     AVStream *st = 0;
835     int tag, len, i, frame;
836
837     for(;;) {
838         tag = get_swf_tag(pb, &len);
839         if (tag < 0)
840             return AVERROR_IO;
841         if (tag == TAG_VIDEOFRAME) {
842             int ch_id = get_le16(pb);
843             len -= 2;
844             for( i=0; i<s->nb_streams; i++ ) {
845                 st = s->streams[i];
846                 if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) {
847                     frame = get_le16(pb);
848                     av_get_packet(pb, pkt, len-2);
849                     pkt->pts = frame * swf->ms_per_frame;
850                     pkt->stream_index = st->index;
851                     return pkt->size;
852                 }
853             }
854         } else if (tag == TAG_STREAMBLOCK) {
855             st = s->streams[swf->audio_stream_index];
856             if (st->codec->codec_id == CODEC_ID_MP3) {
857                 url_fskip(pb, 4);
858                 av_get_packet(pb, pkt, len-4);
859                 pkt->stream_index = st->index;
860                 return pkt->size;
861             }
862         } else if (tag == TAG_JPEG2) {
863             for (i=0; i<s->nb_streams; i++) {
864                 st = s->streams[i];
865                 if (st->id == -2) {
866                     get_le16(pb); /* BITMAP_ID */
867                     av_new_packet(pkt, len-2);
868                     get_buffer(pb, pkt->data, 4);
869                     if (AV_RB32(pkt->data) == 0xffd8ffd9) {
870                         /* old SWF files containing SOI/EOI as data start */
871                         pkt->size -= 4;
872                         get_buffer(pb, pkt->data, pkt->size);
873                     } else {
874                         get_buffer(pb, pkt->data + 4, pkt->size - 4);
875                     }
876                     pkt->stream_index = st->index;
877                     return pkt->size;
878                 }
879             }
880         }
881         url_fskip(pb, len);
882     }
883     return 0;
884 }
885
886 static int swf_read_close(AVFormatContext *s)
887 {
888      return 0;
889 }
890
891 #ifdef CONFIG_SWF_DEMUXER
892 AVInputFormat swf_demuxer = {
893     "swf",
894     "Flash format",
895     sizeof(SWFContext),
896     swf_probe,
897     swf_read_header,
898     swf_read_packet,
899     swf_read_close,
900 };
901 #endif
902 #ifdef CONFIG_SWF_MUXER
903 AVOutputFormat swf_muxer = {
904     "swf",
905     "Flash format",
906     "application/x-shockwave-flash",
907     "swf",
908     sizeof(SWFContext),
909     CODEC_ID_MP3,
910     CODEC_ID_FLV1,
911     swf_write_header,
912     swf_write_packet,
913     swf_write_trailer,
914 };
915 #endif