49 |
{ |
{ |
50 |
const uint32_t edged_width2 = edged_width / 2; |
const uint32_t edged_width2 = edged_width / 2; |
51 |
const uint32_t edged_height2 = edged_height / 2; |
const uint32_t edged_height2 = edged_height / 2; |
|
uint32_t i; |
|
52 |
|
|
53 |
image->y = |
image->y = |
54 |
xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE); |
xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE); |
55 |
if (image->y == NULL) { |
if (image->y == NULL) { |
56 |
return -1; |
return -1; |
57 |
} |
} |
58 |
|
memset(image->y, 0, edged_width * (edged_height + 1) + SAFETY); |
|
for (i = 0; i < edged_width * edged_height + SAFETY; i++) { |
|
|
image->y[i] = 0; |
|
|
} |
|
59 |
|
|
60 |
image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); |
image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); |
61 |
if (image->u == NULL) { |
if (image->u == NULL) { |
62 |
xvid_free(image->y); |
xvid_free(image->y); |
63 |
|
image->y = NULL; |
64 |
return -1; |
return -1; |
65 |
} |
} |
66 |
|
memset(image->u, 0, edged_width2 * edged_height2 + SAFETY); |
67 |
|
|
68 |
image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); |
image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); |
69 |
if (image->v == NULL) { |
if (image->v == NULL) { |
70 |
xvid_free(image->u); |
xvid_free(image->u); |
71 |
|
image->u = NULL; |
72 |
xvid_free(image->y); |
xvid_free(image->y); |
73 |
|
image->y = NULL; |
74 |
return -1; |
return -1; |
75 |
} |
} |
76 |
|
memset(image->v, 0, edged_width2 * edged_height2 + SAFETY); |
77 |
|
|
78 |
image->y += EDGE_SIZE * edged_width + EDGE_SIZE; |
image->y += EDGE_SIZE * edged_width + EDGE_SIZE; |
79 |
image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2; |
image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2; |
93 |
|
|
94 |
if (image->y) { |
if (image->y) { |
95 |
xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE)); |
xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE)); |
96 |
|
image->y = NULL; |
97 |
} |
} |
98 |
if (image->u) { |
if (image->u) { |
99 |
xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); |
xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); |
100 |
|
image->u = NULL; |
101 |
} |
} |
102 |
if (image->v) { |
if (image->v) { |
103 |
xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); |
xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); |
104 |
|
image->v = NULL; |
105 |
} |
} |
106 |
} |
} |
107 |
|
|
127 |
memcpy(image1->v, image2->v, edged_width * height / 4); |
memcpy(image1->v, image2->v, edged_width * height / 4); |
128 |
} |
} |
129 |
|
|
130 |
|
/* setedges bug was fixed in this BS version */ |
131 |
|
#define SETEDGES_BUG_BEFORE 18 |
132 |
|
|
133 |
void |
void |
134 |
image_setedges(IMAGE * image, |
image_setedges(IMAGE * image, |
135 |
uint32_t edged_width, |
uint32_t edged_width, |
136 |
uint32_t edged_height, |
uint32_t edged_height, |
137 |
uint32_t width, |
uint32_t width, |
138 |
uint32_t height) |
uint32_t height, |
139 |
|
int bs_version) |
140 |
{ |
{ |
141 |
const uint32_t edged_width2 = edged_width / 2; |
const uint32_t edged_width2 = edged_width / 2; |
142 |
uint32_t width2; |
uint32_t width2; |
144 |
uint8_t *dst; |
uint8_t *dst; |
145 |
uint8_t *src; |
uint8_t *src; |
146 |
|
|
|
|
|
147 |
dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width); |
dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width); |
148 |
src = image->y; |
src = image->y; |
149 |
|
|
150 |
/* According to the Standard Clause 7.6.4, padding is done starting at 16 |
/* According to the Standard Clause 7.6.4, padding is done starting at 16 |
151 |
* pixel width and height multiples */ |
* pixel width and height multiples. This was not respected in old xvids */ |
152 |
|
if (bs_version == 0 || bs_version >= SETEDGES_BUG_BEFORE) { |
153 |
width = (width+15)&~15; |
width = (width+15)&~15; |
154 |
height = (height+15)&~15; |
height = (height+15)&~15; |
155 |
|
} |
156 |
|
|
157 |
width2 = width/2; |
width2 = width/2; |
158 |
|
|
159 |
for (i = 0; i < EDGE_SIZE; i++) { |
for (i = 0; i < EDGE_SIZE; i++) { |
263 |
n_ptr = refn->y; |
n_ptr = refn->y; |
264 |
h_ptr = refh->y; |
h_ptr = refh->y; |
265 |
v_ptr = refv->y; |
v_ptr = refv->y; |
|
hv_ptr = refhv->y; |
|
266 |
|
|
267 |
n_ptr -= offset; |
n_ptr -= offset; |
268 |
h_ptr -= offset; |
h_ptr -= offset; |
269 |
v_ptr -= offset; |
v_ptr -= offset; |
|
hv_ptr -= offset; |
|
270 |
|
|
271 |
|
/* Note we initialize the hv pointer later, as we can optimize code a bit |
272 |
|
* doing it down to up in quarterpel and up to down in halfpel */ |
273 |
if(quarterpel) { |
if(quarterpel) { |
274 |
|
|
275 |
for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) { |
for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) { |
291 |
n_ptr += stride_add; |
n_ptr += stride_add; |
292 |
} |
} |
293 |
|
|
294 |
h_ptr = refh->y; |
h_ptr = refh->y + (edged_height - EDGE_SIZE - EDGE_SIZE2)*edged_width - EDGE_SIZE2; |
295 |
h_ptr -= offset; |
hv_ptr = refhv->y + (edged_height - EDGE_SIZE - EDGE_SIZE2)*edged_width - EDGE_SIZE2; |
296 |
|
|
297 |
for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) { |
for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) { |
298 |
|
hv_ptr -= stride_add; |
299 |
|
h_ptr -= stride_add; |
300 |
|
hv_ptr -= EDGE_SIZE; |
301 |
|
h_ptr -= EDGE_SIZE; |
302 |
|
|
303 |
for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) { |
for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) { |
304 |
|
hv_ptr -= 8; |
305 |
|
h_ptr -= 8; |
306 |
interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding); |
interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding); |
|
hv_ptr += 8; |
|
|
h_ptr += 8; |
|
|
} |
|
|
|
|
|
hv_ptr += EDGE_SIZE; |
|
|
h_ptr += EDGE_SIZE; |
|
|
|
|
|
hv_ptr += stride_add; |
|
|
h_ptr += stride_add; |
|
307 |
} |
} |
308 |
} |
} |
309 |
else { |
} else { |
310 |
|
|
311 |
|
hv_ptr = refhv->y; |
312 |
|
hv_ptr -= offset; |
313 |
|
|
314 |
for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) { |
for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) { |
315 |
for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) { |
for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) { |
604 |
interlacing?rgbai_to_yv12_c:rgba_to_yv12_c, 4); |
interlacing?rgbai_to_yv12_c:rgba_to_yv12_c, 4); |
605 |
break; |
break; |
606 |
|
|
607 |
|
case XVID_CSP_ARGB: |
608 |
|
safe_packed_conv( |
609 |
|
src[0], src_stride[0], image->y, image->u, image->v, |
610 |
|
edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), |
611 |
|
interlacing?argbi_to_yv12 : argb_to_yv12, |
612 |
|
interlacing?argbi_to_yv12_c: argb_to_yv12_c, 4); |
613 |
|
break; |
614 |
|
|
615 |
case XVID_CSP_YUY2: |
case XVID_CSP_YUY2: |
616 |
safe_packed_conv( |
safe_packed_conv( |
617 |
src[0], src_stride[0], image->y, image->u, image->v, |
src[0], src_stride[0], image->y, image->u, image->v, |
622 |
|
|
623 |
case XVID_CSP_YVYU: /* u/v swapped */ |
case XVID_CSP_YVYU: /* u/v swapped */ |
624 |
safe_packed_conv( |
safe_packed_conv( |
625 |
src[0], src_stride[0], image->y, image->v, image->y, |
src[0], src_stride[0], image->y, image->v, image->u, |
626 |
edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), |
edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), |
627 |
interlacing?yuyvi_to_yv12 :yuyv_to_yv12, |
interlacing?yuyvi_to_yv12 :yuyv_to_yv12, |
628 |
interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2); |
interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2); |
636 |
interlacing?uyvyi_to_yv12_c:uyvy_to_yv12_c, 2); |
interlacing?uyvyi_to_yv12_c:uyvy_to_yv12_c, 2); |
637 |
break; |
break; |
638 |
|
|
639 |
case XVID_CSP_I420: |
case XVID_CSP_I420: /* YCbCr == YUV == internal colorspace for MPEG */ |
640 |
yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2, |
yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2, |
641 |
src[0], src[0] + src_stride[0]*height, src[0] + src_stride[0]*height + (src_stride[0]/2)*height2, |
src[0], src[0] + src_stride[0]*height, src[0] + src_stride[0]*height + (src_stride[0]/2)*height2, |
642 |
src_stride[0], src_stride[0]/2, width, height, (csp & XVID_CSP_VFLIP)); |
src_stride[0], src_stride[0]/2, width, height, (csp & XVID_CSP_VFLIP)); |
643 |
break |
break; |
644 |
; |
|
645 |
case XVID_CSP_YV12: /* u/v swapped */ |
case XVID_CSP_YV12: /* YCrCb == YVA == U and V plane swapped */ |
646 |
yv12_to_yv12(image->y, image->v, image->u, edged_width, edged_width2, |
yv12_to_yv12(image->y, image->v, image->u, edged_width, edged_width2, |
647 |
src[0], src[0] + src_stride[0]*height, src[0] + src_stride[0]*height + (src_stride[0]/2)*height2, |
src[0], src[0] + src_stride[0]*height, src[0] + src_stride[0]*height + (src_stride[0]/2)*height2, |
648 |
src_stride[0], src_stride[0]/2, width, height, (csp & XVID_CSP_VFLIP)); |
src_stride[0], src_stride[0]/2, width, height, (csp & XVID_CSP_VFLIP)); |
649 |
break; |
break; |
650 |
|
|
651 |
case XVID_CSP_USER: |
case XVID_CSP_PLANAR: /* YCbCr with arbitrary pointers and different strides for Y and UV */ |
|
/*XXX: support for different u & v strides */ |
|
652 |
yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2, |
yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2, |
653 |
src[0], src[1], src[2], src_stride[0], src_stride[1], |
src[0], src[1], src[2], src_stride[0], src_stride[1], /* v: dst_stride[2] not yet supported */ |
654 |
width, height, (csp & XVID_CSP_VFLIP)); |
width, height, (csp & XVID_CSP_VFLIP)); |
655 |
break; |
break; |
656 |
|
|
780 |
interlacing?yv12_to_rgbai_c:yv12_to_rgba_c, 4); |
interlacing?yv12_to_rgbai_c:yv12_to_rgba_c, 4); |
781 |
return 0; |
return 0; |
782 |
|
|
783 |
|
case XVID_CSP_ARGB: |
784 |
|
safe_packed_conv( |
785 |
|
dst[0], dst_stride[0], image->y, image->u, image->v, |
786 |
|
edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), |
787 |
|
interlacing?yv12_to_argbi :yv12_to_argb, |
788 |
|
interlacing?yv12_to_argbi_c:yv12_to_argb_c, 4); |
789 |
|
return 0; |
790 |
|
|
791 |
case XVID_CSP_YUY2: |
case XVID_CSP_YUY2: |
792 |
safe_packed_conv( |
safe_packed_conv( |
793 |
dst[0], dst_stride[0], image->y, image->u, image->v, |
dst[0], dst_stride[0], image->y, image->u, image->v, |
812 |
interlacing?yv12_to_uyvyi_c:yv12_to_uyvy_c, 2); |
interlacing?yv12_to_uyvyi_c:yv12_to_uyvy_c, 2); |
813 |
return 0; |
return 0; |
814 |
|
|
815 |
case XVID_CSP_I420: |
case XVID_CSP_I420: /* YCbCr == YUV == internal colorspace for MPEG */ |
816 |
yv12_to_yv12(dst[0], dst[0] + dst_stride[0]*height, dst[0] + dst_stride[0]*height + (dst_stride[0]/2)*height2, |
yv12_to_yv12(dst[0], dst[0] + dst_stride[0]*height, dst[0] + dst_stride[0]*height + (dst_stride[0]/2)*height2, |
817 |
dst_stride[0], dst_stride[0]/2, |
dst_stride[0], dst_stride[0]/2, |
818 |
image->y, image->u, image->v, edged_width, edged_width2, |
image->y, image->u, image->v, edged_width, edged_width2, |
819 |
width, height, (csp & XVID_CSP_VFLIP)); |
width, height, (csp & XVID_CSP_VFLIP)); |
820 |
return 0; |
return 0; |
821 |
|
|
822 |
case XVID_CSP_YV12: /* u,v swapped */ |
case XVID_CSP_YV12: /* YCrCb == YVU == U and V plane swapped */ |
823 |
yv12_to_yv12(dst[0], dst[0] + dst_stride[0]*height, dst[0] + dst_stride[0]*height + (dst_stride[0]/2)*height2, |
yv12_to_yv12(dst[0], dst[0] + dst_stride[0]*height, dst[0] + dst_stride[0]*height + (dst_stride[0]/2)*height2, |
824 |
dst_stride[0], dst_stride[0]/2, |
dst_stride[0], dst_stride[0]/2, |
825 |
image->y, image->v, image->u, edged_width, edged_width2, |
image->y, image->v, image->u, edged_width, edged_width2, |
826 |
width, height, (csp & XVID_CSP_VFLIP)); |
width, height, (csp & XVID_CSP_VFLIP)); |
827 |
return 0; |
return 0; |
828 |
|
|
829 |
case XVID_CSP_USER : /* u,v swapped */ |
case XVID_CSP_PLANAR: /* YCbCr with arbitrary pointers and different strides for Y and UV */ |
830 |
yv12_to_yv12(dst[0], dst[1], dst[2], |
yv12_to_yv12(dst[0], dst[1], dst[2], |
831 |
dst_stride[0], dst_stride[1], /* v: dst_stride[2] */ |
dst_stride[0], dst_stride[1], /* v: dst_stride[2] not yet supported */ |
832 |
image->y, image->v, image->u, edged_width, edged_width2, |
image->y, image->u, image->v, edged_width, edged_width2, |
833 |
width, height, (csp & XVID_CSP_VFLIP)); |
width, height, (csp & XVID_CSP_VFLIP)); |
834 |
return 0; |
return 0; |
835 |
|
|