From d1bf93392898f1393b9063e5d88eccb656c0dc40 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 27 Feb 2015 13:57:40 +0000 Subject: [PATCH] Optimize pixel conversion from yuv to rgb --- lib/PlaYUVerFrame.cpp | 2 +- lib/PlaYUVerFramePixelFormats.cpp | 44 +++++++++++++++++++------------ lib/PlaYUVerFramePixelFormats.h | 32 ++++++---------------- 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index cbd6e34..6a229a0 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -249,7 +249,7 @@ PlaYUVerFrame::Pixel PlaYUVerFrame::ConvertPixel( PlaYUVerFrame::Pixel inputPixe if( eOutputSpace == COLOR_RGB ) { - yuvToRgb( inputPixel.Y(), inputPixel.Cb(), inputPixel.Cr(), outA, outB, outC ); + YUV2RGB( inputPixel.Y(), inputPixel.Cb(), inputPixel.Cr(), outA, outB, outC ); outPixel.R() = outA; outPixel.G() = outB; outPixel.B() = outC; diff --git a/lib/PlaYUVerFramePixelFormats.cpp b/lib/PlaYUVerFramePixelFormats.cpp index ddce223..df05e68 100644 --- a/lib/PlaYUVerFramePixelFormats.cpp +++ b/lib/PlaYUVerFramePixelFormats.cpp @@ -67,23 +67,34 @@ Void bufferFromFrameYUVProgressive( Pel*** in, Pel *out, UInt width, UInt height Void fillRGBbufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt ratioChromaHor, UInt ratioChromaVer ) { - Pel** pY = in[LUMA]; - Pel** pU = in[CHROMA_U]; - Pel** pV = in[CHROMA_V]; + Pel* pY = in[LUMA][0]; + Pel* pU = in[CHROMA_U][0]; + Pel* pV = in[CHROMA_V][0]; Int iY, iU, iV, iR, iG, iB; UInt* buff = ( UInt* )out; - for( UInt y = 0; y < height; y++ ) + pU -= width >> ratioChromaHor; + pV -= width >> ratioChromaHor; + for( UInt y = 0; y < height >> ratioChromaVer; y++ ) { - for( UInt x = 0; x < width; x++ ) + pU += width >> ratioChromaHor; + pV += width >> ratioChromaHor; + for( Int i = 0; i < 1 << ratioChromaVer; i++ ) { - // Pixel (x, y). - iY = pY[y][x]; - iU = pU[y >> ratioChromaVer][x >> ratioChromaHor] - 128; - iV = pV[y >> ratioChromaVer][x >> ratioChromaHor] - 128; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - *buff = pelRgb( iR, iG, iB ); - buff++; + for( UInt x = 0; x < width >> ratioChromaHor; x++ ) + { + iU = *pU++ - 128; + iV = *pV++ - 128; + for( Int j = 0; j < 1 << ratioChromaHor; j++ ) + { + iY = *pY++; + YUV2RGB( iY, iU, iV, iR, iG, iB ); + *buff = PEL_RGB( iR, iG, iB ); + buff++; + } + } + pU -= width >> ratioChromaHor; + pV -= width >> ratioChromaHor; } } } @@ -234,7 +245,7 @@ Void fillRGBbufferGray( Pel*** in, UChar* out, UInt width, UInt height ) for( UInt i = 0; i < height * width; i++ ) { iY = *inPel; - *buff++ = pelRgb( iY, iY, iY ); + *buff++ = PEL_RGB( iY, iY, iY ); inPel++; } } @@ -259,9 +270,9 @@ Void frameFromBufferRGB( Pel *in, Pel*** out, UInt64 size, Pel* pFirst, Pel* pSe { for( UInt i = 0; i < size; i++ ) { - *pFirst++ = *in++; + *pFirst++ = *in++; *pSecond++ = *in++; - *pthird++ = *in++; + *pthird++ = *in++; } } Void bufferFromFrameRGB( Pel ***in, Pel* out, UInt64 size, Pel* pFirst, Pel* pSecond, Pel* pthird ) @@ -285,7 +296,7 @@ Void fillRGBbufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) iR = *pR++; iG = *pG++; iB = *pB++; - *buff++ = pelRgb( iR, iG, iB ); + *buff++ = PEL_RGB( iR, iG, iB ); } } @@ -343,5 +354,4 @@ PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = RGB24, BGR24, }; - } // NAMESPACE diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 9b57c5f..b3439ea 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -22,7 +22,6 @@ * \brief Handling the pixel formats definition */ - #ifndef __PLAYUVERFRAMEPIXELFORMATS_H__ #define __PLAYUVERFRAMEPIXELFORMATS_H__ @@ -32,26 +31,13 @@ namespace plaYUVer { -static inline Void yuvToRgb( Int iY, Int iU, Int iV, Int &iR, Int &iG, Int &iB ) -{ - iR = iY + 1402 * iV / 1000; - iG = iY - ( 101004 * iU + 209599 * iV ) / 293500; - iB = iY + 1772 * iU / 1000; +#define CLAMP(X) X = X < 0 ? 0 : X > 255 ? 255 : X; - if( iR < 0 ) - iR = 0; - if( iG < 0 ) - iG = 0; - if( iB < 0 ) - iB = 0; - - if( iR > 255 ) - iR = 255; - if( iG > 255 ) - iG = 255; - if( iB > 255 ) - iB = 255; -} +#define YUV2RGB( iY, iU, iV, iR, iG, iB ) \ + iR = iY + ( ( 1436 * iV ) >> 10 ); \ + iG = iY - ( ( 352 * iU + 731 * iV ) >> 10 ); \ + iB = iY + ( ( 1812 * iU ) >> 10 ); \ + CLAMP(iR) CLAMP(iG) CLAMP(iB) static inline Void rgbToYuv( Int iR, Int iG, Int iB, Int &iY, Int &iU, Int &iV ) { @@ -80,10 +66,8 @@ inline Int pelAlpha( UInt rgb ) // get alpha part of RGBA return rgb >> 24; } -inline UInt pelRgb( Int r, Int g, Int b ) // set RGB value -{ - return ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff ); -} +#define PEL_RGB( r, g, b ) \ + ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff ) struct structPlaYUVerFramePelFormat {