diff --git a/CMakeLists.txt b/CMakeLists.txt index 80dc2b1..a6ea632 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ ADD_OPTION(CMAKE_BUILD_TYPE "Build type" "Debug" ) ADD_OPTION(USE_WERROR "Warnings as errors" OFF ) ADD_OPTION(USE_QT4 "Build with QT4" OFF ) ADD_OPTION(USE_OPENCV "Add OpenCV support" OFF ) -ADD_OPTION(USE_PIXFC "Add PIXFC support" ON ) +ADD_OPTION(USE_PIXFC "Add PIXFC support" OFF ) ADD_OPTION(USE_FFMPEG "Add FFMPEG support" OFF ) ###################################################################################### @@ -95,5 +95,6 @@ status(" Build type:" ${CMAKE_BUILD_TYPE} ) status(" Warnings as errors:" USE_WERROR THEN YES ELSE NO) status("Dependencies:") status(" QT:" USE_QT4 THEN "QT4" ELSE "QT5" ) -status(" Use OpenCV:" USE_OPENCV THEN YES ELSE NO) +status(" OpenCV:" USE_OPENCV THEN YES ELSE NO) status(" FFMPEG:" USE_FFMPEG THEN YES ELSE NO) +status(" Pixfc-sse:" USE_PIXFC THEN YES ELSE NO) diff --git a/source/lib/PlaYUVerFrame.cpp b/source/lib/PlaYUVerFrame.cpp index 6c7e0b9..252ed7d 100755 --- a/source/lib/PlaYUVerFrame.cpp +++ b/source/lib/PlaYUVerFrame.cpp @@ -80,6 +80,8 @@ PlaYUVerFrame::PlaYUVerFrame( UInt width, UInt height, Int pel_format ) get_mem3Dpel( &m_pppcRGBPel, 3, m_uiHeight, m_uiWidth ); } getMem1D( &m_pcRGBPelInterlaced, m_uiHeight * m_uiWidth * 3 ); + + openPixfc(); } PlaYUVerFrame::~PlaYUVerFrame() @@ -96,9 +98,89 @@ PlaYUVerFrame::~PlaYUVerFrame() if( m_pcRGBPelInterlaced ) freeMem1D( m_pcRGBPelInterlaced ); + + closePixfc(); } +Void PlaYUVerFrame::openPixfc() +{ +#ifdef USE_PIXFC + m_pcPixfc = NULL; + PixFcPixelFormat input_format = PixFcYUV420P; + PixFcFlag flags = (PixFcFlag)(PixFcFlag_Default + PixFcFlag_NNbResamplingOnly); + UInt input_row_size = m_uiWidth * 1.5; // size of each row in ARGB output buffer (in bytes) + if (create_pixfc(&m_pcPixfc, input_format, PixFcRGB24, m_uiWidth, m_uiHeight, input_row_size, m_uiWidth * 3, flags ) != 0) { + fprintf(stderr, "Error creating struct pixfc\n"); + m_pcPixfc = NULL; + return; + } +#endif +} + +Void PlaYUVerFrame::closePixfc() +{ +#ifdef USE_PIXFC + if( m_pcPixfc ) + destroy_pixfc(m_pcPixfc); +#endif +} + +#ifdef USE_PIXFC +inline Void PlaYUVerFrame::FrametoRGB8Pixfc() +{ + Pel* pInputPelY = &( m_pppcInputPel[LUMA][0][0] ); + Pel *pRGBPelR = NULL, *pRGBPelG = NULL, *pRGBPelB = NULL; + + if( m_pppcRGBPel ) + { + pRGBPelR = &( m_pppcRGBPel[COLOR_R][0][0] ); + pRGBPelG = &( m_pppcRGBPel[COLOR_G][0][0] ); + pRGBPelB = &( m_pppcRGBPel[COLOR_B][0][0] ); + } + + Pel* pcRGBPelInterlaced = m_pcRGBPelInterlaced; + + switch( m_iPixelFormat ) + { + case YUV420p: + m_pcPixfc->convert(m_pcPixfc, pInputPelY, pRGBPelR); + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + *pcRGBPelInterlaced++ = *pRGBPelR++; + *pcRGBPelInterlaced++ = *pRGBPelG++; + *pcRGBPelInterlaced++ = *pRGBPelB++; + } + break; + case YUV422p: + break; + case YUV444p: + m_pcPixfc->convert(m_pcPixfc, pInputPelY, pRGBPelR); + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + *pcRGBPelInterlaced++ = *pRGBPelR++; + *pcRGBPelInterlaced++ = *pRGBPelG++; + *pcRGBPelInterlaced++ = *pRGBPelB++; + } + break; + case YUV410p: + case YUV411p: + break; + case GRAY: + break; + case RGB8: + break; + default: + // No action. + break; + } + m_bHasRGBPel = true; +} + +#endif + template Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) { @@ -155,144 +237,151 @@ Void PlaYUVerFrame::FrametoRGB8() { if( m_bHasRGBPel ) return; - - Int iY, iU, iV, iR, iG, iB; - Pel** ppInputPelY = m_pppcInputPel[LUMA]; - Pel* pInputPelY = &( m_pppcInputPel[LUMA][0][0] ); - - Pel *pInputPelU = NULL, *pInputPelV = NULL; - Pel *pRGBPelR = NULL, *pRGBPelG = NULL, *pRGBPelB = NULL; - - if( m_pppcRGBPel ) +#ifdef USE_PIXFC + if( m_pcPixfc ) { - pRGBPelR = &( m_pppcRGBPel[COLOR_R][0][0] ); - pRGBPelG = &( m_pppcRGBPel[COLOR_G][0][0] ); - pRGBPelB = &( m_pppcRGBPel[COLOR_B][0][0] ); + FrametoRGB8Pixfc(); } - if( m_pppcInputPel[CHROMA_U] ) +#endif { - pInputPelU = m_pppcInputPel[CHROMA_U][0]; - pInputPelV = m_pppcInputPel[CHROMA_V][0]; - } + Int iY, iU, iV, iR, iG, iB; + Pel** ppInputPelY = m_pppcInputPel[LUMA]; + Pel* pInputPelY = &( m_pppcInputPel[LUMA][0][0] ); - Pel* pcRGBPelInterlaced = m_pcRGBPelInterlaced; + Pel *pInputPelU = NULL, *pInputPelV = NULL; + Pel *pRGBPelR = NULL, *pRGBPelG = NULL, *pRGBPelB = NULL; - switch( m_iPixelFormat ) - { - case YUV420p: - for( UInt y = 0; y < m_uiHeight; y += 2 ) - for( UInt x = 0; x < m_uiWidth; x += 2 ) - { - // Pixel (x, y). - iY = ppInputPelY[y][x]; - iU = *pInputPelU++ - 128; - iV = *pInputPelV++ - 128; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - m_pppcRGBPel[COLOR_R][y][x] = iR; - m_pppcRGBPel[COLOR_G][y][x] = iG; - m_pppcRGBPel[COLOR_B][y][x] = iB; - // Pixel (x+1, y) - iY = ppInputPelY[y][x + 1]; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - m_pppcRGBPel[COLOR_R][y][x + 1] = iR; - m_pppcRGBPel[COLOR_G][y][x + 1] = iG; - m_pppcRGBPel[COLOR_B][y][x + 1] = iB; - // Pixel (x, y+1) - iY = ppInputPelY[y + 1][x]; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - m_pppcRGBPel[0][y + 1][x] = iR; - m_pppcRGBPel[COLOR_G][y + 1][x] = iG; - m_pppcRGBPel[COLOR_B][y + 1][x] = iB; - // Pixel (x+1, y+1) - iY = ppInputPelY[y + 1][x + 1]; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - m_pppcRGBPel[COLOR_R][y + 1][x + 1] = iR; - m_pppcRGBPel[COLOR_G][y + 1][x + 1] = iG; - m_pppcRGBPel[COLOR_B][y + 1][x + 1] = iB; - } - for( UInt y = 0; y < m_uiHeight; y++ ) - for( UInt x = 0; x < m_uiWidth; x++ ) - { - *pcRGBPelInterlaced++ = *pRGBPelR++; - *pcRGBPelInterlaced++ = *pRGBPelG++; - *pcRGBPelInterlaced++ = *pRGBPelB++; - } - break; - case YUV422p: - for( UInt y = 0; y < m_uiHeight; y += 1 ) - for( UInt x = 0; x < m_uiWidth; x += 2 ) - { - // Pixel (x, y). - iY = ppInputPelY[y][x]; - iU = *pInputPelU++ - 128; - iV = *pInputPelV++ - 128; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - m_pppcRGBPel[COLOR_R][y][x] = iR; - m_pppcRGBPel[COLOR_G][y][x] = iG; - m_pppcRGBPel[COLOR_B][y][x] = iB; - // Pixel (x+1, y) - iY = ppInputPelY[y][x + 1]; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - m_pppcRGBPel[COLOR_R][y][x + 1] = iR; - m_pppcRGBPel[COLOR_G][y][x + 1] = iG; - m_pppcRGBPel[COLOR_B][y][x + 1] = iB; - } - for( UInt y = 0; y < m_uiHeight; y++ ) - for( UInt x = 0; x < m_uiWidth; x++ ) - { - *pcRGBPelInterlaced++ = *pRGBPelR++; - *pcRGBPelInterlaced++ = *pRGBPelG++; - *pcRGBPelInterlaced++ = *pRGBPelB++; - } - break; - case YUV444p: - for( UInt y = 0; y < m_uiHeight; y++ ) - for( UInt x = 0; x < m_uiWidth; x++ ) - { - iY = *pInputPelY++; - iU = *pInputPelU++ - 128; - iV = *pInputPelV++ - 128; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - *pRGBPelR++ = iR; - *pRGBPelG++ = iG; - *pRGBPelB++ = iB; - *pcRGBPelInterlaced++ = iR; - *pcRGBPelInterlaced++ = iG; - *pcRGBPelInterlaced++ = iB; - } - break; - case YUV410p: - case YUV411p: - break; - case GRAY: - for( UInt y = 0; y < m_uiHeight; y++ ) - for( UInt x = 0; x < m_uiWidth; x++ ) - { - iY = *pInputPelY++; - //yuvToRgb( iY, iY, iY, iR, iG, iB ); - iR = iG = iB = iY; - *pRGBPelR++ = iR; - *pRGBPelG++ = iG; - *pRGBPelB++ = iB; - *pcRGBPelInterlaced++ = iR; - *pcRGBPelInterlaced++ = iG; - *pcRGBPelInterlaced++ = iB; - } - break; - case RGB8: - for( UInt y = 0; y < m_uiHeight; y++ ) - for( UInt x = 0; x < m_uiWidth; x++ ) - { - *pcRGBPelInterlaced++ = *pRGBPelR++; - *pcRGBPelInterlaced++ = *pRGBPelG++; - *pcRGBPelInterlaced++ = *pRGBPelB++; - } - break; - default: - // No action. - break; + if( m_pppcRGBPel ) + { + pRGBPelR = &( m_pppcRGBPel[COLOR_R][0][0] ); + pRGBPelG = &( m_pppcRGBPel[COLOR_G][0][0] ); + pRGBPelB = &( m_pppcRGBPel[COLOR_B][0][0] ); + } + if( m_pppcInputPel[CHROMA_U] ) + { + pInputPelU = m_pppcInputPel[CHROMA_U][0]; + pInputPelV = m_pppcInputPel[CHROMA_V][0]; + } + + Pel* pcRGBPelInterlaced = m_pcRGBPelInterlaced; + + switch( m_iPixelFormat ) + { + case YUV420p: + for( UInt y = 0; y < m_uiHeight; y += 2 ) + for( UInt x = 0; x < m_uiWidth; x += 2 ) + { + // Pixel (x, y). + iY = ppInputPelY[y][x]; + iU = *pInputPelU++ - 128; + iV = *pInputPelV++ - 128; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[COLOR_R][y][x] = iR; + m_pppcRGBPel[COLOR_G][y][x] = iG; + m_pppcRGBPel[COLOR_B][y][x] = iB; + // Pixel (x+1, y) + iY = ppInputPelY[y][x + 1]; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[COLOR_R][y][x + 1] = iR; + m_pppcRGBPel[COLOR_G][y][x + 1] = iG; + m_pppcRGBPel[COLOR_B][y][x + 1] = iB; + // Pixel (x, y+1) + iY = ppInputPelY[y + 1][x]; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[0][y + 1][x] = iR; + m_pppcRGBPel[COLOR_G][y + 1][x] = iG; + m_pppcRGBPel[COLOR_B][y + 1][x] = iB; + // Pixel (x+1, y+1) + iY = ppInputPelY[y + 1][x + 1]; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[COLOR_R][y + 1][x + 1] = iR; + m_pppcRGBPel[COLOR_G][y + 1][x + 1] = iG; + m_pppcRGBPel[COLOR_B][y + 1][x + 1] = iB; + } + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + *pcRGBPelInterlaced++ = *pRGBPelR++; + *pcRGBPelInterlaced++ = *pRGBPelG++; + *pcRGBPelInterlaced++ = *pRGBPelB++; + } + break; + case YUV422p: + for( UInt y = 0; y < m_uiHeight; y += 1 ) + for( UInt x = 0; x < m_uiWidth; x += 2 ) + { + // Pixel (x, y). + iY = ppInputPelY[y][x]; + iU = *pInputPelU++ - 128; + iV = *pInputPelV++ - 128; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[COLOR_R][y][x] = iR; + m_pppcRGBPel[COLOR_G][y][x] = iG; + m_pppcRGBPel[COLOR_B][y][x] = iB; + // Pixel (x+1, y) + iY = ppInputPelY[y][x + 1]; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[COLOR_R][y][x + 1] = iR; + m_pppcRGBPel[COLOR_G][y][x + 1] = iG; + m_pppcRGBPel[COLOR_B][y][x + 1] = iB; + } + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + *pcRGBPelInterlaced++ = *pRGBPelR++; + *pcRGBPelInterlaced++ = *pRGBPelG++; + *pcRGBPelInterlaced++ = *pRGBPelB++; + } + break; + case YUV444p: + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + iY = *pInputPelY++; + iU = *pInputPelU++ - 128; + iV = *pInputPelV++ - 128; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + *pRGBPelR++ = iR; + *pRGBPelG++ = iG; + *pRGBPelB++ = iB; + *pcRGBPelInterlaced++ = iR; + *pcRGBPelInterlaced++ = iG; + *pcRGBPelInterlaced++ = iB; + } + break; + case YUV410p: + case YUV411p: + break; + case GRAY: + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + iY = *pInputPelY++; + //yuvToRgb( iY, iY, iY, iR, iG, iB ); + iR = iG = iB = iY; + *pRGBPelR++ = iR; + *pRGBPelG++ = iG; + *pRGBPelB++ = iB; + *pcRGBPelInterlaced++ = iR; + *pcRGBPelInterlaced++ = iG; + *pcRGBPelInterlaced++ = iB; + } + break; + case RGB8: + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + *pcRGBPelInterlaced++ = *pRGBPelR++; + *pcRGBPelInterlaced++ = *pRGBPelG++; + *pcRGBPelInterlaced++ = *pRGBPelB++; + } + break; + default: + // No action. + break; + } + m_bHasRGBPel = true; } - m_bHasRGBPel = true; } Void PlaYUVerFrame::FrameFromBuffer( Pel *input_buffer, Int pel_format ) diff --git a/source/lib/PlaYUVerFrame.h b/source/lib/PlaYUVerFrame.h index 8e78542..f36a9e8 100755 --- a/source/lib/PlaYUVerFrame.h +++ b/source/lib/PlaYUVerFrame.h @@ -31,9 +31,12 @@ #include #include #include - +#ifdef USE_PIXFC +#include "pixfc-sse.h" +#endif #include "TypeDef.h" + class QImage; namespace plaYUVer @@ -132,6 +135,13 @@ private: Pel** m_pppcInputPel[3]; Pel*** m_pppcRGBPel; UChar* m_pcRGBPelInterlaced; + + Void openPixfc(); + Void closePixfc(); +#ifdef USE_PIXFC + PixFcSSE* m_pcPixfc; + inline Void FrametoRGB8Pixfc(); +#endif }; } // NAMESPACE