2 * Flash Screen Video decoder
3 * Copyright (C) 2004 Alex Beregszaszi
4 * Copyright (C) 2006 Benjamin Larsson
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * Flash Screen Video decoder
24 * @author Alex Beregszaszi
25 * @author Benjamin Larsson
28 /* Bitstream description
29 * The picture is divided into blocks that are zlib compressed.
31 * The decoder is fed complete frames, the frameheader contains:
32 * 4bits of block width
33 * 12bits of frame width
34 * 4bits of block height
35 * 12bits of frame height
37 * Directly after the header are the compressed blocks. The blocks
38 * have their compressed size represented with 16bits in the beginnig.
39 * If the size = 0 then the block is unchanged from the previous frame.
40 * All blocks are decompressed until the buffer is consumed.
42 * Encoding ideas, a basic encoder would just use a fixed block size.
43 * Block sizes can be multipels of 16, from 16 to 256. The blocks don't
44 * have to be quadratic. A brute force search with a set of diffrent
45 * block sizes should give a better result then to just use a fixed size.
53 #include "bitstream.h"
59 typedef struct FlashSVContext
{
60 AVCodecContext
*avctx
;
62 int image_width
, image_height
;
63 int block_width
, block_height
;
72 static void copy_region(uint8_t *sptr
, uint8_t *dptr
,
73 int dx
, int dy
, int h
, int w
, int stride
)
77 for (i
= dx
+h
; i
> dx
; i
--)
79 memcpy(dptr
+(i
*stride
)+dy
*3, sptr
, w
*3);
85 static int flashsv_decode_init(AVCodecContext
*avctx
)
87 FlashSVContext
*s
= (FlashSVContext
*)avctx
->priv_data
;
88 int zret
; // Zlib return code
92 s
->zstream
.zalloc
= Z_NULL
;
93 s
->zstream
.zfree
= Z_NULL
;
94 s
->zstream
.opaque
= Z_NULL
;
95 zret
= inflateInit(&(s
->zstream
));
97 av_log(avctx
, AV_LOG_ERROR
, "Inflate init error: %d\n", zret
);
101 av_log(avctx
, AV_LOG_ERROR
, "Zlib support not compiled. Needed for the decoder.\n");
104 avctx
->pix_fmt
= PIX_FMT_BGR24
;
105 avctx
->has_b_frames
= 0;
106 s
->frame
.data
[0] = NULL
;
112 static int flashsv_decode_frame(AVCodecContext
*avctx
,
113 void *data
, int *data_size
,
114 uint8_t *buf
, int buf_size
)
116 FlashSVContext
*s
= (FlashSVContext
*)avctx
->priv_data
;
117 int h_blocks
, v_blocks
, h_part
, v_part
, i
, j
;
120 /* no supplementary picture */
125 avctx
->release_buffer(avctx
, &s
->frame
);
127 init_get_bits(&gb
, buf
, buf_size
* 8);
129 /* start to parse the bitstream */
130 s
->block_width
= 16* (get_bits(&gb
, 4)+1);
131 s
->image_width
= get_bits(&gb
,12);
132 s
->block_height
= 16* (get_bits(&gb
, 4)+1);
133 s
->image_height
= get_bits(&gb
,12);
135 /* calculate amount of blocks and the size of the border blocks */
136 h_blocks
= s
->image_width
/ s
->block_width
;
137 h_part
= s
->image_width
% s
->block_width
;
138 v_blocks
= s
->image_height
/ s
->block_height
;
139 v_part
= s
->image_height
% s
->block_height
;
141 /* the block size could change between frames, make sure the buffer
142 * is large enough, if not, get a larger one */
143 if(s
->block_size
< s
->block_width
*s
->block_height
) {
144 if (s
->tmpblock
!= NULL
)
145 av_free(s
->tmpblock
);
146 s
->block_size
= s
->block_width
*s
->block_height
;
147 if ((s
->tmpblock
= av_malloc(3*s
->block_size
)) == NULL
) {
148 av_log(avctx
, AV_LOG_ERROR
, "Can't allocate decompression buffer.\n");
153 /* init the image size once */
154 if((avctx
->width
==0) && (avctx
->height
==0)){
155 avctx
->width
= s
->image_width
;
156 avctx
->height
= s
->image_height
;
159 /* check for changes of image width and image height */
160 if ((avctx
->width
!= s
->image_width
) || (avctx
->height
!= s
->image_height
)) {
161 av_log(avctx
, AV_LOG_ERROR
, "Frame width or height differs from first frames!\n");
162 av_log(avctx
, AV_LOG_ERROR
, "fh = %d, fv %d vs ch = %d, cv = %d\n",avctx
->height
,
163 avctx
->width
,s
->image_height
,s
->image_width
);
167 av_log(avctx
, AV_LOG_DEBUG
, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
168 s
->image_width
, s
->image_height
, s
->block_width
, s
->block_height
,
169 h_blocks
, v_blocks
, h_part
, v_part
);
171 s
->frame
.reference
= 1;
172 s
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
;
173 if (avctx
->get_buffer(avctx
, &s
->frame
) < 0) {
174 av_log(s
->avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
178 /* loop over all block columns */
179 for (j
= 0; j
< v_blocks
+ (v_part
?1:0); j
++)
182 int hp
= j
*s
->block_height
; // horiz position in frame
183 int hs
= (j
<v_blocks
)?s
->block_height
:v_part
; // size of block
186 /* loop over all block rows */
187 for (i
= 0; i
< h_blocks
+ (h_part
?1:0); i
++)
189 int wp
= i
*s
->block_width
; // vert position in frame
190 int ws
= (i
<h_blocks
)?s
->block_width
:h_part
; // size of block
192 /* get the size of the compressed zlib chunk */
193 int size
= get_bits(&gb
, 16);
196 /* no change, don't do anything */
198 /* decompress block */
200 int ret
= inflateReset(&(s
->zstream
));
203 av_log(avctx
, AV_LOG_ERROR
, "error in decompression (reset) of block %dx%d\n", i
, j
);
206 s
->zstream
.next_in
= buf
+(get_bits_count(&gb
)/8);
207 s
->zstream
.avail_in
= size
;
208 s
->zstream
.next_out
= s
->tmpblock
;
209 s
->zstream
.avail_out
= s
->block_size
*3;
210 ret
= inflate(&(s
->zstream
), Z_FINISH
);
211 if (ret
== Z_DATA_ERROR
)
213 av_log(avctx
, AV_LOG_ERROR
, "Zlib resync occured\n");
214 inflateSync(&(s
->zstream
));
215 ret
= inflate(&(s
->zstream
), Z_FINISH
);
218 if ((ret
!= Z_OK
) && (ret
!= Z_STREAM_END
))
220 av_log(avctx
, AV_LOG_ERROR
, "error in decompression of block %dx%d: %d\n", i
, j
, ret
);
224 av_log(avctx
, AV_LOG_ERROR
, "Zlib support not compiled in.\n");
227 copy_region(s
->tmpblock
, s
->frame
.data
[0], s
->image_height
-(hp
+hs
+1), wp
, hs
, ws
, s
->frame
.linesize
[0]);
228 skip_bits(&gb
, 8*size
); /* skip the consumed bits */
233 *data_size
= sizeof(AVFrame
);
234 *(AVFrame
*)data
= s
->frame
;
236 if ((get_bits_count(&gb
)/8) != buf_size
)
237 av_log(avctx
, AV_LOG_ERROR
, "buffer not fully consumed (%d != %d)\n",
238 buf_size
, (get_bits_count(&gb
)/8));
240 /* report that the buffer was completely consumed */
245 static int flashsv_decode_end(AVCodecContext
*avctx
)
247 FlashSVContext
*s
= (FlashSVContext
*)avctx
->priv_data
;
249 inflateEnd(&(s
->zstream
));
251 /* release the frame if needed */
252 if (s
->frame
.data
[0])
253 avctx
->release_buffer(avctx
, &s
->frame
);
255 /* free the tmpblock */
256 if (s
->tmpblock
!= NULL
)
257 av_free(s
->tmpblock
);
263 AVCodec flashsv_decoder
= {
267 sizeof(FlashSVContext
),
271 flashsv_decode_frame
,
273 .pix_fmts
= (enum PixelFormat
[]){PIX_FMT_BGR24
, -1},