3 |
* XVID MPEG-4 VIDEO CODEC |
* XVID MPEG-4 VIDEO CODEC |
4 |
* image stuff |
* image stuff |
5 |
* |
* |
6 |
|
* This program is an implementation of a part of one or more MPEG-4 |
7 |
|
* Video tools as specified in ISO/IEC 14496-2 standard. Those intending |
8 |
|
* to use this software module in hardware or software products are |
9 |
|
* advised that its use may infringe existing patents or copyrights, and |
10 |
|
* any such use would be at such party's own risk. The original |
11 |
|
* developer of this software module and his/her company, and subsequent |
12 |
|
* editors and their companies, will have no liability for use of this |
13 |
|
* software or modifications or derivatives thereof. |
14 |
|
* |
15 |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
16 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
17 |
* the Free Software Foundation; either version 2 of the License, or |
* the Free Software Foundation; either version 2 of the License, or |
32 |
* |
* |
33 |
* History: |
* History: |
34 |
* |
* |
35 |
|
* 05.10.2002 support for interpolated images in qpel mode - Isibaar |
36 |
* 01.05.2002 BFRAME image-based u,v interpolation |
* 01.05.2002 BFRAME image-based u,v interpolation |
37 |
* 22.04.2002 added some B-frame support |
* 22.04.2002 added some B-frame support |
38 |
* 14.04.2002 added image_dump_yuvpgm(), added image_mad() |
* 14.04.2002 added image_dump_yuvpgm(), added image_mad() |
39 |
* XVID_CSP_USER input support |
* XVID_CSP_USER input support |
40 |
* 09.04.2002 PSNR calculations |
* 09.04.2002 PSNR calculations - Isibaar |
41 |
* 06.04.2002 removed interlaced edging from U,V blocks (as per spec) |
* 06.04.2002 removed interlaced edging from U,V blocks (as per spec) |
42 |
* 26.03.2002 interlacing support (field-based edging in set_edges) |
* 26.03.2002 interlacing support (field-based edging in set_edges) |
43 |
* 26.01.2002 rgb555, rgb565 |
* 26.01.2002 rgb555, rgb565 |
161 |
uint32_t edged_width, |
uint32_t edged_width, |
162 |
uint32_t edged_height, |
uint32_t edged_height, |
163 |
uint32_t width, |
uint32_t width, |
164 |
uint32_t height, |
uint32_t height) |
|
uint32_t interlacing) |
|
165 |
{ |
{ |
166 |
const uint32_t edged_width2 = edged_width / 2; |
const uint32_t edged_width2 = edged_width / 2; |
167 |
const uint32_t width2 = width / 2; |
const uint32_t width2 = width / 2; |
174 |
src = image->y; |
src = image->y; |
175 |
|
|
176 |
for (i = 0; i < EDGE_SIZE; i++) { |
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 { |
|
177 |
memset(dst, *src, EDGE_SIZE); |
memset(dst, *src, EDGE_SIZE); |
178 |
memcpy(dst + EDGE_SIZE, src, width); |
memcpy(dst + EDGE_SIZE, src, width); |
179 |
memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), |
memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), |
180 |
EDGE_SIZE); |
EDGE_SIZE); |
|
} |
|
181 |
dst += edged_width; |
dst += edged_width; |
182 |
} |
} |
183 |
|
|
190 |
|
|
191 |
src -= edged_width; |
src -= edged_width; |
192 |
for (i = 0; i < EDGE_SIZE; i++) { |
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 { |
|
193 |
memset(dst, *src, EDGE_SIZE); |
memset(dst, *src, EDGE_SIZE); |
194 |
memcpy(dst + EDGE_SIZE, src, width); |
memcpy(dst + EDGE_SIZE, src, width); |
195 |
memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), |
memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), |
196 |
EDGE_SIZE); |
EDGE_SIZE); |
|
} |
|
197 |
dst += edged_width; |
dst += edged_width; |
198 |
} |
} |
199 |
|
|
262 |
IMAGE * refhv, |
IMAGE * refhv, |
263 |
uint32_t edged_width, |
uint32_t edged_width, |
264 |
uint32_t edged_height, |
uint32_t edged_height, |
265 |
|
uint32_t quarterpel, |
266 |
uint32_t rounding) |
uint32_t rounding) |
267 |
{ |
{ |
268 |
const uint32_t offset = EDGE_SIZE * (edged_width + 1); |
const uint32_t offset = EDGE_SIZE * (edged_width + 1); |
289 |
v_ptr -= offset; |
v_ptr -= offset; |
290 |
hv_ptr -= offset; |
hv_ptr -= offset; |
291 |
|
|
292 |
|
if(quarterpel) { |
293 |
|
|
294 |
|
for (y = 0; y < edged_height; y += 8) { |
295 |
|
for (x = 0; x < edged_width; x += 8) { |
296 |
|
interpolate8x8_6tap_lowpass_h(h_ptr, n_ptr, edged_width, rounding); |
297 |
|
interpolate8x8_6tap_lowpass_v(v_ptr, n_ptr, edged_width, rounding); |
298 |
|
|
299 |
|
n_ptr += 8; |
300 |
|
h_ptr += 8; |
301 |
|
v_ptr += 8; |
302 |
|
} |
303 |
|
|
304 |
|
h_ptr += stride_add; |
305 |
|
v_ptr += stride_add; |
306 |
|
n_ptr += stride_add; |
307 |
|
} |
308 |
|
|
309 |
|
h_ptr = refh->y; |
310 |
|
h_ptr -= offset; |
311 |
|
|
312 |
for (y = 0; y < edged_height; y = y + 8) { |
for (y = 0; y < edged_height; y = y + 8) { |
313 |
for (x = 0; x < edged_width; x = x + 8) { |
for (x = 0; x < edged_width; x = x + 8) { |
314 |
|
interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding); |
315 |
|
hv_ptr += 8; |
316 |
|
h_ptr += 8; |
317 |
|
} |
318 |
|
hv_ptr += stride_add; |
319 |
|
h_ptr += stride_add; |
320 |
|
} |
321 |
|
} |
322 |
|
else { |
323 |
|
|
324 |
|
for (y = 0; y < edged_height; y += 8) { |
325 |
|
for (x = 0; x < edged_width; x += 8) { |
326 |
interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding); |
interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding); |
327 |
interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding); |
interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding); |
328 |
interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding); |
interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding); |
332 |
v_ptr += 8; |
v_ptr += 8; |
333 |
hv_ptr += 8; |
hv_ptr += 8; |
334 |
} |
} |
335 |
|
|
336 |
h_ptr += stride_add; |
h_ptr += stride_add; |
337 |
v_ptr += stride_add; |
v_ptr += stride_add; |
338 |
hv_ptr += stride_add; |
hv_ptr += stride_add; |
339 |
n_ptr += stride_add; |
n_ptr += stride_add; |
340 |
} |
} |
341 |
|
} |
342 |
|
/* |
343 |
#ifdef BFRAMES |
#ifdef BFRAMES |
344 |
n_ptr = refn->u; |
n_ptr = refn->u; |
345 |
h_ptr = refh->u; |
h_ptr = refh->u; |
351 |
v_ptr -= offset2; |
v_ptr -= offset2; |
352 |
hv_ptr -= offset2; |
hv_ptr -= offset2; |
353 |
|
|
354 |
for (y = 0; y < edged_height2; y = y + 8) { |
for (y = 0; y < edged_height2; y += 8) { |
355 |
for (x = 0; x < edged_width2; x = x + 8) { |
for (x = 0; x < edged_width2; x += 8) { |
356 |
interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding); |
interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding); |
357 |
interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding); |
interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding); |
358 |
interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding); |
interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding); |
395 |
n_ptr += stride_add2; |
n_ptr += stride_add2; |
396 |
} |
} |
397 |
#endif |
#endif |
398 |
|
*/ |
399 |
/* |
/* |
400 |
interpolate_halfpel_h( |
interpolate_halfpel_h( |
401 |
refh->y - offset, |
refh->y - offset, |
549 |
height = -height; |
height = -height; |
550 |
} |
} |
551 |
|
|
552 |
|
// --- xvid 2.1 compatiblity patch --- |
553 |
|
// --- remove when xvid_dec_frame->stride equals real stride |
554 |
|
if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 || |
555 |
|
(csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 || |
556 |
|
(csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 || |
557 |
|
(csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU || |
558 |
|
(csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY) |
559 |
|
{ |
560 |
|
dst_stride *= 2; |
561 |
|
} |
562 |
|
else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24) |
563 |
|
{ |
564 |
|
dst_stride *= 3; |
565 |
|
} |
566 |
|
else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 || |
567 |
|
(csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR || |
568 |
|
(csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA) |
569 |
|
{ |
570 |
|
dst_stride *= 4; |
571 |
|
} |
572 |
|
// ^--- xvid 2.1 compatiblity fix ---^ |
573 |
|
|
574 |
|
|
575 |
switch (csp & ~XVID_CSP_VFLIP) { |
switch (csp & ~XVID_CSP_VFLIP) { |
576 |
case XVID_CSP_RGB555: |
case XVID_CSP_RGB555: |
577 |
yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v, |
yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v, |
593 |
edged_width, edged_width / 2, width, height); |
edged_width, edged_width / 2, width, height); |
594 |
return 0; |
return 0; |
595 |
|
|
596 |
|
case XVID_CSP_ABGR: |
597 |
|
yv12_to_abgr(dst, dst_stride, image->y, image->u, image->v, |
598 |
|
edged_width, edged_width / 2, width, height); |
599 |
|
return 0; |
600 |
|
|
601 |
|
case XVID_CSP_RGBA: |
602 |
|
yv12_to_rgba(dst, dst_stride, image->y, image->u, image->v, |
603 |
|
edged_width, edged_width / 2, width, height); |
604 |
|
return 0; |
605 |
|
|
606 |
case XVID_CSP_I420: |
case XVID_CSP_I420: |
607 |
yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width, |
yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width, |
608 |
edged_width / 2, width, height); |
edged_width / 2, width, height); |
812 |
if(w > width) |
if(w > width) |
813 |
w = width; |
w = width; |
814 |
w2 = w >> 1; |
w2 = w >> 1; |
815 |
void __inline |
|
816 |
dY = (uint8_t*)out_frm->y + (mby << 4) * out_frm->stride_y + (mbx << 4); |
dY = (uint8_t*)out_frm->y + (mby << 4) * out_frm->stride_y + (mbx << 4); |
817 |
dU = (uint8_t*)out_frm->u + (mby << 3) * out_frm->stride_u + (mbx << 3); |
dU = (uint8_t*)out_frm->u + (mby << 3) * out_frm->stride_u + (mbx << 3); |
818 |
dV = (uint8_t*)out_frm->v + (mby << 3) * out_frm->stride_v + (mbx << 3); |
dV = (uint8_t*)out_frm->v + (mby << 3) * out_frm->stride_v + (mbx << 3); |
822 |
|
|
823 |
for(i = 0 ; i < 16 ; i++) { |
for(i = 0 ; i < 16 ; i++) { |
824 |
memcpy(dY,sY,w); |
memcpy(dY,sY,w); |
825 |
dY = out_frm->y + (mby << 4) * out_frm->stride_y + (mbx << 4); |
dY += out_frm->stride_y; |
826 |
dU = out_frm->u + (mby << 3) * out_frm->stride_u + (mbx << 3); |
sY += std; |
827 |
dV = out_frm->v + (mby << 3) * out_frm->stride_v + (mbx << 3); |
} |
828 |
for(i = 0 ; i < 8 ; i++) { |
for(i = 0 ; i < 8 ; i++) { |
829 |
memcpy(dU,sU,w2); |
memcpy(dU,sU,w2); |
830 |
dU += out_frm->stride_u; |
dU += out_frm->stride_u; |