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 */
47
51 uint32_t
pal2[256];
//for quick comparisons
57
60
61
62 /** Block comparing function
63 * XXX should be optimized and moved to DSPContext
64 * TODO handle out of edge ME
65 */
67 uint8_t *src2,
int stride2,
int bw,
int bh,
68 int *xored)
69 {
70 int sum = 0;
71 int i, j;
73
74 *xored = 0;
75 for(j = 0; j < bh; j++){
76 for(i = 0; i < bw; i++){
77 int t = src[i] ^ src2[i];
78 histogram[t]++;
79 *xored |= t;
80 }
82 src2 += stride2;
83 }
84
85 for(i = 1; i < 256; i++)
87
88 return sum;
89 }
90
91 /** Motion estimation function
92 * TODO make better ME decisions
93 */
95 int pstride, int x, int y, int *mx, int *my, int *xored)
96 {
97 int dx, dy, tx, ty, tv, bv, bw, bh;
98
99 *mx = *my = 0;
102 bv =
block_cmp(c, src, sstride, prev, pstride, bw, bh, xored);
103 if(!bv) return 0;
106 if(tx == x && ty == y) continue; // we already tested this block
107 dx = tx - x;
108 dy = ty - y;
109 tv =
block_cmp(c, src, sstride, prev + dx + dy * pstride, pstride, bw, bh, xored);
110 if(tv < bv){
111 bv = tv;
112 *mx = dx;
113 *my = dy;
114 if(!bv) return 0;
115 }
116 }
117 }
118 return bv;
119 }
120
122 const AVFrame *pict,
int *got_packet)
123 {
125 const AVFrame *
const p = pict;
127 uint32_t *palptr;
128 int keyframe, chpal;
129 int fl;
130 int work_size = 0, pkt_size;
131 int bw, bh;
132 int i, j, ret;
133
138 #if FF_API_CODED_FRAME
143 #endif
144 chpal = !keyframe && memcmp(p->
data[1], c->
pal2, 1024);
145
146 palptr = (uint32_t*)p->
data[1];
149 if(chpal){
151 for(i = 0; i < 256; i++){
153 c->
work_buf[work_size++] = tpal[0] ^ c->
pal[i * 3 + 0];
154 c->
work_buf[work_size++] = tpal[1] ^ c->
pal[i * 3 + 1];
155 c->
work_buf[work_size++] = tpal[2] ^ c->
pal[i * 3 + 2];
156 c->
pal[i * 3 + 0] = tpal[0];
157 c->
pal[i * 3 + 1] = tpal[1];
158 c->
pal[i * 3 + 2] = tpal[2];
159 }
161 }
162 if(keyframe){
163 for(i = 0; i < 256; i++){
165 }
168 work_size = 768;
169 for(i = 0; i < avctx->
height; i++){
172 work_size += avctx->
width;
173 }
174 }else{
175 int x, y, bh2, bw2, xored;
178 int mx, my;
179
183 memset(c->
work_buf + work_size, 0, (bw * bh * 2 + 3) & ~3);
184 work_size += (bw * bh * 2 + 3) & ~3;
185 /* for now just XOR'ing */
190
191 tsrc = src + x;
192 tprev = prev + x;
193
195 mv[0] = (mx << 1) | !!xored;
196 mv[1] = my << 1;
198 if(xored){
199 for(j = 0; j < bh2; j++){
200 for(i = 0; i < bw2; i++)
201 c->
work_buf[work_size++] = tsrc[i] ^ tprev[i];
204 }
205 }
206 }
209 }
210 }
211 /* save the previous frame */
214 for(i = 0; i < avctx->
height; i++){
215 memcpy(prev, src, avctx->
width);
218 }
219
220 if (keyframe)
222
224 c->
zstream.avail_in = work_size;
226
232 return -1;
233 }
234
235 pkt_size = c->
zstream.total_out + 1 + 6*keyframe;
237 return ret;
239
241 *buf++ = fl;
242 if (keyframe) {
243 *buf++ = 0; // hi ver
244 *buf++ = 1; // lo ver
245 *buf++ = 1; // comp
246 *buf++ = 4; // format - 8bpp
249 }
251
253 *got_packet = 1;
254
255 return 0;
256 }
257
259 {
261
264
267
268 return 0;
269 }
270
271 /**
272 * Init zmbv encoder
273 */
275 {
277 int zret; // Zlib return code
278 int i;
279 int lvl = 9;
280
281 for(i=1; i<256; i++)
283
285
291
294 if(lvl < 0 || lvl > 9){
297 }
298
299 // Needed if zlib unused or init aborted before deflateInit
300 memset(&c->
zstream, 0,
sizeof(z_stream));
302 ((avctx->
width + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * ((avctx->
height + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * 2 + 4;
306 }
307 /* Conservative upper bound taken from zlib v1.2.1 source via lcl.c */
310
311 /* Allocate compression buffer */
315 }
320 }
321
325 zret = deflateInit(&c->
zstream, lvl);
326 if (zret != Z_OK) {
328 return -1;
329 }
330
331 return 0;
332 }
333
344 };
This structure describes decoded (raw) audio or video data.
static av_cold int init(AVCodecContext *avctx)
static av_cold int encode_end(AVCodecContext *avctx)
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
8 bits with AV_PIX_FMT_RGB32 palette
int me_range
maximum motion estimation search range in subpel units If 0 then no limit.
static void deflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_cold int encode_init(AVCodecContext *avctx)
Init zmbv encoder.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
const char * name
Name of the codec implementation.
int flags
A combination of AV_PKT_FLAG values.
enum AVPictureType pict_type
Picture type of the frame.
int width
picture width / height.
static const int8_t mv[256][2]
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, int pstride, int x, int y, int *mx, int *my, int *xored)
Motion estimation function TODO make better ME decisions.
main external API structure.
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
static enum AVPixelFormat pix_fmts[]
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
GLint GLenum GLboolean GLsizei stride
#define FF_DISABLE_DEPRECATION_WARNINGS
common internal api header.
common internal and external API header
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
#define FF_ENABLE_DEPRECATION_WARNINGS
int key_frame
1 -> keyframe, 0-> not
static int block_cmp(ZmbvEncContext *c, uint8_t *src, int stride, uint8_t *src2, int stride2, int bw, int bh, int *xored)
Block comparing function XXX should be optimized and moved to DSPContext TODO handle out of edge ME...
AVPixelFormat
Pixel format.
This structure stores compressed data.
int keyint_min
minimum GOP size