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/bitstream.h"
27 static void put_swf_tag(AVFormatContext
*s
, int tag
)
29 SWFContext
*swf
= s
->priv_data
;
30 ByteIOContext
*pb
= s
->pb
;
32 swf
->tag_pos
= url_ftell(pb
);
34 /* reserve some room for the tag */
43 static void put_swf_end_tag(AVFormatContext
*s
)
45 SWFContext
*swf
= s
->priv_data
;
46 ByteIOContext
*pb
= s
->pb
;
51 tag_len
= pos
- swf
->tag_pos
- 2;
53 url_fseek(pb
, swf
->tag_pos
, SEEK_SET
);
56 put_le16(pb
, (tag
<< 6) | 0x3f);
57 put_le32(pb
, tag_len
- 4);
59 assert(tag_len
< 0x3f);
60 put_le16(pb
, (tag
<< 6) | tag_len
);
62 url_fseek(pb
, pos
, SEEK_SET
);
65 static inline void max_nbits(int *nbits_ptr
, int val
)
81 static void put_swf_rect(ByteIOContext
*pb
,
82 int xmin
, int xmax
, int ymin
, int ymax
)
88 init_put_bits(&p
, buf
, sizeof(buf
));
91 max_nbits(&nbits
, xmin
);
92 max_nbits(&nbits
, xmax
);
93 max_nbits(&nbits
, ymin
);
94 max_nbits(&nbits
, ymax
);
95 mask
= (1 << nbits
) - 1;
98 put_bits(&p
, 5, nbits
);
99 put_bits(&p
, nbits
, xmin
& mask
);
100 put_bits(&p
, nbits
, xmax
& mask
);
101 put_bits(&p
, nbits
, ymin
& mask
);
102 put_bits(&p
, nbits
, ymax
& mask
);
105 put_buffer(pb
, buf
, pbBufPtr(&p
) - p
.buf
);
108 static void put_swf_line_edge(PutBitContext
*pb
, int dx
, int dy
)
112 put_bits(pb
, 1, 1); /* edge */
113 put_bits(pb
, 1, 1); /* line select */
115 max_nbits(&nbits
, dx
);
116 max_nbits(&nbits
, dy
);
118 mask
= (1 << nbits
) - 1;
119 put_bits(pb
, 4, nbits
- 2); /* 16 bits precision */
123 put_bits(pb
, nbits
, dy
& mask
);
124 } else if (dy
== 0) {
127 put_bits(pb
, nbits
, dx
& mask
);
130 put_bits(pb
, nbits
, dx
& mask
);
131 put_bits(pb
, nbits
, dy
& mask
);
138 static void put_swf_matrix(ByteIOContext
*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 put_buffer(pb
, buf
, pbBufPtr(&p
) - p
.buf
);
175 static int swf_write_header(AVFormatContext
*s
)
177 SWFContext
*swf
= s
->priv_data
;
178 ByteIOContext
*pb
= s
->pb
;
179 AVCodecContext
*enc
, *audio_enc
, *video_enc
;
182 int i
, width
, height
, rate
, rate_base
;
185 swf
->audio_in_pos
= 0;
186 swf
->sound_samples
= 0;
187 swf
->swf_frame_number
= 0;
188 swf
->video_frame_number
= 0;
192 for(i
=0;i
<s
->nb_streams
;i
++) {
193 enc
= s
->streams
[i
]->codec
;
194 if (enc
->codec_type
== CODEC_TYPE_AUDIO
) {
195 if (enc
->codec_id
== CODEC_ID_MP3
) {
196 if (!enc
->frame_size
) {
197 av_log(s
, AV_LOG_ERROR
, "audio frame size not set\n");
202 av_log(s
, AV_LOG_ERROR
, "SWF muxer only supports MP3\n");
206 if (enc
->codec_id
== CODEC_ID_VP6F
||
207 enc
->codec_id
== CODEC_ID_FLV1
||
208 enc
->codec_id
== CODEC_ID_MJPEG
) {
211 av_log(s
, AV_LOG_ERROR
, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
218 /* currently, cannot work correctly if audio only */
225 swf
->video_type
= video_enc
->codec_id
;
226 width
= video_enc
->width
;
227 height
= video_enc
->height
;
228 rate
= video_enc
->time_base
.den
;
229 rate_base
= video_enc
->time_base
.num
;
234 swf
->samples_per_frame
= (44100. * rate_base
) / rate
;
236 swf
->audio_type
= audio_enc
->codec_id
;
237 swf
->samples_per_frame
= (audio_enc
->sample_rate
* rate_base
) / rate
;
240 is_avm2
= !strcmp("avm2", s
->oformat
->name
);
245 } else if (video_enc
&& video_enc
->codec_id
== CODEC_ID_VP6F
) {
246 put_byte(pb
, 8); /* version (version 8 and above support VP6 codec) */
247 } else if (video_enc
&& video_enc
->codec_id
== CODEC_ID_FLV1
) {
248 put_byte(pb
, 6); /* version (version 6 and above support FLV1 codec) */
250 put_byte(pb
, 4); /* version (should use 4 for mpeg audio support) */
252 put_le32(pb
, DUMMY_FILE_SIZE
); /* dummy size
253 (will be patched if not streamed) */
255 put_swf_rect(pb
, 0, width
* 20, 0, height
* 20);
256 put_le16(pb
, (rate
* 256) / rate_base
); /* frame rate */
257 swf
->duration_pos
= url_ftell(pb
);
258 put_le16(pb
, (uint16_t)(DUMMY_DURATION
* (int64_t)rate
/ rate_base
)); /* frame count */
260 /* avm2/swf v9 (also v8?) files require a file attribute tag */
262 put_swf_tag(s
, TAG_FILEATTRIBUTES
);
263 put_le32(pb
, 1<<3); /* set ActionScript v3/AVM2 flag */
267 /* define a shape with the jpeg inside */
268 if (video_enc
&& (video_enc
->codec_id
== CODEC_ID_VP6F
||
269 video_enc
->codec_id
== CODEC_ID_FLV1
)) {
270 } else if (video_enc
&& video_enc
->codec_id
== CODEC_ID_MJPEG
) {
271 put_swf_tag(s
, TAG_DEFINESHAPE
);
273 put_le16(pb
, SHAPE_ID
); /* ID of shape */
274 /* bounding rectangle */
275 put_swf_rect(pb
, 0, width
, 0, height
);
277 put_byte(pb
, 1); /* one fill style */
278 put_byte(pb
, 0x41); /* clipped bitmap fill */
279 put_le16(pb
, BITMAP_ID
); /* bitmap ID */
280 /* position of the bitmap */
281 put_swf_matrix(pb
, (int)(1.0 * (1 << FRAC_BITS
)), 0,
282 0, (int)(1.0 * (1 << FRAC_BITS
)), 0, 0);
283 put_byte(pb
, 0); /* no line style */
286 init_put_bits(&p
, buf1
, sizeof(buf1
));
287 put_bits(&p
, 4, 1); /* one fill bit */
288 put_bits(&p
, 4, 0); /* zero line bit */
290 put_bits(&p
, 1, 0); /* not an edge */
291 put_bits(&p
, 5, FLAG_MOVETO
| FLAG_SETFILL0
);
292 put_bits(&p
, 5, 1); /* nbits */
293 put_bits(&p
, 1, 0); /* X */
294 put_bits(&p
, 1, 0); /* Y */
295 put_bits(&p
, 1, 1); /* set fill style 1 */
297 /* draw the rectangle ! */
298 put_swf_line_edge(&p
, width
, 0);
299 put_swf_line_edge(&p
, 0, height
);
300 put_swf_line_edge(&p
, -width
, 0);
301 put_swf_line_edge(&p
, 0, -height
);
304 put_bits(&p
, 1, 0); /* not an edge */
308 put_buffer(pb
, buf1
, pbBufPtr(&p
) - p
.buf
);
313 if (audio_enc
&& audio_enc
->codec_id
== CODEC_ID_MP3
) {
317 put_swf_tag(s
, TAG_STREAMHEAD2
);
320 switch(audio_enc
->sample_rate
) {
332 av_log(s
, AV_LOG_ERROR
, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n");
335 v
|= 0x02; /* 16 bit playback */
336 if (audio_enc
->channels
== 2)
337 v
|= 0x01; /* stereo playback */
339 v
|= 0x20; /* mp3 compressed */
341 put_le16(s
->pb
, swf
->samples_per_frame
); /* avg samples per frame */
347 put_flush_packet(s
->pb
);
351 static int swf_write_video(AVFormatContext
*s
,
352 AVCodecContext
*enc
, const uint8_t *buf
, int size
)
354 SWFContext
*swf
= s
->priv_data
;
355 ByteIOContext
*pb
= s
->pb
;
357 /* Flash Player limit */
358 if (swf
->swf_frame_number
== 16000) {
359 av_log(enc
, AV_LOG_INFO
, "warning: Flash Player limit of 16000 frames reached\n");
362 if (swf
->video_type
== CODEC_ID_VP6F
||
363 swf
->video_type
== CODEC_ID_FLV1
) {
364 if (swf
->video_frame_number
== 0) {
365 /* create a new video object */
366 put_swf_tag(s
, TAG_VIDEOSTREAM
);
367 put_le16(pb
, VIDEO_ID
);
368 put_le16(pb
, 15000); /* hard flash player limit */
369 put_le16(pb
, enc
->width
);
370 put_le16(pb
, enc
->height
);
372 put_byte(pb
,codec_get_tag(swf_codec_tags
,swf
->video_type
));
375 /* place the video object for the first time */
376 put_swf_tag(s
, TAG_PLACEOBJECT2
);
379 put_le16(pb
, VIDEO_ID
);
380 put_swf_matrix(pb
, 1 << FRAC_BITS
, 0, 0, 1 << FRAC_BITS
, 0, 0);
381 put_le16(pb
, swf
->video_frame_number
);
390 /* mark the character for update */
391 put_swf_tag(s
, TAG_PLACEOBJECT2
);
394 put_le16(pb
, swf
->video_frame_number
);
398 /* set video frame data */
399 put_swf_tag(s
, TAG_VIDEOFRAME
| TAG_LONG
);
400 put_le16(pb
, VIDEO_ID
);
401 put_le16(pb
, swf
->video_frame_number
++);
402 put_buffer(pb
, buf
, size
);
404 } else if (swf
->video_type
== CODEC_ID_MJPEG
) {
405 if (swf
->swf_frame_number
> 0) {
406 /* remove the shape */
407 put_swf_tag(s
, TAG_REMOVEOBJECT
);
408 put_le16(pb
, SHAPE_ID
); /* shape ID */
409 put_le16(pb
, 1); /* depth */
412 /* free the bitmap */
413 put_swf_tag(s
, TAG_FREECHARACTER
);
414 put_le16(pb
, BITMAP_ID
);
418 put_swf_tag(s
, TAG_JPEG2
| TAG_LONG
);
420 put_le16(pb
, BITMAP_ID
); /* ID of the image */
422 /* a dummy jpeg header seems to be required */
427 /* write the jpeg image */
428 put_buffer(pb
, buf
, size
);
434 put_swf_tag(s
, TAG_PLACEOBJECT
);
435 put_le16(pb
, SHAPE_ID
); /* shape ID */
436 put_le16(pb
, 1); /* depth */
437 put_swf_matrix(pb
, 20 << FRAC_BITS
, 0, 0, 20 << FRAC_BITS
, 0, 0);
443 swf
->swf_frame_number
++;
445 /* streaming sound always should be placed just before showframe tags */
446 if (swf
->audio_type
&& swf
->audio_in_pos
) {
447 put_swf_tag(s
, TAG_STREAMBLOCK
| TAG_LONG
);
448 put_le16(pb
, swf
->sound_samples
);
449 put_le16(pb
, 0); // seek samples
450 put_buffer(pb
, swf
->audio_fifo
, swf
->audio_in_pos
);
454 swf
->sound_samples
= 0;
455 swf
->audio_in_pos
= 0;
458 /* output the frame */
459 put_swf_tag(s
, TAG_SHOWFRAME
);
462 put_flush_packet(s
->pb
);
467 static int swf_write_audio(AVFormatContext
*s
,
468 AVCodecContext
*enc
, const uint8_t *buf
, int size
)
470 SWFContext
*swf
= s
->priv_data
;
472 /* Flash Player limit */
473 if (swf
->swf_frame_number
== 16000) {
474 av_log(enc
, AV_LOG_INFO
, "warning: Flash Player limit of 16000 frames reached\n");
477 if (swf
->audio_in_pos
+ size
>= AUDIO_FIFO_SIZE
) {
478 av_log(s
, AV_LOG_ERROR
, "audio fifo too small to mux audio essence\n");
482 memcpy(swf
->audio_fifo
+ swf
->audio_in_pos
, buf
, size
);
483 swf
->audio_in_pos
+= size
;
484 swf
->sound_samples
+= enc
->frame_size
;
486 /* if audio only stream make sure we add swf frames */
487 if (swf
->video_type
== 0) {
488 swf_write_video(s
, enc
, 0, 0);
494 static int swf_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
496 AVCodecContext
*codec
= s
->streams
[pkt
->stream_index
]->codec
;
497 if (codec
->codec_type
== CODEC_TYPE_AUDIO
)
498 return swf_write_audio(s
, codec
, pkt
->data
, pkt
->size
);
500 return swf_write_video(s
, codec
, pkt
->data
, pkt
->size
);
503 static int swf_write_trailer(AVFormatContext
*s
)
505 SWFContext
*swf
= s
->priv_data
;
506 ByteIOContext
*pb
= s
->pb
;
507 AVCodecContext
*enc
, *video_enc
;
511 for(i
=0;i
<s
->nb_streams
;i
++) {
512 enc
= s
->streams
[i
]->codec
;
513 if (enc
->codec_type
== CODEC_TYPE_VIDEO
)
517 put_swf_tag(s
, TAG_END
);
520 put_flush_packet(s
->pb
);
522 /* patch file size and number of frames if not streamed */
523 if (!url_is_streamed(s
->pb
) && video_enc
) {
524 file_size
= url_ftell(pb
);
525 url_fseek(pb
, 4, SEEK_SET
);
526 put_le32(pb
, file_size
);
527 url_fseek(pb
, swf
->duration_pos
, SEEK_SET
);
528 put_le16(pb
, video_enc
->frame_number
);
529 url_fseek(pb
, file_size
, SEEK_SET
);
534 #ifdef CONFIG_SWF_MUXER
535 AVOutputFormat swf_muxer
= {
538 "application/x-shockwave-flash",
548 #ifdef CONFIG_AVM2_MUXER
549 AVOutputFormat avm2_muxer
= {
551 "Flash 9 (AVM2) format",
552 "application/x-shockwave-flash",