comparison roqvideo.c @ 4586:365f2fed8461 libavcodec

Use pointers to avoid copying AVFrame. This ensure get_buffer() won't be confused with an AVFrame pointer which looks like it wasn't released.
author aurel
date Sat, 24 Feb 2007 00:55:50 +0000
parents c8c591fe26f8
children 66ef3690d108
comparison
equal deleted inserted replaced
4585:869c9a1a5006 4586:365f2fed8461
49 49
50 typedef struct RoqContext { 50 typedef struct RoqContext {
51 51
52 AVCodecContext *avctx; 52 AVCodecContext *avctx;
53 DSPContext dsp; 53 DSPContext dsp;
54 AVFrame last_frame; 54 AVFrame frames[2];
55 AVFrame current_frame; 55 AVFrame *last_frame;
56 AVFrame *current_frame;
56 int first_frame; 57 int first_frame;
57 int y_stride; 58 int y_stride;
58 int c_stride; 59 int c_stride;
59 60
60 roq_cell cells[256]; 61 roq_cell cells[256];
85 86
86 static void apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) 87 static void apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell)
87 { 88 {
88 unsigned char *yptr; 89 unsigned char *yptr;
89 90
90 yptr = ri->current_frame.data[0] + (y * ri->y_stride) + x; 91 yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
91 *yptr++ = cell->y0; 92 *yptr++ = cell->y0;
92 *yptr++ = cell->y1; 93 *yptr++ = cell->y1;
93 yptr += (ri->y_stride - 2); 94 yptr += (ri->y_stride - 2);
94 *yptr++ = cell->y2; 95 *yptr++ = cell->y2;
95 *yptr++ = cell->y3; 96 *yptr++ = cell->y3;
96 ri->current_frame.data[1][(y/2) * (ri->c_stride) + x/2] = cell->u; 97 ri->current_frame->data[1][(y/2) * (ri->c_stride) + x/2] = cell->u;
97 ri->current_frame.data[2][(y/2) * (ri->c_stride) + x/2] = cell->v; 98 ri->current_frame->data[2][(y/2) * (ri->c_stride) + x/2] = cell->v;
98 } 99 }
99 100
100 static void apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) 101 static void apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
101 { 102 {
102 unsigned long row_inc, c_row_inc; 103 unsigned long row_inc, c_row_inc;
103 register unsigned char y0, y1, u, v; 104 register unsigned char y0, y1, u, v;
104 unsigned char *yptr, *uptr, *vptr; 105 unsigned char *yptr, *uptr, *vptr;
105 106
106 yptr = ri->current_frame.data[0] + (y * ri->y_stride) + x; 107 yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
107 uptr = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2; 108 uptr = ri->current_frame->data[1] + (y/2) * (ri->c_stride) + x/2;
108 vptr = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2; 109 vptr = ri->current_frame->data[2] + (y/2) * (ri->c_stride) + x/2;
109 110
110 row_inc = ri->y_stride - 4; 111 row_inc = ri->y_stride - 4;
111 c_row_inc = (ri->c_stride) - 2; 112 c_row_inc = (ri->c_stride) - 2;
112 *yptr++ = y0 = cell->y0; *uptr++ = u = cell->u; *vptr++ = v = cell->v; 113 *yptr++ = y0 = cell->y0; *uptr++ = u = cell->u; *vptr++ = v = cell->v;
113 *yptr++ = y0; 114 *yptr++ = y0;
151 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", 152 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
152 mx, my, ri->avctx->width, ri->avctx->height); 153 mx, my, ri->avctx->width, ri->avctx->height);
153 return; 154 return;
154 } 155 }
155 156
156 pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; 157 pa = ri->current_frame->data[0] + (y * ri->y_stride) + x;
157 pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; 158 pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx;
158 for(i = 0; i < 4; i++) { 159 for(i = 0; i < 4; i++) {
159 pa[0] = pb[0]; 160 pa[0] = pb[0];
160 pa[1] = pb[1]; 161 pa[1] = pb[1];
161 pa[2] = pb[2]; 162 pa[2] = pb[2];
162 pa[3] = pb[3]; 163 pa[3] = pb[3];
163 pa += ri->y_stride; 164 pa += ri->y_stride;
164 pb += ri->y_stride; 165 pb += ri->y_stride;
165 } 166 }
166 167
167 hw = ri->y_stride/2; 168 hw = ri->y_stride/2;
168 pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; 169 pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2;
169 pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; 170 pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
170 171
171 for(i = 0; i < 2; i++) { 172 for(i = 0; i < 2; i++) {
172 switch(((my & 0x01) << 1) | (mx & 0x01)) { 173 switch(((my & 0x01) << 1) | (mx & 0x01)) {
173 174
174 case 0: 175 case 0:
198 pa[hw] = avg4(pb[hw], pb[hw+1], pb[hw*2], pb[(hw*2)+1]); 199 pa[hw] = avg4(pb[hw], pb[hw+1], pb[hw*2], pb[(hw*2)+1]);
199 pa[hw+1] = avg4(pb[hw+1], pb[hw+2], pb[(hw*2)+1], pb[(hw*2)+1]); 200 pa[hw+1] = avg4(pb[hw+1], pb[hw+2], pb[(hw*2)+1], pb[(hw*2)+1]);
200 break; 201 break;
201 } 202 }
202 203
203 pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; 204 pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
204 pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; 205 pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
205 } 206 }
206 } 207 }
207 208
208 static void apply_motion_8x8(RoqContext *ri, int x, int y, 209 static void apply_motion_8x8(RoqContext *ri, int x, int y,
209 unsigned char mv, signed char mean_x, signed char mean_y) 210 unsigned char mv, signed char mean_x, signed char mean_y)
220 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", 221 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
221 mx, my, ri->avctx->width, ri->avctx->height); 222 mx, my, ri->avctx->width, ri->avctx->height);
222 return; 223 return;
223 } 224 }
224 225
225 pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; 226 pa = ri->current_frame->data[0] + (y * ri->y_stride) + x;
226 pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; 227 pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx;
227 for(i = 0; i < 8; i++) { 228 for(i = 0; i < 8; i++) {
228 pa[0] = pb[0]; 229 pa[0] = pb[0];
229 pa[1] = pb[1]; 230 pa[1] = pb[1];
230 pa[2] = pb[2]; 231 pa[2] = pb[2];
231 pa[3] = pb[3]; 232 pa[3] = pb[3];
236 pa += ri->y_stride; 237 pa += ri->y_stride;
237 pb += ri->y_stride; 238 pb += ri->y_stride;
238 } 239 }
239 240
240 hw = ri->c_stride; 241 hw = ri->c_stride;
241 pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; 242 pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2;
242 pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; 243 pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
243 for(j = 0; j < 2; j++) { 244 for(j = 0; j < 2; j++) {
244 for(i = 0; i < 4; i++) { 245 for(i = 0; i < 4; i++) {
245 switch(((my & 0x01) << 1) | (mx & 0x01)) { 246 switch(((my & 0x01) << 1) | (mx & 0x01)) {
246 247
247 case 0: 248 case 0:
274 } 275 }
275 pa += ri->c_stride; 276 pa += ri->c_stride;
276 pb += ri->c_stride; 277 pb += ri->c_stride;
277 } 278 }
278 279
279 pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; 280 pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
280 pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; 281 pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
281 } 282 }
282 } 283 }
283 284
284 static void roqvideo_decode_frame(RoqContext *ri) 285 static void roqvideo_decode_frame(RoqContext *ri)
285 { 286 {
405 RoqContext *s = avctx->priv_data; 406 RoqContext *s = avctx->priv_data;
406 int i; 407 int i;
407 408
408 s->avctx = avctx; 409 s->avctx = avctx;
409 s->first_frame = 1; 410 s->first_frame = 1;
411 s->last_frame = &s->frames[0];
412 s->current_frame = &s->frames[1];
410 avctx->pix_fmt = PIX_FMT_YUV420P; 413 avctx->pix_fmt = PIX_FMT_YUV420P;
411 avctx->has_b_frames = 0; 414 avctx->has_b_frames = 0;
412 dsputil_init(&s->dsp, avctx); 415 dsputil_init(&s->dsp, avctx);
413 416
414 uiclp = uiclip+512; 417 uiclp = uiclip+512;
422 void *data, int *data_size, 425 void *data, int *data_size,
423 uint8_t *buf, int buf_size) 426 uint8_t *buf, int buf_size)
424 { 427 {
425 RoqContext *s = avctx->priv_data; 428 RoqContext *s = avctx->priv_data;
426 429
427 if (avctx->get_buffer(avctx, &s->current_frame)) { 430 if (avctx->get_buffer(avctx, s->current_frame)) {
428 av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); 431 av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n");
429 return -1; 432 return -1;
430 } 433 }
431 s->y_stride = s->current_frame.linesize[0]; 434 s->y_stride = s->current_frame->linesize[0];
432 s->c_stride = s->current_frame.linesize[1]; 435 s->c_stride = s->current_frame->linesize[1];
433 436
434 s->buf = buf; 437 s->buf = buf;
435 s->size = buf_size; 438 s->size = buf_size;
436 roqvideo_decode_frame(s); 439 roqvideo_decode_frame(s);
437 440
438 /* release the last frame if it is allocated */ 441 /* release the last frame if it is allocated */
439 if (s->first_frame) 442 if (s->first_frame)
440 s->first_frame = 0; 443 s->first_frame = 0;
441 else 444 else
442 avctx->release_buffer(avctx, &s->last_frame); 445 avctx->release_buffer(avctx, s->last_frame);
446
447 *data_size = sizeof(AVFrame);
448 *(AVFrame*)data = *s->current_frame;
443 449
444 /* shuffle frames */ 450 /* shuffle frames */
445 s->last_frame = s->current_frame; 451 FFSWAP(AVFrame *, s->current_frame, s->last_frame);
446
447 *data_size = sizeof(AVFrame);
448 *(AVFrame*)data = s->current_frame;
449 452
450 return buf_size; 453 return buf_size;
451 } 454 }
452 455
453 static int roq_decode_end(AVCodecContext *avctx) 456 static int roq_decode_end(AVCodecContext *avctx)
454 { 457 {
455 RoqContext *s = avctx->priv_data; 458 RoqContext *s = avctx->priv_data;
456 459
457 /* release the last frame */ 460 /* release the last frame */
458 if (s->last_frame.data[0]) 461 if (s->last_frame->data[0])
459 avctx->release_buffer(avctx, &s->last_frame); 462 avctx->release_buffer(avctx, s->last_frame);
460 463
461 return 0; 464 return 0;
462 } 465 }
463 466
464 AVCodec roq_decoder = { 467 AVCodec roq_decoder = {