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