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