--- branches/dev-api-3/xvidcore/src/image/image.c 2002/09/23 20:36:02 530 +++ branches/dev-api-3/xvidcore/src/image/image.c 2002/10/09 15:56:16 586 @@ -32,11 +32,12 @@ * * History: * + * 05.10.2002 support for interpolated images in qpel mode - Isibaar * 01.05.2002 BFRAME image-based u,v interpolation * 22.04.2002 added some B-frame support * 14.04.2002 added image_dump_yuvpgm(), added image_mad() * XVID_CSP_USER input support - * 09.04.2002 PSNR calculations + * 09.04.2002 PSNR calculations - Isibaar * 06.04.2002 removed interlaced edging from U,V blocks (as per spec) * 26.03.2002 interlacing support (field-based edging in set_edges) * 26.01.2002 rgb555, rgb565 @@ -160,8 +161,7 @@ uint32_t edged_width, uint32_t edged_height, uint32_t width, - uint32_t height, - uint32_t interlacing) + uint32_t height) { const uint32_t edged_width2 = edged_width / 2; const uint32_t width2 = width / 2; @@ -174,18 +174,10 @@ src = image->y; for (i = 0; i < EDGE_SIZE; i++) { - // if interlacing, edges contain top-most data from each field - if (interlacing && (i & 1)) { - memset(dst, *(src + edged_width), EDGE_SIZE); - memcpy(dst + EDGE_SIZE, src + edged_width, width); - memset(dst + edged_width - EDGE_SIZE, - *(src + edged_width + width - 1), EDGE_SIZE); - } else { - memset(dst, *src, EDGE_SIZE); - memcpy(dst + EDGE_SIZE, src, width); - memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), - EDGE_SIZE); - } + memset(dst, *src, EDGE_SIZE); + memcpy(dst + EDGE_SIZE, src, width); + memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), + EDGE_SIZE); dst += edged_width; } @@ -198,18 +190,10 @@ src -= edged_width; for (i = 0; i < EDGE_SIZE; i++) { - // if interlacing, edges contain bottom-most data from each field - if (interlacing && !(i & 1)) { - memset(dst, *(src - edged_width), EDGE_SIZE); - memcpy(dst + EDGE_SIZE, src - edged_width, width); - memset(dst + edged_width - EDGE_SIZE, - *(src - edged_width + width - 1), EDGE_SIZE); - } else { - memset(dst, *src, EDGE_SIZE); - memcpy(dst + EDGE_SIZE, src, width); - memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), + memset(dst, *src, EDGE_SIZE); + memcpy(dst + EDGE_SIZE, src, width); + memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), EDGE_SIZE); - } dst += edged_width; } @@ -278,18 +262,19 @@ IMAGE * refhv, uint32_t edged_width, uint32_t edged_height, + uint32_t quarterpel, uint32_t rounding) { - const uint32_t offset = EDGE_SIZE * (edged_width + 1); + const uint32_t offset = EDGE_SIZE2 * (edged_width + 1); // we only interpolate half of the edge area const uint32_t stride_add = 7 * edged_width; - +/* #ifdef BFRAMES const uint32_t edged_width2 = edged_width / 2; const uint32_t edged_height2 = edged_height / 2; const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1); const uint32_t stride_add2 = 7 * edged_width2; #endif - +*/ uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr; uint32_t x, y; @@ -304,21 +289,68 @@ v_ptr -= offset; hv_ptr -= offset; - for (y = 0; y < edged_height; y += 8) { - for (x = 0; x < edged_width; x += 8) { - interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding); - interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding); - interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding); + if(quarterpel) { + + for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) { + for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) { + interpolate8x8_6tap_lowpass_h(h_ptr, n_ptr, edged_width, rounding); + interpolate8x8_6tap_lowpass_v(v_ptr, n_ptr, edged_width, rounding); + + n_ptr += 8; + h_ptr += 8; + v_ptr += 8; + } + + n_ptr += EDGE_SIZE; + h_ptr += EDGE_SIZE; + v_ptr += EDGE_SIZE; + + h_ptr += stride_add; + v_ptr += stride_add; + n_ptr += stride_add; + } - n_ptr += 8; - h_ptr += 8; - v_ptr += 8; - hv_ptr += 8; + h_ptr = refh->y; + h_ptr -= offset; + + for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) { + for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) { + interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding); + hv_ptr += 8; + h_ptr += 8; + } + + hv_ptr += EDGE_SIZE2; + h_ptr += EDGE_SIZE2; + + hv_ptr += stride_add; + h_ptr += stride_add; + } + } + else { + + for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) { + for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) { + interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding); + interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding); + interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding); + + n_ptr += 8; + h_ptr += 8; + v_ptr += 8; + hv_ptr += 8; + } + + h_ptr += EDGE_SIZE; + v_ptr += EDGE_SIZE; + hv_ptr += EDGE_SIZE; + n_ptr += EDGE_SIZE; + + h_ptr += stride_add; + v_ptr += stride_add; + hv_ptr += stride_add; + n_ptr += stride_add; } - h_ptr += stride_add; - v_ptr += stride_add; - hv_ptr += stride_add; - n_ptr += stride_add; } /* #ifdef BFRAMES @@ -530,6 +562,29 @@ height = -height; } + // --- xvid 2.1 compatiblity patch --- + // --- remove when xvid_dec_frame->stride equals real stride + if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 || + (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 || + (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 || + (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU || + (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY) + { + dst_stride *= 2; + } + else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24) + { + dst_stride *= 3; + } + else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 || + (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR || + (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA) + { + dst_stride *= 4; + } + // ^--- xvid 2.1 compatiblity fix ---^ + + switch (csp & ~XVID_CSP_VFLIP) { case XVID_CSP_RGB555: yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v, @@ -551,6 +606,16 @@ edged_width, edged_width / 2, width, height); return 0; + case XVID_CSP_ABGR: + yv12_to_abgr(dst, dst_stride, image->y, image->u, image->v, + edged_width, edged_width / 2, width, height); + return 0; + + case XVID_CSP_RGBA: + yv12_to_rgba(dst, dst_stride, image->y, image->u, image->v, + edged_width, edged_width / 2, width, height); + return 0; + case XVID_CSP_I420: yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height);