From d4854a85d2a2084d8816b8e59fec7dc62938e4ab Mon Sep 17 00:00:00 2001 From: Jamie Tittle Date: Fri, 17 Mar 2006 03:08:15 +0000 Subject: added YUV422_to_YV12_altivec() svn path=/trunk/externals/gem2pdp/; revision=4719 --- pix_2pdp.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- pix_2pdp.h | 5 ++++ 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/pix_2pdp.cpp b/pix_2pdp.cpp index 19ad3e1..69c367f 100755 --- a/pix_2pdp.cpp +++ b/pix_2pdp.cpp @@ -7,7 +7,7 @@ * Many thanks to IOhannes M Zmölnig * * Copyright (c) 2005 Georg Holzmann - * parts Copyright (c) 2005 James Tittle II + * parts Copyright (c) 2005-2006 James Tittle II * */ @@ -95,12 +95,15 @@ void pix_2pdp::bangMess() // YUV case GL_YUV422_GEM: { +#ifdef __VEC__ + YUV422_to_YV12_altivec(pY, pY2, pV, pU, psize); +#else int row=gem_ysize>>1; int cols=gem_xsize>>1; short u,v; unsigned char *pixel = gem_image; unsigned char *pixel2 = gem_image + gem_xsize * gem_csize; - const int row_length = gem_xsize* gem_csize; + const int row_length = gem_xsize* gem_csize; if(0==gem_upsidedown){ pixel=gem_image+row_length * (gem_ysize-1); pixel2=gem_image+row_length * (gem_ysize-2); @@ -113,9 +116,7 @@ void pix_2pdp::bangMess() *pY++ = (pixel[1])<<7; *pV = v; *pY++ = (pixel[3])<<7; - *pU = u; *pY2++ = (pixel2[1])<<7; - *pV = v; *pY2++ = (pixel2[3])<<7; pixel+=4; pixel2+=4; @@ -130,6 +131,7 @@ void pix_2pdp::bangMess() } pY += gem_xsize; pY2 += gem_xsize; } +#endif // __VEC__ pdp_packet_pass_if_valid(m_pdpoutlet, &m_packet0); } break; @@ -158,6 +160,78 @@ void pix_2pdp::bangMess() } } +#ifdef __VEC__ +void pix_2pdp :: YUV422_to_YV12_altivec(short*pY, short*pY2, short*pU, short*pV, size_t psize) +{ + // UYVY UYVY UYVY UYVY + vector unsigned char *pixels1=(vector unsigned char *)gem_image; + vector unsigned char *pixels2=(vector unsigned char *)(gem_image+(gem_xsize*2)); + // PDP packet to be filled: + // first Y plane + vector signed short *py1 = (vector signed short *)pY; + // 2nd Y pixel + vector signed short *py2 = (vector signed short *)pY2; + // U plane + vector signed short *pCr = (vector signed short *)pU; + // V plane + vector signed short *pCb = (vector signed short *)pV; + vector signed short uvSub = (vector signed short)( 128, 128, 128, 128, + 128, 128, 128, 128 ); + vector signed short yShift = (vector signed short)( 7, 7, 7, 7, 7, 7, 7, 7 ); + vector signed short uvShift = (vector signed short)( 8, 8, 8, 8, 8, 8, 8, 8 ); + + vector signed short tempY1, tempY2, tempY3, tempY4, + tempUV1, tempUV2, tempUV3, tempUV4, tempUV5, tempUV6; + + vector unsigned char uvPerm = (vector unsigned char)( 16, 0, 17, 4, 18, 8, 19, 12, // u0..u3 + 20, 2, 21, 6, 22, 10, 23, 14 ); // v0..v3 + + vector unsigned char uPerm = (vector unsigned char)( 0, 1, 2, 3, 4, 5, 6, 7, + 16,17,18,19,20,21,22,23); + vector unsigned char vPerm = (vector unsigned char)( 8, 9, 10,11,12,13,14,15, + 24,25,26,27,28,29,30,31); + + vector unsigned char yPerm = (vector unsigned char)( 16, 1, 17, 3, 18, 5, 19, 7, // y0..y3 + 20, 9, 21, 11, 23, 13, 25, 15);// y4..y7 + vector unsigned char zeroVec = (vector unsigned char)(0); + + int row=gem_ysize>>1; + int cols=gem_xsize>>4; + + while(row--){ + int col=cols; + while(col--){ + tempUV1 = (vector signed short) vec_perm( *pixels1, zeroVec, uvPerm); + tempY1 = (vector signed short) vec_perm( *pixels1, zeroVec, yPerm); + tempY2 = (vector signed short) vec_perm( *pixels2, zeroVec, yPerm); + pixels1++;pixels2++; + + tempUV2 = (vector signed short) vec_perm( *pixels1, zeroVec, uvPerm); + tempY3 = (vector signed short) vec_perm( *pixels1, zeroVec, yPerm); + tempY4 = (vector signed short) vec_perm( *pixels2, zeroVec, yPerm); + pixels1++;pixels2++; + + tempUV3 = vec_sub( tempUV1, uvSub ); + tempUV4 = vec_sub( tempUV2, uvSub ); + tempUV5 = vec_sl( tempUV3, uvShift ); + tempUV6 = vec_sl( tempUV4, uvShift ); + + *pCb = vec_perm( tempUV5, tempUV6, uPerm ); + *pCr = vec_perm( tempUV5, tempUV6, vPerm ); + pCr++; pCb++; + + *py1++ = vec_sl( tempY1, yShift); + *py2++ = vec_sl( tempY2, yShift); + *py1++ = vec_sl( tempY3, yShift); + *py2++ = vec_sl( tempY4, yShift); + } + + py1+=(gem_xsize>>3); py2+=(gem_xsize>>3); + pixels1+=(gem_xsize*2)>>4; pixels2+=(gem_xsize*2)>>4; + } +} +#endif + void pix_2pdp::obj_setupCallback(t_class *classPtr) { post( "pix_2pdp : a bridge between a Gem pix and PDP/PiDiP, Georg Holzmann 2005 & tigital 2005 " ); diff --git a/pix_2pdp.h b/pix_2pdp.h index f097d1a..bda7a8f 100755 --- a/pix_2pdp.h +++ b/pix_2pdp.h @@ -36,6 +36,11 @@ class GEM_EXTERN pix_2pdp : public GemPixObj // pdp processing virtual void bangMess(void); + // altivec processing +#ifdef __VEC__ + virtual void YUV422_to_YV12_altivec(short*pY, short*pY2, short*pU, short*pV, size_t psize); +#endif + // the pixBlock with the current image unsigned char *gem_image; int gem_xsize; -- cgit v1.2.1