Mercurial > libavcodec.hg
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, |