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 */
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.
62 #include "bitstream.h"
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 if (avcodec_check_dimensions(avctx
, avctx
->width
, avctx
->height
) < 0) {
115 // Needed if zlib unused or init aborted before deflateInit
116 memset(&(s
->zstream
), 0, sizeof(z_stream
));
120 s
->image_width
= avctx
->width
;
121 s
->image_height
= avctx
->height
;
123 s
->tmpblock
= av_mallocz(3*256*256);
124 s
->encbuffer
= av_mallocz(s
->image_width
*s
->image_height
*3);
126 if (!s
->tmpblock
|| !s
->encbuffer
) {
127 av_log(avctx
, AV_LOG_ERROR
, "Memory allocation failed.\n");
135 static int encode_bitstream(FlashSVContext
*s
, AVFrame
*p
, uint8_t *buf
, int buf_size
,
136 int block_width
, int block_height
, uint8_t *previous_frame
, int* I_frame
) {
139 int h_blocks
, v_blocks
, h_part
, v_part
, i
, j
;
143 init_put_bits(&pb
, buf
, buf_size
*8);
145 put_bits(&pb
, 4, (block_width
/16)-1);
146 put_bits(&pb
, 12, s
->image_width
);
147 put_bits(&pb
, 4, (block_height
/16)-1);
148 put_bits(&pb
, 12, s
->image_height
);
152 h_blocks
= s
->image_width
/ block_width
;
153 h_part
= s
->image_width
% block_width
;
154 v_blocks
= s
->image_height
/ block_height
;
155 v_part
= s
->image_height
% block_height
;
157 /* loop over all block columns */
158 for (j
= 0; j
< v_blocks
+ (v_part
?1:0); j
++)
161 int hp
= j
*block_height
; // horiz position in frame
162 int hs
= (j
<v_blocks
)?block_height
:v_part
; // size of block
164 /* loop over all block rows */
165 for (i
= 0; i
< h_blocks
+ (h_part
?1:0); i
++)
167 int wp
= i
*block_width
; // vert position in frame
168 int ws
= (i
<h_blocks
)?block_width
:h_part
; // size of block
174 //copy the block to the temp buffer before compression (if it differs from the previous frame's block)
175 res
= copy_region_enc(p
->data
[0], s
->tmpblock
, s
->image_height
-(hp
+hs
+1), wp
, hs
, ws
, p
->linesize
[0], previous_frame
);
177 if (res
|| *I_frame
) {
179 zsize
= 3*block_width
*block_height
;
180 ret
= compress2(ptr
+2, &zsize
, s
->tmpblock
, 3*ws
*hs
, 9);
183 //ret = deflateReset(&(s->zstream));
185 av_log(s
->avctx
, AV_LOG_ERROR
, "error while compressing block %dx%d\n", i
, j
);
187 bytestream_put_be16(&ptr
,(unsigned int)zsize
);
189 //av_log(avctx, AV_LOG_ERROR, "buf_pos = %d\n", buf_pos);
192 bytestream_put_be16(&ptr
,0);
207 static int flashsv_encode_frame(AVCodecContext
*avctx
, uint8_t *buf
, int buf_size
, void *data
)
209 FlashSVContext
* const s
= avctx
->priv_data
;
210 AVFrame
*pict
= data
;
211 AVFrame
* const p
= &s
->frame
;
219 /* First frame needs to be a keyframe */
220 if (avctx
->frame_number
== 0) {
221 s
->previous_frame
= av_mallocz(FFABS(p
->linesize
[0])*s
->image_height
);
222 if (!s
->previous_frame
) {
223 av_log(avctx
, AV_LOG_ERROR
, "Memory allocation failed.\n");
229 if (p
->linesize
[0] < 0)
230 pfptr
= s
->previous_frame
- ((s
->image_height
-1) * p
->linesize
[0]);
232 pfptr
= s
->previous_frame
;
234 /* Check the placement of keyframes */
235 if (avctx
->gop_size
> 0) {
236 if (avctx
->frame_number
>= s
->last_key_frame
+ avctx
->gop_size
) {
244 if (buf_size
< s
->image_width
*s
->image_height
*3) {
245 //Conservative upper bound check for compressed data
246 av_log(avctx
, AV_LOG_ERROR
, "buf_size %d < %d\n", buf_size
, s
->image_width
*s
->image_height
*3);
250 res
= encode_bitstream(s
, p
, buf
, buf_size
, opt_w
*16, opt_h
*16, pfptr
, &I_frame
);
252 //save the current frame
253 if(p
->linesize
[0] > 0)
254 memcpy(s
->previous_frame
, p
->data
[0], s
->image_height
*p
->linesize
[0]);
256 memcpy(s
->previous_frame
, p
->data
[0] + p
->linesize
[0] * (s
->image_height
-1), s
->image_height
*FFABS(p
->linesize
[0]));
258 //mark the frame type so the muxer can mux it correctly
260 p
->pict_type
= FF_I_TYPE
;
262 s
->last_key_frame
= avctx
->frame_number
;
263 av_log(avctx
, AV_LOG_DEBUG
, "Inserting key frame at frame %d\n",avctx
->frame_number
);
265 p
->pict_type
= FF_P_TYPE
;
269 avctx
->coded_frame
= p
;
274 static av_cold
int flashsv_encode_end(AVCodecContext
*avctx
)
276 FlashSVContext
*s
= avctx
->priv_data
;
278 deflateEnd(&(s
->zstream
));
280 av_free(s
->encbuffer
);
281 av_free(s
->previous_frame
);
282 av_free(s
->tmpblock
);
287 AVCodec flashsv_encoder
= {
291 sizeof(FlashSVContext
),
293 flashsv_encode_frame
,
295 .pix_fmts
= (enum PixelFormat
[]){PIX_FMT_BGR24
, PIX_FMT_NONE
},
296 .long_name
= NULL_IF_CONFIG_SMALL("Flash Screen Video"),