Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Clément Bœsch authored on 2015/12/03 08:41:00... | ... |
@@ -2256,6 +2256,7 @@ sdp_demuxer_select="rtpdec" |
2256 | 2256 |
smoothstreaming_muxer_select="ismv_muxer" |
2257 | 2257 |
spdif_muxer_select="aac_parser" |
2258 | 2258 |
spx_muxer_select="ogg_muxer" |
2259 |
+swf_demuxer_suggest="zlib" |
|
2259 | 2260 |
tak_demuxer_select="tak_parser" |
2260 | 2261 |
tg2_muxer_select="mov_muxer" |
2261 | 2262 |
tgp_muxer_select="mov_muxer" |
... | ... |
@@ -23,6 +23,12 @@ |
23 | 23 |
#ifndef AVFORMAT_SWF_H |
24 | 24 |
#define AVFORMAT_SWF_H |
25 | 25 |
|
26 |
+#include "config.h" |
|
27 |
+ |
|
28 |
+#if CONFIG_ZLIB |
|
29 |
+#include <zlib.h> |
|
30 |
+#endif |
|
31 |
+ |
|
26 | 32 |
#include "libavutil/fifo.h" |
27 | 33 |
#include "avformat.h" |
28 | 34 |
#include "avio.h" |
... | ... |
@@ -77,6 +83,13 @@ typedef struct SWFContext { |
77 | 77 |
AVFifoBuffer *audio_fifo; |
78 | 78 |
AVCodecContext *audio_enc, *video_enc; |
79 | 79 |
AVStream *video_st; |
80 |
+#if CONFIG_ZLIB |
|
81 |
+#define ZBUF_SIZE 4096 |
|
82 |
+ AVIOContext *zpb; |
|
83 |
+ uint8_t *zbuf_in; |
|
84 |
+ uint8_t *zbuf_out; |
|
85 |
+ z_stream zstream; |
|
86 |
+#endif |
|
80 | 87 |
} SWFContext; |
81 | 88 |
|
82 | 89 |
extern const AVCodecTag ff_swf_codec_tags[]; |
... | ... |
@@ -20,6 +20,12 @@ |
20 | 20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | 21 |
*/ |
22 | 22 |
|
23 |
+#include "config.h" |
|
24 |
+ |
|
25 |
+#if CONFIG_ZLIB |
|
26 |
+#include <zlib.h> |
|
27 |
+#endif |
|
28 |
+ |
|
23 | 29 |
#include "libavutil/channel_layout.h" |
24 | 30 |
#include "libavutil/intreadwrite.h" |
25 | 31 |
#include "swf.h" |
... | ... |
@@ -61,6 +67,39 @@ static int swf_probe(AVProbeData *p) |
61 | 61 |
return 0; |
62 | 62 |
} |
63 | 63 |
|
64 |
+#if CONFIG_ZLIB |
|
65 |
+static int zlib_refill(void *opaque, uint8_t *buf, int buf_size) |
|
66 |
+{ |
|
67 |
+ AVFormatContext *s = opaque; |
|
68 |
+ SWFContext *swf = s->priv_data; |
|
69 |
+ z_stream *z = &swf->zstream; |
|
70 |
+ int ret; |
|
71 |
+ |
|
72 |
+retry: |
|
73 |
+ if (!z->avail_in) { |
|
74 |
+ int n = avio_read(s->pb, swf->zbuf_in, ZBUF_SIZE); |
|
75 |
+ if (n < 0) |
|
76 |
+ return n; |
|
77 |
+ z->next_in = swf->zbuf_in; |
|
78 |
+ z->avail_in = n; |
|
79 |
+ } |
|
80 |
+ |
|
81 |
+ z->next_out = buf; |
|
82 |
+ z->avail_out = buf_size; |
|
83 |
+ |
|
84 |
+ ret = inflate(z, Z_NO_FLUSH); |
|
85 |
+ if (ret != Z_OK && ret != Z_STREAM_END) { |
|
86 |
+ av_log(s, AV_LOG_ERROR, "Inflate error: %d\n", ret); |
|
87 |
+ return AVERROR_UNKNOWN; |
|
88 |
+ } |
|
89 |
+ |
|
90 |
+ if (buf_size - z->avail_out == 0) |
|
91 |
+ goto retry; |
|
92 |
+ |
|
93 |
+ return buf_size - z->avail_out; |
|
94 |
+} |
|
95 |
+#endif |
|
96 |
+ |
|
64 | 97 |
static int swf_read_header(AVFormatContext *s) |
65 | 98 |
{ |
66 | 99 |
SWFContext *swf = s->priv_data; |
... | ... |
@@ -68,14 +107,33 @@ static int swf_read_header(AVFormatContext *s) |
68 | 68 |
int nbits, len, tag; |
69 | 69 |
|
70 | 70 |
tag = avio_rb32(pb) & 0xffffff00; |
71 |
+ avio_rl32(pb); |
|
71 | 72 |
|
72 | 73 |
if (tag == MKBETAG('C', 'W', 'S', 0)) { |
73 |
- av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n"); |
|
74 |
+ av_log(s, AV_LOG_INFO, "Compressed SWF file detected\n"); |
|
75 |
+#if CONFIG_ZLIB |
|
76 |
+ if (inflateInit(&swf->zstream) != Z_OK) { |
|
77 |
+ av_log(s, AV_LOG_ERROR, "Unable to init zlib context\n"); |
|
78 |
+ return AVERROR(EINVAL); |
|
79 |
+ } |
|
80 |
+ swf->zbuf_in = av_malloc(ZBUF_SIZE); |
|
81 |
+ swf->zbuf_out = av_malloc(ZBUF_SIZE); |
|
82 |
+ swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, s, |
|
83 |
+ zlib_refill, NULL, NULL); |
|
84 |
+ if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb) { |
|
85 |
+ av_freep(&swf->zbuf_in); |
|
86 |
+ av_freep(&swf->zbuf_out); |
|
87 |
+ av_freep(&swf->zpb); |
|
88 |
+ return AVERROR(ENOMEM); |
|
89 |
+ } |
|
90 |
+ swf->zpb->seekable = 0; |
|
91 |
+ pb = swf->zpb; |
|
92 |
+#else |
|
93 |
+ av_log(s, AV_LOG_ERROR, "missing zlib support, unable to open\n"); |
|
74 | 94 |
return AVERROR(EIO); |
75 |
- } |
|
76 |
- if (tag != MKBETAG('F', 'W', 'S', 0)) |
|
95 |
+#endif |
|
96 |
+ } else if (tag != MKBETAG('F', 'W', 'S', 0)) |
|
77 | 97 |
return AVERROR(EIO); |
78 |
- avio_rl32(pb); |
|
79 | 98 |
/* skip rectangle size */ |
80 | 99 |
nbits = avio_r8(pb) >> 3; |
81 | 100 |
len = (4 * nbits - 3 + 7) / 8; |
... | ... |
@@ -95,6 +153,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
95 | 95 |
AVStream *vst = NULL, *ast = NULL, *st = 0; |
96 | 96 |
int tag, len, i, frame, v, res; |
97 | 97 |
|
98 |
+#if CONFIG_ZLIB |
|
99 |
+ if (swf->zpb) |
|
100 |
+ pb = swf->zpb; |
|
101 |
+#endif |
|
102 |
+ |
|
98 | 103 |
for(;;) { |
99 | 104 |
uint64_t pos = avio_tell(pb); |
100 | 105 |
tag = get_swf_tag(pb, &len); |
... | ... |
@@ -240,6 +303,18 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
240 | 240 |
} |
241 | 241 |
} |
242 | 242 |
|
243 |
+#if CONFIG_ZLIB |
|
244 |
+static av_cold int swf_read_close(AVFormatContext *avctx) |
|
245 |
+{ |
|
246 |
+ SWFContext *s = avctx->priv_data; |
|
247 |
+ inflateEnd(&s->zstream); |
|
248 |
+ av_freep(&s->zbuf_in); |
|
249 |
+ av_freep(&s->zbuf_out); |
|
250 |
+ av_freep(&s->zpb); |
|
251 |
+ return 0; |
|
252 |
+} |
|
253 |
+#endif |
|
254 |
+ |
|
243 | 255 |
AVInputFormat ff_swf_demuxer = { |
244 | 256 |
.name = "swf", |
245 | 257 |
.long_name = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"), |
... | ... |
@@ -247,4 +322,7 @@ AVInputFormat ff_swf_demuxer = { |
247 | 247 |
.read_probe = swf_probe, |
248 | 248 |
.read_header = swf_read_header, |
249 | 249 |
.read_packet = swf_read_packet, |
250 |
+#if CONFIG_ZLIB |
|
251 |
+ .read_close = swf_read_close, |
|
252 |
+#endif |
|
250 | 253 |
}; |