yading@10
|
1 /*
|
yading@10
|
2 * Flash Screen Video decoder
|
yading@10
|
3 * Copyright (C) 2004 Alex Beregszaszi
|
yading@10
|
4 * Copyright (C) 2006 Benjamin Larsson
|
yading@10
|
5 *
|
yading@10
|
6 * This file is part of FFmpeg.
|
yading@10
|
7 *
|
yading@10
|
8 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
9 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
10 * License as published by the Free Software Foundation; either
|
yading@10
|
11 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
12 *
|
yading@10
|
13 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
16 * Lesser General Public License for more details.
|
yading@10
|
17 *
|
yading@10
|
18 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
19 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
21 */
|
yading@10
|
22
|
yading@10
|
23 /**
|
yading@10
|
24 * @file
|
yading@10
|
25 * Flash Screen Video decoder
|
yading@10
|
26 * @author Alex Beregszaszi
|
yading@10
|
27 * @author Benjamin Larsson
|
yading@10
|
28 * @author Daniel Verkamp
|
yading@10
|
29 * @author Konstantin Shishkov
|
yading@10
|
30 *
|
yading@10
|
31 * A description of the bitstream format for Flash Screen Video version 1/2
|
yading@10
|
32 * is part of the SWF File Format Specification (version 10), which can be
|
yading@10
|
33 * downloaded from http://www.adobe.com/devnet/swf.html.
|
yading@10
|
34 */
|
yading@10
|
35
|
yading@10
|
36 #include <stdio.h>
|
yading@10
|
37 #include <stdlib.h>
|
yading@10
|
38 #include <zlib.h>
|
yading@10
|
39
|
yading@10
|
40 #include "libavutil/intreadwrite.h"
|
yading@10
|
41 #include "avcodec.h"
|
yading@10
|
42 #include "bytestream.h"
|
yading@10
|
43 #include "get_bits.h"
|
yading@10
|
44 #include "internal.h"
|
yading@10
|
45
|
yading@10
|
46 typedef struct BlockInfo {
|
yading@10
|
47 uint8_t *pos;
|
yading@10
|
48 int size;
|
yading@10
|
49 } BlockInfo;
|
yading@10
|
50
|
yading@10
|
51 typedef struct FlashSVContext {
|
yading@10
|
52 AVCodecContext *avctx;
|
yading@10
|
53 AVFrame frame;
|
yading@10
|
54 int image_width, image_height;
|
yading@10
|
55 int block_width, block_height;
|
yading@10
|
56 uint8_t *tmpblock;
|
yading@10
|
57 int block_size;
|
yading@10
|
58 z_stream zstream;
|
yading@10
|
59 int ver;
|
yading@10
|
60 const uint32_t *pal;
|
yading@10
|
61 int is_keyframe;
|
yading@10
|
62 uint8_t *keyframedata;
|
yading@10
|
63 uint8_t *keyframe;
|
yading@10
|
64 BlockInfo *blocks;
|
yading@10
|
65 uint8_t *deflate_block;
|
yading@10
|
66 int deflate_block_size;
|
yading@10
|
67 int color_depth;
|
yading@10
|
68 int zlibprime_curr, zlibprime_prev;
|
yading@10
|
69 int diff_start, diff_height;
|
yading@10
|
70 } FlashSVContext;
|
yading@10
|
71
|
yading@10
|
72
|
yading@10
|
73 static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
|
yading@10
|
74 int h, int w, int stride, const uint32_t *pal)
|
yading@10
|
75 {
|
yading@10
|
76 int x, y;
|
yading@10
|
77 const uint8_t *orig_src = sptr;
|
yading@10
|
78
|
yading@10
|
79 for (y = dx+h; y > dx; y--) {
|
yading@10
|
80 uint8_t *dst = dptr + (y * stride) + dy * 3;
|
yading@10
|
81 for (x = 0; x < w; x++) {
|
yading@10
|
82 if (*sptr & 0x80) {
|
yading@10
|
83 /* 15-bit color */
|
yading@10
|
84 unsigned c = AV_RB16(sptr) & ~0x8000;
|
yading@10
|
85 unsigned b = c & 0x1F;
|
yading@10
|
86 unsigned g = (c >> 5) & 0x1F;
|
yading@10
|
87 unsigned r = c >> 10;
|
yading@10
|
88 /* 000aaabb -> aaabbaaa */
|
yading@10
|
89 *dst++ = (b << 3) | (b >> 2);
|
yading@10
|
90 *dst++ = (g << 3) | (g >> 2);
|
yading@10
|
91 *dst++ = (r << 3) | (r >> 2);
|
yading@10
|
92 sptr += 2;
|
yading@10
|
93 } else {
|
yading@10
|
94 /* palette index */
|
yading@10
|
95 uint32_t c = pal[*sptr++];
|
yading@10
|
96 bytestream_put_le24(&dst, c);
|
yading@10
|
97 }
|
yading@10
|
98 }
|
yading@10
|
99 }
|
yading@10
|
100 return sptr - orig_src;
|
yading@10
|
101 }
|
yading@10
|
102
|
yading@10
|
103 static av_cold int flashsv_decode_init(AVCodecContext *avctx)
|
yading@10
|
104 {
|
yading@10
|
105 FlashSVContext *s = avctx->priv_data;
|
yading@10
|
106 int zret; // Zlib return code
|
yading@10
|
107
|
yading@10
|
108 s->avctx = avctx;
|
yading@10
|
109 s->zstream.zalloc = Z_NULL;
|
yading@10
|
110 s->zstream.zfree = Z_NULL;
|
yading@10
|
111 s->zstream.opaque = Z_NULL;
|
yading@10
|
112 zret = inflateInit(&s->zstream);
|
yading@10
|
113 if (zret != Z_OK) {
|
yading@10
|
114 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
|
yading@10
|
115 return 1;
|
yading@10
|
116 }
|
yading@10
|
117 avctx->pix_fmt = AV_PIX_FMT_BGR24;
|
yading@10
|
118 avcodec_get_frame_defaults(&s->frame);
|
yading@10
|
119
|
yading@10
|
120 return 0;
|
yading@10
|
121 }
|
yading@10
|
122
|
yading@10
|
123
|
yading@10
|
124 static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
|
yading@10
|
125 {
|
yading@10
|
126 z_stream zs;
|
yading@10
|
127 int zret; // Zlib return code
|
yading@10
|
128
|
yading@10
|
129 if (!src)
|
yading@10
|
130 return AVERROR_INVALIDDATA;
|
yading@10
|
131
|
yading@10
|
132 zs.zalloc = NULL;
|
yading@10
|
133 zs.zfree = NULL;
|
yading@10
|
134 zs.opaque = NULL;
|
yading@10
|
135
|
yading@10
|
136 s->zstream.next_in = src;
|
yading@10
|
137 s->zstream.avail_in = size;
|
yading@10
|
138 s->zstream.next_out = s->tmpblock;
|
yading@10
|
139 s->zstream.avail_out = s->block_size * 3;
|
yading@10
|
140 inflate(&s->zstream, Z_SYNC_FLUSH);
|
yading@10
|
141
|
yading@10
|
142 if (deflateInit(&zs, 0) != Z_OK)
|
yading@10
|
143 return -1;
|
yading@10
|
144 zs.next_in = s->tmpblock;
|
yading@10
|
145 zs.avail_in = s->block_size * 3 - s->zstream.avail_out;
|
yading@10
|
146 zs.next_out = s->deflate_block;
|
yading@10
|
147 zs.avail_out = s->deflate_block_size;
|
yading@10
|
148 deflate(&zs, Z_SYNC_FLUSH);
|
yading@10
|
149 deflateEnd(&zs);
|
yading@10
|
150
|
yading@10
|
151 if ((zret = inflateReset(&s->zstream)) != Z_OK) {
|
yading@10
|
152 av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
|
yading@10
|
153 return AVERROR_UNKNOWN;
|
yading@10
|
154 }
|
yading@10
|
155
|
yading@10
|
156 s->zstream.next_in = s->deflate_block;
|
yading@10
|
157 s->zstream.avail_in = s->deflate_block_size - zs.avail_out;
|
yading@10
|
158 s->zstream.next_out = s->tmpblock;
|
yading@10
|
159 s->zstream.avail_out = s->block_size * 3;
|
yading@10
|
160 inflate(&s->zstream, Z_SYNC_FLUSH);
|
yading@10
|
161
|
yading@10
|
162 return 0;
|
yading@10
|
163 }
|
yading@10
|
164
|
yading@10
|
165 static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
|
yading@10
|
166 GetBitContext *gb, int block_size,
|
yading@10
|
167 int width, int height, int x_pos, int y_pos,
|
yading@10
|
168 int blk_idx)
|
yading@10
|
169 {
|
yading@10
|
170 struct FlashSVContext *s = avctx->priv_data;
|
yading@10
|
171 uint8_t *line = s->tmpblock;
|
yading@10
|
172 int k;
|
yading@10
|
173 int ret = inflateReset(&s->zstream);
|
yading@10
|
174 if (ret != Z_OK) {
|
yading@10
|
175 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
|
yading@10
|
176 return AVERROR_UNKNOWN;
|
yading@10
|
177 }
|
yading@10
|
178 if (s->zlibprime_curr || s->zlibprime_prev) {
|
yading@10
|
179 ret = flashsv2_prime(s,
|
yading@10
|
180 s->blocks[blk_idx].pos,
|
yading@10
|
181 s->blocks[blk_idx].size);
|
yading@10
|
182 if (ret < 0)
|
yading@10
|
183 return ret;
|
yading@10
|
184 }
|
yading@10
|
185 s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8;
|
yading@10
|
186 s->zstream.avail_in = block_size;
|
yading@10
|
187 s->zstream.next_out = s->tmpblock;
|
yading@10
|
188 s->zstream.avail_out = s->block_size * 3;
|
yading@10
|
189 ret = inflate(&s->zstream, Z_FINISH);
|
yading@10
|
190 if (ret == Z_DATA_ERROR) {
|
yading@10
|
191 av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
|
yading@10
|
192 inflateSync(&s->zstream);
|
yading@10
|
193 ret = inflate(&s->zstream, Z_FINISH);
|
yading@10
|
194 }
|
yading@10
|
195
|
yading@10
|
196 if (ret != Z_OK && ret != Z_STREAM_END) {
|
yading@10
|
197 //return -1;
|
yading@10
|
198 }
|
yading@10
|
199
|
yading@10
|
200 if (s->is_keyframe) {
|
yading@10
|
201 s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8);
|
yading@10
|
202 s->blocks[blk_idx].size = block_size;
|
yading@10
|
203 }
|
yading@10
|
204 if (!s->color_depth) {
|
yading@10
|
205 /* Flash Screen Video stores the image upside down, so copy
|
yading@10
|
206 * lines to destination in reverse order. */
|
yading@10
|
207 for (k = 1; k <= s->diff_height; k++) {
|
yading@10
|
208 memcpy(s->frame.data[0] + x_pos * 3 +
|
yading@10
|
209 (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
|
yading@10
|
210 line, width * 3);
|
yading@10
|
211 /* advance source pointer to next line */
|
yading@10
|
212 line += width * 3;
|
yading@10
|
213 }
|
yading@10
|
214 } else {
|
yading@10
|
215 /* hybrid 15-bit/palette mode */
|
yading@10
|
216 decode_hybrid(s->tmpblock, s->frame.data[0],
|
yading@10
|
217 s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
|
yading@10
|
218 x_pos, s->diff_height, width,
|
yading@10
|
219 s->frame.linesize[0], s->pal);
|
yading@10
|
220 }
|
yading@10
|
221 skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
|
yading@10
|
222 return 0;
|
yading@10
|
223 }
|
yading@10
|
224
|
yading@10
|
225 static int calc_deflate_block_size(int tmpblock_size)
|
yading@10
|
226 {
|
yading@10
|
227 z_stream zstream;
|
yading@10
|
228 int size;
|
yading@10
|
229
|
yading@10
|
230 zstream.zalloc = Z_NULL;
|
yading@10
|
231 zstream.zfree = Z_NULL;
|
yading@10
|
232 zstream.opaque = Z_NULL;
|
yading@10
|
233 if (deflateInit(&zstream, 0) != Z_OK)
|
yading@10
|
234 return -1;
|
yading@10
|
235 size = deflateBound(&zstream, tmpblock_size);
|
yading@10
|
236 deflateEnd(&zstream);
|
yading@10
|
237
|
yading@10
|
238 return size;
|
yading@10
|
239 }
|
yading@10
|
240
|
yading@10
|
241 static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
|
yading@10
|
242 int *got_frame, AVPacket *avpkt)
|
yading@10
|
243 {
|
yading@10
|
244 int buf_size = avpkt->size;
|
yading@10
|
245 FlashSVContext *s = avctx->priv_data;
|
yading@10
|
246 int h_blocks, v_blocks, h_part, v_part, i, j, ret;
|
yading@10
|
247 GetBitContext gb;
|
yading@10
|
248 int last_blockwidth = s->block_width;
|
yading@10
|
249 int last_blockheight= s->block_height;
|
yading@10
|
250
|
yading@10
|
251 /* no supplementary picture */
|
yading@10
|
252 if (buf_size == 0)
|
yading@10
|
253 return 0;
|
yading@10
|
254 if (buf_size < 4)
|
yading@10
|
255 return -1;
|
yading@10
|
256
|
yading@10
|
257 init_get_bits(&gb, avpkt->data, buf_size * 8);
|
yading@10
|
258
|
yading@10
|
259 /* start to parse the bitstream */
|
yading@10
|
260 s->block_width = 16 * (get_bits(&gb, 4) + 1);
|
yading@10
|
261 s->image_width = get_bits(&gb, 12);
|
yading@10
|
262 s->block_height = 16 * (get_bits(&gb, 4) + 1);
|
yading@10
|
263 s->image_height = get_bits(&gb, 12);
|
yading@10
|
264
|
yading@10
|
265 if ( last_blockwidth != s->block_width
|
yading@10
|
266 || last_blockheight!= s->block_height)
|
yading@10
|
267 av_freep(&s->blocks);
|
yading@10
|
268
|
yading@10
|
269 if (s->ver == 2) {
|
yading@10
|
270 skip_bits(&gb, 6);
|
yading@10
|
271 if (get_bits1(&gb)) {
|
yading@10
|
272 avpriv_request_sample(avctx, "iframe");
|
yading@10
|
273 return AVERROR_PATCHWELCOME;
|
yading@10
|
274 }
|
yading@10
|
275 if (get_bits1(&gb)) {
|
yading@10
|
276 avpriv_request_sample(avctx, "Custom palette");
|
yading@10
|
277 return AVERROR_PATCHWELCOME;
|
yading@10
|
278 }
|
yading@10
|
279 }
|
yading@10
|
280
|
yading@10
|
281 /* calculate number of blocks and size of border (partial) blocks */
|
yading@10
|
282 h_blocks = s->image_width / s->block_width;
|
yading@10
|
283 h_part = s->image_width % s->block_width;
|
yading@10
|
284 v_blocks = s->image_height / s->block_height;
|
yading@10
|
285 v_part = s->image_height % s->block_height;
|
yading@10
|
286
|
yading@10
|
287 /* the block size could change between frames, make sure the buffer
|
yading@10
|
288 * is large enough, if not, get a larger one */
|
yading@10
|
289 if (s->block_size < s->block_width * s->block_height) {
|
yading@10
|
290 int tmpblock_size = 3 * s->block_width * s->block_height;
|
yading@10
|
291
|
yading@10
|
292 s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
|
yading@10
|
293 if (!s->tmpblock) {
|
yading@10
|
294 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
|
yading@10
|
295 return AVERROR(ENOMEM);
|
yading@10
|
296 }
|
yading@10
|
297 if (s->ver == 2) {
|
yading@10
|
298 s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
|
yading@10
|
299 if (s->deflate_block_size <= 0) {
|
yading@10
|
300 av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
|
yading@10
|
301 return -1;
|
yading@10
|
302 }
|
yading@10
|
303 s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
|
yading@10
|
304 if (!s->deflate_block) {
|
yading@10
|
305 av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
|
yading@10
|
306 return AVERROR(ENOMEM);
|
yading@10
|
307 }
|
yading@10
|
308 }
|
yading@10
|
309 }
|
yading@10
|
310 s->block_size = s->block_width * s->block_height;
|
yading@10
|
311
|
yading@10
|
312 /* initialize the image size once */
|
yading@10
|
313 if (avctx->width == 0 && avctx->height == 0) {
|
yading@10
|
314 avcodec_set_dimensions(avctx, s->image_width, s->image_height);
|
yading@10
|
315 }
|
yading@10
|
316
|
yading@10
|
317 /* check for changes of image width and image height */
|
yading@10
|
318 if (avctx->width != s->image_width || avctx->height != s->image_height) {
|
yading@10
|
319 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
320 "Frame width or height differs from first frame!\n");
|
yading@10
|
321 av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n",
|
yading@10
|
322 avctx->height, avctx->width, s->image_height, s->image_width);
|
yading@10
|
323 return AVERROR_INVALIDDATA;
|
yading@10
|
324 }
|
yading@10
|
325
|
yading@10
|
326 /* we care for keyframes only in Screen Video v2 */
|
yading@10
|
327 s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
|
yading@10
|
328 if (s->is_keyframe) {
|
yading@10
|
329 s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
|
yading@10
|
330 memcpy(s->keyframedata, avpkt->data, avpkt->size);
|
yading@10
|
331 }
|
yading@10
|
332 if(s->ver == 2 && !s->blocks)
|
yading@10
|
333 s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part)
|
yading@10
|
334 * sizeof(s->blocks[0]));
|
yading@10
|
335
|
yading@10
|
336 av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
|
yading@10
|
337 s->image_width, s->image_height, s->block_width, s->block_height,
|
yading@10
|
338 h_blocks, v_blocks, h_part, v_part);
|
yading@10
|
339
|
yading@10
|
340 if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
|
yading@10
|
341 return ret;
|
yading@10
|
342
|
yading@10
|
343 /* loop over all block columns */
|
yading@10
|
344 for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
|
yading@10
|
345
|
yading@10
|
346 int y_pos = j * s->block_height; // vertical position in frame
|
yading@10
|
347 int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
|
yading@10
|
348
|
yading@10
|
349 /* loop over all block rows */
|
yading@10
|
350 for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
|
yading@10
|
351 int x_pos = i * s->block_width; // horizontal position in frame
|
yading@10
|
352 int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
|
yading@10
|
353 int has_diff = 0;
|
yading@10
|
354
|
yading@10
|
355 /* get the size of the compressed zlib chunk */
|
yading@10
|
356 int size = get_bits(&gb, 16);
|
yading@10
|
357
|
yading@10
|
358 s->color_depth = 0;
|
yading@10
|
359 s->zlibprime_curr = 0;
|
yading@10
|
360 s->zlibprime_prev = 0;
|
yading@10
|
361 s->diff_start = 0;
|
yading@10
|
362 s->diff_height = cur_blk_height;
|
yading@10
|
363
|
yading@10
|
364 if (8 * size > get_bits_left(&gb)) {
|
yading@10
|
365 av_frame_unref(&s->frame);
|
yading@10
|
366 return AVERROR_INVALIDDATA;
|
yading@10
|
367 }
|
yading@10
|
368
|
yading@10
|
369 if (s->ver == 2 && size) {
|
yading@10
|
370 skip_bits(&gb, 3);
|
yading@10
|
371 s->color_depth = get_bits(&gb, 2);
|
yading@10
|
372 has_diff = get_bits1(&gb);
|
yading@10
|
373 s->zlibprime_curr = get_bits1(&gb);
|
yading@10
|
374 s->zlibprime_prev = get_bits1(&gb);
|
yading@10
|
375
|
yading@10
|
376 if (s->color_depth != 0 && s->color_depth != 2) {
|
yading@10
|
377 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
378 "%dx%d invalid color depth %d\n", i, j, s->color_depth);
|
yading@10
|
379 return AVERROR_INVALIDDATA;
|
yading@10
|
380 }
|
yading@10
|
381
|
yading@10
|
382 if (has_diff) {
|
yading@10
|
383 if (!s->keyframe) {
|
yading@10
|
384 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
385 "inter frame without keyframe\n");
|
yading@10
|
386 return AVERROR_INVALIDDATA;
|
yading@10
|
387 }
|
yading@10
|
388 s->diff_start = get_bits(&gb, 8);
|
yading@10
|
389 s->diff_height = get_bits(&gb, 8);
|
yading@10
|
390 av_log(avctx, AV_LOG_DEBUG,
|
yading@10
|
391 "%dx%d diff start %d height %d\n",
|
yading@10
|
392 i, j, s->diff_start, s->diff_height);
|
yading@10
|
393 size -= 2;
|
yading@10
|
394 }
|
yading@10
|
395
|
yading@10
|
396 if (s->zlibprime_prev)
|
yading@10
|
397 av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
|
yading@10
|
398
|
yading@10
|
399 if (s->zlibprime_curr) {
|
yading@10
|
400 int col = get_bits(&gb, 8);
|
yading@10
|
401 int row = get_bits(&gb, 8);
|
yading@10
|
402 av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
|
yading@10
|
403 size -= 2;
|
yading@10
|
404 avpriv_request_sample(avctx, "zlibprime_curr");
|
yading@10
|
405 return AVERROR_PATCHWELCOME;
|
yading@10
|
406 }
|
yading@10
|
407 if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
|
yading@10
|
408 av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
|
yading@10
|
409 "priming\n");
|
yading@10
|
410 return AVERROR_INVALIDDATA;
|
yading@10
|
411 }
|
yading@10
|
412 size--; // account for flags byte
|
yading@10
|
413 }
|
yading@10
|
414
|
yading@10
|
415 if (has_diff) {
|
yading@10
|
416 int k;
|
yading@10
|
417 int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
|
yading@10
|
418
|
yading@10
|
419 for (k = 0; k < cur_blk_height; k++)
|
yading@10
|
420 memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
|
yading@10
|
421 s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
|
yading@10
|
422 cur_blk_width * 3);
|
yading@10
|
423 }
|
yading@10
|
424
|
yading@10
|
425 /* skip unchanged blocks, which have size 0 */
|
yading@10
|
426 if (size) {
|
yading@10
|
427 if (flashsv_decode_block(avctx, avpkt, &gb, size,
|
yading@10
|
428 cur_blk_width, cur_blk_height,
|
yading@10
|
429 x_pos, y_pos,
|
yading@10
|
430 i + j * (h_blocks + !!h_part)))
|
yading@10
|
431 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
432 "error in decompression of block %dx%d\n", i, j);
|
yading@10
|
433 }
|
yading@10
|
434 }
|
yading@10
|
435 }
|
yading@10
|
436 if (s->is_keyframe && s->ver == 2) {
|
yading@10
|
437 if (!s->keyframe) {
|
yading@10
|
438 s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
|
yading@10
|
439 if (!s->keyframe) {
|
yading@10
|
440 av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
|
yading@10
|
441 return AVERROR(ENOMEM);
|
yading@10
|
442 }
|
yading@10
|
443 }
|
yading@10
|
444 memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
|
yading@10
|
445 }
|
yading@10
|
446
|
yading@10
|
447 if ((ret = av_frame_ref(data, &s->frame)) < 0)
|
yading@10
|
448 return ret;
|
yading@10
|
449
|
yading@10
|
450 *got_frame = 1;
|
yading@10
|
451
|
yading@10
|
452 if ((get_bits_count(&gb) / 8) != buf_size)
|
yading@10
|
453 av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
|
yading@10
|
454 buf_size, (get_bits_count(&gb) / 8));
|
yading@10
|
455
|
yading@10
|
456 /* report that the buffer was completely consumed */
|
yading@10
|
457 return buf_size;
|
yading@10
|
458 }
|
yading@10
|
459
|
yading@10
|
460
|
yading@10
|
461 static av_cold int flashsv_decode_end(AVCodecContext *avctx)
|
yading@10
|
462 {
|
yading@10
|
463 FlashSVContext *s = avctx->priv_data;
|
yading@10
|
464 inflateEnd(&s->zstream);
|
yading@10
|
465 /* release the frame if needed */
|
yading@10
|
466 av_frame_unref(&s->frame);
|
yading@10
|
467
|
yading@10
|
468 /* free the tmpblock */
|
yading@10
|
469 av_free(s->tmpblock);
|
yading@10
|
470
|
yading@10
|
471 return 0;
|
yading@10
|
472 }
|
yading@10
|
473
|
yading@10
|
474
|
yading@10
|
475 #if CONFIG_FLASHSV_DECODER
|
yading@10
|
476 AVCodec ff_flashsv_decoder = {
|
yading@10
|
477 .name = "flashsv",
|
yading@10
|
478 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
479 .id = AV_CODEC_ID_FLASHSV,
|
yading@10
|
480 .priv_data_size = sizeof(FlashSVContext),
|
yading@10
|
481 .init = flashsv_decode_init,
|
yading@10
|
482 .close = flashsv_decode_end,
|
yading@10
|
483 .decode = flashsv_decode_frame,
|
yading@10
|
484 .capabilities = CODEC_CAP_DR1,
|
yading@10
|
485 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
|
yading@10
|
486 .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
|
yading@10
|
487 };
|
yading@10
|
488 #endif /* CONFIG_FLASHSV_DECODER */
|
yading@10
|
489
|
yading@10
|
490 #if CONFIG_FLASHSV2_DECODER
|
yading@10
|
491 static const uint32_t ff_flashsv2_default_palette[128] = {
|
yading@10
|
492 0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
|
yading@10
|
493 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
|
yading@10
|
494 0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
|
yading@10
|
495 0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
|
yading@10
|
496 0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
|
yading@10
|
497 0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
|
yading@10
|
498 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
|
yading@10
|
499 0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
|
yading@10
|
500 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
|
yading@10
|
501 0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
|
yading@10
|
502 0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
|
yading@10
|
503 0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
|
yading@10
|
504 0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
|
yading@10
|
505 0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
|
yading@10
|
506 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
|
yading@10
|
507 0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
|
yading@10
|
508 0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
|
yading@10
|
509 0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
|
yading@10
|
510 0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
|
yading@10
|
511 0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
|
yading@10
|
512 0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
|
yading@10
|
513 0xDDDDDD, 0xEEEEEE
|
yading@10
|
514 };
|
yading@10
|
515
|
yading@10
|
516 static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
|
yading@10
|
517 {
|
yading@10
|
518 FlashSVContext *s = avctx->priv_data;
|
yading@10
|
519 flashsv_decode_init(avctx);
|
yading@10
|
520 s->pal = ff_flashsv2_default_palette;
|
yading@10
|
521 s->ver = 2;
|
yading@10
|
522
|
yading@10
|
523 return 0;
|
yading@10
|
524 }
|
yading@10
|
525
|
yading@10
|
526 static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
|
yading@10
|
527 {
|
yading@10
|
528 FlashSVContext *s = avctx->priv_data;
|
yading@10
|
529
|
yading@10
|
530 av_freep(&s->keyframedata);
|
yading@10
|
531 av_freep(&s->blocks);
|
yading@10
|
532 av_freep(&s->keyframe);
|
yading@10
|
533 av_freep(&s->deflate_block);
|
yading@10
|
534 flashsv_decode_end(avctx);
|
yading@10
|
535
|
yading@10
|
536 return 0;
|
yading@10
|
537 }
|
yading@10
|
538
|
yading@10
|
539 AVCodec ff_flashsv2_decoder = {
|
yading@10
|
540 .name = "flashsv2",
|
yading@10
|
541 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
542 .id = AV_CODEC_ID_FLASHSV2,
|
yading@10
|
543 .priv_data_size = sizeof(FlashSVContext),
|
yading@10
|
544 .init = flashsv2_decode_init,
|
yading@10
|
545 .close = flashsv2_decode_end,
|
yading@10
|
546 .decode = flashsv_decode_frame,
|
yading@10
|
547 .capabilities = CODEC_CAP_DR1,
|
yading@10
|
548 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
|
yading@10
|
549 .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
|
yading@10
|
550 };
|
yading@10
|
551 #endif /* CONFIG_FLASHSV2_DECODER */
|