Statistics
| Branch: | Revision:

ffmpeg / libavformat / swf.c @ 71e445fc

History | View | Annotate | Download (27.7 KB)

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