2 * Zip Motion Blocks Video (ZMBV) encoder
3 * Copyright (c) 2006 Konstantin Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * Zip Motion Blocks Video encoder
34 #define ZMBV_KEYFRAME 1
35 #define ZMBV_DELTAPAL 2
42 typedef struct ZmbvEncContext
{
43 AVCodecContext
*avctx
;
47 uint8_t *comp_buf
, *work_buf
;
49 uint32_t pal2
[256]; //for quick comparisons
57 /** Block comparing function
58 * XXX should be optimized and moved to DSPContext
59 * TODO handle out of edge ME
61 static inline int block_cmp(uint8_t *src
, int stride
, uint8_t *src2
, int stride2
, int bw
, int bh
)
66 for(j
= 0; j
< bh
; j
++){
67 for(i
= 0; i
< bw
; i
++)
68 sum
+= src
[i
] ^ src2
[i
];
75 /** Motion estimation function
76 * TODO make better ME decisions
78 static int zmbv_me(ZmbvEncContext
*c
, uint8_t *src
, int sstride
, uint8_t *prev
, int pstride
,
79 int x
, int y
, int *mx
, int *my
)
81 int dx
, dy
, tx
, ty
, tv
, bv
, bw
, bh
;
84 bw
= FFMIN(ZMBV_BLOCK
, c
->avctx
->width
- x
);
85 bh
= FFMIN(ZMBV_BLOCK
, c
->avctx
->height
- y
);
86 bv
= block_cmp(src
, sstride
, prev
, pstride
, bw
, bh
);
88 for(ty
= FFMAX(y
- c
->range
, 0); ty
< FFMIN(y
+ c
->range
, c
->avctx
->height
- bh
); ty
++){
89 for(tx
= FFMAX(x
- c
->range
, 0); tx
< FFMIN(x
+ c
->range
, c
->avctx
->width
- bw
); tx
++){
90 if(tx
== x
&& ty
== y
) continue; // we already tested this block
93 tv
= block_cmp(src
, sstride
, prev
+ dx
+ dy
*pstride
, pstride
, bw
, bh
);
105 static int encode_frame(AVCodecContext
*avctx
, uint8_t *buf
, int buf_size
, void *data
)
107 ZmbvEncContext
* const c
= avctx
->priv_data
;
108 AVFrame
*pict
= data
;
109 AVFrame
* const p
= &c
->pic
;
120 keyframe
= !c
->curfrm
;
122 if(c
->curfrm
== c
->keyint
)
125 p
->pict_type
= keyframe
? FF_I_TYPE
: FF_P_TYPE
;
126 p
->key_frame
= keyframe
;
127 chpal
= !keyframe
&& memcmp(p
->data
[1], c
->pal2
, 1024);
129 fl
= (keyframe
? ZMBV_KEYFRAME
: 0) | (chpal
? ZMBV_DELTAPAL
: 0);
132 deflateReset(&c
->zstream
);
133 *buf
++ = 0; len
++; // hi ver
134 *buf
++ = 1; len
++; // lo ver
135 *buf
++ = 1; len
++; // comp
136 *buf
++ = 4; len
++; // format - 8bpp
137 *buf
++ = ZMBV_BLOCK
; len
++; // block width
138 *buf
++ = ZMBV_BLOCK
; len
++; // block height
140 palptr
= (uint32_t*)p
->data
[1];
145 for(i
= 0; i
< 256; i
++){
146 AV_WB24(tpal
, palptr
[i
]);
147 c
->work_buf
[work_size
++] = tpal
[0] ^ c
->pal
[i
* 3 + 0];
148 c
->work_buf
[work_size
++] = tpal
[1] ^ c
->pal
[i
* 3 + 1];
149 c
->work_buf
[work_size
++] = tpal
[2] ^ c
->pal
[i
* 3 + 2];
150 c
->pal
[i
* 3 + 0] = tpal
[0];
151 c
->pal
[i
* 3 + 1] = tpal
[1];
152 c
->pal
[i
* 3 + 2] = tpal
[2];
154 memcpy(c
->pal2
, p
->data
[1], 1024);
157 for(i
= 0; i
< 256; i
++){
158 AV_WB24(c
->pal
+(i
*3), palptr
[i
]);
160 memcpy(c
->work_buf
, c
->pal
, 768);
161 memcpy(c
->pal2
, p
->data
[1], 1024);
163 for(i
= 0; i
< avctx
->height
; i
++){
164 memcpy(c
->work_buf
+ work_size
, src
, avctx
->width
);
165 src
+= p
->linesize
[0];
166 work_size
+= avctx
->width
;
170 uint8_t *tsrc
, *tprev
;
174 bw
= (avctx
->width
+ ZMBV_BLOCK
- 1) / ZMBV_BLOCK
;
175 bh
= (avctx
->height
+ ZMBV_BLOCK
- 1) / ZMBV_BLOCK
;
176 mv
= c
->work_buf
+ work_size
;
177 memset(c
->work_buf
+ work_size
, 0, (bw
* bh
* 2 + 3) & ~3);
178 work_size
+= (bw
* bh
* 2 + 3) & ~3;
179 /* for now just XOR'ing */
180 for(y
= 0; y
< avctx
->height
; y
+= ZMBV_BLOCK
) {
181 bh2
= FFMIN(avctx
->height
- y
, ZMBV_BLOCK
);
182 for(x
= 0; x
< avctx
->width
; x
+= ZMBV_BLOCK
, mv
+= 2) {
183 bw2
= FFMIN(avctx
->width
- x
, ZMBV_BLOCK
);
188 bv
= zmbv_me(c
, tsrc
, p
->linesize
[0], tprev
, c
->pstride
, x
, y
, &mx
, &my
);
189 mv
[0] = (mx
<< 1) | !!bv
;
191 tprev
+= mx
+ my
* c
->pstride
;
193 for(j
= 0; j
< bh2
; j
++){
194 for(i
= 0; i
< bw2
; i
++)
195 c
->work_buf
[work_size
++] = tsrc
[i
] ^ tprev
[i
];
196 tsrc
+= p
->linesize
[0];
201 src
+= p
->linesize
[0] * ZMBV_BLOCK
;
202 prev
+= c
->pstride
* ZMBV_BLOCK
;
205 /* save the previous frame */
208 for(i
= 0; i
< avctx
->height
; i
++){
209 memcpy(prev
, src
, avctx
->width
);
211 src
+= p
->linesize
[0];
214 c
->zstream
.next_in
= c
->work_buf
;
215 c
->zstream
.avail_in
= work_size
;
216 c
->zstream
.total_in
= 0;
218 c
->zstream
.next_out
= c
->comp_buf
;
219 c
->zstream
.avail_out
= c
->comp_size
;
220 c
->zstream
.total_out
= 0;
221 if((zret
= deflate(&c
->zstream
, Z_SYNC_FLUSH
)) != Z_OK
){
222 av_log(avctx
, AV_LOG_ERROR
, "Error compressing data\n");
226 memcpy(buf
, c
->comp_buf
, c
->zstream
.total_out
);
227 return len
+ c
->zstream
.total_out
;
234 static int encode_init(AVCodecContext
*avctx
)
236 ZmbvEncContext
* const c
= avctx
->priv_data
;
237 int zret
; // Zlib return code
242 c
->pic
.data
[0] = NULL
;
244 c
->keyint
= avctx
->keyint_min
;
246 if(avctx
->me_range
> 0)
247 c
->range
= FFMIN(avctx
->me_range
, 127);
249 if(avctx
->compression_level
>= 0)
250 lvl
= avctx
->compression_level
;
251 if(lvl
< 0 || lvl
> 9){
252 av_log(avctx
, AV_LOG_ERROR
, "Compression level should be 0-9, not %i\n", lvl
);
256 if (avcodec_check_dimensions(avctx
, avctx
->width
, avctx
->height
) < 0) {
260 // Needed if zlib unused or init aborted before deflateInit
261 memset(&(c
->zstream
), 0, sizeof(z_stream
));
262 c
->comp_size
= avctx
->width
* avctx
->height
+ 1024 +
263 ((avctx
->width
+ ZMBV_BLOCK
- 1) / ZMBV_BLOCK
) * ((avctx
->height
+ ZMBV_BLOCK
- 1) / ZMBV_BLOCK
) * 2 + 4;
264 if ((c
->work_buf
= av_malloc(c
->comp_size
)) == NULL
) {
265 av_log(avctx
, AV_LOG_ERROR
, "Can't allocate work buffer.\n");
268 /* Conservative upper bound taken from zlib v1.2.1 source via lcl.c */
269 c
->comp_size
= c
->comp_size
+ ((c
->comp_size
+ 7) >> 3) +
270 ((c
->comp_size
+ 63) >> 6) + 11;
272 /* Allocate compression buffer */
273 if ((c
->comp_buf
= av_malloc(c
->comp_size
)) == NULL
) {
274 av_log(avctx
, AV_LOG_ERROR
, "Can't allocate compression buffer.\n");
277 c
->pstride
= (avctx
->width
+ 15) & ~15;
278 if ((c
->prev
= av_malloc(c
->pstride
* avctx
->height
)) == NULL
) {
279 av_log(avctx
, AV_LOG_ERROR
, "Can't allocate picture.\n");
283 c
->zstream
.zalloc
= Z_NULL
;
284 c
->zstream
.zfree
= Z_NULL
;
285 c
->zstream
.opaque
= Z_NULL
;
286 zret
= deflateInit(&(c
->zstream
), lvl
);
288 av_log(avctx
, AV_LOG_ERROR
, "Inflate init error: %d\n", zret
);
298 * Uninit zmbv encoder
300 static int encode_end(AVCodecContext
*avctx
)
302 ZmbvEncContext
* const c
= avctx
->priv_data
;
304 av_freep(&c
->comp_buf
);
305 av_freep(&c
->work_buf
);
307 deflateEnd(&(c
->zstream
));
313 AVCodec zmbv_encoder
= {
317 sizeof(ZmbvEncContext
),
321 .pix_fmts
= (enum PixelFormat
[]){PIX_FMT_PAL8
, -1},