Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6148 serge 1
/*
2
 * Flash Compatible Streaming Format muxer
3
 * Copyright (c) 2000 Fabrice Bellard
4
 * Copyright (c) 2003 Tinic Uro
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
 
23
#include "libavcodec/put_bits.h"
24
#include "libavutil/avassert.h"
25
#include "avformat.h"
26
#include "swf.h"
27
 
28
static void put_swf_tag(AVFormatContext *s, int tag)
29
{
30
    SWFContext *swf = s->priv_data;
31
    AVIOContext *pb = s->pb;
32
 
33
    swf->tag_pos = avio_tell(pb);
34
    swf->tag = tag;
35
    /* reserve some room for the tag */
36
    if (tag & TAG_LONG) {
37
        avio_wl16(pb, 0);
38
        avio_wl32(pb, 0);
39
    } else {
40
        avio_wl16(pb, 0);
41
    }
42
}
43
 
44
static void put_swf_end_tag(AVFormatContext *s)
45
{
46
    SWFContext *swf = s->priv_data;
47
    AVIOContext *pb = s->pb;
48
    int64_t pos;
49
    int tag_len, tag;
50
 
51
    pos = avio_tell(pb);
52
    tag_len = pos - swf->tag_pos - 2;
53
    tag = swf->tag;
54
    avio_seek(pb, swf->tag_pos, SEEK_SET);
55
    if (tag & TAG_LONG) {
56
        tag &= ~TAG_LONG;
57
        avio_wl16(pb, (tag << 6) | 0x3f);
58
        avio_wl32(pb, tag_len - 4);
59
    } else {
60
        av_assert0(tag_len < 0x3f);
61
        avio_wl16(pb, (tag << 6) | tag_len);
62
    }
63
    avio_seek(pb, pos, SEEK_SET);
64
}
65
 
66
static inline void max_nbits(int *nbits_ptr, int val)
67
{
68
    int n;
69
 
70
    if (val == 0)
71
        return;
72
    val = abs(val);
73
    n = 1;
74
    while (val != 0) {
75
        n++;
76
        val >>= 1;
77
    }
78
    if (n > *nbits_ptr)
79
        *nbits_ptr = n;
80
}
81
 
82
static void put_swf_rect(AVIOContext *pb,
83
                         int xmin, int xmax, int ymin, int ymax)
84
{
85
    PutBitContext p;
86
    uint8_t buf[256];
87
    int nbits, mask;
88
 
89
    init_put_bits(&p, buf, sizeof(buf));
90
 
91
    nbits = 0;
92
    max_nbits(&nbits, xmin);
93
    max_nbits(&nbits, xmax);
94
    max_nbits(&nbits, ymin);
95
    max_nbits(&nbits, ymax);
96
    mask = (1 << nbits) - 1;
97
 
98
    /* rectangle info */
99
    put_bits(&p, 5, nbits);
100
    put_bits(&p, nbits, xmin & mask);
101
    put_bits(&p, nbits, xmax & mask);
102
    put_bits(&p, nbits, ymin & mask);
103
    put_bits(&p, nbits, ymax & mask);
104
 
105
    flush_put_bits(&p);
106
    avio_write(pb, buf, put_bits_ptr(&p) - p.buf);
107
}
108
 
109
static void put_swf_line_edge(PutBitContext *pb, int dx, int dy)
110
{
111
    int nbits, mask;
112
 
113
    put_bits(pb, 1, 1); /* edge */
114
    put_bits(pb, 1, 1); /* line select */
115
    nbits = 2;
116
    max_nbits(&nbits, dx);
117
    max_nbits(&nbits, dy);
118
 
119
    mask = (1 << nbits) - 1;
120
    put_bits(pb, 4, nbits - 2); /* 16 bits precision */
121
    if (dx == 0) {
122
        put_bits(pb, 1, 0);
123
        put_bits(pb, 1, 1);
124
        put_bits(pb, nbits, dy & mask);
125
    } else if (dy == 0) {
126
        put_bits(pb, 1, 0);
127
        put_bits(pb, 1, 0);
128
        put_bits(pb, nbits, dx & mask);
129
    } else {
130
        put_bits(pb, 1, 1);
131
        put_bits(pb, nbits, dx & mask);
132
        put_bits(pb, nbits, dy & mask);
133
    }
134
}
135
 
136
#define FRAC_BITS 16
137
 
138
static void put_swf_matrix(AVIOContext *pb,
139
                           int a, int b, int c, int d, int tx, int ty)
140
{
141
    PutBitContext p;
142
    uint8_t buf[256];
143
    int nbits;
144
 
145
    init_put_bits(&p, buf, sizeof(buf));
146
 
147
    put_bits(&p, 1, 1); /* a, d present */
148
    nbits = 1;
149
    max_nbits(&nbits, a);
150
    max_nbits(&nbits, d);
151
    put_bits(&p, 5, nbits); /* nb bits */
152
    put_bits(&p, nbits, a);
153
    put_bits(&p, nbits, d);
154
 
155
    put_bits(&p, 1, 1); /* b, c present */
156
    nbits = 1;
157
    max_nbits(&nbits, c);
158
    max_nbits(&nbits, b);
159
    put_bits(&p, 5, nbits); /* nb bits */
160
    put_bits(&p, nbits, c);
161
    put_bits(&p, nbits, b);
162
 
163
    nbits = 1;
164
    max_nbits(&nbits, tx);
165
    max_nbits(&nbits, ty);
166
    put_bits(&p, 5, nbits); /* nb bits */
167
    put_bits(&p, nbits, tx);
168
    put_bits(&p, nbits, ty);
169
 
170
    flush_put_bits(&p);
171
    avio_write(pb, buf, put_bits_ptr(&p) - p.buf);
172
}
173
 
174
static int swf_write_header(AVFormatContext *s)
175
{
176
    SWFContext *swf = s->priv_data;
177
    AVIOContext *pb = s->pb;
178
    PutBitContext p;
179
    uint8_t buf1[256];
180
    int i, width, height, rate, rate_base;
181
    int version;
182
 
183
    swf->sound_samples = 0;
184
    swf->swf_frame_number = 0;
185
    swf->video_frame_number = 0;
186
 
187
    for(i=0;inb_streams;i++) {
188
        AVCodecContext *enc = s->streams[i]->codec;
189
        if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
190
            if (swf->audio_enc) {
191
                av_log(s, AV_LOG_ERROR, "SWF muxer only supports 1 audio stream\n");
192
                return AVERROR_INVALIDDATA;
193
            }
194
            if (enc->codec_id == AV_CODEC_ID_MP3) {
195
                if (!enc->frame_size) {
196
                    av_log(s, AV_LOG_ERROR, "audio frame size not set\n");
197
                    return -1;
198
                }
199
                swf->audio_enc = enc;
200
                swf->audio_fifo= av_fifo_alloc(AUDIO_FIFO_SIZE);
201
                if (!swf->audio_fifo)
202
                    return AVERROR(ENOMEM);
203
            } else {
204
                av_log(s, AV_LOG_ERROR, "SWF muxer only supports MP3\n");
205
                return -1;
206
            }
207
        } else {
208
            if (swf->video_enc) {
209
                av_log(s, AV_LOG_ERROR, "SWF muxer only supports 1 video stream\n");
210
                return AVERROR_INVALIDDATA;
211
            }
212
            if (enc->codec_id == AV_CODEC_ID_VP6F ||
213
                enc->codec_id == AV_CODEC_ID_FLV1 ||
214
                enc->codec_id == AV_CODEC_ID_MJPEG) {
215
                swf->video_enc = enc;
216
            } else {
217
                av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
218
                return -1;
219
            }
220
        }
221
    }
222
 
223
    if (!swf->video_enc) {
224
        /* currently, cannot work correctly if audio only */
225
        width = 320;
226
        height = 200;
227
        rate = 10;
228
        rate_base= 1;
229
    } else {
230
        width = swf->video_enc->width;
231
        height = swf->video_enc->height;
232
        rate = swf->video_enc->time_base.den;
233
        rate_base = swf->video_enc->time_base.num;
234
    }
235
 
236
    if (!swf->audio_enc)
237
        swf->samples_per_frame = (44100.0 * rate_base) / rate;
238
    else
239
        swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate;
240
 
241
    avio_write(pb, "FWS", 3);
242
 
243
    if (!strcmp("avm2", s->oformat->name))
244
        version = 9;
245
    else if (swf->video_enc && swf->video_enc->codec_id == AV_CODEC_ID_VP6F)
246
        version = 8; /* version 8 and above support VP6 codec */
247
    else if (swf->video_enc && swf->video_enc->codec_id == AV_CODEC_ID_FLV1)
248
        version = 6; /* version 6 and above support FLV1 codec */
249
    else
250
        version = 4; /* version 4 for mpeg audio support */
251
    avio_w8(pb, version);
252
 
253
    avio_wl32(pb, DUMMY_FILE_SIZE); /* dummy size
254
                                      (will be patched if not streamed) */
255
 
256
    put_swf_rect(pb, 0, width * 20, 0, height * 20);
257
    avio_wl16(pb, (rate * 256) / rate_base); /* frame rate */
258
    swf->duration_pos = avio_tell(pb);
259
    avio_wl16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
260
 
261
    /* avm2/swf v9 (also v8?) files require a file attribute tag */
262
    if (version == 9) {
263
        put_swf_tag(s, TAG_FILEATTRIBUTES);
264
        avio_wl32(pb, 1<<3); /* set ActionScript v3/AVM2 flag */
265
        put_swf_end_tag(s);
266
    }
267
 
268
    /* define a shape with the jpeg inside */
269
    if (swf->video_enc && swf->video_enc->codec_id == AV_CODEC_ID_MJPEG) {
270
        put_swf_tag(s, TAG_DEFINESHAPE);
271
 
272
        avio_wl16(pb, SHAPE_ID); /* ID of shape */
273
        /* bounding rectangle */
274
        put_swf_rect(pb, 0, width, 0, height);
275
        /* style info */
276
        avio_w8(pb, 1); /* one fill style */
277
        avio_w8(pb, 0x41); /* clipped bitmap fill */
278
        avio_wl16(pb, BITMAP_ID); /* bitmap ID */
279
        /* position of the bitmap */
280
        put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0,
281
                       0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0);
282
        avio_w8(pb, 0); /* no line style */
283
 
284
        /* shape drawing */
285
        init_put_bits(&p, buf1, sizeof(buf1));
286
        put_bits(&p, 4, 1); /* one fill bit */
287
        put_bits(&p, 4, 0); /* zero line bit */
288
 
289
        put_bits(&p, 1, 0); /* not an edge */
290
        put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0);
291
        put_bits(&p, 5, 1); /* nbits */
292
        put_bits(&p, 1, 0); /* X */
293
        put_bits(&p, 1, 0); /* Y */
294
        put_bits(&p, 1, 1); /* set fill style 1 */
295
 
296
        /* draw the rectangle ! */
297
        put_swf_line_edge(&p, width, 0);
298
        put_swf_line_edge(&p, 0, height);
299
        put_swf_line_edge(&p, -width, 0);
300
        put_swf_line_edge(&p, 0, -height);
301
 
302
        /* end of shape */
303
        put_bits(&p, 1, 0); /* not an edge */
304
        put_bits(&p, 5, 0);
305
 
306
        flush_put_bits(&p);
307
        avio_write(pb, buf1, put_bits_ptr(&p) - p.buf);
308
 
309
        put_swf_end_tag(s);
310
    }
311
 
312
    if (swf->audio_enc && swf->audio_enc->codec_id == AV_CODEC_ID_MP3) {
313
        int v = 0;
314
 
315
        /* start sound */
316
        put_swf_tag(s, TAG_STREAMHEAD2);
317
        switch(swf->audio_enc->sample_rate) {
318
        case 11025: v |= 1 << 2; break;
319
        case 22050: v |= 2 << 2; break;
320
        case 44100: v |= 3 << 2; break;
321
        default:
322
            /* not supported */
323
            av_log(s, AV_LOG_ERROR, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n");
324
            return -1;
325
        }
326
        v |= 0x02; /* 16 bit playback */
327
        if (swf->audio_enc->channels == 2)
328
            v |= 0x01; /* stereo playback */
329
        avio_w8(s->pb, v);
330
        v |= 0x20; /* mp3 compressed */
331
        avio_w8(s->pb, v);
332
        avio_wl16(s->pb, swf->samples_per_frame);  /* avg samples per frame */
333
        avio_wl16(s->pb, 0);
334
 
335
        put_swf_end_tag(s);
336
    }
337
 
338
    avio_flush(s->pb);
339
    return 0;
340
}
341
 
342
static int swf_write_video(AVFormatContext *s,
343
                           AVCodecContext *enc, const uint8_t *buf, int size)
344
{
345
    SWFContext *swf = s->priv_data;
346
    AVIOContext *pb = s->pb;
347
 
348
    /* Flash Player limit */
349
    if (swf->swf_frame_number == 16000)
350
        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
351
 
352
    if (enc->codec_id == AV_CODEC_ID_VP6F ||
353
        enc->codec_id == AV_CODEC_ID_FLV1) {
354
        if (swf->video_frame_number == 0) {
355
            /* create a new video object */
356
            put_swf_tag(s, TAG_VIDEOSTREAM);
357
            avio_wl16(pb, VIDEO_ID);
358
            swf->vframes_pos = avio_tell(pb);
359
            avio_wl16(pb, 15000); /* hard flash player limit */
360
            avio_wl16(pb, enc->width);
361
            avio_wl16(pb, enc->height);
362
            avio_w8(pb, 0);
363
            avio_w8(pb,ff_codec_get_tag(ff_swf_codec_tags, enc->codec_id));
364
            put_swf_end_tag(s);
365
 
366
            /* place the video object for the first time */
367
            put_swf_tag(s, TAG_PLACEOBJECT2);
368
            avio_w8(pb, 0x36);
369
            avio_wl16(pb, 1);
370
            avio_wl16(pb, VIDEO_ID);
371
            put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);
372
            avio_wl16(pb, swf->video_frame_number);
373
            avio_write(pb, "video", 5);
374
            avio_w8(pb, 0x00);
375
            put_swf_end_tag(s);
376
        } else {
377
            /* mark the character for update */
378
            put_swf_tag(s, TAG_PLACEOBJECT2);
379
            avio_w8(pb, 0x11);
380
            avio_wl16(pb, 1);
381
            avio_wl16(pb, swf->video_frame_number);
382
            put_swf_end_tag(s);
383
        }
384
 
385
        /* set video frame data */
386
        put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);
387
        avio_wl16(pb, VIDEO_ID);
388
        avio_wl16(pb, swf->video_frame_number++);
389
        avio_write(pb, buf, size);
390
        put_swf_end_tag(s);
391
    } else if (enc->codec_id == AV_CODEC_ID_MJPEG) {
392
        if (swf->swf_frame_number > 0) {
393
            /* remove the shape */
394
            put_swf_tag(s, TAG_REMOVEOBJECT);
395
            avio_wl16(pb, SHAPE_ID); /* shape ID */
396
            avio_wl16(pb, 1); /* depth */
397
            put_swf_end_tag(s);
398
 
399
            /* free the bitmap */
400
            put_swf_tag(s, TAG_FREECHARACTER);
401
            avio_wl16(pb, BITMAP_ID);
402
            put_swf_end_tag(s);
403
        }
404
 
405
        put_swf_tag(s, TAG_JPEG2 | TAG_LONG);
406
 
407
        avio_wl16(pb, BITMAP_ID); /* ID of the image */
408
 
409
        /* a dummy jpeg header seems to be required */
410
        avio_wb32(pb, 0xffd8ffd9);
411
        /* write the jpeg image */
412
        avio_write(pb, buf, size);
413
 
414
        put_swf_end_tag(s);
415
 
416
        /* draw the shape */
417
 
418
        put_swf_tag(s, TAG_PLACEOBJECT);
419
        avio_wl16(pb, SHAPE_ID); /* shape ID */
420
        avio_wl16(pb, 1); /* depth */
421
        put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);
422
        put_swf_end_tag(s);
423
    }
424
 
425
    swf->swf_frame_number++;
426
 
427
    /* streaming sound always should be placed just before showframe tags */
428
    if (swf->audio_enc && av_fifo_size(swf->audio_fifo)) {
429
        int frame_size = av_fifo_size(swf->audio_fifo);
430
        put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
431
        avio_wl16(pb, swf->sound_samples);
432
        avio_wl16(pb, 0); // seek samples
433
        av_fifo_generic_read(swf->audio_fifo, pb, frame_size, (void*)avio_write);
434
        put_swf_end_tag(s);
435
 
436
        /* update FIFO */
437
        swf->sound_samples = 0;
438
    }
439
 
440
    /* output the frame */
441
    put_swf_tag(s, TAG_SHOWFRAME);
442
    put_swf_end_tag(s);
443
 
444
    return 0;
445
}
446
 
447
static int swf_write_audio(AVFormatContext *s,
448
                           AVCodecContext *enc, uint8_t *buf, int size)
449
{
450
    SWFContext *swf = s->priv_data;
451
 
452
    /* Flash Player limit */
453
    if (swf->swf_frame_number == 16000)
454
        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
455
 
456
    if (av_fifo_size(swf->audio_fifo) + size > AUDIO_FIFO_SIZE) {
457
        av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n");
458
        return -1;
459
    }
460
 
461
    av_fifo_generic_write(swf->audio_fifo, buf, size, NULL);
462
    swf->sound_samples += enc->frame_size;
463
 
464
    /* if audio only stream make sure we add swf frames */
465
    if (!swf->video_enc)
466
        swf_write_video(s, enc, 0, 0);
467
 
468
    return 0;
469
}
470
 
471
static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
472
{
473
    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
474
    if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
475
        return swf_write_audio(s, codec, pkt->data, pkt->size);
476
    else
477
        return swf_write_video(s, codec, pkt->data, pkt->size);
478
}
479
 
480
static int swf_write_trailer(AVFormatContext *s)
481
{
482
    SWFContext *swf = s->priv_data;
483
    AVIOContext *pb = s->pb;
484
    AVCodecContext *enc, *video_enc;
485
    int file_size, i;
486
 
487
    video_enc = NULL;
488
    for(i=0;inb_streams;i++) {
489
        enc = s->streams[i]->codec;
490
        if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
491
            video_enc = enc;
492
        else {
493
            av_fifo_free(swf->audio_fifo);
494
            swf->audio_fifo = NULL;
495
        }
496
    }
497
 
498
    put_swf_tag(s, TAG_END);
499
    put_swf_end_tag(s);
500
 
501
    /* patch file size and number of frames if not streamed */
502
    if (s->pb->seekable && video_enc) {
503
        file_size = avio_tell(pb);
504
        avio_seek(pb, 4, SEEK_SET);
505
        avio_wl32(pb, file_size);
506
        avio_seek(pb, swf->duration_pos, SEEK_SET);
507
        avio_wl16(pb, swf->video_frame_number);
508
        if (swf->vframes_pos) {
509
        avio_seek(pb, swf->vframes_pos, SEEK_SET);
510
        avio_wl16(pb, swf->video_frame_number);
511
        }
512
        avio_seek(pb, file_size, SEEK_SET);
513
    }
514
    return 0;
515
}
516
 
517
#if CONFIG_SWF_MUXER
518
AVOutputFormat ff_swf_muxer = {
519
    .name              = "swf",
520
    .long_name         = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
521
    .mime_type         = "application/x-shockwave-flash",
522
    .extensions        = "swf",
523
    .priv_data_size    = sizeof(SWFContext),
524
    .audio_codec       = AV_CODEC_ID_MP3,
525
    .video_codec       = AV_CODEC_ID_FLV1,
526
    .write_header      = swf_write_header,
527
    .write_packet      = swf_write_packet,
528
    .write_trailer     = swf_write_trailer,
529
    .flags             = AVFMT_TS_NONSTRICT,
530
};
531
#endif
532
#if CONFIG_AVM2_MUXER
533
AVOutputFormat ff_avm2_muxer = {
534
    .name              = "avm2",
535
    .long_name         = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash) (AVM2)"),
536
    .mime_type         = "application/x-shockwave-flash",
537
    .priv_data_size    = sizeof(SWFContext),
538
    .audio_codec       = AV_CODEC_ID_MP3,
539
    .video_codec       = AV_CODEC_ID_FLV1,
540
    .write_header      = swf_write_header,
541
    .write_packet      = swf_write_packet,
542
    .write_trailer     = swf_write_trailer,
543
    .flags             = AVFMT_TS_NONSTRICT,
544
};
545
#endif