remove nonsense time base code, use swf ms per frame, only video frames contains pts
[ffmpeg.git] / 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 firstTagOff;
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     firstTagOff = url_ftell(pb);
773     for(;;) {
774         tag = get_swf_tag(pb, &len);
775         if (tag < 0) {
776             if ( ast || vst )
777                 break;
778             av_log(s, AV_LOG_ERROR, "No media found in SWF\n");
779             return AVERROR_IO;
780         }
781         if ( tag == TAG_VIDEOSTREAM && !vst) {
782             int ch_id = get_le16(pb);
783             get_le16(pb);
784             get_le16(pb);
785             get_le16(pb);
786             get_byte(pb);
787             /* Check for FLV1 */
788             vst = av_new_stream(s, ch_id);
789             av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
790             vst->codec->codec_type = CODEC_TYPE_VIDEO;
791             vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
792             if (swf->ms_per_frame) {
793                 vst->codec->time_base.den = 1000. / swf->ms_per_frame;
794                 vst->codec->time_base.num = 1;
795             }
796         } else if ( ( tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2 ) && !ast) {
797             /* streaming found */
798             int sample_rate_code;
799             get_byte(pb);
800             v = get_byte(pb);
801             swf->samples_per_frame = get_le16(pb);
802             ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */
803             av_set_pts_info(ast, 24, 1, 1000); /* 24 bit pts in ms */
804             swf->audio_stream_index = ast->index;
805             ast->codec->channels = 1 + (v&1);
806             ast->codec->codec_type = CODEC_TYPE_AUDIO;
807             if (v & 0x20)
808                 ast->codec->codec_id = CODEC_ID_MP3;
809             ast->need_parsing = 1;
810             sample_rate_code= (v>>2) & 3;
811             if (!sample_rate_code)
812                 return AVERROR_IO;
813             ast->codec->sample_rate = 11025 << (sample_rate_code-1);
814             if (len > 4)
815                 url_fskip(pb,len-4);
816
817         } else if (tag == TAG_JPEG2 && !vst) {
818             vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */
819             av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
820             vst->codec->codec_type = CODEC_TYPE_VIDEO;
821             vst->codec->codec_id = CODEC_ID_MJPEG;
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             url_fskip(pb, len);
827         } else {
828             url_fskip(pb, len);
829         }
830     }
831     url_fseek(pb, firstTagOff, SEEK_SET);
832
833     return 0;
834 }
835
836 static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
837 {
838     SWFContext *swf = s->priv_data;
839     ByteIOContext *pb = &s->pb;
840     AVStream *st = 0;
841     int tag, len, i, frame;
842
843     for(;;) {
844         tag = get_swf_tag(pb, &len);
845         if (tag < 0)
846             return AVERROR_IO;
847         if (tag == TAG_VIDEOFRAME) {
848             int ch_id = get_le16(pb);
849             len -= 2;
850             for( i=0; i<s->nb_streams; i++ ) {
851                 st = s->streams[i];
852                 if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) {
853                     frame = get_le16(pb);
854                     av_get_packet(pb, pkt, len-2);
855                     pkt->pts = frame * swf->ms_per_frame;
856                     pkt->stream_index = st->index;
857                     return pkt->size;
858                 }
859             }
860         } else if (tag == TAG_STREAMBLOCK) {
861             st = s->streams[swf->audio_stream_index];
862             if (st->codec->codec_id == CODEC_ID_MP3) {
863                 url_fskip(pb, 4);
864                 av_get_packet(pb, pkt, len-4);
865                 pkt->stream_index = st->index;
866                 return pkt->size;
867             }
868         } else if (tag == TAG_JPEG2) {
869             for (i=0; i<s->nb_streams; i++) {
870                 st = s->streams[i];
871                 if (st->id == -2) {
872                     get_le16(pb); /* BITMAP_ID */
873                     av_new_packet(pkt, len-2);
874                     get_buffer(pb, pkt->data, 4);
875                     if (AV_RB32(pkt->data) == 0xffd8ffd9) {
876                         /* old SWF files containing SOI/EOI as data start */
877                         pkt->size -= 4;
878                         get_buffer(pb, pkt->data, pkt->size);
879                     } else {
880                         get_buffer(pb, pkt->data + 4, pkt->size - 4);
881                     }
882                     pkt->stream_index = st->index;
883                     return pkt->size;
884                 }
885             }
886         }
887         url_fskip(pb, len);
888     }
889     return 0;
890 }
891
892 static int swf_read_close(AVFormatContext *s)
893 {
894      return 0;
895 }
896
897 #ifdef CONFIG_SWF_DEMUXER
898 AVInputFormat swf_demuxer = {
899     "swf",
900     "Flash format",
901     sizeof(SWFContext),
902     swf_probe,
903     swf_read_header,
904     swf_read_packet,
905     swf_read_close,
906 };
907 #endif
908 #ifdef CONFIG_SWF_MUXER
909 AVOutputFormat swf_muxer = {
910     "swf",
911     "Flash format",
912     "application/x-shockwave-flash",
913     "swf",
914     sizeof(SWFContext),
915     CODEC_ID_MP3,
916     CODEC_ID_FLV1,
917     swf_write_header,
918     swf_write_packet,
919     swf_write_trailer,
920 };
921 #endif