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