2 * Flash Compatible Streaming Format muxer
3 * Copyright (c) 2000 Fabrice Bellard
4 * Copyright (c) 2003 Tinic Uro
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavcodec/put_bits.h"
24 #include "libavutil/avassert.h"
28 static void put_swf_tag(AVFormatContext
*s
, int tag
)
30 SWFContext
*swf
= s
->priv_data
;
31 AVIOContext
*pb
= s
->pb
;
33 swf
->tag_pos
= avio_tell(pb
);
35 /* reserve some room for the tag */
44 static void put_swf_end_tag(AVFormatContext
*s
)
46 SWFContext
*swf
= s
->priv_data
;
47 AVIOContext
*pb
= s
->pb
;
52 tag_len
= pos
- swf
->tag_pos
- 2;
54 avio_seek(pb
, swf
->tag_pos
, SEEK_SET
);
57 avio_wl16(pb
, (tag
<< 6) | 0x3f);
58 avio_wl32(pb
, tag_len
- 4);
60 av_assert0(tag_len
< 0x3f);
61 avio_wl16(pb
, (tag
<< 6) | tag_len
);
63 avio_seek(pb
, pos
, SEEK_SET
);
66 static inline void max_nbits(int *nbits_ptr
, int val
)
82 static void put_swf_rect(AVIOContext
*pb
,
83 int xmin
, int xmax
, int ymin
, int ymax
)
89 init_put_bits(&p
, buf
, sizeof(buf
));
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;
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
);
106 avio_write(pb
, buf
, put_bits_ptr(&p
) - p
.buf
);
109 static void put_swf_line_edge(PutBitContext
*pb
, int dx
, int dy
)
113 put_bits(pb
, 1, 1); /* edge */
114 put_bits(pb
, 1, 1); /* line select */
116 max_nbits(&nbits
, dx
);
117 max_nbits(&nbits
, dy
);
119 mask
= (1 << nbits
) - 1;
120 put_bits(pb
, 4, nbits
- 2); /* 16 bits precision */
124 put_bits(pb
, nbits
, dy
& mask
);
125 } else if (dy
== 0) {
128 put_bits(pb
, nbits
, dx
& mask
);
131 put_bits(pb
, nbits
, dx
& mask
);
132 put_bits(pb
, nbits
, dy
& mask
);
138 static void put_swf_matrix(AVIOContext
*pb
,
139 int a
, int b
, int c
, int d
, int tx
, int ty
)
145 init_put_bits(&p
, buf
, sizeof(buf
));
147 put_bits(&p
, 1, 1); /* a, d present */
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
);
155 put_bits(&p
, 1, 1); /* b, c present */
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
);
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
);
171 avio_write(pb
, buf
, put_bits_ptr(&p
) - p
.buf
);
174 static int swf_write_header(AVFormatContext
*s
)
176 SWFContext
*swf
= s
->priv_data
;
177 AVIOContext
*pb
= s
->pb
;
180 int i
, width
, height
, rate
, rate_base
;
183 swf
->sound_samples
= 0;
184 swf
->swf_frame_number
= 0;
185 swf
->video_frame_number
= 0;
187 for(i
=0;i
<s
->nb_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
;
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");
199 swf
->audio_enc
= enc
;
200 swf
->audio_fifo
= av_fifo_alloc(AUDIO_FIFO_SIZE
);
201 if (!swf
->audio_fifo
)
202 return AVERROR(ENOMEM
);
204 av_log(s
, AV_LOG_ERROR
, "SWF muxer only supports MP3\n");
208 if (swf
->video_enc
) {
209 av_log(s
, AV_LOG_ERROR
, "SWF muxer only supports 1 video stream\n");
210 return AVERROR_INVALIDDATA
;
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_st
= s
->streams
[i
];
216 swf
->video_enc
= enc
;
218 av_log(s
, AV_LOG_ERROR
, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
224 if (!swf
->video_enc
) {
225 /* currently, cannot work correctly if audio only */
231 width
= swf
->video_enc
->width
;
232 height
= swf
->video_enc
->height
;
233 // TODO: should be avg_frame_rate
234 rate
= swf
->video_st
->time_base
.den
;
235 rate_base
= swf
->video_st
->time_base
.num
;
239 swf
->samples_per_frame
= (44100.0 * rate_base
) / rate
;
241 swf
->samples_per_frame
= (swf
->audio_enc
->sample_rate
* rate_base
) / rate
;
243 avio_write(pb
, "FWS", 3);
245 if (!strcmp("avm2", s
->oformat
->name
))
247 else if (swf
->video_enc
&& swf
->video_enc
->codec_id
== AV_CODEC_ID_VP6F
)
248 version
= 8; /* version 8 and above support VP6 codec */
249 else if (swf
->video_enc
&& swf
->video_enc
->codec_id
== AV_CODEC_ID_FLV1
)
250 version
= 6; /* version 6 and above support FLV1 codec */
252 version
= 4; /* version 4 for mpeg audio support */
253 avio_w8(pb
, version
);
255 avio_wl32(pb
, DUMMY_FILE_SIZE
); /* dummy size
256 (will be patched if not streamed) */
258 put_swf_rect(pb
, 0, width
* 20, 0, height
* 20);
259 avio_wl16(pb
, (rate
* 256) / rate_base
); /* frame rate */
260 swf
->duration_pos
= avio_tell(pb
);
261 avio_wl16(pb
, (uint16_t)(DUMMY_DURATION
* (int64_t)rate
/ rate_base
)); /* frame count */
263 /* avm2/swf v9 (also v8?) files require a file attribute tag */
265 put_swf_tag(s
, TAG_FILEATTRIBUTES
);
266 avio_wl32(pb
, 1<<3); /* set ActionScript v3/AVM2 flag */
270 /* define a shape with the jpeg inside */
271 if (swf
->video_enc
&& swf
->video_enc
->codec_id
== AV_CODEC_ID_MJPEG
) {
272 put_swf_tag(s
, TAG_DEFINESHAPE
);
274 avio_wl16(pb
, SHAPE_ID
); /* ID of shape */
275 /* bounding rectangle */
276 put_swf_rect(pb
, 0, width
, 0, height
);
278 avio_w8(pb
, 1); /* one fill style */
279 avio_w8(pb
, 0x41); /* clipped bitmap fill */
280 avio_wl16(pb
, BITMAP_ID
); /* bitmap ID */
281 /* position of the bitmap */
282 put_swf_matrix(pb
, (int)(1.0 * (1 << FRAC_BITS
)), 0,
283 0, (int)(1.0 * (1 << FRAC_BITS
)), 0, 0);
284 avio_w8(pb
, 0); /* no line style */
287 init_put_bits(&p
, buf1
, sizeof(buf1
));
288 put_bits(&p
, 4, 1); /* one fill bit */
289 put_bits(&p
, 4, 0); /* zero line bit */
291 put_bits(&p
, 1, 0); /* not an edge */
292 put_bits(&p
, 5, FLAG_MOVETO
| FLAG_SETFILL0
);
293 put_bits(&p
, 5, 1); /* nbits */
294 put_bits(&p
, 1, 0); /* X */
295 put_bits(&p
, 1, 0); /* Y */
296 put_bits(&p
, 1, 1); /* set fill style 1 */
298 /* draw the rectangle ! */
299 put_swf_line_edge(&p
, width
, 0);
300 put_swf_line_edge(&p
, 0, height
);
301 put_swf_line_edge(&p
, -width
, 0);
302 put_swf_line_edge(&p
, 0, -height
);
305 put_bits(&p
, 1, 0); /* not an edge */
309 avio_write(pb
, buf1
, put_bits_ptr(&p
) - p
.buf
);
314 if (swf
->audio_enc
&& swf
->audio_enc
->codec_id
== AV_CODEC_ID_MP3
) {
318 put_swf_tag(s
, TAG_STREAMHEAD2
);
319 switch(swf
->audio_enc
->sample_rate
) {
320 case 11025: v
|= 1 << 2; break;
321 case 22050: v
|= 2 << 2; break;
322 case 44100: v
|= 3 << 2; break;
325 av_log(s
, AV_LOG_ERROR
, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n");
328 v
|= 0x02; /* 16 bit playback */
329 if (swf
->audio_enc
->channels
== 2)
330 v
|= 0x01; /* stereo playback */
332 v
|= 0x20; /* mp3 compressed */
334 avio_wl16(s
->pb
, swf
->samples_per_frame
); /* avg samples per frame */
344 static int swf_write_video(AVFormatContext
*s
,
345 AVCodecContext
*enc
, const uint8_t *buf
, int size
)
347 SWFContext
*swf
= s
->priv_data
;
348 AVIOContext
*pb
= s
->pb
;
350 /* Flash Player limit */
351 if (swf
->swf_frame_number
== 16000)
352 av_log(enc
, AV_LOG_INFO
, "warning: Flash Player limit of 16000 frames reached\n");
354 if (enc
->codec_id
== AV_CODEC_ID_VP6F
||
355 enc
->codec_id
== AV_CODEC_ID_FLV1
) {
356 if (swf
->video_frame_number
== 0) {
357 /* create a new video object */
358 put_swf_tag(s
, TAG_VIDEOSTREAM
);
359 avio_wl16(pb
, VIDEO_ID
);
360 swf
->vframes_pos
= avio_tell(pb
);
361 avio_wl16(pb
, 15000); /* hard flash player limit */
362 avio_wl16(pb
, enc
->width
);
363 avio_wl16(pb
, enc
->height
);
365 avio_w8(pb
,ff_codec_get_tag(ff_swf_codec_tags
, enc
->codec_id
));
368 /* place the video object for the first time */
369 put_swf_tag(s
, TAG_PLACEOBJECT2
);
372 avio_wl16(pb
, VIDEO_ID
);
373 put_swf_matrix(pb
, 1 << FRAC_BITS
, 0, 0, 1 << FRAC_BITS
, 0, 0);
374 avio_wl16(pb
, swf
->video_frame_number
);
375 avio_write(pb
, "video", 5);
379 /* mark the character for update */
380 put_swf_tag(s
, TAG_PLACEOBJECT2
);
383 avio_wl16(pb
, swf
->video_frame_number
);
387 /* set video frame data */
388 put_swf_tag(s
, TAG_VIDEOFRAME
| TAG_LONG
);
389 avio_wl16(pb
, VIDEO_ID
);
390 avio_wl16(pb
, swf
->video_frame_number
++);
391 avio_write(pb
, buf
, size
);
393 } else if (enc
->codec_id
== AV_CODEC_ID_MJPEG
) {
394 if (swf
->swf_frame_number
> 0) {
395 /* remove the shape */
396 put_swf_tag(s
, TAG_REMOVEOBJECT
);
397 avio_wl16(pb
, SHAPE_ID
); /* shape ID */
398 avio_wl16(pb
, 1); /* depth */
401 /* free the bitmap */
402 put_swf_tag(s
, TAG_FREECHARACTER
);
403 avio_wl16(pb
, BITMAP_ID
);
407 put_swf_tag(s
, TAG_JPEG2
| TAG_LONG
);
409 avio_wl16(pb
, BITMAP_ID
); /* ID of the image */
411 /* a dummy jpeg header seems to be required */
412 avio_wb32(pb
, 0xffd8ffd9);
413 /* write the jpeg image */
414 avio_write(pb
, buf
, size
);
420 put_swf_tag(s
, TAG_PLACEOBJECT
);
421 avio_wl16(pb
, SHAPE_ID
); /* shape ID */
422 avio_wl16(pb
, 1); /* depth */
423 put_swf_matrix(pb
, 20 << FRAC_BITS
, 0, 0, 20 << FRAC_BITS
, 0, 0);
427 swf
->swf_frame_number
++;
429 /* streaming sound always should be placed just before showframe tags */
430 if (swf
->audio_enc
&& av_fifo_size(swf
->audio_fifo
)) {
431 int frame_size
= av_fifo_size(swf
->audio_fifo
);
432 put_swf_tag(s
, TAG_STREAMBLOCK
| TAG_LONG
);
433 avio_wl16(pb
, swf
->sound_samples
);
434 avio_wl16(pb
, 0); // seek samples
435 av_fifo_generic_read(swf
->audio_fifo
, pb
, frame_size
, (void*)avio_write
);
439 swf
->sound_samples
= 0;
442 /* output the frame */
443 put_swf_tag(s
, TAG_SHOWFRAME
);
449 static int swf_write_audio(AVFormatContext
*s
,
450 AVCodecContext
*enc
, uint8_t *buf
, int size
)
452 SWFContext
*swf
= s
->priv_data
;
454 /* Flash Player limit */
455 if (swf
->swf_frame_number
== 16000)
456 av_log(enc
, AV_LOG_INFO
, "warning: Flash Player limit of 16000 frames reached\n");
458 if (av_fifo_size(swf
->audio_fifo
) + size
> AUDIO_FIFO_SIZE
) {
459 av_log(s
, AV_LOG_ERROR
, "audio fifo too small to mux audio essence\n");
463 av_fifo_generic_write(swf
->audio_fifo
, buf
, size
, NULL
);
464 swf
->sound_samples
+= enc
->frame_size
;
466 /* if audio only stream make sure we add swf frames */
468 swf_write_video(s
, enc
, 0, 0);
473 static int swf_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
475 AVCodecContext
*codec
= s
->streams
[pkt
->stream_index
]->codec
;
476 if (codec
->codec_type
== AVMEDIA_TYPE_AUDIO
)
477 return swf_write_audio(s
, codec
, pkt
->data
, pkt
->size
);
479 return swf_write_video(s
, codec
, pkt
->data
, pkt
->size
);
482 static int swf_write_trailer(AVFormatContext
*s
)
484 SWFContext
*swf
= s
->priv_data
;
485 AVIOContext
*pb
= s
->pb
;
486 AVCodecContext
*enc
, *video_enc
;
490 for(i
=0;i
<s
->nb_streams
;i
++) {
491 enc
= s
->streams
[i
]->codec
;
492 if (enc
->codec_type
== AVMEDIA_TYPE_VIDEO
)
495 av_fifo_freep(&swf
->audio_fifo
);
499 put_swf_tag(s
, TAG_END
);
502 /* patch file size and number of frames if not streamed */
503 if (s
->pb
->seekable
&& video_enc
) {
504 file_size
= avio_tell(pb
);
505 avio_seek(pb
, 4, SEEK_SET
);
506 avio_wl32(pb
, file_size
);
507 avio_seek(pb
, swf
->duration_pos
, SEEK_SET
);
508 avio_wl16(pb
, swf
->video_frame_number
);
509 if (swf
->vframes_pos
) {
510 avio_seek(pb
, swf
->vframes_pos
, SEEK_SET
);
511 avio_wl16(pb
, swf
->video_frame_number
);
513 avio_seek(pb
, file_size
, SEEK_SET
);
519 AVOutputFormat ff_swf_muxer
= {
521 .long_name
= NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
522 .mime_type
= "application/x-shockwave-flash",
524 .priv_data_size
= sizeof(SWFContext
),
525 .audio_codec
= AV_CODEC_ID_MP3
,
526 .video_codec
= AV_CODEC_ID_FLV1
,
527 .write_header
= swf_write_header
,
528 .write_packet
= swf_write_packet
,
529 .write_trailer
= swf_write_trailer
,
530 .flags
= AVFMT_TS_NONSTRICT
,
533 #if CONFIG_AVM2_MUXER
534 AVOutputFormat ff_avm2_muxer
= {
536 .long_name
= NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash) (AVM2)"),
537 .mime_type
= "application/x-shockwave-flash",
538 .priv_data_size
= sizeof(SWFContext
),
539 .audio_codec
= AV_CODEC_ID_MP3
,
540 .video_codec
= AV_CODEC_ID_FLV1
,
541 .write_header
= swf_write_header
,
542 .write_packet
= swf_write_packet
,
543 .write_trailer
= swf_write_trailer
,
544 .flags
= AVFMT_TS_NONSTRICT
,