Statistics
| Branch: | Revision:

ffmpeg / libavformat / swf.c @ 20cd83e2

History | View | Annotate | Download (27.3 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 747a0554 Tinic Uro
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
    int ch_id;
73 de6d9b64 Fabrice Bellard
    int tag;
74 747a0554 Tinic Uro
75
    uint8_t *audio_fifo;
76
    int audio_in_pos;
77
    int audio_out_pos;
78
    int audio_size;
79
80
    int video_type;
81
    int audio_type;
82 de6d9b64 Fabrice Bellard
} SWFContext;
83
84 5ce117c3 Aurelien Jacobs
static const CodecTag swf_codec_tags[] = {
85
    {CODEC_ID_FLV1, 0x02},
86
    {CODEC_ID_VP6F, 0x04},
87
    {0, 0},
88
};
89
90 747a0554 Tinic Uro
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 115329f1 Diego Biurrun
131 747a0554 Tinic Uro
    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 a9e35095 Diego Biurrun
#ifdef CONFIG_MUXERS
159 de6d9b64 Fabrice Bellard
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 8be1c656 Fabrice Bellard
    offset_t pos;
180 de6d9b64 Fabrice Bellard
    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 115329f1 Diego Biurrun
static void put_swf_rect(ByteIOContext *pb,
214 de6d9b64 Fabrice Bellard
                         int xmin, int xmax, int ymin, int ymax)
215
{
216
    PutBitContext p;
217 0c1a9eda Zdenek Kabelac
    uint8_t buf[256];
218 de6d9b64 Fabrice Bellard
    int nbits, mask;
219
220 117a5490 Alex Beregszaszi
    init_put_bits(&p, buf, sizeof(buf));
221 115329f1 Diego Biurrun
222 de6d9b64 Fabrice Bellard
    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 115329f1 Diego Biurrun
236 de6d9b64 Fabrice Bellard
    flush_put_bits(&p);
237 17592475 Michael Niedermayer
    put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
238 de6d9b64 Fabrice Bellard
}
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 115329f1 Diego Biurrun
      put_bits(pb, 1, 0);
254
      put_bits(pb, 1, 1);
255 de6d9b64 Fabrice Bellard
      put_bits(pb, nbits, dy & mask);
256
    } else if (dy == 0) {
257 115329f1 Diego Biurrun
      put_bits(pb, 1, 0);
258
      put_bits(pb, 1, 0);
259 de6d9b64 Fabrice Bellard
      put_bits(pb, nbits, dx & mask);
260
    } else {
261 115329f1 Diego Biurrun
      put_bits(pb, 1, 1);
262 de6d9b64 Fabrice Bellard
      put_bits(pb, nbits, dx & mask);
263
      put_bits(pb, nbits, dy & mask);
264
    }
265
}
266
267
#define FRAC_BITS 16
268
269 747a0554 Tinic Uro
/* put matrix */
270 de6d9b64 Fabrice Bellard
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 0c1a9eda Zdenek Kabelac
    uint8_t buf[256];
275 747a0554 Tinic Uro
    int nbits;
276 de6d9b64 Fabrice Bellard
277 117a5490 Alex Beregszaszi
    init_put_bits(&p, buf, sizeof(buf));
278 115329f1 Diego Biurrun
279 de6d9b64 Fabrice Bellard
    put_bits(&p, 1, 1); /* a, d present */
280 747a0554 Tinic Uro
    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 115329f1 Diego Biurrun
287 de6d9b64 Fabrice Bellard
    put_bits(&p, 1, 1); /* b, c present */
288 747a0554 Tinic Uro
    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 de6d9b64 Fabrice Bellard
302
    flush_put_bits(&p);
303 17592475 Michael Niedermayer
    put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
304 de6d9b64 Fabrice Bellard
}
305
306 747a0554 Tinic Uro
/* */
307 de6d9b64 Fabrice Bellard
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 0c1a9eda Zdenek Kabelac
    uint8_t buf1[256];
314 14bea432 Michael Niedermayer
    int i, width, height, rate, rate_base;
315 de6d9b64 Fabrice Bellard
316 1ea4f593 Fabrice Bellard
    swf = av_malloc(sizeof(SWFContext));
317 de6d9b64 Fabrice Bellard
    if (!swf)
318
        return -1;
319
    s->priv_data = swf;
320
321 747a0554 Tinic Uro
    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->sound_samples = 0;
327
    swf->video_samples = 0;
328
    swf->swf_frame_number = 0;
329
    swf->video_frame_number = 0;
330
331 de6d9b64 Fabrice Bellard
    video_enc = NULL;
332
    audio_enc = NULL;
333
    for(i=0;i<s->nb_streams;i++) {
334 01f4895c Michael Niedermayer
        enc = s->streams[i]->codec;
335 de6d9b64 Fabrice Bellard
        if (enc->codec_type == CODEC_TYPE_AUDIO)
336
            audio_enc = enc;
337 747a0554 Tinic Uro
        else {
338 5ce117c3 Aurelien Jacobs
            if ( enc->codec_id == CODEC_ID_VP6F ||
339
                 enc->codec_id == CODEC_ID_FLV1 ||
340
                 enc->codec_id == CODEC_ID_MJPEG ) {
341 747a0554 Tinic Uro
                video_enc = enc;
342
            } else {
343 5ce117c3 Aurelien Jacobs
                av_log(enc, AV_LOG_ERROR, "SWF only supports VP6, FLV1 and MJPEG\n");
344 747a0554 Tinic Uro
                return -1;
345
            }
346
        }
347 de6d9b64 Fabrice Bellard
    }
348
349
    if (!video_enc) {
350
        /* currenty, cannot work correctly if audio only */
351 747a0554 Tinic Uro
        swf->video_type = 0;
352 de6d9b64 Fabrice Bellard
        width = 320;
353
        height = 200;
354 14bea432 Michael Niedermayer
        rate = 10;
355
        rate_base= 1;
356 de6d9b64 Fabrice Bellard
    } else {
357 747a0554 Tinic Uro
        swf->video_type = video_enc->codec_id;
358 de6d9b64 Fabrice Bellard
        width = video_enc->width;
359
        height = video_enc->height;
360 c0df9d75 Michael Niedermayer
        rate = video_enc->time_base.den;
361
        rate_base = video_enc->time_base.num;
362 de6d9b64 Fabrice Bellard
    }
363
364 747a0554 Tinic Uro
    if (!audio_enc ) {
365
        swf->audio_type = 0;
366
        swf->samples_per_frame = ( 44100. * rate_base ) / rate;
367
    } else {
368
        swf->audio_type = audio_enc->codec_id;
369
        swf->samples_per_frame = ( ( audio_enc->sample_rate ) * rate_base ) / rate;
370
    }
371
372 de6d9b64 Fabrice Bellard
    put_tag(pb, "FWS");
373 5ce117c3 Aurelien Jacobs
    if ( video_enc && video_enc->codec_id == CODEC_ID_VP6F ) {
374
        put_byte(pb, 8); /* version (version 8 and above support VP6 codec) */
375
    } else if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
376 747a0554 Tinic Uro
        put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */
377
    } else {
378
        put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */
379
    }
380 115329f1 Diego Biurrun
    put_le32(pb, DUMMY_FILE_SIZE); /* dummy size
381
                                      (will be patched if not streamed) */
382 de6d9b64 Fabrice Bellard
383 747a0554 Tinic Uro
    put_swf_rect(pb, 0, width * 20, 0, height * 20);
384 14bea432 Michael Niedermayer
    put_le16(pb, (rate * 256) / rate_base); /* frame rate */
385 de6d9b64 Fabrice Bellard
    swf->duration_pos = url_ftell(pb);
386 14bea432 Michael Niedermayer
    put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
387 115329f1 Diego Biurrun
388 de6d9b64 Fabrice Bellard
    /* define a shape with the jpeg inside */
389 5ce117c3 Aurelien Jacobs
    if ( video_enc && (video_enc->codec_id == CODEC_ID_VP6F ||
390
                       video_enc->codec_id == CODEC_ID_FLV1 )) {
391 747a0554 Tinic Uro
    } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) {
392
        put_swf_tag(s, TAG_DEFINESHAPE);
393
394
        put_le16(pb, SHAPE_ID); /* ID of shape */
395
        /* bounding rectangle */
396
        put_swf_rect(pb, 0, width, 0, height);
397
        /* style info */
398
        put_byte(pb, 1); /* one fill style */
399
        put_byte(pb, 0x41); /* clipped bitmap fill */
400
        put_le16(pb, BITMAP_ID); /* bitmap ID */
401
        /* position of the bitmap */
402 115329f1 Diego Biurrun
        put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0,
403 747a0554 Tinic Uro
                        0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
404
        put_byte(pb, 0); /* no line style */
405 115329f1 Diego Biurrun
406 747a0554 Tinic Uro
        /* shape drawing */
407
        init_put_bits(&p, buf1, sizeof(buf1));
408
        put_bits(&p, 4, 1); /* one fill bit */
409
        put_bits(&p, 4, 0); /* zero line bit */
410 115329f1 Diego Biurrun
411 747a0554 Tinic Uro
        put_bits(&p, 1, 0); /* not an edge */
412
        put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
413
        put_bits(&p, 5, 1); /* nbits */
414
        put_bits(&p, 1, 0); /* X */
415
        put_bits(&p, 1, 0); /* Y */
416
        put_bits(&p, 1, 1); /* set fill style 1 */
417 115329f1 Diego Biurrun
418 747a0554 Tinic Uro
        /* draw the rectangle ! */
419
        put_swf_line_edge(&p, width, 0);
420
        put_swf_line_edge(&p, 0, height);
421
        put_swf_line_edge(&p, -width, 0);
422
        put_swf_line_edge(&p, 0, -height);
423 115329f1 Diego Biurrun
424 747a0554 Tinic Uro
        /* end of shape */
425
        put_bits(&p, 1, 0); /* not an edge */
426
        put_bits(&p, 5, 0);
427 de6d9b64 Fabrice Bellard
428 747a0554 Tinic Uro
        flush_put_bits(&p);
429
        put_buffer(pb, buf1, pbBufPtr(&p) - p.buf);
430 de6d9b64 Fabrice Bellard
431 747a0554 Tinic Uro
        put_swf_end_tag(s);
432
    }
433 115329f1 Diego Biurrun
434 747a0554 Tinic Uro
    if (audio_enc && audio_enc->codec_id == CODEC_ID_MP3 ) {
435 de6d9b64 Fabrice Bellard
        int v;
436
437
        /* start sound */
438 747a0554 Tinic Uro
        put_swf_tag(s, TAG_STREAMHEAD2);
439 de6d9b64 Fabrice Bellard
440
        v = 0;
441
        switch(audio_enc->sample_rate) {
442
        case 11025:
443
            v |= 1 << 2;
444
            break;
445
        case 22050:
446
            v |= 2 << 2;
447
            break;
448
        case 44100:
449
            v |= 3 << 2;
450
            break;
451
        default:
452
            /* not supported */
453 747a0554 Tinic Uro
            av_free(swf->audio_fifo);
454 1ea4f593 Fabrice Bellard
            av_free(swf);
455 de6d9b64 Fabrice Bellard
            return -1;
456
        }
457 747a0554 Tinic Uro
        v |= 0x02; /* 16 bit playback */
458 de6d9b64 Fabrice Bellard
        if (audio_enc->channels == 2)
459 747a0554 Tinic Uro
            v |= 0x01; /* stereo playback */
460
        put_byte(&s->pb, v);
461 de6d9b64 Fabrice Bellard
        v |= 0x20; /* mp3 compressed */
462
        put_byte(&s->pb, v);
463 747a0554 Tinic Uro
        put_le16(&s->pb, swf->samples_per_frame);  /* avg samples per frame */
464
        put_le16(&s->pb, 0);
465 115329f1 Diego Biurrun
466 de6d9b64 Fabrice Bellard
        put_swf_end_tag(s);
467
    }
468
469
    put_flush_packet(&s->pb);
470
    return 0;
471
}
472
473 115329f1 Diego Biurrun
static int swf_write_video(AVFormatContext *s,
474 49057904 Fabrice Bellard
                           AVCodecContext *enc, const uint8_t *buf, int size)
475 de6d9b64 Fabrice Bellard
{
476 747a0554 Tinic Uro
    SWFContext *swf = s->priv_data;
477 de6d9b64 Fabrice Bellard
    ByteIOContext *pb = &s->pb;
478 747a0554 Tinic Uro
    int c = 0;
479
    int outSize = 0;
480
    int outSamples = 0;
481 115329f1 Diego Biurrun
482 747a0554 Tinic Uro
    /* Flash Player limit */
483 d3e18ad0 Michael Niedermayer
    if ( swf->swf_frame_number == 16000 ) {
484 bc874dae Michel Bardiaux
        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
485 de6d9b64 Fabrice Bellard
    }
486
487 747a0554 Tinic Uro
    if ( swf->audio_type ) {
488
        /* Prescan audio data for this swf frame */
489
retry_swf_audio_packet:
490
        if ( ( swf->audio_size-outSize ) >= 4 ) {
491
            int mp3FrameSize = 0;
492
            int mp3SampleRate = 0;
493
            int mp3IsMono = 0;
494
            int mp3SamplesPerFrame = 0;
495 115329f1 Diego Biurrun
496 747a0554 Tinic Uro
            /* copy out mp3 header from ring buffer */
497
            uint8_t header[4];
498
            for (c=0; c<4; c++) {
499
                header[c] = swf->audio_fifo[(swf->audio_in_pos+outSize+c) % AUDIO_FIFO_SIZE];
500
            }
501 115329f1 Diego Biurrun
502 747a0554 Tinic Uro
            if ( swf_mp3_info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) {
503
                if ( ( swf->audio_size-outSize ) >= mp3FrameSize ) {
504
                    outSize += mp3FrameSize;
505
                    outSamples += mp3SamplesPerFrame;
506
                    if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
507
                        goto retry_swf_audio_packet;
508
                    }
509
                }
510
            } else {
511
                /* invalid mp3 data, skip forward
512 115329f1 Diego Biurrun
                we need to do this since the Flash Player
513 747a0554 Tinic Uro
                does not like custom headers */
514
                swf->audio_in_pos ++;
515
                swf->audio_size --;
516
                swf->audio_in_pos %= AUDIO_FIFO_SIZE;
517
                goto retry_swf_audio_packet;
518
            }
519
        }
520 115329f1 Diego Biurrun
521 747a0554 Tinic Uro
        /* audio stream is behind video stream, bail */
522
        if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
523
            return 0;
524
        }
525
    }
526 de6d9b64 Fabrice Bellard
527 5ce117c3 Aurelien Jacobs
            if ( swf->video_type == CODEC_ID_VP6F ||
528
                 swf->video_type == CODEC_ID_FLV1 ) {
529 747a0554 Tinic Uro
                if ( swf->video_frame_number == 0 ) {
530
                    /* create a new video object */
531
                    put_swf_tag(s, TAG_VIDEOSTREAM);
532
                    put_le16(pb, VIDEO_ID);
533
                    put_le16(pb, 15000 ); /* hard flash player limit */
534
                    put_le16(pb, enc->width);
535
                    put_le16(pb, enc->height);
536
                    put_byte(pb, 0);
537 5ce117c3 Aurelien Jacobs
                    put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type));
538 747a0554 Tinic Uro
                    put_swf_end_tag(s);
539 115329f1 Diego Biurrun
540 747a0554 Tinic Uro
                    /* place the video object for the first time */
541
                    put_swf_tag(s, TAG_PLACEOBJECT2);
542
                    put_byte(pb, 0x36);
543
                    put_le16(pb, 1);
544
                    put_le16(pb, VIDEO_ID);
545
                    put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
546
                    put_le16(pb, swf->video_frame_number );
547
                    put_byte(pb, 'v');
548
                    put_byte(pb, 'i');
549
                    put_byte(pb, 'd');
550
                    put_byte(pb, 'e');
551
                    put_byte(pb, 'o');
552
                    put_byte(pb, 0x00);
553
                    put_swf_end_tag(s);
554
                } else {
555
                    /* mark the character for update */
556
                    put_swf_tag(s, TAG_PLACEOBJECT2);
557
                    put_byte(pb, 0x11);
558
                    put_le16(pb, 1);
559
                    put_le16(pb, swf->video_frame_number );
560
                    put_swf_end_tag(s);
561
                }
562 115329f1 Diego Biurrun
563 747a0554 Tinic Uro
                    /* set video frame data */
564
                    put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
565 115329f1 Diego Biurrun
                    put_le16(pb, VIDEO_ID);
566 747a0554 Tinic Uro
                    put_le16(pb, swf->video_frame_number++ );
567 14a68b89 Michael Niedermayer
                    put_buffer(pb, buf, size);
568 747a0554 Tinic Uro
                    put_swf_end_tag(s);
569
            } else if ( swf->video_type == CODEC_ID_MJPEG ) {
570
                if (swf->swf_frame_number > 0) {
571
                    /* remove the shape */
572
                    put_swf_tag(s, TAG_REMOVEOBJECT);
573
                    put_le16(pb, SHAPE_ID); /* shape ID */
574
                    put_le16(pb, 1); /* depth */
575
                    put_swf_end_tag(s);
576 115329f1 Diego Biurrun
577 747a0554 Tinic Uro
                    /* free the bitmap */
578
                    put_swf_tag(s, TAG_FREECHARACTER);
579
                    put_le16(pb, BITMAP_ID);
580
                    put_swf_end_tag(s);
581
                }
582 115329f1 Diego Biurrun
583 747a0554 Tinic Uro
                put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
584 115329f1 Diego Biurrun
585 747a0554 Tinic Uro
                put_le16(pb, BITMAP_ID); /* ID of the image */
586 115329f1 Diego Biurrun
587 747a0554 Tinic Uro
                /* a dummy jpeg header seems to be required */
588 115329f1 Diego Biurrun
                put_byte(pb, 0xff);
589 747a0554 Tinic Uro
                put_byte(pb, 0xd8);
590
                put_byte(pb, 0xff);
591
                put_byte(pb, 0xd9);
592
                /* write the jpeg image */
593 14a68b89 Michael Niedermayer
                put_buffer(pb, buf, size);
594 115329f1 Diego Biurrun
595 747a0554 Tinic Uro
                put_swf_end_tag(s);
596 115329f1 Diego Biurrun
597 747a0554 Tinic Uro
                /* draw the shape */
598 115329f1 Diego Biurrun
599 747a0554 Tinic Uro
                put_swf_tag(s, TAG_PLACEOBJECT);
600
                put_le16(pb, SHAPE_ID); /* shape ID */
601
                put_le16(pb, 1); /* depth */
602
                put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
603
                put_swf_end_tag(s);
604
            } else {
605
                /* invalid codec */
606
            }
607 115329f1 Diego Biurrun
608 747a0554 Tinic Uro
            swf->swf_frame_number ++;
609 de6d9b64 Fabrice Bellard
610 747a0554 Tinic Uro
    swf->video_samples += swf->samples_per_frame;
611 de6d9b64 Fabrice Bellard
612 747a0554 Tinic Uro
    /* streaming sound always should be placed just before showframe tags */
613
    if ( outSize > 0 ) {
614
        put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
615
        put_le16(pb, outSamples);
616
        put_le16(pb, 0);
617
        for (c=0; c<outSize; c++) {
618
            put_byte(pb,swf->audio_fifo[(swf->audio_in_pos+c) % AUDIO_FIFO_SIZE]);
619
        }
620
        put_swf_end_tag(s);
621 115329f1 Diego Biurrun
622 747a0554 Tinic Uro
        /* update FIFO */
623
        swf->sound_samples += outSamples;
624
        swf->audio_in_pos += outSize;
625
        swf->audio_size -= outSize;
626
        swf->audio_in_pos %= AUDIO_FIFO_SIZE;
627
    }
628
629 de6d9b64 Fabrice Bellard
    /* output the frame */
630
    put_swf_tag(s, TAG_SHOWFRAME);
631
    put_swf_end_tag(s);
632 115329f1 Diego Biurrun
633 de6d9b64 Fabrice Bellard
    put_flush_packet(&s->pb);
634 115329f1 Diego Biurrun
635 de6d9b64 Fabrice Bellard
    return 0;
636
}
637
638 115329f1 Diego Biurrun
static int swf_write_audio(AVFormatContext *s,
639 747a0554 Tinic Uro
                           AVCodecContext *enc, const uint8_t *buf, int size)
640 de6d9b64 Fabrice Bellard
{
641 747a0554 Tinic Uro
    SWFContext *swf = s->priv_data;
642
    int c = 0;
643 de6d9b64 Fabrice Bellard
644 747a0554 Tinic Uro
    /* Flash Player limit */
645 d3e18ad0 Michael Niedermayer
    if ( swf->swf_frame_number == 16000 ) {
646 bc874dae Michel Bardiaux
        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
647 747a0554 Tinic Uro
    }
648
649
    if (enc->codec_id == CODEC_ID_MP3 ) {
650
        for (c=0; c<size; c++) {
651
            swf->audio_fifo[(swf->audio_out_pos+c)%AUDIO_FIFO_SIZE] = buf[c];
652
        }
653
        swf->audio_size += size;
654
        swf->audio_out_pos += size;
655
        swf->audio_out_pos %= AUDIO_FIFO_SIZE;
656
    }
657
658
    /* if audio only stream make sure we add swf frames */
659
    if ( swf->video_type == 0 ) {
660
        swf_write_video(s, enc, 0, 0);
661
    }
662 de6d9b64 Fabrice Bellard
663
    return 0;
664
}
665
666 e928649b Michael Niedermayer
static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
667 de6d9b64 Fabrice Bellard
{
668 01f4895c Michael Niedermayer
    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
669 de6d9b64 Fabrice Bellard
    if (codec->codec_type == CODEC_TYPE_AUDIO)
670 e928649b Michael Niedermayer
        return swf_write_audio(s, codec, pkt->data, pkt->size);
671 de6d9b64 Fabrice Bellard
    else
672 e928649b Michael Niedermayer
        return swf_write_video(s, codec, pkt->data, pkt->size);
673 de6d9b64 Fabrice Bellard
}
674
675
static int swf_write_trailer(AVFormatContext *s)
676
{
677
    SWFContext *swf = s->priv_data;
678
    ByteIOContext *pb = &s->pb;
679
    AVCodecContext *enc, *video_enc;
680
    int file_size, i;
681
682
    video_enc = NULL;
683
    for(i=0;i<s->nb_streams;i++) {
684 01f4895c Michael Niedermayer
        enc = s->streams[i]->codec;
685 de6d9b64 Fabrice Bellard
        if (enc->codec_type == CODEC_TYPE_VIDEO)
686
            video_enc = enc;
687
    }
688
689
    put_swf_tag(s, TAG_END);
690
    put_swf_end_tag(s);
691 115329f1 Diego Biurrun
692 de6d9b64 Fabrice Bellard
    put_flush_packet(&s->pb);
693
694
    /* patch file size and number of frames if not streamed */
695
    if (!url_is_streamed(&s->pb) && video_enc) {
696
        file_size = url_ftell(pb);
697
        url_fseek(pb, 4, SEEK_SET);
698
        put_le32(pb, file_size);
699
        url_fseek(pb, swf->duration_pos, SEEK_SET);
700
        put_le16(pb, video_enc->frame_number);
701
    }
702 115329f1 Diego Biurrun
703 747a0554 Tinic Uro
    av_free(swf->audio_fifo);
704
705 de6d9b64 Fabrice Bellard
    return 0;
706
}
707 a9e35095 Diego Biurrun
#endif //CONFIG_MUXERS
708 de6d9b64 Fabrice Bellard
709 747a0554 Tinic Uro
/*********************************************/
710
/* Extract FLV encoded frame and MP3 from swf
711
   Note that the detection of the real frame
712
   is inaccurate at this point as it can be
713 115329f1 Diego Biurrun
   quite tricky to determine, you almost certainly
714 747a0554 Tinic Uro
   will get a bad audio/video sync */
715 de6d9b64 Fabrice Bellard
716
static int get_swf_tag(ByteIOContext *pb, int *len_ptr)
717
{
718
    int tag, len;
719 115329f1 Diego Biurrun
720 de6d9b64 Fabrice Bellard
    if (url_feof(pb))
721
        return -1;
722
723
    tag = get_le16(pb);
724
    len = tag & 0x3f;
725
    tag = tag >> 6;
726
    if (len == 0x3f) {
727
        len = get_le32(pb);
728
    }
729 e227d197 Alex Beregszaszi
//    av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len);
730 de6d9b64 Fabrice Bellard
    *len_ptr = len;
731
    return tag;
732
}
733
734 c9a65ca8 Fabrice Bellard
735
static int swf_probe(AVProbeData *p)
736
{
737
    /* check file header */
738
    if (p->buf_size <= 16)
739
        return 0;
740 e227d197 Alex Beregszaszi
    if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&
741 17269bdf Fabrice Bellard
        p->buf[2] == 'S')
742 c9a65ca8 Fabrice Bellard
        return AVPROBE_SCORE_MAX;
743
    else
744
        return 0;
745
}
746
747 de6d9b64 Fabrice Bellard
static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
748
{
749 747a0554 Tinic Uro
    SWFContext *swf = 0;
750 de6d9b64 Fabrice Bellard
    ByteIOContext *pb = &s->pb;
751
    int nbits, len, frame_rate, tag, v;
752 747a0554 Tinic Uro
    offset_t firstTagOff;
753
    AVStream *ast = 0;
754
    AVStream *vst = 0;
755
756
    swf = av_malloc(sizeof(SWFContext));
757
    if (!swf)
758
        return -1;
759
    s->priv_data = swf;
760 de6d9b64 Fabrice Bellard
761 e227d197 Alex Beregszaszi
    tag = get_be32(pb) & 0xffffff00;
762
763
    if (tag == MKBETAG('C', 'W', 'S', 0))
764
    {
765 bb270c08 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");
766 e227d197 Alex Beregszaszi
        return AVERROR_IO;
767
    }
768
    if (tag != MKBETAG('F', 'W', 'S', 0))
769 0bd586c5 Mike Melanson
        return AVERROR_IO;
770 de6d9b64 Fabrice Bellard
    get_le32(pb);
771
    /* skip rectangle size */
772
    nbits = get_byte(pb) >> 3;
773
    len = (4 * nbits - 3 + 7) / 8;
774
    url_fskip(pb, len);
775
    frame_rate = get_le16(pb);
776
    get_le16(pb); /* frame count */
777 115329f1 Diego Biurrun
778
    /* The Flash Player converts 8.8 frame rates
779
       to milliseconds internally. Do the same to get
780 747a0554 Tinic Uro
       a correct framerate */
781
    swf->ms_per_frame = ( 1000 * 256 ) / frame_rate;
782
    swf->samples_per_frame = 0;
783
    swf->ch_id = -1;
784
785
    firstTagOff = url_ftell(pb);
786 de6d9b64 Fabrice Bellard
    for(;;) {
787
        tag = get_swf_tag(pb, &len);
788
        if (tag < 0) {
789 747a0554 Tinic Uro
            if ( ast || vst ) {
790
                if ( vst && ast ) {
791 01f4895c Michael Niedermayer
                    vst->codec->time_base.den = ast->codec->sample_rate / swf->samples_per_frame;
792
                    vst->codec->time_base.num = 1;
793 747a0554 Tinic Uro
                }
794
                break;
795
            }
796 bc874dae Michel Bardiaux
            av_log(s, AV_LOG_ERROR, "No media found in SWF\n");
797 0bd586c5 Mike Melanson
            return AVERROR_IO;
798 de6d9b64 Fabrice Bellard
        }
799 747a0554 Tinic Uro
        if ( tag == TAG_VIDEOSTREAM && !vst) {
800 5ce117c3 Aurelien Jacobs
            int codec_id;
801 747a0554 Tinic Uro
            swf->ch_id = get_le16(pb);
802
            get_le16(pb);
803
            get_le16(pb);
804
            get_le16(pb);
805
            get_byte(pb);
806
            /* Check for FLV1 */
807 5ce117c3 Aurelien Jacobs
            codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
808
            if ( codec_id ) {
809 747a0554 Tinic Uro
                vst = av_new_stream(s, 0);
810 9ee91c2f Michael Niedermayer
                av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
811 115329f1 Diego Biurrun
812 01f4895c Michael Niedermayer
                vst->codec->codec_type = CODEC_TYPE_VIDEO;
813 5ce117c3 Aurelien Jacobs
                vst->codec->codec_id = codec_id;
814 747a0554 Tinic Uro
                if ( swf->samples_per_frame ) {
815 01f4895c Michael Niedermayer
                    vst->codec->time_base.den = 1000. / swf->ms_per_frame;
816
                    vst->codec->time_base.num = 1;
817 747a0554 Tinic Uro
                }
818
            }
819
        } else if ( ( tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2 ) && !ast) {
820 de6d9b64 Fabrice Bellard
            /* streaming found */
821
            get_byte(pb);
822
            v = get_byte(pb);
823 747a0554 Tinic Uro
            swf->samples_per_frame = get_le16(pb);
824 647b7762 Glyn Kennington
            if (len!=4)
825
                url_fskip(pb,len-4);
826 de6d9b64 Fabrice Bellard
            /* if mp3 streaming found, OK */
827
            if ((v & 0x20) != 0) {
828 747a0554 Tinic Uro
                if ( tag == TAG_STREAMHEAD2 ) {
829
                    get_le16(pb);
830
                }
831
                ast = av_new_stream(s, 1);
832
                if (!ast)
833 de6d9b64 Fabrice Bellard
                    return -ENOMEM;
834 fa73604f Aurelien Jacobs
                av_set_pts_info(ast, 24, 1, 1000); /* 24 bit pts in ms */
835 1e491e29 Michael Niedermayer
836 de6d9b64 Fabrice Bellard
                if (v & 0x01)
837 01f4895c Michael Niedermayer
                    ast->codec->channels = 2;
838 de6d9b64 Fabrice Bellard
                else
839 01f4895c Michael Niedermayer
                    ast->codec->channels = 1;
840 de6d9b64 Fabrice Bellard
841
                switch((v>> 2) & 0x03) {
842
                case 1:
843 01f4895c Michael Niedermayer
                    ast->codec->sample_rate = 11025;
844 de6d9b64 Fabrice Bellard
                    break;
845
                case 2:
846 01f4895c Michael Niedermayer
                    ast->codec->sample_rate = 22050;
847 de6d9b64 Fabrice Bellard
                    break;
848
                case 3:
849 01f4895c Michael Niedermayer
                    ast->codec->sample_rate = 44100;
850 de6d9b64 Fabrice Bellard
                    break;
851
                default:
852 747a0554 Tinic Uro
                    av_free(ast);
853 0bd586c5 Mike Melanson
                    return AVERROR_IO;
854 de6d9b64 Fabrice Bellard
                }
855 01f4895c Michael Niedermayer
                ast->codec->codec_type = CODEC_TYPE_AUDIO;
856
                ast->codec->codec_id = CODEC_ID_MP3;
857 21e3c26c Aurelien Jacobs
                ast->need_parsing = 1;
858 de6d9b64 Fabrice Bellard
            }
859
        } else {
860
            url_fskip(pb, len);
861
        }
862
    }
863 747a0554 Tinic Uro
    url_fseek(pb, firstTagOff, SEEK_SET);
864 115329f1 Diego Biurrun
865 de6d9b64 Fabrice Bellard
    return 0;
866
}
867
868
static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
869
{
870 747a0554 Tinic Uro
    SWFContext *swf = s->priv_data;
871 de6d9b64 Fabrice Bellard
    ByteIOContext *pb = &s->pb;
872 747a0554 Tinic Uro
    AVStream *st = 0;
873
    int tag, len, i, frame;
874 115329f1 Diego Biurrun
875 de6d9b64 Fabrice Bellard
    for(;;) {
876
        tag = get_swf_tag(pb, &len);
877 115329f1 Diego Biurrun
        if (tag < 0)
878 0bd586c5 Mike Melanson
            return AVERROR_IO;
879 747a0554 Tinic Uro
        if (tag == TAG_VIDEOFRAME) {
880
            for( i=0; i<s->nb_streams; i++ ) {
881 bb270c08 Diego Biurrun
                st = s->streams[i];
882 747a0554 Tinic Uro
                if (st->id == 0) {
883
                    if ( get_le16(pb) == swf->ch_id ) {
884
                        frame = get_le16(pb);
885 2692067a Michael Niedermayer
                        av_get_packet(pb, pkt, len-4);
886 747a0554 Tinic Uro
                        pkt->pts = frame * swf->ms_per_frame;
887
                        pkt->stream_index = st->index;
888
                        return pkt->size;
889
                    } else {
890
                        url_fskip(pb, len-2);
891
                        continue;
892
                    }
893
                }
894 115329f1 Diego Biurrun
            }
895 747a0554 Tinic Uro
            url_fskip(pb, len);
896
        } else if (tag == TAG_STREAMBLOCK) {
897
            for( i=0; i<s->nb_streams; i++ ) {
898 bb270c08 Diego Biurrun
                st = s->streams[i];
899 747a0554 Tinic Uro
                if (st->id == 1) {
900 21e3c26c Aurelien Jacobs
                    url_fskip(pb, 4);
901
                    av_get_packet(pb, pkt, len-4);
902 747a0554 Tinic Uro
                    pkt->stream_index = st->index;
903
                    return pkt->size;
904
                }
905
            }
906
            url_fskip(pb, len);
907 de6d9b64 Fabrice Bellard
        } else {
908
            url_fskip(pb, len);
909
        }
910
    }
911
    return 0;
912
}
913
914
static int swf_read_close(AVFormatContext *s)
915
{
916
     return 0;
917
}
918
919 ff70e601 Måns Rullgård
#ifdef CONFIG_SWF_DEMUXER
920
AVInputFormat swf_demuxer = {
921 c9a65ca8 Fabrice Bellard
    "swf",
922
    "Flash format",
923 747a0554 Tinic Uro
    sizeof(SWFContext),
924 c9a65ca8 Fabrice Bellard
    swf_probe,
925
    swf_read_header,
926
    swf_read_packet,
927
    swf_read_close,
928
};
929 ff70e601 Måns Rullgård
#endif
930
#ifdef CONFIG_SWF_MUXER
931
AVOutputFormat swf_muxer = {
932 de6d9b64 Fabrice Bellard
    "swf",
933
    "Flash format",
934
    "application/x-shockwave-flash",
935
    "swf",
936 c9a65ca8 Fabrice Bellard
    sizeof(SWFContext),
937 747a0554 Tinic Uro
    CODEC_ID_MP3,
938
    CODEC_ID_FLV1,
939 de6d9b64 Fabrice Bellard
    swf_write_header,
940
    swf_write_packet,
941
    swf_write_trailer,
942
};
943 ff70e601 Måns Rullgård
#endif