1 /*
2 * Zip Motion Blocks Video (ZMBV) encoder
3 * Copyright (c) 2006 Konstantin Shishkov
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
22 /**
23 * @file
24 * Zip Motion Blocks Video encoder
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29
34
35 #include <zlib.h>
36
37 #define ZMBV_KEYFRAME 1
38 #define ZMBV_DELTAPAL 2
39
41
42 /**
43 * Encoder context
44 */
48
52 uint32_t
pal2[256];
//for quick comparisons
59
61
62 /** Block comparing function
63 * XXX should be optimized and moved to DSPContext
64 * TODO handle out of edge ME
65 */
67 int bw, int bh, int *xored)
68 {
69 int sum = 0;
70 int i, j;
72
73 *xored = 0;
74 for(j = 0; j < bh; j++){
75 for(i = 0; i < bw; i++){
76 int t = src[i] ^ src2[i];
79 }
81 src2 += stride2;
82 }
83
84 for(i = 1; i < 256; i++)
86
87 return sum;
88 }
89
90 /** Motion estimation function
91 * TODO make better ME decisions
92 */
94 int pstride, int x, int y, int *mx, int *my, int *xored)
95 {
96 int dx, dy, tx, ty, tv, bv, bw, bh;
97
98 *mx = *my = 0;
101 bv =
block_cmp(src, sstride, prev, pstride, bw, bh, xored);
102 if(!bv) return 0;
105 if(tx == x && ty == y) continue; // we already tested this block
106 dx = tx - x;
107 dy = ty - y;
108 tv =
block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh, xored);
109 if(tv < bv){
110 bv = tv;
111 *mx = dx;
112 *my = dy;
113 if(!bv) return 0;
114 }
115 }
116 }
117 return bv;
118 }
119
121 const AVFrame *pict,
int *got_packet)
122 {
126 uint32_t *palptr;
127 int keyframe, chpal;
128 int fl;
129 int work_size = 0, pkt_size;
130 int bw, bh;
131 int i, j, ret;
132
137 *p = *pict;
140 chpal = !keyframe && memcmp(p->
data[1], c->
pal2, 1024);
141
142 palptr = (uint32_t*)p->
data[1];
145 if(chpal){
147 for(i = 0; i < 256; i++){
149 c->
work_buf[work_size++] = tpal[0] ^ c->
pal[i * 3 + 0];
150 c->
work_buf[work_size++] = tpal[1] ^ c->
pal[i * 3 + 1];
151 c->
work_buf[work_size++] = tpal[2] ^ c->
pal[i * 3 + 2];
152 c->
pal[i * 3 + 0] = tpal[0];
153 c->
pal[i * 3 + 1] = tpal[1];
154 c->
pal[i * 3 + 2] = tpal[2];
155 }
157 }
158 if(keyframe){
159 for(i = 0; i < 256; i++){
161 }
164 work_size = 768;
165 for(i = 0; i < avctx->
height; i++){
168 work_size += avctx->
width;
169 }
170 }else{
171 int x, y, bh2, bw2, xored;
174 int mx, my;
175
179 memset(c->
work_buf + work_size, 0, (bw * bh * 2 + 3) & ~3);
180 work_size += (bw * bh * 2 + 3) & ~3;
181 /* for now just XOR'ing */
186
187 tsrc = src + x;
188 tprev = prev + x;
189
191 mv[0] = (mx << 1) | !!xored;
192 mv[1] = my << 1;
194 if(xored){
195 for(j = 0; j < bh2; j++){
196 for(i = 0; i < bw2; i++)
197 c->
work_buf[work_size++] = tsrc[i] ^ tprev[i];
200 }
201 }
202 }
205 }
206 }
207 /* save the previous frame */
210 for(i = 0; i < avctx->
height; i++){
211 memcpy(prev, src, avctx->
width);
214 }
215
216 if (keyframe)
218
220 c->
zstream.avail_in = work_size;
222
226 if(deflate(&c->
zstream, Z_SYNC_FLUSH) != Z_OK){
228 return -1;
229 }
230
231 pkt_size = c->
zstream.total_out + 1 + 6*keyframe;
233 return ret;
235
237 *buf++ = fl;
238 if (keyframe) {
239 *buf++ = 0; // hi ver
240 *buf++ = 1; // lo ver
241 *buf++ = 1; // comp
242 *buf++ = 4; // format - 8bpp
245 }
247
249 *got_packet = 1;
250
251 return 0;
252 }
253
254
255 /**
256 * Init zmbv encoder
257 */
259 {
261 int zret; // Zlib return code
262 int i;
263 int lvl = 9;
264
265 for(i=1; i<256; i++)
267
269
275
278 if(lvl < 0 || lvl > 9){
281 }
282
283 // Needed if zlib unused or init aborted before deflateInit
284 memset(&c->
zstream, 0,
sizeof(z_stream));
286 ((avctx->
width + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * ((avctx->
height + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * 2 + 4;
290 }
291 /* Conservative upper bound taken from zlib v1.2.1 source via lcl.c */
294
295 /* Allocate compression buffer */
299 }
304 }
305
309 zret = deflateInit(&c->
zstream, lvl);
310 if (zret != Z_OK) {
312 return -1;
313 }
314
316
317 return 0;
318 }
319
320
321
322 /**
323 * Uninit zmbv encoder
324 */
326 {
328
331
334
335 return 0;
336 }
337
348 };