annotate ffmpeg/libavformat/swfdec.c @ 13:844d341cf643 tip

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