2 * Flash Screen Video encoder
3 * Copyright (C) 2004 Alex Beregszaszi
4 * Copyright (C) 2006 Benjamin Larsson
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 /* Encoding development sponsored by http://fh-campuswien.ac.at */
26 * @file libavcodec/flashsvenc.c
27 * Flash Screen Video encoder
28 * @author Alex Beregszaszi
29 * @author Benjamin Larsson
32 /* Bitstream description
33 * The picture is divided into blocks that are zlib-compressed.
35 * The decoder is fed complete frames, the frameheader contains:
36 * 4bits of block width
37 * 12bits of frame width
38 * 4bits of block height
39 * 12bits of frame height
41 * Directly after the header are the compressed blocks. The blocks
42 * have their compressed size represented with 16bits in the beginig.
43 * If the size = 0 then the block is unchanged from the previous frame.
44 * All blocks are decompressed until the buffer is consumed.
46 * Encoding ideas, a basic encoder would just use a fixed block size.
47 * Block sizes can be multipels of 16, from 16 to 256. The blocks don't
48 * have to be quadratic. A brute force search with a set of different
49 * block sizes should give a better result than to just use a fixed size.
53 * Don't reencode the frame in brute force mode if the frame is a dupe. Speed up.
54 * Make the difference check faster.
63 #include "bytestream.h"
66 typedef struct FlashSVContext
{
67 AVCodecContext
*avctx
;
68 uint8_t *previous_frame
;
70 int image_width
, image_height
;
71 int block_width
, block_height
;
79 static int copy_region_enc(uint8_t *sptr
, uint8_t *dptr
,
80 int dx
, int dy
, int h
, int w
, int stride
, uint8_t *pfptr
) {
86 for (i
= dx
+h
; i
> dx
; i
--) {
87 nsptr
= sptr
+(i
*stride
)+dy
*3;
88 npfptr
= pfptr
+(i
*stride
)+dy
*3;
89 for (j
=0 ; j
<w
*3 ; j
++) {
90 diff
|=npfptr
[j
]^nsptr
[j
];
100 static av_cold
int flashsv_encode_init(AVCodecContext
*avctx
)
102 FlashSVContext
*s
= avctx
->priv_data
;
106 if ((avctx
->width
> 4095) || (avctx
->height
> 4095)) {
107 av_log(avctx
, AV_LOG_ERROR
, "Input dimensions too large, input must be max 4096x4096 !\n");
111 // Needed if zlib unused or init aborted before deflateInit
112 memset(&(s
->zstream
), 0, sizeof(z_stream
));
116 s
->image_width
= avctx
->width
;
117 s
->image_height
= avctx
->height
;
119 s
->tmpblock
= av_mallocz(3*256*256);
120 s
->encbuffer
= av_mallocz(s
->image_width
*s
->image_height
*3);
122 if (!s
->tmpblock
|| !s
->encbuffer
) {
123 av_log(avctx
, AV_LOG_ERROR
, "Memory allocation failed.\n");
131 static int encode_bitstream(FlashSVContext
*s
, AVFrame
*p
, uint8_t *buf
, int buf_size
,
132 int block_width
, int block_height
, uint8_t *previous_frame
, int* I_frame
) {
135 int h_blocks
, v_blocks
, h_part
, v_part
, i
, j
;
139 init_put_bits(&pb
, buf
, buf_size
*8);
141 put_bits(&pb
, 4, (block_width
/16)-1);
142 put_bits(&pb
, 12, s
->image_width
);
143 put_bits(&pb
, 4, (block_height
/16)-1);
144 put_bits(&pb
, 12, s
->image_height
);
148 h_blocks
= s
->image_width
/ block_width
;
149 h_part
= s
->image_width
% block_width
;
150 v_blocks
= s
->image_height
/ block_height
;
151 v_part
= s
->image_height
% block_height
;
153 /* loop over all block columns */
154 for (j
= 0; j
< v_blocks
+ (v_part
?1:0); j
++)
157 int hp
= j
*block_height
; // horiz position in frame
158 int hs
= (j
<v_blocks
)?block_height
:v_part
; // size of block
160 /* loop over all block rows */
161 for (i
= 0; i
< h_blocks
+ (h_part
?1:0); i
++)
163 int wp
= i
*block_width
; // vert position in frame
164 int ws
= (i
<h_blocks
)?block_width
:h_part
; // size of block
170 //copy the block to the temp buffer before compression (if it differs from the previous frame's block)
171 res
= copy_region_enc(p
->data
[0], s
->tmpblock
, s
->image_height
-(hp
+hs
+1), wp
, hs
, ws
, p
->linesize
[0], previous_frame
);
173 if (res
|| *I_frame
) {
175 zsize
= 3*block_width
*block_height
;
176 ret
= compress2(ptr
+2, &zsize
, s
->tmpblock
, 3*ws
*hs
, 9);
179 //ret = deflateReset(&(s->zstream));
181 av_log(s
->avctx
, AV_LOG_ERROR
, "error while compressing block %dx%d\n", i
, j
);
183 bytestream_put_be16(&ptr
,(unsigned int)zsize
);
185 //av_log(avctx, AV_LOG_ERROR, "buf_pos = %d\n", buf_pos);
188 bytestream_put_be16(&ptr
,0);
203 static int flashsv_encode_frame(AVCodecContext
*avctx
, uint8_t *buf
, int buf_size
, void *data
)
205 FlashSVContext
* const s
= avctx
->priv_data
;
206 AVFrame
*pict
= data
;
207 AVFrame
* const p
= &s
->frame
;
215 /* First frame needs to be a keyframe */
216 if (avctx
->frame_number
== 0) {
217 s
->previous_frame
= av_mallocz(FFABS(p
->linesize
[0])*s
->image_height
);
218 if (!s
->previous_frame
) {
219 av_log(avctx
, AV_LOG_ERROR
, "Memory allocation failed.\n");
225 if (p
->linesize
[0] < 0)
226 pfptr
= s
->previous_frame
- ((s
->image_height
-1) * p
->linesize
[0]);
228 pfptr
= s
->previous_frame
;
230 /* Check the placement of keyframes */
231 if (avctx
->gop_size
> 0) {
232 if (avctx
->frame_number
>= s
->last_key_frame
+ avctx
->gop_size
) {
240 if (buf_size
< s
->image_width
*s
->image_height
*3) {
241 //Conservative upper bound check for compressed data
242 av_log(avctx
, AV_LOG_ERROR
, "buf_size %d < %d\n", buf_size
, s
->image_width
*s
->image_height
*3);
246 res
= encode_bitstream(s
, p
, buf
, buf_size
, opt_w
*16, opt_h
*16, pfptr
, &I_frame
);
248 //save the current frame
249 if(p
->linesize
[0] > 0)
250 memcpy(s
->previous_frame
, p
->data
[0], s
->image_height
*p
->linesize
[0]);
252 memcpy(s
->previous_frame
, p
->data
[0] + p
->linesize
[0] * (s
->image_height
-1), s
->image_height
*FFABS(p
->linesize
[0]));
254 //mark the frame type so the muxer can mux it correctly
256 p
->pict_type
= FF_I_TYPE
;
258 s
->last_key_frame
= avctx
->frame_number
;
259 av_log(avctx
, AV_LOG_DEBUG
, "Inserting key frame at frame %d\n",avctx
->frame_number
);
261 p
->pict_type
= FF_P_TYPE
;
265 avctx
->coded_frame
= p
;
270 static av_cold
int flashsv_encode_end(AVCodecContext
*avctx
)
272 FlashSVContext
*s
= avctx
->priv_data
;
274 deflateEnd(&(s
->zstream
));
276 av_free(s
->encbuffer
);
277 av_free(s
->previous_frame
);
278 av_free(s
->tmpblock
);
283 AVCodec flashsv_encoder
= {
287 sizeof(FlashSVContext
),
289 flashsv_encode_frame
,
291 .pix_fmts
= (const enum PixelFormat
[]){PIX_FMT_BGR24
, PIX_FMT_NONE
},
292 .long_name
= NULL_IF_CONFIG_SMALL("Flash Screen Video"),