FFmpeg
 All Data Structures 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_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. * 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) {
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) {
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 */
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 */
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 
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 */
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);
364  put_swf_end_tag(s);
365 
366  /* place the video object for the first time */
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 */
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 */
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 */
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 */
401  avio_wl16(pb, BITMAP_ID);
402  put_swf_end_tag(s);
403  }
404 
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 
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);
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 */
442  put_swf_end_tag(s);
443 
444  avio_flush(s->pb);
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_free(swf->audio_fifo);
496  swf->audio_fifo = NULL;
497  }
498  }
499 
500  put_swf_tag(s, TAG_END);
501  put_swf_end_tag(s);
502 
503  /* patch file size and number of frames if not streamed */
504  if (s->pb->seekable && video_enc) {
505  file_size = avio_tell(pb);
506  avio_seek(pb, 4, SEEK_SET);
507  avio_wl32(pb, file_size);
508  avio_seek(pb, swf->duration_pos, SEEK_SET);
509  avio_wl16(pb, swf->video_frame_number);
510  if (swf->vframes_pos) {
511  avio_seek(pb, swf->vframes_pos, SEEK_SET);
512  avio_wl16(pb, swf->video_frame_number);
513  }
514  avio_seek(pb, file_size, SEEK_SET);
515  }
516  return 0;
517 }
518 
519 #if CONFIG_SWF_MUXER
520 AVOutputFormat ff_swf_muxer = {
521  .name = "swf",
522  .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
523  .mime_type = "application/x-shockwave-flash",
524  .extensions = "swf",
525  .priv_data_size = sizeof(SWFContext),
526  .audio_codec = AV_CODEC_ID_MP3,
527  .video_codec = AV_CODEC_ID_FLV1,
532 };
533 #endif
534 #if CONFIG_AVM2_MUXER
535 AVOutputFormat ff_avm2_muxer = {
536  .name = "avm2",
537  .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash) (AVM2)"),
538  .mime_type = "application/x-shockwave-flash",
539  .priv_data_size = sizeof(SWFContext),
540  .audio_codec = AV_CODEC_ID_MP3,
541  .video_codec = AV_CODEC_ID_FLV1,
546 };
547 #endif