comparison roqvideo.c @ 5078:4f36b52179d1 libavcodec

cosmetics and function rename patch by Vitor ken1001 gmail com | sed -e s/ken/vitor/ reference thread: subject: [FFmpeg-devel] [PATCH] RoQ video encoder, take 2 date: 05/27/2007 12:21 PM
author benoit
date Tue, 29 May 2007 12:20:40 +0000
parents 6166fbf375cc
children e72265f4e518
comparison
equal deleted inserted replaced
5077:cf6608b00186 5078:4f36b52179d1
34 #include "avcodec.h" 34 #include "avcodec.h"
35 #include "bytestream.h" 35 #include "bytestream.h"
36 #include "dsputil.h" 36 #include "dsputil.h"
37 37
38 typedef struct { 38 typedef struct {
39 unsigned char y0, y1, y2, y3, u, v; 39 unsigned char y[4];
40 unsigned char u, v;
40 } roq_cell; 41 } roq_cell;
41 42
42 typedef struct { 43 typedef struct {
43 int idx[4]; 44 int idx[4];
44 } roq_qcell; 45 } roq_qcell;
45 46
46 static int uiclip[1024], *uiclp; /* clipping table */ 47 #define avg2(a,b) av_clip_uint8(((int)(a)+(int)(b)+1)>>1)
47 #define avg2(a,b) uiclp[(((int)(a)+(int)(b)+1)>>1)] 48 #define avg4(a,b,c,d) av_clip_uint8(((int)(a)+(int)(b)+(int)(c)+(int)(d)+2)>>2)
48 #define avg4(a,b,c,d) uiclp[(((int)(a)+(int)(b)+(int)(c)+(int)(d)+2)>>2)]
49 49
50 typedef struct RoqContext { 50 typedef struct RoqContext {
51 51
52 AVCodecContext *avctx; 52 AVCodecContext *avctx;
53 DSPContext dsp; 53 DSPContext dsp;
78 #define RoQ_ID_CCC 0x03 78 #define RoQ_ID_CCC 0x03
79 79
80 #define get_byte(in_buffer) *(in_buffer++) 80 #define get_byte(in_buffer) *(in_buffer++)
81 81
82 82
83 static void apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) 83 void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell)
84 { 84 {
85 unsigned char *yptr; 85 unsigned char *yptr;
86 86
87 yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x; 87 yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
88 *yptr++ = cell->y0; 88 *yptr++ = cell->y[0];
89 *yptr++ = cell->y1; 89 *yptr++ = cell->y[1];
90 yptr += (ri->y_stride - 2); 90 yptr += (ri->y_stride - 2);
91 *yptr++ = cell->y2; 91 *yptr++ = cell->y[2];
92 *yptr++ = cell->y3; 92 *yptr++ = cell->y[3];
93 ri->current_frame->data[1][(y/2) * (ri->c_stride) + x/2] = cell->u; 93 ri->current_frame->data[1][(y/2) * (ri->c_stride) + x/2] = cell->u;
94 ri->current_frame->data[2][(y/2) * (ri->c_stride) + x/2] = cell->v; 94 ri->current_frame->data[2][(y/2) * (ri->c_stride) + x/2] = cell->v;
95 } 95 }
96 96
97 static void apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) 97 void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
98 { 98 {
99 unsigned long row_inc, c_row_inc; 99 unsigned long row_inc, c_row_inc;
100 register unsigned char y0, y1, u, v; 100 register unsigned char y0, y1, u, v;
101 unsigned char *yptr, *uptr, *vptr; 101 unsigned char *yptr, *uptr, *vptr;
102 102
104 uptr = ri->current_frame->data[1] + (y/2) * (ri->c_stride) + x/2; 104 uptr = ri->current_frame->data[1] + (y/2) * (ri->c_stride) + x/2;
105 vptr = ri->current_frame->data[2] + (y/2) * (ri->c_stride) + x/2; 105 vptr = ri->current_frame->data[2] + (y/2) * (ri->c_stride) + x/2;
106 106
107 row_inc = ri->y_stride - 4; 107 row_inc = ri->y_stride - 4;
108 c_row_inc = (ri->c_stride) - 2; 108 c_row_inc = (ri->c_stride) - 2;
109 *yptr++ = y0 = cell->y0; *uptr++ = u = cell->u; *vptr++ = v = cell->v; 109 *yptr++ = y0 = cell->y[0]; *uptr++ = u = cell->u; *vptr++ = v = cell->v;
110 *yptr++ = y0; 110 *yptr++ = y0;
111 *yptr++ = y1 = cell->y1; *uptr++ = u; *vptr++ = v; 111 *yptr++ = y1 = cell->y[1]; *uptr++ = u; *vptr++ = v;
112 *yptr++ = y1; 112 *yptr++ = y1;
113 113
114 yptr += row_inc; 114 yptr += row_inc;
115 115
116 *yptr++ = y0; 116 *yptr++ = y0;
118 *yptr++ = y1; 118 *yptr++ = y1;
119 *yptr++ = y1; 119 *yptr++ = y1;
120 120
121 yptr += row_inc; uptr += c_row_inc; vptr += c_row_inc; 121 yptr += row_inc; uptr += c_row_inc; vptr += c_row_inc;
122 122
123 *yptr++ = y0 = cell->y2; *uptr++ = u; *vptr++ = v; 123 *yptr++ = y0 = cell->y[2]; *uptr++ = u; *vptr++ = v;
124 *yptr++ = y0; 124 *yptr++ = y0;
125 *yptr++ = y1 = cell->y3; *uptr++ = u; *vptr++ = v; 125 *yptr++ = y1 = cell->y[3]; *uptr++ = u; *vptr++ = v;
126 *yptr++ = y1; 126 *yptr++ = y1;
127 127
128 yptr += row_inc; 128 yptr += row_inc;
129 129
130 *yptr++ = y0; 130 *yptr++ = y0;
131 *yptr++ = y0; 131 *yptr++ = y0;
132 *yptr++ = y1; 132 *yptr++ = y1;
133 *yptr++ = y1; 133 *yptr++ = y1;
134 } 134 }
135 135
136 static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv, 136 void ff_apply_motion_4x4(RoqContext *ri, int x, int y,
137 signed char mean_x, signed char mean_y) 137 int deltax, int deltay)
138 { 138 {
139 int i, hw, mx, my; 139 int i, hw, mx, my;
140 unsigned char *pa, *pb; 140 unsigned char *pa, *pb;
141 141
142 mx = x + 8 - (mv >> 4) - mean_x; 142 mx = x + deltax;
143 my = y + 8 - (mv & 0xf) - mean_y; 143 my = y + deltay;
144 144
145 /* check MV against frame boundaries */ 145 /* check MV against frame boundaries */
146 if ((mx < 0) || (mx > ri->avctx->width - 4) || 146 if ((mx < 0) || (mx > ri->avctx->width - 4) ||
147 (my < 0) || (my > ri->avctx->height - 4)) { 147 (my < 0) || (my > ri->avctx->height - 4)) {
148 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", 148 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
200 pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2; 200 pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
201 pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; 201 pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
202 } 202 }
203 } 203 }
204 204
205 static void apply_motion_8x8(RoqContext *ri, int x, int y, 205 void ff_apply_motion_8x8(RoqContext *ri, int x, int y,
206 unsigned char mv, signed char mean_x, signed char mean_y) 206 int deltax, int deltay)
207 { 207 {
208 int mx, my, i, j, hw; 208 int mx, my, i, j, hw;
209 unsigned char *pa, *pb; 209 unsigned char *pa, *pb;
210 210
211 mx = x + 8 - (mv >> 4) - mean_x; 211 mx = x + deltax;
212 my = y + 8 - (mv & 0xf) - mean_y; 212 my = y + deltay;
213 213
214 /* check MV against frame boundaries */ 214 /* check MV against frame boundaries */
215 if ((mx < 0) || (mx > ri->avctx->width - 8) || 215 if ((mx < 0) || (mx > ri->avctx->width - 8) ||
216 (my < 0) || (my > ri->avctx->height - 8)) { 216 (my < 0) || (my > ri->avctx->height - 8)) {
217 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", 217 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
281 static void roqvideo_decode_frame(RoqContext *ri) 281 static void roqvideo_decode_frame(RoqContext *ri)
282 { 282 {
283 unsigned int chunk_id = 0, chunk_arg = 0; 283 unsigned int chunk_id = 0, chunk_arg = 0;
284 unsigned long chunk_size = 0; 284 unsigned long chunk_size = 0;
285 int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; 285 int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1;
286 int vqid, bpos, xpos, ypos, xp, yp, x, y; 286 int vqid, bpos, xpos, ypos, xp, yp, x, y, mx, my;
287 int frame_stats[2][4] = {{0},{0}}; 287 int frame_stats[2][4] = {{0},{0}};
288 roq_qcell *qcell; 288 roq_qcell *qcell;
289 unsigned char *buf = ri->buf; 289 unsigned char *buf = ri->buf;
290 unsigned char *buf_end = ri->buf + ri->size; 290 unsigned char *buf_end = ri->buf + ri->size;
291 291
300 if((nv1 = chunk_arg >> 8) == 0) 300 if((nv1 = chunk_arg >> 8) == 0)
301 nv1 = 256; 301 nv1 = 256;
302 if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) 302 if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size)
303 nv2 = 256; 303 nv2 = 256;
304 for(i = 0; i < nv1; i++) { 304 for(i = 0; i < nv1; i++) {
305 ri->cells[i].y0 = get_byte(buf); 305 ri->cells[i].y[0] = get_byte(buf);
306 ri->cells[i].y1 = get_byte(buf); 306 ri->cells[i].y[1] = get_byte(buf);
307 ri->cells[i].y2 = get_byte(buf); 307 ri->cells[i].y[2] = get_byte(buf);
308 ri->cells[i].y3 = get_byte(buf); 308 ri->cells[i].y[3] = get_byte(buf);
309 ri->cells[i].u = get_byte(buf); 309 ri->cells[i].u = get_byte(buf);
310 ri->cells[i].v = get_byte(buf); 310 ri->cells[i].v = get_byte(buf);
311 } 311 }
312 for(i = 0; i < nv2; i++) 312 for(i = 0; i < nv2; i++)
313 for(j = 0; j < 4; j++) 313 for(j = 0; j < 4; j++)
327 frame_stats[0][vqid]++; 327 frame_stats[0][vqid]++;
328 vqflg_pos--; 328 vqflg_pos--;
329 329
330 switch(vqid) { 330 switch(vqid) {
331 case RoQ_ID_MOT: 331 case RoQ_ID_MOT:
332 apply_motion_8x8(ri, xp, yp, 0, 8, 8); 332 ff_apply_motion_8x8(ri, xp, yp, 0, 0);
333 break; 333 break;
334 case RoQ_ID_FCC: 334 case RoQ_ID_FCC:
335 apply_motion_8x8(ri, xp, yp, buf[bpos++], chunk_arg >> 8, 335 mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8));
336 chunk_arg & 0xff); 336 my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg);
337 ff_apply_motion_8x8(ri, xp, yp, mx, my);
337 break; 338 break;
338 case RoQ_ID_SLD: 339 case RoQ_ID_SLD:
339 qcell = ri->qcells + buf[bpos++]; 340 qcell = ri->qcells + buf[bpos++];
340 apply_vector_4x4(ri, xp, yp, ri->cells + qcell->idx[0]); 341 ff_apply_vector_4x4(ri, xp, yp, ri->cells + qcell->idx[0]);
341 apply_vector_4x4(ri, xp+4, yp, ri->cells + qcell->idx[1]); 342 ff_apply_vector_4x4(ri, xp+4, yp, ri->cells + qcell->idx[1]);
342 apply_vector_4x4(ri, xp, yp+4, ri->cells + qcell->idx[2]); 343 ff_apply_vector_4x4(ri, xp, yp+4, ri->cells + qcell->idx[2]);
343 apply_vector_4x4(ri, xp+4, yp+4, ri->cells + qcell->idx[3]); 344 ff_apply_vector_4x4(ri, xp+4, yp+4, ri->cells + qcell->idx[3]);
344 break; 345 break;
345 case RoQ_ID_CCC: 346 case RoQ_ID_CCC:
346 for (k = 0; k < 4; k++) { 347 for (k = 0; k < 4; k++) {
347 x = xp; y = yp; 348 x = xp; y = yp;
348 if(k & 0x01) x += 4; 349 if(k & 0x01) x += 4;
356 vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; 357 vqid = (vqflg >> (vqflg_pos * 2)) & 0x3;
357 frame_stats[1][vqid]++; 358 frame_stats[1][vqid]++;
358 vqflg_pos--; 359 vqflg_pos--;
359 switch(vqid) { 360 switch(vqid) {
360 case RoQ_ID_MOT: 361 case RoQ_ID_MOT:
361 apply_motion_4x4(ri, x, y, 0, 8, 8); 362 ff_apply_motion_4x4(ri, x, y, 0, 0);
362 break; 363 break;
363 case RoQ_ID_FCC: 364 case RoQ_ID_FCC:
364 apply_motion_4x4(ri, x, y, buf[bpos++], 365 mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8));
365 chunk_arg >> 8, chunk_arg & 0xff); 366 my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg);
367 ff_apply_motion_4x4(ri, x, y, mx, my);
366 break; 368 break;
367 case RoQ_ID_SLD: 369 case RoQ_ID_SLD:
368 qcell = ri->qcells + buf[bpos++]; 370 qcell = ri->qcells + buf[bpos++];
369 apply_vector_2x2(ri, x, y, ri->cells + qcell->idx[0]); 371 ff_apply_vector_2x2(ri, x, y, ri->cells + qcell->idx[0]);
370 apply_vector_2x2(ri, x+2, y, ri->cells + qcell->idx[1]); 372 ff_apply_vector_2x2(ri, x+2, y, ri->cells + qcell->idx[1]);
371 apply_vector_2x2(ri, x, y+2, ri->cells + qcell->idx[2]); 373 ff_apply_vector_2x2(ri, x, y+2, ri->cells + qcell->idx[2]);
372 apply_vector_2x2(ri, x+2, y+2, ri->cells + qcell->idx[3]); 374 ff_apply_vector_2x2(ri, x+2, y+2, ri->cells + qcell->idx[3]);
373 break; 375 break;
374 case RoQ_ID_CCC: 376 case RoQ_ID_CCC:
375 apply_vector_2x2(ri, x, y, ri->cells + buf[bpos]); 377 ff_apply_vector_2x2(ri, x, y, ri->cells + buf[bpos]);
376 apply_vector_2x2(ri, x+2, y, ri->cells + buf[bpos+1]); 378 ff_apply_vector_2x2(ri, x+2, y, ri->cells + buf[bpos+1]);
377 apply_vector_2x2(ri, x, y+2, ri->cells + buf[bpos+2]); 379 ff_apply_vector_2x2(ri, x, y+2, ri->cells + buf[bpos+2]);
378 apply_vector_2x2(ri, x+2, y+2, ri->cells + buf[bpos+3]); 380 ff_apply_vector_2x2(ri, x+2, y+2, ri->cells + buf[bpos+3]);
379 bpos += 4; 381 bpos += 4;
380 break; 382 break;
381 } 383 }
382 } 384 }
383 break; 385 break;
398 400
399 401
400 static int roq_decode_init(AVCodecContext *avctx) 402 static int roq_decode_init(AVCodecContext *avctx)
401 { 403 {
402 RoqContext *s = avctx->priv_data; 404 RoqContext *s = avctx->priv_data;
403 int i;
404 405
405 s->avctx = avctx; 406 s->avctx = avctx;
406 s->first_frame = 1; 407 s->first_frame = 1;
407 s->last_frame = &s->frames[0]; 408 s->last_frame = &s->frames[0];
408 s->current_frame = &s->frames[1]; 409 s->current_frame = &s->frames[1];
409 avctx->pix_fmt = PIX_FMT_YUV420P; 410 avctx->pix_fmt = PIX_FMT_YUV420P;
410 dsputil_init(&s->dsp, avctx); 411 dsputil_init(&s->dsp, avctx);
411
412 uiclp = uiclip+512;
413 for(i = -512; i < 512; i++)
414 uiclp[i] = (i < 0 ? 0 : (i > 255 ? 255 : i));
415 412
416 return 0; 413 return 0;
417 } 414 }
418 415
419 static int roq_decode_frame(AVCodecContext *avctx, 416 static int roq_decode_frame(AVCodecContext *avctx,