diff --git a/lib/LibAvContextHandle.cpp b/lib/LibAvContextHandle.cpp index 6e33518..0d66a7d 100644 --- a/lib/LibAvContextHandle.cpp +++ b/lib/LibAvContextHandle.cpp @@ -158,7 +158,7 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& av_dict_set( &format_opts, "video_size", aux_string, 0 ); } - Int ffmpeg_pel_format = g_PlaYUVerFramePelFormatsList[pixel_format].ffmpegPelFormat; + Int ffmpeg_pel_format = g_PlaYUVerPixFmtDescriptorsList[pixel_format].ffmpegPelFormat; if( ffmpeg_pel_format >= 0 ) { av_dict_set( &format_opts, "pixel_format", av_get_pix_fmt_name( AVPixelFormat( ffmpeg_pel_format ) ), 0 ); @@ -247,7 +247,7 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& pixel_format = PlaYUVerFrame::NO_FMT; for( Int i = 0; i < PLAYUVER_NUMBER_FORMATS; i++ ) { - if( g_PlaYUVerFramePelFormatsList[i].ffmpegPelFormat == pix_fmt ) + if( g_PlaYUVerPixFmtDescriptorsList[i].ffmpegPelFormat == pix_fmt ) { pixel_format = i; break; diff --git a/lib/PlaYUVerDefs.h b/lib/PlaYUVerDefs.h index febe010..cfedd79 100644 --- a/lib/PlaYUVerDefs.h +++ b/lib/PlaYUVerDefs.h @@ -47,7 +47,8 @@ typedef unsigned int UInt; typedef double Double; typedef float Float; -//typedef uint32_t UInt32; +typedef unsigned char UInt8; +typedef unsigned int UInt16; // ==================================================================================================================== // 64-bit integer type diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index fef348d..552af17 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -47,7 +47,7 @@ std::vector PlaYUVerFrame::supportedPixelFormatListNames() Int numberFormats = PLAYUVER_NUMBER_FORMATS; for( Int i = 0; i < numberFormats; i++ ) { - formatsList.push_back( g_PlaYUVerFramePelFormatsList[i].name ); + formatsList.push_back( g_PlaYUVerPixFmtDescriptorsList[i].name ); } return formatsList; } @@ -81,12 +81,12 @@ PlaYUVerFrame::~PlaYUVerFrame() closePixfc(); } -static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int ratioDim1Chroma, Int ratioDim2Chroma ) +static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int log2ChromaHeight, Int log2ChromaWidth ) { Int dim0 = 3; Int i; UInt64 total_mem_size = 0; - UInt64 mem_size = ( dim1 * dim2 + CHROMA_RESAMPLING( dim1 ) / ratioDim1Chroma * CHROMA_RESAMPLING( dim2 ) / ratioDim2Chroma * 2 ); + UInt64 mem_size = ( dim1 * dim2 + CHROMASHIFT( dim1, log2ChromaHeight ) * CHROMASHIFT( dim2, log2ChromaWidth ) * 2 ); total_mem_size += getMem2D( array3D, dim0, dim1 ); @@ -102,8 +102,8 @@ static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int rati // Chroma ( *array3D )[1][0] = ( *array3D )[0][0] + dim2 * dim1; - dim1 = CHROMARATIO( dim1, ratioDim1Chroma ); - dim2 = CHROMARATIO( dim2, ratioDim2Chroma ); + dim1 = CHROMASHIFT( dim1, log2ChromaHeight ); + dim2 = CHROMASHIFT( dim2, log2ChromaWidth ); for( i = 1; i < dim1; i++ ) ( *array3D )[1][i] = ( *array3D )[1][i - 1] + dim2; @@ -132,7 +132,7 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format ) return; } - m_pcPelFormat = &( g_PlaYUVerFramePelFormatsList[pel_format] ); + m_pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[pel_format] ); m_bHasRGBPel = false; if( m_pcPelFormat->colorSpace == COLOR_GRAY ) @@ -141,7 +141,7 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format ) } else { - getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->ratioChromaHeight, m_pcPelFormat->ratioChromaWidth ); + getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->log2ChromaHeight, m_pcPelFormat->log2ChromaWidth ); } getMem1D( &m_pcARGB32, m_uiHeight * m_uiWidth * 4 ); @@ -166,12 +166,11 @@ UInt64 PlaYUVerFrame::getBytesPerFrame() UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelFormat ) { - PlaYUVerFramePelFormat* pcPelFormat = &( g_PlaYUVerFramePelFormatsList[iPixelFormat] ); + PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[iPixelFormat] ); UInt64 numberBytes = uiWidth * uiHeight; if( pcPelFormat->numberChannels > 1 ) { - UInt64 numberBytesChroma = ( CHROMA_RESAMPLING( uiWidth ) * CHROMA_RESAMPLING( uiHeight ) ) - / ( pcPelFormat->ratioChromaWidth * pcPelFormat->ratioChromaHeight ); + UInt64 numberBytesChroma = CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaWidth ) * CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaHeight ); numberBytes += ( pcPelFormat->numberChannels - 1 ) * numberBytesChroma; } return numberBytes; @@ -179,20 +178,12 @@ UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelF UInt PlaYUVerFrame::getChromaWidth() const { - if( m_pcPelFormat->ratioChromaWidth > 0 ) - { - return m_pcPelFormat->ratioChromaWidth > 1 ? ( m_uiWidth + 1 ) / m_pcPelFormat->ratioChromaWidth : m_uiWidth; - } - return 0; + return CHROMASHIFT( m_uiWidth, m_pcPelFormat->log2ChromaWidth ); } UInt PlaYUVerFrame::getChromaHeight() const { - if( m_pcPelFormat->ratioChromaHeight > 0 ) - { - return m_pcPelFormat->ratioChromaHeight > 1 ? ( m_uiHeight + 1 ) / m_pcPelFormat->ratioChromaHeight : m_uiHeight; - } - return 0; + return CHROMASHIFT( m_uiHeight, m_pcPelFormat->log2ChromaHeight ); } UInt PlaYUVerFrame::getChromaLength() const @@ -204,15 +195,70 @@ Void PlaYUVerFrame::frameFromBuffer( Pel *Buff, UInt64 uiBuffSize ) { if( uiBuffSize != getBytesPerFrame() ) return; - m_pcPelFormat->frameFromBuffer( Buff, m_pppcInputPel, m_uiWidth, m_uiHeight ); + + Pel* ppBuff[MAX_NUMBER_PLANES]; + Pel* pTmpPel, *pTmpBuff; + Int ratioH, ratioW, step; + UInt i, ch; + + ppBuff[0] = Buff; + for( Int i = 1; i < MAX_NUMBER_PLANES; i++ ) + { + ratioW = i > 1 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = i > 1 ? m_pcPelFormat->log2ChromaHeight : 0; + ppBuff[i] = ppBuff[i - 1] + CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); + } + + for( ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) + { + ratioW = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + step = m_pcPelFormat->comp[ch].step_minus1 + 1; + + pTmpPel = m_pppcInputPel[ch][0]; + pTmpBuff = ppBuff[m_pcPelFormat->comp[ch].plane] + ( m_pcPelFormat->comp[ch].offset_plus1 - 1 ); + + for( i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); i++ ) + { + *pTmpPel++ = *pTmpBuff; + pTmpBuff += step; + } + } + m_bHasRGBPel = false; m_bHasHistogram = false; - //fillRGBBuffer(); } Void PlaYUVerFrame::frameToBuffer( Pel *output_buffer ) { - m_pcPelFormat->bufferFromFrame( m_pppcInputPel, output_buffer, m_uiWidth, m_uiHeight ); + Pel* ppBuff[MAX_NUMBER_PLANES]; + Pel* pTmpPel, *pTmpBuff; + Int ratioH, ratioW, step; + UInt i, ch; + + ppBuff[0] = output_buffer; + for( Int i = 1; i < MAX_NUMBER_PLANES; i++ ) + { + ratioW = i > 1 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = i > 1 ? m_pcPelFormat->log2ChromaHeight : 0; + ppBuff[i] = ppBuff[i - 1] + CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); + } + + for( ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) + { + ratioW = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + step = m_pcPelFormat->comp[ch].step_minus1 + 1; + + pTmpPel = m_pppcInputPel[ch][0]; + pTmpBuff = ppBuff[m_pcPelFormat->comp[ch].plane]; + + for( i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); i++ ) + { + *pTmpBuff++ = *pTmpPel++; + } + } + } Void PlaYUVerFrame::fillRGBBuffer() @@ -234,21 +280,21 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame ) Void PlaYUVerFrame::adjustSelectedAreaDims( UInt& posX, UInt& posY, UInt& areaWidth, UInt& areaHeight, Int pelFormat ) { - PlaYUVerFramePelFormat* pcPelFormat = &( g_PlaYUVerFramePelFormatsList[pelFormat] ); - if( pcPelFormat->ratioChromaWidth ) + PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[pelFormat] ); + if( pcPelFormat->log2ChromaWidth ) { - if( posX % pcPelFormat->ratioChromaWidth ) + if( posX % ( 1 << pcPelFormat->log2ChromaWidth ) ) posX--; - if( ( posX + areaWidth ) % pcPelFormat->ratioChromaWidth ) + if( ( posX + areaWidth ) % ( 1 << pcPelFormat->log2ChromaWidth ) ) areaWidth++; } - if( pcPelFormat->ratioChromaHeight ) + if( pcPelFormat->log2ChromaHeight ) { - if( posY % pcPelFormat->ratioChromaHeight ) + if( posY % ( 1 << pcPelFormat->log2ChromaHeight ) ) posY--; - if( ( posY + areaHeight ) % pcPelFormat->ratioChromaHeight ) + if( ( posY + areaHeight ) % ( 1 << pcPelFormat->log2ChromaHeight ) ) areaHeight++; } } @@ -260,11 +306,11 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame, UInt xPos, UInt yPos ) Pel ***pInput = input_frame->getPelBufferYUV(); for( UInt ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) { - Int ratioH = ch > 0 ? m_pcPelFormat->ratioChromaHeight : 1; - Int ratioW = ch > 0 ? m_pcPelFormat->ratioChromaWidth : 1; - for( UInt i = 0; i < m_uiHeight / ratioH; i++ ) + Int ratioH = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + Int ratioW = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + for( UInt i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ); i++ ) { - memcpy( m_pppcInputPel[ch][i], &( pInput[ch][yPos / ratioH + i][xPos / ratioW] ), m_uiWidth / ratioW * sizeof(Pel) ); + memcpy( m_pppcInputPel[ch][i], &( pInput[ch][( yPos >> ratioH ) + i][( xPos >> ratioW )] ), ( m_uiWidth >> ratioW ) * sizeof(Pel) ); } } m_bHasRGBPel = false; @@ -276,9 +322,9 @@ PlaYUVerFrame::Pixel PlaYUVerFrame::getPixelValue( Int xPos, Int yPos, Int eColo PlaYUVerFrame::Pixel PixelValue( m_pcPelFormat->colorSpace, 0, 0, 0 ); for( UInt ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) { - Int ratioH = ch > 0 ? m_pcPelFormat->ratioChromaHeight : 1; - Int ratioW = ch > 0 ? m_pcPelFormat->ratioChromaWidth : 1; - PixelValue.Components()[ch] = m_pppcInputPel[ch][yPos / ratioH][xPos / ratioW]; + Int ratioH = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + Int ratioW = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + PixelValue.Components()[ch] = m_pppcInputPel[ch][( yPos >> ratioH )][( xPos >> ratioW )]; } return ConvertPixel( PixelValue, eColorSpace ); } diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index e699ceb..b2163a3 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -233,7 +233,7 @@ public: private: - struct structPlaYUVerFramePelFormat* m_pcPelFormat; + struct PlaYUVerPixFmtDescriptor* m_pcPelFormat; UInt m_uiWidth; UInt m_uiHeight; diff --git a/lib/PlaYUVerFramePixelFormats.cpp b/lib/PlaYUVerFramePixelFormats.cpp index aa316d2..703d676 100644 --- a/lib/PlaYUVerFramePixelFormats.cpp +++ b/lib/PlaYUVerFramePixelFormats.cpp @@ -51,26 +51,6 @@ namespace plaYUVer #define ADD_FFMPEG_PEL_FMT( fmt ) 0 #endif -/** - * YUV Formats - * Progressive and interlaces - */ - -Void frameFromBufferYUVProgressive( Pel* in, Pel ***out, UInt width, UInt height, UInt ratioChromaWidth, UInt ratioChromaHeight ) -{ - UInt64 chromaSize = CHROMASHIFT( width, ratioChromaWidth ) * CHROMASHIFT( height, ratioChromaHeight ); - memcpy( &out[LUMA][0][0], in, width * height * sizeof(Pel) ); - memcpy( &out[CHROMA_U][0][0], in + width * height, chromaSize * sizeof(Pel) ); - memcpy( &out[CHROMA_V][0][0], in + width * height + chromaSize, chromaSize * sizeof(Pel) ); -} - -Void bufferFromFrameYUVProgressive( Pel*** in, Pel *out, UInt width, UInt height, UInt ratioChromaWidth, UInt ratioChromaHeight ) -{ - UInt64 chromaSize = CHROMASHIFT( width, ratioChromaWidth ) * CHROMASHIFT( height, ratioChromaHeight ); - memcpy( out, &in[LUMA][0][0], width * height * sizeof(Pel) ); - memcpy( out + width * height, &in[CHROMA_U][0][0], chromaSize * sizeof(Pel) ); - memcpy( out + width * height + chromaSize, &in[CHROMA_V][0][0], chromaSize * sizeof(Pel) ); -} Void fillARGB32bufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt ratioChromaHor, UInt ratioChromaVer ) { @@ -112,18 +92,6 @@ Void fillARGB32bufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt r } } -/** - * YUV420p 12 bits per pixel - */ - -Void frameFromBufferYUV420p( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferYUVProgressive( in, out, width, height, 1, 1 ); -} -Void bufferFromFrameYUV420p( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameYUVProgressive( in, out, width, height, 1, 1 ); -} Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) { #ifdef USE_SSE @@ -271,128 +239,23 @@ Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) } } -PlaYUVerFramePelFormat yuv420p = -{ - "YUV420p", - PlaYUVerFrame::COLOR_YUV, - 3, - 2, - 2, - frameFromBufferYUV420p, - bufferFromFrameYUV420p, - fillARGB32bufferYUV420p, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ), }; -/** - * YUV444p 24 bits per pixel - */ -Void frameFromBufferYUV444p( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferYUVProgressive( in, out, width, height, 0, 0 ); -} -Void bufferFromFrameYUV444p( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameYUVProgressive( in, out, width, height, 0, 0 ); -} Void fillARGB32bufferYUV444p( Pel*** in, UChar* out, UInt width, UInt height ) { fillARGB32bufferYUV( in, out, width, height, 0, 0 ); } -PlaYUVerFramePelFormat yuv444p = -{ - "YUV444p", - PlaYUVerFrame::COLOR_YUV, - 3, - 1, - 1, - frameFromBufferYUV444p, - bufferFromFrameYUV444p, - fillARGB32bufferYUV444p, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ), }; -/** - * YUV422p 16 bits per pixel - */ -Void frameFromBufferYUV422p( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferYUVProgressive( in, out, width, height, 1, 0 ); -} -Void bufferFromFrameYUV422p( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameYUVProgressive( in, out, width, height, 1, 0 ); -} + Void fillARGB32bufferYUV422( Pel*** in, UChar* out, UInt width, UInt height ) { fillARGB32bufferYUV( in, out, width, height, 1, 0 ); } -PlaYUVerFramePelFormat yuv422p = -{ - "YUV422p", - PlaYUVerFrame::COLOR_YUV, - 3, - 2, - 1, - frameFromBufferYUV422p, - bufferFromFrameYUV422p, - fillARGB32bufferYUV422, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ), }; -/** - * YUYV422 16 bits per pixel - */ -Void frameFromBufferYUYV422( Pel *in, Pel*** out, UInt width, UInt height ) -{ - Pel* pY = out[LUMA][0]; - Pel* pU = out[CHROMA_U][0]; - Pel* pV = out[CHROMA_V][0]; - for( UInt i = 0; i < width * height / 2; i++ ) - { - *pY++ = *in++; - *pU++ = *in++; - *pY++ = *in++; - *pV++ = *in++; - } -} -Void bufferFromFrameYUYV422( Pel ***in, Pel* out, UInt width, UInt height ) -{ - Pel* pY = in[LUMA][0]; - Pel* pU = in[CHROMA_U][0]; - Pel* pV = in[CHROMA_V][0]; - for( UInt i = 0; i < height * width / 2; i++ ) - { - *out++ = *pY++; - *out++ = *pU++; - *out++ = *pY++; - *out++ = *pV++; - } -} -PlaYUVerFramePelFormat yuyv422 = -{ - "YUYV422", - PlaYUVerFrame::COLOR_YUV, - 3, - 2, - 1, - frameFromBufferYUYV422, - bufferFromFrameYUYV422, - fillARGB32bufferYUV422, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ), }; -/** - * Gray Format - */ -Void frameFromBufferGray( Pel *in, Pel*** out, UInt width, UInt height ) -{ - memcpy( &out[LUMA][0][0], in, width * height * sizeof(Pel) ); -} -Void bufferFromFrameGray( Pel ***in, Pel* out, UInt width, UInt height ) -{ - memcpy( out, &in[LUMA][0][0], width * height * sizeof(Pel) ); -} Void fillARGB32bufferGray( Pel*** in, UChar* out, UInt width, UInt height ) { Pel *inPel = in[0][0]; @@ -405,41 +268,7 @@ Void fillARGB32bufferGray( Pel*** in, UChar* out, UInt width, UInt height ) inPel++; } } -PlaYUVerFramePelFormat gray = -{ - "GRAY", - PlaYUVerFrame::COLOR_GRAY, - 1, - 0, - 0, - frameFromBufferGray, - bufferFromFrameGray, - fillARGB32bufferGray, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ), }; -/** - * RGB formats - * Interlaced - */ - -Void frameFromBufferRGB( Pel *in, Pel*** out, UInt64 size, Pel* pFirst, Pel* pSecond, Pel* pthird ) -{ - for( UInt i = 0; i < size; i++ ) - { - *pFirst++ = *in++; - *pSecond++ = *in++; - *pthird++ = *in++; - } -} -Void bufferFromFrameRGB( Pel ***in, Pel* out, UInt64 size, Pel* pFirst, Pel* pSecond, Pel* pthird ) -{ - for( UInt i = 0; i < size; i++ ) - { - *out++ = *pFirst++; - *out++ = *pSecond++; - *out++ = *pthird++; - } -} Void fillARGB32bufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) { Pel* pR = in[COLOR_R][0]; @@ -456,51 +285,122 @@ Void fillARGB32bufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) } } -/** RGB 8 bits per pixel / 3 channels */ -Void frameFromBufferRGB24( Pel *in, Pel*** out, UInt width, UInt height ) +PlaYUVerPixFmtDescriptor yuv420p = { - frameFromBufferRGB( in, out, width * height, out[COLOR_R][0], out[COLOR_G][0], out[COLOR_B][0] ); -} -Void bufferFromFrameRGB24( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameRGB( in, out, width * height, in[COLOR_R][0], in[COLOR_G][0], in[COLOR_B][0] ); -} + "YUV420p", + PlaYUVerFrame::COLOR_YUV, + 3, + 3, + 1, + 1, + fillARGB32bufferYUV420p, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ), + { + { 0, 0, 1, 0, 7 }, /* Y */ + { 1, 0, 1, 0, 7 }, /* U */ + { 2, 0, 1, 0, 7 }, /* V */ + }, +}; -PlaYUVerFramePelFormat RGB24 = +PlaYUVerPixFmtDescriptor yuv422p = +{ + "YUV422p", + PlaYUVerFrame::COLOR_YUV, + 3, + 3, + 1, + 0, + fillARGB32bufferYUV422, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ), + { + { 0, 0, 1, 0, 7 }, /* Y */ + { 1, 0, 1, 0, 7 }, /* U */ + { 2, 0, 1, 0, 7 }, /* V */ + }, +}; + +PlaYUVerPixFmtDescriptor yuv444p = +{ + "YUV444p", + PlaYUVerFrame::COLOR_YUV, + 3, + 3, + 0, + 0, + fillARGB32bufferYUV444p, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ), + { + { 0, 0, 1, 0, 7 }, /* Y */ + { 1, 0, 1, 0, 7 }, /* U */ + { 2, 0, 1, 0, 7 }, /* V */ + }, +}; + +PlaYUVerPixFmtDescriptor yuyv422 = +{ + "YUYV422", + PlaYUVerFrame::COLOR_YUV, + 3, + 1, + 1, + 0, + fillARGB32bufferYUV422, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ), + { + { 0, 1, 1, 0, 7 }, /* Y */ + { 0, 3, 2, 0, 7 }, /* U */ + { 0, 3, 4, 0, 7 }, /* V */ + }, +}; + +PlaYUVerPixFmtDescriptor gray = +{ + "GRAY", + PlaYUVerFrame::COLOR_GRAY, + 1, + 1, + 0, + 0, + fillARGB32bufferGray, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ), + { { 0, 0, 1, 0, 7 } }, /* Y */ +}; + +PlaYUVerPixFmtDescriptor RGB24 = { "RGB24", PlaYUVerFrame::COLOR_RGB, 3, 1, - 1, - frameFromBufferRGB24, - bufferFromFrameRGB24, + 0, + 0, fillARGB32bufferRGB, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), }; + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), + { + { 0, 2, 1, 0, 7 }, /* R */ + { 0, 2, 2, 0, 7 }, /* G */ + { 0, 2, 3, 0, 7 }, /* B */ + }, +}; -/** BGR 8 bits per pixel / 3 channels */ -Void frameFromBufferBGR24( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferRGB( in, out, width * height, out[COLOR_B][0], out[COLOR_G][0], out[COLOR_R][0] ); -} -Void bufferFromFrameBGR24( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameRGB( in, out, width * height, in[COLOR_B][0], in[COLOR_G][0], in[COLOR_R][0] ); -} - -PlaYUVerFramePelFormat BGR24 = +PlaYUVerPixFmtDescriptor BGR24 = { "BRG24", PlaYUVerFrame::COLOR_RGB, 3, 1, - 1, - frameFromBufferBGR24, - bufferFromFrameBGR24, + 0, + 0, fillARGB32bufferRGB, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ), }; + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ), + { + { 0, 2, 3, 0, 7 }, /* R */ + { 0, 2, 2, 0, 7 }, /* G */ + { 0, 2, 1, 0, 7 }, /* B */ + }, +}; -PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = +PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PLAYUVER_NUMBER_FORMATS] = { yuv420p, yuv444p, diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 88ce8de..0714eea 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -34,7 +34,8 @@ namespace plaYUVer #define CHROMA_RESAMPLING( X ) ( ( ( X + 1 ) >> 1 ) << 1 ) #define CHROMARATIO( SIZE, RATIO ) ( RATIO > 1 ? ( ( SIZE + 1 ) / RATIO ) : SIZE ) -#define CHROMASHIFT( SIZE, SHIFT ) ( SHIFT > 0 ? ( ( SIZE + 1 ) >> SHIFT ) : SIZE ) + +#define CHROMASHIFT( SIZE, SHIFT ) UInt( -( ( - ( Int( SIZE ) ) ) >> SHIFT ) ) #define CLAMP(X) X = X < 0 ? 0 : X > 255 ? 255 : X; @@ -74,23 +75,94 @@ inline Int pelAlpha( UInt rgb ) // get alpha part of RGBA #define PEL_RGB( r, g, b ) \ ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff ) -struct structPlaYUVerFramePelFormat +typedef struct PlaYUVerComponentDescriptor { - const Char* name; - Int colorSpace; - UInt numberChannels; - Int ratioChromaWidth; - Int ratioChromaHeight; - Void (*frameFromBuffer)( Pel *in, Pel*** out, UInt width, UInt height ); - Void (*bufferFromFrame)( Pel ***in, Pel* out, UInt width, UInt height ); - Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); - Int ffmpegPelFormat; -}; + /** + * Which of the 4 planes contains the component. + */ + UInt16 plane; -typedef struct structPlaYUVerFramePelFormat PlaYUVerFramePelFormat; + /** + * Number of elements between 2 horizontally consecutive pixels minus 1. + * Elements are bits for bitstream formats, bytes otherwise. + */ + UInt16 step_minus1; + + /** + * Number of elements before the component of the first pixel plus 1. + * Elements are bits for bitstream formats, bytes otherwise. + */ + UInt16 offset_plus1; + + /** + * Number of least significant bits that must be shifted away + * to get the value. + */ + UInt16 shift; + + /** + * Number of bits in the component minus 1. + */ + UInt16 depth_minus1; +} PlaYUVerComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV + * and all the YUV variants) AVPixFmtDescriptor just stores how values + * are stored not what these values represent. + */ +typedef struct PlaYUVerPixFmtDescriptor +{ + const char *name; + + Int colorSpace; + + UInt8 numberChannels; ///< The number of components each pixel has, (1-4) + + UInt8 numberPlanes; ///< The number of planes that should be read from the file + + /** + * Amount to shift the luma width right to find the chroma width. + * For YV12 this is 1 for example. + * chroma_width = -((-luma_width) >> log2ChromaWidth) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + UInt8 log2ChromaWidth; ///< chroma_width = -((-luma_width )>>log2ChromaWidth) + + /** + * Amount to shift the luma height right to find the chroma height. + * For YV12 this is 1 for example. + * chroma_height= -((-luma_height) >> log2ChromaHeight) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + UInt8 log2ChromaHeight; + + Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); + + Int ffmpegPelFormat; + + /** + * Parameters that describe how pixels are packed. + * If the format has 2 or 4 components, then alpha is last. + * If the format has 1 or 2 components, then luma is 0. + * If the format has 3 or 4 components, + * if the RGB flag is set then 0 is red, 1 is green and 2 is blue; + * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V. + */ + PlaYUVerComponentDescriptor comp[4]; + +} PlaYUVerPixFmtDescriptor; + +#define MAX_NUMBER_PLANES 3 #define PLAYUVER_NUMBER_FORMATS 7 -extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS]; +extern PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PLAYUVER_NUMBER_FORMATS]; } // NAMESPACE