FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
swfdec.c
Go to the documentation of this file.
1 /*
2  * Flash Compatible Streaming Format demuxer
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 "libavutil/avassert.h"
25 #include "libavutil/imgutils.h"
26 #include "libavutil/intreadwrite.h"
27 #include "swf.h"
28 
29 static const AVCodecTag swf_audio_codec_tags[] = {
30  { AV_CODEC_ID_PCM_S16LE, 0x00 },
31  { AV_CODEC_ID_ADPCM_SWF, 0x01 },
32  { AV_CODEC_ID_MP3, 0x02 },
33  { AV_CODEC_ID_PCM_S16LE, 0x03 },
34 // { AV_CODEC_ID_NELLYMOSER, 0x06 },
35  { AV_CODEC_ID_NONE, 0 },
36 };
37 
38 static int get_swf_tag(AVIOContext *pb, int *len_ptr)
39 {
40  int tag, len;
41 
42  if (url_feof(pb))
43  return AVERROR_EOF;
44 
45  tag = avio_rl16(pb);
46  len = tag & 0x3f;
47  tag = tag >> 6;
48  if (len == 0x3f) {
49  len = avio_rl32(pb);
50  }
51  *len_ptr = len;
52  return tag;
53 }
54 
55 
56 static int swf_probe(AVProbeData *p)
57 {
58  /* check file header */
59  if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&
60  p->buf[2] == 'S')
61  return AVPROBE_SCORE_MAX;
62  else
63  return 0;
64 }
65 
66 #if CONFIG_ZLIB
67 static int zlib_refill(void *opaque, uint8_t *buf, int buf_size)
68 {
69  AVFormatContext *s = opaque;
70  SWFContext *swf = s->priv_data;
71  z_stream *z = &swf->zstream;
72  int ret;
73 
74 retry:
75  if (!z->avail_in) {
76  int n = avio_read(s->pb, swf->zbuf_in, ZBUF_SIZE);
77  if (n < 0)
78  return n;
79  z->next_in = swf->zbuf_in;
80  z->avail_in = n;
81  }
82 
83  z->next_out = buf;
84  z->avail_out = buf_size;
85 
86  ret = inflate(z, Z_NO_FLUSH);
87  if (ret < 0)
88  return AVERROR(EINVAL);
89  if (ret == Z_STREAM_END)
90  return AVERROR_EOF;
91 
92  if (buf_size - z->avail_out == 0)
93  goto retry;
94 
95  return buf_size - z->avail_out;
96 }
97 #endif
98 
100 {
101  SWFContext *swf = s->priv_data;
102  AVIOContext *pb = s->pb;
103  int nbits, len, tag;
104 
105  tag = avio_rb32(pb) & 0xffffff00;
106  avio_rl32(pb);
107 
108  if (tag == MKBETAG('C', 'W', 'S', 0)) {
109  av_log(s, AV_LOG_INFO, "SWF compressed file detected\n");
110 #if CONFIG_ZLIB
111  swf->zbuf_in = av_malloc(ZBUF_SIZE);
112  swf->zbuf_out = av_malloc(ZBUF_SIZE);
113  swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, s,
114  zlib_refill, NULL, NULL);
115  if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb)
116  return AVERROR(ENOMEM);
117  swf->zpb->seekable = 0;
118  if (inflateInit(&swf->zstream) != Z_OK) {
119  av_log(s, AV_LOG_ERROR, "Unable to init zlib context\n");
120  return AVERROR(EINVAL);
121  }
122  pb = swf->zpb;
123 #else
124  av_log(s, AV_LOG_ERROR, "zlib support is required to read SWF compressed files\n");
125  return AVERROR(EIO);
126 #endif
127  } else if (tag != MKBETAG('F', 'W', 'S', 0))
128  return AVERROR(EIO);
129  /* skip rectangle size */
130  nbits = avio_r8(pb) >> 3;
131  len = (4 * nbits - 3 + 7) / 8;
132  avio_skip(pb, len);
133  swf->frame_rate = avio_rl16(pb); /* 8.8 fixed */
134  avio_rl16(pb); /* frame count */
135 
136  swf->samples_per_frame = 0;
138  return 0;
139 }
140 
142 {
143  SWFContext *swf = s->priv_data;
144  AVIOContext *pb = s->pb;
145  AVStream *vst = NULL, *ast = NULL, *st = 0;
146  int tag, len, i, frame, v, res;
147 
148 #if CONFIG_ZLIB
149  if (swf->zpb)
150  pb = swf->zpb;
151 #endif
152 
153  for(;;) {
154  uint64_t pos = avio_tell(pb);
155  tag = get_swf_tag(pb, &len);
156  if (tag < 0)
157  return tag;
158  if (len < 0) {
159  av_log(s, AV_LOG_ERROR, "invalid tag length: %d\n", len);
160  return AVERROR_INVALIDDATA;
161  }
162  if (tag == TAG_VIDEOSTREAM) {
163  int ch_id = avio_rl16(pb);
164  len -= 2;
165 
166  for (i=0; i<s->nb_streams; i++) {
167  st = s->streams[i];
168  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id)
169  goto skip;
170  }
171 
172  avio_rl16(pb);
173  avio_rl16(pb);
174  avio_rl16(pb);
175  avio_r8(pb);
176  /* Check for FLV1 */
177  vst = avformat_new_stream(s, NULL);
178  if (!vst)
179  return AVERROR(ENOMEM);
180  vst->id = ch_id;
183  avpriv_set_pts_info(vst, 16, 256, swf->frame_rate);
184  len -= 8;
185  } else if (tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) {
186  /* streaming found */
187  int sample_rate_code;
188 
189  for (i=0; i<s->nb_streams; i++) {
190  st = s->streams[i];
191  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1)
192  goto skip;
193  }
194 
195  avio_r8(pb);
196  v = avio_r8(pb);
197  swf->samples_per_frame = avio_rl16(pb);
198  ast = avformat_new_stream(s, NULL);
199  if (!ast)
200  return AVERROR(ENOMEM);
201  ast->id = -1; /* -1 to avoid clash with video stream ch_id */
202  if (v & 1) {
203  ast->codec->channels = 2;
204  ast->codec->channel_layout = AV_CH_LAYOUT_STEREO;
205  } else {
206  ast->codec->channels = 1;
207  ast->codec->channel_layout = AV_CH_LAYOUT_MONO;
208  }
209  ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
210  ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
211  ast->need_parsing = AVSTREAM_PARSE_FULL;
212  sample_rate_code= (v>>2) & 3;
213  ast->codec->sample_rate = 44100 >> (3 - sample_rate_code);
214  avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
215  len -= 4;
216  } else if (tag == TAG_DEFINESOUND) {
217  /* audio stream */
218  int sample_rate_code;
219  int ch_id = avio_rl16(pb);
220 
221  for (i=0; i<s->nb_streams; i++) {
222  st = s->streams[i];
223  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == ch_id)
224  goto skip;
225  }
226 
227  // FIXME: 8-bit uncompressed PCM audio will be interpreted as 16-bit
228  // FIXME: The entire audio stream is stored in a single chunk/tag. Normally,
229  // these are smaller audio streams in DEFINESOUND tags, but it's technically
230  // possible they could be huge. Break it up into multiple packets if it's big.
231  v = avio_r8(pb);
232  ast = avformat_new_stream(s, NULL);
233  if (!ast)
234  return AVERROR(ENOMEM);
235  ast->id = ch_id;
236  ast->codec->channels = 1 + (v&1);
237  ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
238  ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
239  ast->need_parsing = AVSTREAM_PARSE_FULL;
240  sample_rate_code= (v>>2) & 3;
241  ast->codec->sample_rate = 44100 >> (3 - sample_rate_code);
242  avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
243  ast->duration = avio_rl32(pb); // number of samples
244  if (((v>>4) & 15) == 2) { // MP3 sound data record
245  ast->skip_samples = avio_rl16(pb);
246  len -= 2;
247  }
248  len -= 7;
249  if ((res = av_get_packet(pb, pkt, len)) < 0)
250  return res;
251  pkt->pos = pos;
252  pkt->stream_index = ast->index;
253  return pkt->size;
254  } else if (tag == TAG_VIDEOFRAME) {
255  int ch_id = avio_rl16(pb);
256  len -= 2;
257  for(i=0; i<s->nb_streams; i++) {
258  st = s->streams[i];
259  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) {
260  frame = avio_rl16(pb);
261  len -= 2;
262  if (len <= 0)
263  goto skip;
264  if ((res = av_get_packet(pb, pkt, len)) < 0)
265  return res;
266  pkt->pos = pos;
267  pkt->pts = frame;
268  pkt->stream_index = st->index;
269  return pkt->size;
270  }
271  }
272  } else if (tag == TAG_DEFINEBITSLOSSLESS || tag == TAG_DEFINEBITSLOSSLESS2) {
273 #if CONFIG_ZLIB
274  long out_len;
275  uint8_t *buf = NULL, *zbuf = NULL, *pal;
276  uint32_t colormap[AVPALETTE_COUNT] = {0};
277  const int alpha_bmp = tag == TAG_DEFINEBITSLOSSLESS2;
278  const int colormapbpp = 3 + alpha_bmp;
279  int linesize, colormapsize = 0;
280 
281  const int ch_id = avio_rl16(pb);
282  const int bmp_fmt = avio_r8(pb);
283  const int width = avio_rl16(pb);
284  const int height = avio_rl16(pb);
285 
286  len -= 2+1+2+2;
287 
288  switch (bmp_fmt) {
289  case 3: // PAL-8
290  linesize = width;
291  colormapsize = avio_r8(pb) + 1;
292  len--;
293  break;
294  case 4: // RGB15
295  linesize = width * 2;
296  break;
297  case 5: // RGB24 (0RGB)
298  linesize = width * 4;
299  break;
300  default:
301  av_log(s, AV_LOG_ERROR, "invalid bitmap format %d, skipped\n", bmp_fmt);
302  goto bitmap_end_skip;
303  }
304 
305  linesize = FFALIGN(linesize, 4);
306 
307  if (av_image_check_size(width, height, 0, s) < 0 ||
308  linesize >= INT_MAX / height ||
309  linesize * height >= INT_MAX - colormapsize * colormapbpp) {
310  av_log(s, AV_LOG_ERROR, "invalid frame size %dx%d\n", width, height);
311  goto bitmap_end_skip;
312  }
313 
314  out_len = colormapsize * colormapbpp + linesize * height;
315 
316  av_dlog(s, "bitmap: ch=%d fmt=%d %dx%d (linesize=%d) len=%d->%ld pal=%d\n",
317  ch_id, bmp_fmt, width, height, linesize, len, out_len, colormapsize);
318 
319  zbuf = av_malloc(len);
320  buf = av_malloc(out_len);
321  if (!zbuf || !buf) {
322  res = AVERROR(ENOMEM);
323  goto bitmap_end;
324  }
325 
326  len = avio_read(pb, zbuf, len);
327  if (len < 0 || (res = uncompress(buf, &out_len, zbuf, len)) != Z_OK) {
328  av_log(s, AV_LOG_WARNING, "Failed to uncompress one bitmap\n");
329  goto bitmap_end_skip;
330  }
331 
332  for (i = 0; i < s->nb_streams; i++) {
333  st = s->streams[i];
334  if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && st->id == -3)
335  break;
336  }
337  if (i == s->nb_streams) {
338  vst = avformat_new_stream(s, NULL);
339  if (!vst) {
340  res = AVERROR(ENOMEM);
341  goto bitmap_end;
342  }
343  vst->id = -3; /* -3 to avoid clash with video stream and audio stream */
346  avpriv_set_pts_info(vst, 64, 256, swf->frame_rate);
347  st = vst;
348  }
349  st->codec->width = width;
350  st->codec->height = height;
351 
352  if ((res = av_new_packet(pkt, out_len - colormapsize * colormapbpp)) < 0)
353  goto bitmap_end;
354  pkt->pos = pos;
355  pkt->stream_index = st->index;
356 
357  switch (bmp_fmt) {
358  case 3:
359  st->codec->pix_fmt = AV_PIX_FMT_PAL8;
360  for (i = 0; i < colormapsize; i++)
361  if (alpha_bmp) colormap[i] = buf[3]<<24 | AV_RB24(buf + 4*i);
362  else colormap[i] = 0xffU <<24 | AV_RB24(buf + 3*i);
364  if (!pal) {
365  res = AVERROR(ENOMEM);
366  goto bitmap_end;
367  }
368  memcpy(pal, colormap, AVPALETTE_SIZE);
369  break;
370  case 4:
371  st->codec->pix_fmt = AV_PIX_FMT_RGB555;
372  break;
373  case 5:
374  st->codec->pix_fmt = alpha_bmp ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB;
375  break;
376  default:
377  av_assert0(0);
378  }
379 
380  if (linesize * height > pkt->size) {
381  res = AVERROR_INVALIDDATA;
382  goto bitmap_end;
383  }
384  memcpy(pkt->data, buf + colormapsize*colormapbpp, linesize * height);
385 
386  res = pkt->size;
387 
388 bitmap_end:
389  av_freep(&zbuf);
390  av_freep(&buf);
391  return res;
392 bitmap_end_skip:
393  av_freep(&zbuf);
394  av_freep(&buf);
395 #else
396  av_log(s, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
397 #endif
398  } else if (tag == TAG_STREAMBLOCK) {
399  for (i = 0; i < s->nb_streams; i++) {
400  st = s->streams[i];
401  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) {
402  if (st->codec->codec_id == AV_CODEC_ID_MP3) {
403  avio_skip(pb, 4);
404  len -= 4;
405  if (len <= 0)
406  goto skip;
407  if ((res = av_get_packet(pb, pkt, len)) < 0)
408  return res;
409  } else { // ADPCM, PCM
410  if (len <= 0)
411  goto skip;
412  if ((res = av_get_packet(pb, pkt, len)) < 0)
413  return res;
414  }
415  pkt->pos = pos;
416  pkt->stream_index = st->index;
417  return pkt->size;
418  }
419  }
420  } else if (tag == TAG_JPEG2) {
421  for (i=0; i<s->nb_streams; i++) {
422  st = s->streams[i];
423  if (st->codec->codec_id == AV_CODEC_ID_MJPEG && st->id == -2)
424  break;
425  }
426  if (i == s->nb_streams) {
427  vst = avformat_new_stream(s, NULL);
428  if (!vst)
429  return AVERROR(ENOMEM);
430  vst->id = -2; /* -2 to avoid clash with video stream and audio stream */
433  avpriv_set_pts_info(vst, 64, 256, swf->frame_rate);
434  st = vst;
435  }
436  avio_rl16(pb); /* BITMAP_ID */
437  len -= 2;
438  if (len < 4)
439  goto skip;
440  if ((res = av_new_packet(pkt, len)) < 0)
441  return res;
442  avio_read(pb, pkt->data, 4);
443  if (AV_RB32(pkt->data) == 0xffd8ffd9 ||
444  AV_RB32(pkt->data) == 0xffd9ffd8) {
445  /* old SWF files containing SOI/EOI as data start */
446  /* files created by swink have reversed tag */
447  pkt->size -= 4;
448  avio_read(pb, pkt->data, pkt->size);
449  } else {
450  avio_read(pb, pkt->data + 4, pkt->size - 4);
451  }
452  pkt->pos = pos;
453  pkt->stream_index = st->index;
454  return pkt->size;
455  } else {
456  av_log(s, AV_LOG_DEBUG, "Unknown tag: %d\n", tag);
457  }
458  skip:
459  if(len<0)
460  av_log(s, AV_LOG_WARNING, "Cliping len %d\n", len);
461  len = FFMAX(0, len);
462  avio_skip(pb, len);
463  }
464 }
465 
466 #if CONFIG_ZLIB
467 static av_cold int swf_read_close(AVFormatContext *avctx)
468 {
469  SWFContext *s = avctx->priv_data;
470  inflateEnd(&s->zstream);
471  av_freep(&s->zbuf_in);
472  av_freep(&s->zbuf_out);
473  av_freep(&s->zpb);
474  return 0;
475 }
476 #endif
477 
479  .name = "swf",
480  .long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
481  .priv_data_size = sizeof(SWFContext),
485 #if CONFIG_ZLIB
486  .read_close = swf_read_close,
487 #endif
488 };