FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
swfenc.c
Go to the documentation of this file.
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 
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 
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;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;
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;
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_st = s->streams[i];
216  swf->video_enc = enc;
217  } else {
218  av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
219  return -1;
220  }
221  }
222  }
223 
224  if (!swf->video_enc) {
225  /* currently, cannot work correctly if audio only */
226  width = 320;
227  height = 200;
228  rate = 10;
229  rate_base= 1;
230  } else {
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;
236  }
237 
238  if (!swf->audio_enc)
239  swf->samples_per_frame = (44100.0 * rate_base) / rate;
240  else
241  swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate;
242 
243  avio_write(pb, "FWS", 3);
244 
245  if (!strcmp("avm2", s->oformat->name))
246  version = 9;
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 */
251  else
252  version = 4; /* version 4 for mpeg audio support */
253  avio_w8(pb, version);
254 
255  avio_wl32(pb, DUMMY_FILE_SIZE); /* dummy size
256  (will be patched if not streamed) */
257 
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 */
262 
263  /* avm2/swf v9 (also v8?) files require a file attribute tag */
264  if (version == 9) {
266  avio_wl32(pb, 1<<3); /* set ActionScript v3/AVM2 flag */
267  put_swf_end_tag(s);
268  }
269 
270  /* define a shape with the jpeg inside */
271  if (swf->video_enc && swf->video_enc->codec_id == AV_CODEC_ID_MJPEG) {
273 
274  avio_wl16(pb, SHAPE_ID); /* ID of shape */
275  /* bounding rectangle */
276  put_swf_rect(pb, 0, width, 0, height);
277  /* style info */
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 */
285 
286  /* shape drawing */
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 */
290 
291  put_bits(&p, 1, 0); /* not an edge */
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 */
297 
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);
303 
304  /* end of shape */
305  put_bits(&p, 1, 0); /* not an edge */
306  put_bits(&p, 5, 0);
307 
308  flush_put_bits(&p);
309  avio_write(pb, buf1, put_bits_ptr(&p) - p.buf);
310 
311  put_swf_end_tag(s);
312  }
313 
314  if (swf->audio_enc && swf->audio_enc->codec_id == AV_CODEC_ID_MP3) {
315  int v = 0;
316 
317  /* start sound */
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;
323  default:
324  /* not supported */
325  av_log(s, AV_LOG_ERROR, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n");
326  return -1;
327  }
328  v |= 0x02; /* 16 bit playback */
329  if (swf->audio_enc->channels == 2)
330  v |= 0x01; /* stereo playback */
331  avio_w8(s->pb, v);
332  v |= 0x20; /* mp3 compressed */
333  avio_w8(s->pb, v);
334  avio_wl16(s->pb, swf->samples_per_frame); /* avg samples per frame */
335  avio_wl16(s->pb, 0);
336 
337  put_swf_end_tag(s);
338  }
339 
340  avio_flush(s->pb);
341  return 0;
342 }
343 
345  AVCodecContext *enc, const uint8_t *buf, int size)
346 {
347  SWFContext *swf = s->priv_data;
348  AVIOContext *pb = s->pb;
349 
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");
353 
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 */
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);
364  avio_w8(pb, 0);
366  put_swf_end_tag(s);
367 
368  /* place the video object for the first time */
370  avio_w8(pb, 0x36);
371  avio_wl16(pb, 1);
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);
376  avio_w8(pb, 0x00);
377  put_swf_end_tag(s);
378  } else {
379  /* mark the character for update */
381  avio_w8(pb, 0x11);
382  avio_wl16(pb, 1);
383  avio_wl16(pb, swf->video_frame_number);
384  put_swf_end_tag(s);
385  }
386 
387  /* set video frame data */
389  avio_wl16(pb, VIDEO_ID);
390  avio_wl16(pb, swf->video_frame_number++);
391  avio_write(pb, buf, size);
392  put_swf_end_tag(s);
393  } else if (enc->codec_id == AV_CODEC_ID_MJPEG) {
394  if (swf->swf_frame_number > 0) {
395  /* remove the shape */
397  avio_wl16(pb, SHAPE_ID); /* shape ID */
398  avio_wl16(pb, 1); /* depth */
399  put_swf_end_tag(s);
400 
401  /* free the bitmap */
403  avio_wl16(pb, BITMAP_ID);
404  put_swf_end_tag(s);
405  }
406 
408 
409  avio_wl16(pb, BITMAP_ID); /* ID of the image */
410 
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);
415 
416  put_swf_end_tag(s);
417 
418  /* draw the shape */
419 
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);
424  put_swf_end_tag(s);
425  }
426 
427  swf->swf_frame_number++;
428 
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);
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);
436  put_swf_end_tag(s);
437 
438  /* update FIFO */
439  swf->sound_samples = 0;
440  }
441 
442  /* output the frame */
444  put_swf_end_tag(s);
445 
446  return 0;
447 }
448 
450  AVCodecContext *enc, uint8_t *buf, int size)
451 {
452  SWFContext *swf = s->priv_data;
453 
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");
457 
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");
460  return -1;
461  }
462 
463  av_fifo_generic_write(swf->audio_fifo, buf, size, NULL);
464  swf->sound_samples += enc->frame_size;
465 
466  /* if audio only stream make sure we add swf frames */
467  if (!swf->video_enc)
468  swf_write_video(s, enc, 0, 0);
469 
470  return 0;
471 }
472 
474 {
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);
478  else
479  return swf_write_video(s, codec, pkt->data, pkt->size);
480 }
481 
483 {
484  SWFContext *swf = s->priv_data;
485  AVIOContext *pb = s->pb;
486  AVCodecContext *enc, *video_enc;
487  int file_size, i;
488 
489  video_enc = NULL;
490  for(i=0;i<s->nb_streams;i++) {
491  enc = s->streams[i]->codec;
492  if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
493  video_enc = enc;
494  else {
495  av_fifo_freep(&swf->audio_fifo);
496  }
497  }
498 
499  put_swf_tag(s, TAG_END);
500  put_swf_end_tag(s);
501 
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);
512  }
513  avio_seek(pb, file_size, SEEK_SET);
514  }
515  return 0;
516 }
517 
518 #if CONFIG_SWF_MUXER
519 AVOutputFormat ff_swf_muxer = {
520  .name = "swf",
521  .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
522  .mime_type = "application/x-shockwave-flash",
523  .extensions = "swf",
524  .priv_data_size = sizeof(SWFContext),
525  .audio_codec = AV_CODEC_ID_MP3,
526  .video_codec = AV_CODEC_ID_FLV1,
531 };
532 #endif
533 #if CONFIG_AVM2_MUXER
534 AVOutputFormat ff_avm2_muxer = {
535  .name = "avm2",
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,
545 };
546 #endif