mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
swfdec: support compressed swf.
This commit is contained in:
parent
38477e1981
commit
588eaa106d
@ -23,6 +23,10 @@
|
||||
#ifndef AVFORMAT_SWF_H
|
||||
#define AVFORMAT_SWF_H
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "libavutil/fifo.h"
|
||||
#include "avformat.h"
|
||||
#include "avio.h"
|
||||
@ -76,6 +80,13 @@ typedef struct {
|
||||
int tag;
|
||||
AVFifoBuffer *audio_fifo;
|
||||
AVCodecContext *audio_enc, *video_enc;
|
||||
#if CONFIG_ZLIB
|
||||
AVIOContext *zpb;
|
||||
#define ZBUF_SIZE 4096
|
||||
uint8_t *zbuf_in;
|
||||
uint8_t *zbuf_out;
|
||||
z_stream zstream;
|
||||
#endif
|
||||
} SWFContext;
|
||||
|
||||
static const AVCodecTag swf_codec_tags[] = {
|
||||
|
@ -52,6 +52,39 @@ static int swf_probe(AVProbeData *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
static int zlib_refill(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
AVFormatContext *s = opaque;
|
||||
SWFContext *swf = s->priv_data;
|
||||
z_stream *z = &swf->zstream;
|
||||
int ret;
|
||||
|
||||
retry:
|
||||
if (!z->avail_in) {
|
||||
int n = avio_read(s->pb, swf->zbuf_in, ZBUF_SIZE);
|
||||
if (n <= 0)
|
||||
return n;
|
||||
z->next_in = swf->zbuf_in;
|
||||
z->avail_in = n;
|
||||
}
|
||||
|
||||
z->next_out = buf;
|
||||
z->avail_out = buf_size;
|
||||
|
||||
ret = inflate(z, Z_NO_FLUSH);
|
||||
if (ret < 0)
|
||||
return AVERROR(EINVAL);
|
||||
if (ret == Z_STREAM_END)
|
||||
return AVERROR_EOF;
|
||||
|
||||
if (buf_size - z->avail_out == 0)
|
||||
goto retry;
|
||||
|
||||
return buf_size - z->avail_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int swf_read_header(AVFormatContext *s)
|
||||
{
|
||||
SWFContext *swf = s->priv_data;
|
||||
@ -59,14 +92,29 @@ static int swf_read_header(AVFormatContext *s)
|
||||
int nbits, len, tag;
|
||||
|
||||
tag = avio_rb32(pb) & 0xffffff00;
|
||||
avio_rl32(pb);
|
||||
|
||||
if (tag == MKBETAG('C', 'W', 'S', 0)) {
|
||||
av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");
|
||||
av_log(s, AV_LOG_INFO, "SWF compressed file detected\n");
|
||||
#if CONFIG_ZLIB
|
||||
swf->zbuf_in = av_malloc(ZBUF_SIZE);
|
||||
swf->zbuf_out = av_malloc(ZBUF_SIZE);
|
||||
swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, s,
|
||||
zlib_refill, NULL, NULL);
|
||||
if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb)
|
||||
return AVERROR(ENOMEM);
|
||||
swf->zpb->seekable = 0;
|
||||
if (inflateInit(&swf->zstream) != Z_OK) {
|
||||
av_log(s, AV_LOG_ERROR, "Unable to init zlib context\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
pb = swf->zpb;
|
||||
#else
|
||||
av_log(s, AV_LOG_ERROR, "zlib support is required to read SWF compressed files\n");
|
||||
return AVERROR(EIO);
|
||||
}
|
||||
if (tag != MKBETAG('F', 'W', 'S', 0))
|
||||
#endif
|
||||
} else if (tag != MKBETAG('F', 'W', 'S', 0))
|
||||
return AVERROR(EIO);
|
||||
avio_rl32(pb);
|
||||
/* skip rectangle size */
|
||||
nbits = avio_r8(pb) >> 3;
|
||||
len = (4 * nbits - 3 + 7) / 8;
|
||||
@ -86,6 +134,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
AVStream *vst = NULL, *ast = NULL, *st = 0;
|
||||
int tag, len, i, frame, v, res;
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
if (swf->zpb)
|
||||
pb = swf->zpb;
|
||||
#endif
|
||||
|
||||
for(;;) {
|
||||
uint64_t pos = avio_tell(pb);
|
||||
tag = get_swf_tag(pb, &len);
|
||||
@ -209,6 +262,18 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
static av_cold int swf_read_close(AVFormatContext *avctx)
|
||||
{
|
||||
SWFContext *s = avctx->priv_data;
|
||||
inflateEnd(&s->zstream);
|
||||
av_freep(&s->zbuf_in);
|
||||
av_freep(&s->zbuf_out);
|
||||
av_freep(&s->zpb);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
AVInputFormat ff_swf_demuxer = {
|
||||
.name = "swf",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Flash format"),
|
||||
@ -216,4 +281,7 @@ AVInputFormat ff_swf_demuxer = {
|
||||
.read_probe = swf_probe,
|
||||
.read_header = swf_read_header,
|
||||
.read_packet = swf_read_packet,
|
||||
#if CONFIG_ZLIB
|
||||
.read_close = swf_read_close,
|
||||
#endif
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user