Statistics
| Branch: | Revision:

ffmpeg / libavformat / swf.c @ 5a757507

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