Statistics
| Branch: | Revision:

ffmpeg / libavformat / swf.c @ 5a757507

History | View | Annotate | Download (28.7 KB)

1
/*
2
 * Flash Compatible Streaming Format
3
 * Copyright (c) 2000 Fabrice Bellard.
4
 * Copyright (c) 2003 Tinic Uro.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include "avformat.h"
21

    
22
/* should have a generic way to indicate probable size */
23
#define DUMMY_FILE_SIZE   (100 * 1024 * 1024)
24
#define DUMMY_DURATION    600 /* in seconds */
25

    
26
#define TAG_END           0
27
#define TAG_SHOWFRAME     1
28
#define TAG_DEFINESHAPE   2
29
#define TAG_FREECHARACTER 3
30
#define TAG_PLACEOBJECT   4
31
#define TAG_REMOVEOBJECT  5
32
#define TAG_STREAMHEAD    45
33
#define TAG_STREAMBLOCK   19
34
#define TAG_JPEG2         21
35
#define TAG_PLACEOBJECT2  26
36
#define TAG_STREAMHEAD2   45
37
#define TAG_VIDEOSTREAM          60
38
#define TAG_VIDEOFRAME    61
39

    
40
#define TAG_LONG         0x100
41

    
42
/* flags for shape definition */
43
#define FLAG_MOVETO      0x01
44
#define FLAG_SETFILL0    0x02
45
#define FLAG_SETFILL1    0x04
46

    
47
#define SWF_VIDEO_CODEC_FLV1        0x02
48

    
49
#define AUDIO_FIFO_SIZE 65536
50

    
51
/* character id used */
52
#define BITMAP_ID 0
53
#define VIDEO_ID 0
54
#define SHAPE_ID  1
55

    
56
typedef struct SWFFrame_s {
57
    void *data;
58
    int size;
59
    struct SWFFrame_s *prev;
60
    struct SWFFrame_s *next;
61
} SWFFrame;
62

    
63
typedef struct {
64

    
65
    offset_t duration_pos;
66
    offset_t tag_pos;
67
    
68
    int samples_per_frame;
69
    int sound_samples;
70
    int video_samples;
71
    int skip_samples;
72
    int swf_frame_number;
73
    int video_frame_number;
74
    int ms_per_frame;
75
    int ch_id;
76
    int tag;
77

    
78
    uint8_t *audio_fifo;
79
    int audio_in_pos;
80
    int audio_out_pos;
81
    int audio_size;
82

    
83
    int video_type;
84
    int audio_type;
85
    
86
    SWFFrame *frame_head;
87
    SWFFrame *frame_tail;
88
} SWFContext;
89

    
90
static const int sSampleRates[3][4] = {
91
    {44100, 48000, 32000, 0},
92
    {22050, 24000, 16000, 0},
93
    {11025, 12000,  8000, 0},
94
};
95

    
96
static const int sBitRates[2][3][15] = {
97
    {   {  0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448},
98
        {  0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384},
99
        {  0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}
100
    },
101
    {   {  0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256},
102
        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160},
103
        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}
104
    },
105
};
106

    
107
static const int sSamplesPerFrame[3][3] =
108
{
109
    {  384,     1152,    1152 },
110
    {  384,     1152,     576 },
111
    {  384,     1152,     576 }
112
};
113

    
114
static const int sBitsPerSlot[3] = {
115
    32,
116
    8,
117
    8
118
};
119

    
120
static int swf_mp3_info(void *data, int *byteSize, int *samplesPerFrame, int *sampleRate, int *isMono )
121
{
122
    uint8_t *dataTmp = (uint8_t *)data;
123
    uint32_t header = ( (uint32_t)dataTmp[0] << 24 ) | ( (uint32_t)dataTmp[1] << 16 ) | ( (uint32_t)dataTmp[2] << 8 ) | (uint32_t)dataTmp[3];
124
    int layerID = 3 - ((header >> 17) & 0x03);
125
    int bitRateID = ((header >> 12) & 0x0f);
126
    int sampleRateID = ((header >> 10) & 0x03);
127
    int bitRate = 0;
128
    int bitsPerSlot = sBitsPerSlot[layerID];
129
    int isPadded = ((header >> 9) & 0x01);
130
    
131
    if ( (( header >> 21 ) & 0x7ff) != 0x7ff ) {
132
        return 0;
133
    }
134

    
135
    *isMono = ((header >>  6) & 0x03) == 0x03;
136

    
137
    if ( (header >> 19 ) & 0x01 ) {
138
        *sampleRate = sSampleRates[0][sampleRateID];
139
        bitRate = sBitRates[0][layerID][bitRateID] * 1000;
140
        *samplesPerFrame = sSamplesPerFrame[0][layerID];
141
    } else {
142
        if ( (header >> 20) & 0x01 ) {
143
            *sampleRate = sSampleRates[1][sampleRateID];
144
            bitRate = sBitRates[1][layerID][bitRateID] * 1000;
145
            *samplesPerFrame = sSamplesPerFrame[1][layerID];
146
        } else {
147
            *sampleRate = sSampleRates[2][sampleRateID];
148
            bitRate = sBitRates[1][layerID][bitRateID] * 1000;
149
            *samplesPerFrame = sSamplesPerFrame[2][layerID];
150
        }
151
    }
152

    
153
    *byteSize = ( ( ( ( *samplesPerFrame * (bitRate / bitsPerSlot) ) / *sampleRate ) + isPadded ) );
154

    
155
    return 1;
156
}
157

    
158
#ifdef CONFIG_ENCODERS
159
static void put_swf_tag(AVFormatContext *s, int tag)
160
{
161
    SWFContext *swf = s->priv_data;
162
    ByteIOContext *pb = &s->pb;
163

    
164
    swf->tag_pos = url_ftell(pb);
165
    swf->tag = tag;
166
    /* reserve some room for the tag */
167
    if (tag & TAG_LONG) {
168
        put_le16(pb, 0);
169
        put_le32(pb, 0);
170
    } else {
171
        put_le16(pb, 0);
172
    }
173
}
174

    
175
static void put_swf_end_tag(AVFormatContext *s)
176
{
177
    SWFContext *swf = s->priv_data;
178
    ByteIOContext *pb = &s->pb;
179
    offset_t pos;
180
    int tag_len, tag;
181

    
182
    pos = url_ftell(pb);
183
    tag_len = pos - swf->tag_pos - 2;
184
    tag = swf->tag;
185
    url_fseek(pb, swf->tag_pos, SEEK_SET);
186
    if (tag & TAG_LONG) {
187
        tag &= ~TAG_LONG;
188
        put_le16(pb, (tag << 6) | 0x3f);
189
        put_le32(pb, tag_len - 4);
190
    } else {
191
        assert(tag_len < 0x3f);
192
        put_le16(pb, (tag << 6) | tag_len);
193
    }
194
    url_fseek(pb, pos, SEEK_SET);
195
}
196

    
197
static inline void max_nbits(int *nbits_ptr, int val)
198
{
199
    int n;
200

    
201
    if (val == 0)
202
        return;
203
    val = abs(val);
204
    n = 1;
205
    while (val != 0) {
206
        n++;
207
        val >>= 1;
208
    }
209
    if (n > *nbits_ptr)
210
        *nbits_ptr = n;
211
}
212

    
213
static void put_swf_rect(ByteIOContext *pb, 
214
                         int xmin, int xmax, int ymin, int ymax)
215
{
216
    PutBitContext p;
217
    uint8_t buf[256];
218
    int nbits, mask;
219

    
220
    init_put_bits(&p, buf, sizeof(buf));
221
    
222
    nbits = 0;
223
    max_nbits(&nbits, xmin);
224
    max_nbits(&nbits, xmax);
225
    max_nbits(&nbits, ymin);
226
    max_nbits(&nbits, ymax);
227
    mask = (1 << nbits) - 1;
228

    
229
    /* rectangle info */
230
    put_bits(&p, 5, nbits);
231
    put_bits(&p, nbits, xmin & mask);
232
    put_bits(&p, nbits, xmax & mask);
233
    put_bits(&p, nbits, ymin & mask);
234
    put_bits(&p, nbits, ymax & mask);
235
    
236
    flush_put_bits(&p);
237
    put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
238
}
239

    
240
static void put_swf_line_edge(PutBitContext *pb, int dx, int dy)
241
{
242
    int nbits, mask;
243

    
244
    put_bits(pb, 1, 1); /* edge */
245
    put_bits(pb, 1, 1); /* line select */
246
    nbits = 2;
247
    max_nbits(&nbits, dx);
248
    max_nbits(&nbits, dy);
249

    
250
    mask = (1 << nbits) - 1;
251
    put_bits(pb, 4, nbits - 2); /* 16 bits precision */
252
    if (dx == 0) {
253
      put_bits(pb, 1, 0); 
254
      put_bits(pb, 1, 1); 
255
      put_bits(pb, nbits, dy & mask);
256
    } else if (dy == 0) {
257
      put_bits(pb, 1, 0); 
258
      put_bits(pb, 1, 0); 
259
      put_bits(pb, nbits, dx & mask);
260
    } else {
261
      put_bits(pb, 1, 1); 
262
      put_bits(pb, nbits, dx & mask);
263
      put_bits(pb, nbits, dy & mask);
264
    }
265
}
266

    
267
#define FRAC_BITS 16
268

    
269
/* put matrix */
270
static void put_swf_matrix(ByteIOContext *pb,
271
                           int a, int b, int c, int d, int tx, int ty)
272
{
273
    PutBitContext p;
274
    uint8_t buf[256];
275
    int nbits;
276

    
277
    init_put_bits(&p, buf, sizeof(buf));
278
    
279
    put_bits(&p, 1, 1); /* a, d present */
280
    nbits = 1;
281
    max_nbits(&nbits, a);
282
    max_nbits(&nbits, d);
283
    put_bits(&p, 5, nbits); /* nb bits */
284
    put_bits(&p, nbits, a);
285
    put_bits(&p, nbits, d);
286
    
287
    put_bits(&p, 1, 1); /* b, c present */
288
    nbits = 1;
289
    max_nbits(&nbits, c);
290
    max_nbits(&nbits, b);
291
    put_bits(&p, 5, nbits); /* nb bits */
292
    put_bits(&p, nbits, c);
293
    put_bits(&p, nbits, b);
294

    
295
    nbits = 1;
296
    max_nbits(&nbits, tx);
297
    max_nbits(&nbits, ty);
298
    put_bits(&p, 5, nbits); /* nb bits */
299
    put_bits(&p, nbits, tx);
300
    put_bits(&p, nbits, ty);
301

    
302
    flush_put_bits(&p);
303
    put_buffer(pb, buf, pbBufPtr(&p) - p.buf);
304
}
305

    
306
/* */
307
static int swf_write_header(AVFormatContext *s)
308
{
309
    SWFContext *swf;
310
    ByteIOContext *pb = &s->pb;
311
    AVCodecContext *enc, *audio_enc, *video_enc;
312
    PutBitContext p;
313
    uint8_t buf1[256];
314
    int i, width, height, rate, rate_base;
315

    
316
    swf = av_malloc(sizeof(SWFContext));
317
    if (!swf)
318
        return -1;
319
    s->priv_data = swf;
320

    
321
    swf->ch_id = -1;
322
    swf->audio_in_pos = 0;
323
    swf->audio_out_pos = 0;
324
    swf->audio_size = 0;
325
    swf->audio_fifo = av_malloc(AUDIO_FIFO_SIZE);
326
    swf->frame_head = 0;
327
    swf->frame_tail = 0;
328
    swf->sound_samples = 0;
329
    swf->video_samples = 0;
330
    swf->swf_frame_number = 0;
331
    swf->video_frame_number = 0;
332
    swf->skip_samples = 0;
333

    
334
    video_enc = NULL;
335
    audio_enc = NULL;
336
    for(i=0;i<s->nb_streams;i++) {
337
        enc = &s->streams[i]->codec;
338
        if (enc->codec_type == CODEC_TYPE_AUDIO)
339
            audio_enc = enc;
340
        else {
341
            if ( enc->codec_id == CODEC_ID_FLV1 || enc->codec_id == CODEC_ID_MJPEG ) {
342
                video_enc = enc;
343
            } else {
344
                av_log(enc, AV_LOG_ERROR, "SWF only supports FLV1 and MJPEG\n");
345
                return -1;
346
            }
347
        }
348
    }
349

    
350
    if (!video_enc) {
351
        /* currenty, cannot work correctly if audio only */
352
        swf->video_type = 0;
353
        width = 320;
354
        height = 200;
355
        rate = 10;
356
        rate_base= 1;
357
    } else {
358
        swf->video_type = video_enc->codec_id;
359
        width = video_enc->width;
360
        height = video_enc->height;
361
        rate = video_enc->frame_rate;
362
        rate_base = video_enc->frame_rate_base;
363
    }
364

    
365
    if (!audio_enc ) {
366
        swf->audio_type = 0;
367
        swf->samples_per_frame = ( 44100. * rate_base ) / rate;
368
    } else {
369
        swf->audio_type = audio_enc->codec_id;
370
        swf->samples_per_frame = ( ( audio_enc->sample_rate ) * rate_base ) / rate;
371
    }
372

    
373
    put_tag(pb, "FWS");
374
    if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
375
        put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */
376
    } else {
377
        put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */
378
    }
379
    put_le32(pb, DUMMY_FILE_SIZE); /* dummy size 
380
                                      (will be patched if not streamed) */ 
381

    
382
    put_swf_rect(pb, 0, width * 20, 0, height * 20);
383
    put_le16(pb, (rate * 256) / rate_base); /* frame rate */
384
    swf->duration_pos = url_ftell(pb);
385
    put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
386
    
387
    /* define a shape with the jpeg inside */
388
    if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
389
    } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) {
390
        put_swf_tag(s, TAG_DEFINESHAPE);
391

    
392
        put_le16(pb, SHAPE_ID); /* ID of shape */
393
        /* bounding rectangle */
394
        put_swf_rect(pb, 0, width, 0, height);
395
        /* style info */
396
        put_byte(pb, 1); /* one fill style */
397
        put_byte(pb, 0x41); /* clipped bitmap fill */
398
        put_le16(pb, BITMAP_ID); /* bitmap ID */
399
        /* position of the bitmap */
400
        put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0, 
401
                        0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
402
        put_byte(pb, 0); /* no line style */
403
    
404
        /* shape drawing */
405
        init_put_bits(&p, buf1, sizeof(buf1));
406
        put_bits(&p, 4, 1); /* one fill bit */
407
        put_bits(&p, 4, 0); /* zero line bit */
408
     
409
        put_bits(&p, 1, 0); /* not an edge */
410
        put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
411
        put_bits(&p, 5, 1); /* nbits */
412
        put_bits(&p, 1, 0); /* X */
413
        put_bits(&p, 1, 0); /* Y */
414
        put_bits(&p, 1, 1); /* set fill style 1 */
415
    
416
        /* draw the rectangle ! */
417
        put_swf_line_edge(&p, width, 0);
418
        put_swf_line_edge(&p, 0, height);
419
        put_swf_line_edge(&p, -width, 0);
420
        put_swf_line_edge(&p, 0, -height);
421
    
422
        /* end of shape */
423
        put_bits(&p, 1, 0); /* not an edge */
424
        put_bits(&p, 5, 0);
425

    
426
        flush_put_bits(&p);
427
        put_buffer(pb, buf1, pbBufPtr(&p) - p.buf);
428

    
429
        put_swf_end_tag(s);
430
    }
431
    
432
    if (audio_enc && audio_enc->codec_id == CODEC_ID_MP3 ) {
433
        int v;
434

    
435
        /* start sound */
436
        put_swf_tag(s, TAG_STREAMHEAD2);
437

    
438
        v = 0;
439
        switch(audio_enc->sample_rate) {
440
        case 11025:
441
            v |= 1 << 2;
442
            break;
443
        case 22050:
444
            v |= 2 << 2;
445
            break;
446
        case 44100:
447
            v |= 3 << 2;
448
            break;
449
        default:
450
            /* not supported */
451
            av_free(swf->audio_fifo);
452
            av_free(swf);
453
            return -1;
454
        }
455
        v |= 0x02; /* 16 bit playback */
456
        if (audio_enc->channels == 2)
457
            v |= 0x01; /* stereo playback */
458
        put_byte(&s->pb, v);
459
        v |= 0x20; /* mp3 compressed */
460
        put_byte(&s->pb, v);
461
        put_le16(&s->pb, swf->samples_per_frame);  /* avg samples per frame */
462
        put_le16(&s->pb, 0);
463
        
464
        put_swf_end_tag(s);
465
    }
466

    
467
    put_flush_packet(&s->pb);
468
    return 0;
469
}
470

    
471
static int swf_write_video(AVFormatContext *s, 
472
                           AVCodecContext *enc, const uint8_t *buf, int size)
473
{
474
    SWFContext *swf = s->priv_data;
475
    ByteIOContext *pb = &s->pb;
476
    int c = 0;
477
    int outSize = 0;
478
    int outSamples = 0;
479
    
480
    /* Flash Player limit */
481
    if ( swf->swf_frame_number == 16000 ) {
482
        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
483
    }
484

    
485
    /* Store video data in queue */
486
    if ( enc->codec_type == CODEC_TYPE_VIDEO ) {
487
        SWFFrame *new_frame = av_malloc(sizeof(SWFFrame));
488
        new_frame->prev = 0;
489
        new_frame->next = swf->frame_head;
490
        new_frame->data = av_malloc(size);
491
        new_frame->size = size;
492
        memcpy(new_frame->data,buf,size);
493
        swf->frame_head = new_frame;
494
        if ( swf->frame_tail == 0 ) {
495
            swf->frame_tail = new_frame;
496
        }
497
    }
498
    
499
    if ( swf->audio_type ) {
500
        /* Prescan audio data for this swf frame */
501
retry_swf_audio_packet:
502
        if ( ( swf->audio_size-outSize ) >= 4 ) {
503
            int mp3FrameSize = 0;
504
            int mp3SampleRate = 0;
505
            int mp3IsMono = 0;
506
            int mp3SamplesPerFrame = 0;
507
            
508
            /* copy out mp3 header from ring buffer */
509
            uint8_t header[4];
510
            for (c=0; c<4; c++) {
511
                header[c] = swf->audio_fifo[(swf->audio_in_pos+outSize+c) % AUDIO_FIFO_SIZE];
512
            }
513
            
514
            if ( swf_mp3_info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) {
515
                if ( ( swf->audio_size-outSize ) >= mp3FrameSize ) {
516
                    outSize += mp3FrameSize;
517
                    outSamples += mp3SamplesPerFrame;
518
                    if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
519
                        goto retry_swf_audio_packet;
520
                    }
521
                }
522
            } else {
523
                /* invalid mp3 data, skip forward
524
                we need to do this since the Flash Player 
525
                does not like custom headers */
526
                swf->audio_in_pos ++;
527
                swf->audio_size --;
528
                swf->audio_in_pos %= AUDIO_FIFO_SIZE;
529
                goto retry_swf_audio_packet;
530
            }
531
        }
532
        
533
        /* audio stream is behind video stream, bail */
534
        if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
535
            return 0;
536
        }
537

    
538
        /* compute audio/video drift */
539
        if ( enc->codec_type == CODEC_TYPE_VIDEO ) {
540
            swf->skip_samples = (int)( ( (double)(swf->swf_frame_number) * (double)enc->frame_rate_base * 44100. ) / (double)(enc->frame_rate) );
541
            swf->skip_samples -=  swf->video_samples;
542
        }
543
    }
544

    
545
    /* check if we need to insert a padding frame */
546
    if (swf->skip_samples <= ( swf->samples_per_frame / 2 ) ) {
547
        /* no, it is time for a real frame, check if one is available */
548
        if ( swf->frame_tail ) {
549
            if ( swf->video_type == CODEC_ID_FLV1 ) {
550
                if ( swf->video_frame_number == 0 ) {
551
                    /* create a new video object */
552
                    put_swf_tag(s, TAG_VIDEOSTREAM);
553
                    put_le16(pb, VIDEO_ID);
554
                    put_le16(pb, 15000 ); /* hard flash player limit */
555
                    put_le16(pb, enc->width);
556
                    put_le16(pb, enc->height);
557
                    put_byte(pb, 0);
558
                    put_byte(pb, SWF_VIDEO_CODEC_FLV1);
559
                    put_swf_end_tag(s);
560
                    
561
                    /* place the video object for the first time */
562
                    put_swf_tag(s, TAG_PLACEOBJECT2);
563
                    put_byte(pb, 0x36);
564
                    put_le16(pb, 1);
565
                    put_le16(pb, VIDEO_ID);
566
                    put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
567
                    put_le16(pb, swf->video_frame_number );
568
                    put_byte(pb, 'v');
569
                    put_byte(pb, 'i');
570
                    put_byte(pb, 'd');
571
                    put_byte(pb, 'e');
572
                    put_byte(pb, 'o');
573
                    put_byte(pb, 0x00);
574
                    put_swf_end_tag(s);
575
                } else {
576
                    /* mark the character for update */
577
                    put_swf_tag(s, TAG_PLACEOBJECT2);
578
                    put_byte(pb, 0x11);
579
                    put_le16(pb, 1);
580
                    put_le16(pb, swf->video_frame_number );
581
                    put_swf_end_tag(s);
582
                }
583
    
584
                // write out pending frames
585
                for (; ( enc->frame_number - swf->video_frame_number ) > 0;) {
586
                    /* set video frame data */
587
                    put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
588
                    put_le16(pb, VIDEO_ID); 
589
                    put_le16(pb, swf->video_frame_number++ );
590
                    put_buffer(pb, swf->frame_tail->data, swf->frame_tail->size);
591
                    put_swf_end_tag(s);
592
                }
593

    
594
            } else if ( swf->video_type == CODEC_ID_MJPEG ) {
595
                if (swf->swf_frame_number > 0) {
596
                    /* remove the shape */
597
                    put_swf_tag(s, TAG_REMOVEOBJECT);
598
                    put_le16(pb, SHAPE_ID); /* shape ID */
599
                    put_le16(pb, 1); /* depth */
600
                    put_swf_end_tag(s);
601
                
602
                    /* free the bitmap */
603
                    put_swf_tag(s, TAG_FREECHARACTER);
604
                    put_le16(pb, BITMAP_ID);
605
                    put_swf_end_tag(s);
606
                }
607
        
608
                put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
609
        
610
                put_le16(pb, BITMAP_ID); /* ID of the image */
611
        
612
                /* a dummy jpeg header seems to be required */
613
                put_byte(pb, 0xff); 
614
                put_byte(pb, 0xd8);
615
                put_byte(pb, 0xff);
616
                put_byte(pb, 0xd9);
617
                /* write the jpeg image */
618
                put_buffer(pb, swf->frame_tail->data, swf->frame_tail->size);
619
        
620
                put_swf_end_tag(s);
621
        
622
                /* draw the shape */
623
        
624
                put_swf_tag(s, TAG_PLACEOBJECT);
625
                put_le16(pb, SHAPE_ID); /* shape ID */
626
                put_le16(pb, 1); /* depth */
627
                put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
628
                put_swf_end_tag(s);
629
            } else {
630
                /* invalid codec */
631
            }
632
    
633
            av_free(swf->frame_tail->data);
634
            swf->frame_tail = swf->frame_tail->prev;
635
            if ( swf->frame_tail ) {
636
                if ( swf->frame_tail->next ) {
637
                    av_free(swf->frame_tail->next);
638
                }
639
                swf->frame_tail->next = 0;
640
            } else {
641
                swf->frame_head = 0;
642
            }
643
            swf->swf_frame_number ++;
644
        }
645
    }
646

    
647
    swf->video_samples += swf->samples_per_frame;
648

    
649
    /* streaming sound always should be placed just before showframe tags */
650
    if ( outSize > 0 ) {
651
        put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
652
        put_le16(pb, outSamples);
653
        put_le16(pb, 0);
654
        for (c=0; c<outSize; c++) {
655
            put_byte(pb,swf->audio_fifo[(swf->audio_in_pos+c) % AUDIO_FIFO_SIZE]);
656
        }
657
        put_swf_end_tag(s);
658
    
659
        /* update FIFO */
660
        swf->sound_samples += outSamples;
661
        swf->audio_in_pos += outSize;
662
        swf->audio_size -= outSize;
663
        swf->audio_in_pos %= AUDIO_FIFO_SIZE;
664
    }
665

    
666
    /* output the frame */
667
    put_swf_tag(s, TAG_SHOWFRAME);
668
    put_swf_end_tag(s);
669
    
670
    put_flush_packet(&s->pb);
671
    
672
    return 0;
673
}
674

    
675
static int swf_write_audio(AVFormatContext *s, 
676
                           AVCodecContext *enc, const uint8_t *buf, int size)
677
{
678
    SWFContext *swf = s->priv_data;
679
    int c = 0;
680

    
681
    /* Flash Player limit */
682
    if ( swf->swf_frame_number == 16000 ) {
683
        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
684
    }
685

    
686
    if (enc->codec_id == CODEC_ID_MP3 ) {
687
        for (c=0; c<size; c++) {
688
            swf->audio_fifo[(swf->audio_out_pos+c)%AUDIO_FIFO_SIZE] = buf[c];
689
        }
690
        swf->audio_size += size;
691
        swf->audio_out_pos += size;
692
        swf->audio_out_pos %= AUDIO_FIFO_SIZE;
693
    }
694

    
695
    /* if audio only stream make sure we add swf frames */
696
    if ( swf->video_type == 0 ) {
697
        swf_write_video(s, enc, 0, 0);
698
    }
699

    
700
    return 0;
701
}
702

    
703
static int swf_write_packet(AVFormatContext *s, int stream_index, 
704
                           const uint8_t *buf, int size, int64_t pts)
705
{
706
    AVCodecContext *codec = &s->streams[stream_index]->codec;
707
    if (codec->codec_type == CODEC_TYPE_AUDIO)
708
        return swf_write_audio(s, codec, buf, size);
709
    else
710
        return swf_write_video(s, codec, buf, size);
711
}
712

    
713
static int swf_write_trailer(AVFormatContext *s)
714
{
715
    SWFContext *swf = s->priv_data;
716
    ByteIOContext *pb = &s->pb;
717
    AVCodecContext *enc, *video_enc;
718
    int file_size, i;
719

    
720
    video_enc = NULL;
721
    for(i=0;i<s->nb_streams;i++) {
722
        enc = &s->streams[i]->codec;
723
        if (enc->codec_type == CODEC_TYPE_VIDEO)
724
            video_enc = enc;
725
    }
726

    
727
    put_swf_tag(s, TAG_END);
728
    put_swf_end_tag(s);
729
    
730
    put_flush_packet(&s->pb);
731

    
732
    /* patch file size and number of frames if not streamed */
733
    if (!url_is_streamed(&s->pb) && video_enc) {
734
        file_size = url_ftell(pb);
735
        url_fseek(pb, 4, SEEK_SET);
736
        put_le32(pb, file_size);
737
        url_fseek(pb, swf->duration_pos, SEEK_SET);
738
        put_le16(pb, video_enc->frame_number);
739
    }
740
    
741
    av_free(swf->audio_fifo);
742

    
743
    return 0;
744
}
745
#endif //CONFIG_ENCODERS
746

    
747
/*********************************************/
748
/* Extract FLV encoded frame and MP3 from swf
749
   Note that the detection of the real frame
750
   is inaccurate at this point as it can be
751
   quite tricky to determine, you almost certainly 
752
   will get a bad audio/video sync */
753

    
754
static int get_swf_tag(ByteIOContext *pb, int *len_ptr)
755
{
756
    int tag, len;
757
    
758
    if (url_feof(pb))
759
        return -1;
760

    
761
    tag = get_le16(pb);
762
    len = tag & 0x3f;
763
    tag = tag >> 6;
764
    if (len == 0x3f) {
765
        len = get_le32(pb);
766
    }
767
    *len_ptr = len;
768
    return tag;
769
}
770

    
771

    
772
static int swf_probe(AVProbeData *p)
773
{
774
    /* check file header */
775
    if (p->buf_size <= 16)
776
        return 0;
777
    if (p->buf[0] == 'F' && p->buf[1] == 'W' &&
778
        p->buf[2] == 'S')
779
        return AVPROBE_SCORE_MAX;
780
    else
781
        return 0;
782
}
783

    
784
static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
785
{
786
    SWFContext *swf = 0;
787
    ByteIOContext *pb = &s->pb;
788
    int nbits, len, frame_rate, tag, v;
789
    offset_t firstTagOff;
790
    AVStream *ast = 0;
791
    AVStream *vst = 0;
792

    
793
    swf = av_malloc(sizeof(SWFContext));
794
    if (!swf)
795
        return -1;
796
    s->priv_data = swf;
797

    
798
    if ((get_be32(pb) & 0xffffff00) != MKBETAG('F', 'W', 'S', 0))
799
        return -EIO;
800
    get_le32(pb);
801
    /* skip rectangle size */
802
    nbits = get_byte(pb) >> 3;
803
    len = (4 * nbits - 3 + 7) / 8;
804
    url_fskip(pb, len);
805
    frame_rate = get_le16(pb);
806
    get_le16(pb); /* frame count */
807
    
808
    av_set_pts_info(s, 24, 1, 1000); /* 24 bit pts in ms */
809
    
810
    /* The Flash Player converts 8.8 frame rates 
811
       to milliseconds internally. Do the same to get 
812
       a correct framerate */
813
    swf->ms_per_frame = ( 1000 * 256 ) / frame_rate;
814
    swf->samples_per_frame = 0;
815
    swf->ch_id = -1;
816

    
817
    firstTagOff = url_ftell(pb);
818
    for(;;) {
819
        tag = get_swf_tag(pb, &len);
820
        if (tag < 0) {
821
            if ( ast || vst ) {
822
                if ( vst && ast ) {
823
                    vst->codec.frame_rate = ast->codec.sample_rate / swf->samples_per_frame;
824
                    vst->codec.frame_rate_base = 1;
825
                }
826
                break;
827
            }
828
            av_log(s, AV_LOG_ERROR, "No media found in SWF\n");
829
            return -EIO;
830
        }
831
        if ( tag == TAG_VIDEOSTREAM && !vst) {
832
            swf->ch_id = get_le16(pb);
833
            get_le16(pb);
834
            get_le16(pb);
835
            get_le16(pb);
836
            get_byte(pb);
837
            /* Check for FLV1 */
838
            if ( get_byte(pb) == SWF_VIDEO_CODEC_FLV1 ) {
839
                vst = av_new_stream(s, 0);
840
                vst->codec.codec_type = CODEC_TYPE_VIDEO;
841
                vst->codec.codec_id = CODEC_ID_FLV1;
842
                if ( swf->samples_per_frame ) {
843
                    vst->codec.frame_rate = 1000. / swf->ms_per_frame;
844
                    vst->codec.frame_rate_base = 1;
845
                }
846
            }
847
        } else if ( ( tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2 ) && !ast) {
848
            /* streaming found */
849
            get_byte(pb);
850
            v = get_byte(pb);
851
            swf->samples_per_frame = get_le16(pb);
852
            if (len!=4)
853
                url_fskip(pb,len-4);
854
            /* if mp3 streaming found, OK */
855
            if ((v & 0x20) != 0) {
856
                if ( tag == TAG_STREAMHEAD2 ) {
857
                    get_le16(pb);
858
                }
859
                ast = av_new_stream(s, 1);
860
                if (!ast)
861
                    return -ENOMEM;
862

    
863
                if (v & 0x01)
864
                    ast->codec.channels = 2;
865
                else
866
                    ast->codec.channels = 1;
867

    
868
                switch((v>> 2) & 0x03) {
869
                case 1:
870
                    ast->codec.sample_rate = 11025;
871
                    break;
872
                case 2:
873
                    ast->codec.sample_rate = 22050;
874
                    break;
875
                case 3:
876
                    ast->codec.sample_rate = 44100;
877
                    break;
878
                default:
879
                    av_free(ast);
880
                    return -EIO;
881
                }
882
                ast->codec.codec_type = CODEC_TYPE_AUDIO;
883
                ast->codec.codec_id = CODEC_ID_MP3;
884
            }
885
        } else {
886
            url_fskip(pb, len);
887
        }
888
    }
889
    url_fseek(pb, firstTagOff, SEEK_SET);
890
    
891
    return 0;
892
}
893

    
894
static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
895
{
896
    SWFContext *swf = s->priv_data;
897
    ByteIOContext *pb = &s->pb;
898
    AVStream *st = 0;
899
    int tag, len, i, frame;
900
    
901
    for(;;) {
902
        tag = get_swf_tag(pb, &len);
903
        if (tag < 0) 
904
            return -EIO;
905
        if (tag == TAG_VIDEOFRAME) {
906
            for( i=0; i<s->nb_streams; i++ ) {
907
                st = s->streams[i];
908
                if (st->id == 0) {
909
                    if ( get_le16(pb) == swf->ch_id ) {
910
                        frame = get_le16(pb);
911
                        av_new_packet(pkt, len-4);
912
                        pkt->pts = frame * swf->ms_per_frame;
913
                        pkt->stream_index = st->index;
914
                        get_buffer(pb, pkt->data, pkt->size);
915
                        return pkt->size;
916
                    } else {
917
                        url_fskip(pb, len-2);
918
                        continue;
919
                    }
920
                }
921
            }    
922
            url_fskip(pb, len);
923
        } else if (tag == TAG_STREAMBLOCK) {
924
            for( i=0; i<s->nb_streams; i++ ) {
925
                st = s->streams[i];
926
                if (st->id == 1) {
927
                    av_new_packet(pkt, len);
928
                    pkt->stream_index = st->index;
929
                    get_buffer(pb, pkt->data, pkt->size);
930
                    return pkt->size;
931
                }
932
            }
933
            url_fskip(pb, len);
934
        } else {
935
            url_fskip(pb, len);
936
        }
937
    }
938
    return 0;
939
}
940

    
941
static int swf_read_close(AVFormatContext *s)
942
{
943
     return 0;
944
}
945

    
946
static AVInputFormat swf_iformat = {
947
    "swf",
948
    "Flash format",
949
    sizeof(SWFContext),
950
    swf_probe,
951
    swf_read_header,
952
    swf_read_packet,
953
    swf_read_close,
954
};
955

    
956
#ifdef CONFIG_ENCODERS
957
static AVOutputFormat swf_oformat = {
958
    "swf",
959
    "Flash format",
960
    "application/x-shockwave-flash",
961
    "swf",
962
    sizeof(SWFContext),
963
    CODEC_ID_MP3,
964
    CODEC_ID_FLV1,
965
    swf_write_header,
966
    swf_write_packet,
967
    swf_write_trailer,
968
};
969
#endif //CONFIG_ENCODERS
970

    
971
int swf_init(void)
972
{
973
    av_register_input_format(&swf_iformat);
974
#ifdef CONFIG_ENCODERS
975
    av_register_output_format(&swf_oformat);
976
#endif //CONFIG_ENCODERS
977
    return 0;
978
}