Improve PlaYUVerPixel and add support for RGBA format

Changes ColorSpace enum
Add Alpha channel support in pixel class
Add RGBA pixel format to the list of supported formats
This commit is contained in:
2018-02-04 20:32:59 +00:00
parent d735df75fd
commit 2d6ba03d4a
8 changed files with 287 additions and 243 deletions
+3 -3
View File
@@ -295,7 +295,7 @@ Void FramePropertiesDock::setFrame( PlaYUVerFrame* pcFrame )
if( m_iLastFrameType != colorSpace )
{
m_iLastFrameType = colorSpace;
if( colorSpace == PlaYUVerPixel::COLOR_RGB || colorSpace == PlaYUVerPixel::COLOR_ARGB )
if( colorSpace == PlaYUVerPixel::COLOR_RGB || colorSpace == PlaYUVerPixel::COLOR_RGBA )
{
channelCB->clear();
channelCB->clear();
@@ -303,7 +303,7 @@ Void FramePropertiesDock::setFrame( PlaYUVerFrame* pcFrame )
channelCB->insertItem( FirstChannel, QIcon( ":/images/channel-red.png" ), "Red" );
channelCB->insertItem( SecondChannel, QIcon( ":/images/channel-green.png" ), "Green" );
channelCB->insertItem( ThirdChannel, QIcon( ":/images/channel-blue.png" ), "Blue" );
if( colorSpace == PlaYUVerPixel::COLOR_ARGB )
if( colorSpace == PlaYUVerPixel::COLOR_RGBA )
{
channelCB->insertItem( AlphaChannel, QIcon( ":/images/channel-alpha.png" ), "Alpha" );
}
@@ -513,7 +513,7 @@ Void FramePropertiesDock::slotChannelChanged( Int channel )
{
if( m_pcFrame->getColorSpace() == PlaYUVerPixel::COLOR_YUV )
channel += 1;
if( channel == AlphaChannel && m_pcFrame->getColorSpace() != PlaYUVerPixel::COLOR_ARGB )
if( channel == AlphaChannel && m_pcFrame->getColorSpace() != PlaYUVerPixel::COLOR_RGBA )
channel = ColorChannels;
switch( channel )
+24 -20
View File
@@ -977,7 +977,6 @@ Void VideoSubWindow::updatePixelValueStatusBar( const QPoint& pos )
{
if( m_pcCurrFrame )
{
PlaYUVerPixel sPixelValue;
Int iWidth, iHeight;
Int posX = pos.x();
Int posY = pos.y();
@@ -990,28 +989,33 @@ Void VideoSubWindow::updatePixelValueStatusBar( const QPoint& pos )
{
strStatus = QString( "(%1,%2) " ).arg( posX ).arg( posY );
Int ColorSpace = m_pcCurrFrame->getColorSpace();
if( ColorSpace == PlaYUVerPixel::COLOR_GRAY )
Int colorSpace = m_pcCurrFrame->getColorSpace();
PlaYUVerPixel pixelValue = m_pcCurrFrame->getPixelValue( pos.x(), pos.y() );
switch( colorSpace )
{
sPixelValue = m_pcCurrFrame->getPixelValue( pos.x(), pos.y() );
strStatus.append( QString( "Y: %1" ).arg( sPixelValue.Y() ) );
}
if( ColorSpace == PlaYUVerPixel::COLOR_YUV )
{
sPixelValue = m_pcCurrFrame->getPixelValue( pos.x(), pos.y() );
case PlaYUVerPixel::COLOR_GRAY:
strStatus.append( QString( "Y: %1" ).arg( pixelValue.Y() ) );
break;
case PlaYUVerPixel::COLOR_YUV:
strStatus.append( QString( "Y: %1 U: %2 V: %3" )
.arg( sPixelValue.Y() )
.arg( sPixelValue.Cb() )
.arg( sPixelValue.Cr() ) );
}
if( ( ColorSpace == PlaYUVerPixel::COLOR_RGB ) )
{
sPixelValue = m_pcCurrFrame->getPixelValue( pos.x(), pos.y() );
.arg( pixelValue.Y() )
.arg( pixelValue.Cb() )
.arg( pixelValue.Cr() ) );
break;
case PlaYUVerPixel::COLOR_RGB:
strStatus.append( QString( "R: %1 G: %2 B: %3" )
.arg( sPixelValue.R() )
.arg( sPixelValue.G() )
.arg( sPixelValue.B() ) );
.arg( pixelValue.R() )
.arg( pixelValue.G() )
.arg( pixelValue.B() ) );
break;
case PlaYUVerPixel::COLOR_RGBA:
strStatus.append( QString( "R: %1 G: %2 B: %3 A: %4" )
.arg( pixelValue.R() )
.arg( pixelValue.G() )
.arg( pixelValue.B() )
.arg( pixelValue.A() ) );
break;
}
emit updateStatusBar( strStatus );
}
+12 -4
View File
@@ -541,10 +541,18 @@ Void ViewArea::paintEvent( QPaintEvent* event )
else
paInter.setPen( QColor( Qt::black ) );
paInter.drawText( pixelRect, Qt::AlignCenter,
"R: " + QString::number( sPixelValue.R() ) + "\n" +
"G: " + QString::number( sPixelValue.G() ) + "\n" +
"B: " + QString::number( sPixelValue.B() ) );
paInter.drawText( pixelRect, Qt::AlignCenter, "R: " + QString::number( sPixelValue.R() ) + "\nG: " + QString::number( sPixelValue.G() ) + "\nB: " + QString::number( sPixelValue.B() ) );
}
if( ( frFormat == PlaYUVerPixel::COLOR_RGBA ) )
{
sPixelValue = m_pcCurrFrame->getPixelValue( pixelTopLeft.x(), pixelTopLeft.y() );
if( ( sPixelValue.R() + sPixelValue.G() + sPixelValue.B() ) < ( m_uiPixelHalfScale * 3 ) )
paInter.setPen( QColor( Qt::white ) );
else
paInter.setPen( QColor( Qt::black ) );
paInter.drawText( pixelRect, Qt::AlignCenter, "R: " + QString::number( sPixelValue.R() ) + "\nG: " + QString::number( sPixelValue.G() ) + "\nB: " + QString::number( sPixelValue.B() ) + "\nA: " + QString::number( sPixelValue.A() ) );
}
}
}
+73 -95
View File
@@ -41,13 +41,14 @@ std::vector<String> PlaYUVerFrame::supportedColorSpacesListNames()
"YUV",
"RGB",
"GRAY",
"ARGB",
};
}
std::vector<String> PlaYUVerFrame::supportedPixelFormatListNames()
{
std::vector<String> formatsList;
for( Int i = 0; i < NUMBER_PEL_FORMATS; i++ )
for( Int i = 0; i < numberOfFormats(); i++ )
{
formatsList.push_back( g_PlaYUVerPixFmtDescriptorsMap.at( i ).name );
}
@@ -57,7 +58,7 @@ std::vector<String> PlaYUVerFrame::supportedPixelFormatListNames()
std::vector<String> PlaYUVerFrame::supportedPixelFormatListNames( Int colorSpace )
{
std::vector<String> formatsList;
for( Int i = 0; i < NUMBER_PEL_FORMATS; i++ )
for( Int i = 0; i < numberOfFormats(); i++ )
{
if( g_PlaYUVerPixFmtDescriptorsMap.at( i ).colorSpace == colorSpace )
formatsList.push_back( g_PlaYUVerPixFmtDescriptorsMap.at( i ).name );
@@ -65,9 +66,14 @@ std::vector<String> PlaYUVerFrame::supportedPixelFormatListNames( Int colorSpace
return formatsList;
}
Int PlaYUVerFrame::numberOfFormats()
{
return g_PlaYUVerPixFmtDescriptorsMap.size();
}
Int PlaYUVerFrame::findPixelFormat( const String& name )
{
for( Int i = 0; i < NUMBER_PEL_FORMATS; i++ )
for( Int i = 0; i < numberOfFormats(); i++ )
{
if( g_PlaYUVerPixFmtDescriptorsMap.at( i ).name == name )
return i;
@@ -290,7 +296,7 @@ PlaYUVerPixel PlaYUVerPixel::ConvertPixel( ColorSpace eOutputSpace )
Int outA, outB, outC;
PlaYUVerPixel outPixel( COLOR_INVALID, 0, 0, 0 );
if( ColorSpace() == eOutputSpace || eOutputSpace == COLOR_ARGB || eOutputSpace == COLOR_GRAY )
if( ColorSpace() == eOutputSpace || eOutputSpace == COLOR_RGBA || eOutputSpace == COLOR_GRAY )
return *this;
if( eOutputSpace == COLOR_RGB )
@@ -310,51 +316,6 @@ PlaYUVerPixel PlaYUVerPixel::ConvertPixel( ColorSpace eOutputSpace )
return outPixel;
}
static Int getImgMemory( 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 + CHROMASHIFT( dim1, log2ChromaHeight ) * CHROMASHIFT( dim2, log2ChromaWidth ) * 2 );
total_mem_size += getMem2D<Pel*>( array3D, dim0, dim1 );
if( ( ( *array3D )[0][0] = (Pel*)xCallocMem( mem_size, sizeof( Pel ) ) ) == NULL )
printf( "getImgMemory: array1D" );
total_mem_size += mem_size * sizeof( Pel );
// Luma
for( i = 1; i < dim1; i++ )
( *array3D )[0][i] = ( *array3D )[0][i - 1] + dim2;
// Chroma
( *array3D )[1][0] = ( *array3D )[0][0] + dim2 * dim1;
dim1 = CHROMASHIFT( dim1, log2ChromaHeight );
dim2 = CHROMASHIFT( dim2, log2ChromaWidth );
for( i = 1; i < dim1; i++ )
( *array3D )[1][i] = ( *array3D )[1][i - 1] + dim2;
( *array3D )[2][0] = ( *array3D )[1][0] + dim2 * dim1;
for( i = 1; i < dim1; i++ )
( *array3D )[2][i] = ( *array3D )[2][i - 1] + dim2;
return total_mem_size;
}
Void freeImgMemory( Pel*** array3D )
{
if( array3D )
{
if( **array3D )
xFreeMem( **array3D );
freeMem2D( array3D );
}
}
struct PlaYUVerFramePrivate
{
Bool m_bInit;
@@ -365,12 +326,8 @@ struct PlaYUVerFramePrivate
UInt m_uiWidth; //!< Width of the frame
UInt m_uiHeight; //!< Height of the frame
Int m_iPixelFormat; //!< Pixel format number (it follows the list of
//!< supported
//! pixel formats)
Int m_iNumberChannels; //!< Number of channels
Int m_iPixelFormat; //!< Pixel format number (it follows the list of supported pixel formats)
UInt m_uiBitsPel; //!< Bits per pixel/channel
// Int m_iEndianness; //!< Endiannes of bytes
UInt m_uiHalfPelValue; //!< Bits per pixel/channel
Pel*** m_pppcInputPel;
@@ -389,22 +346,22 @@ struct PlaYUVerFramePrivate
UInt m_uiHistoSegments;
/**
* Common constructor function of a frame
*
* @param width width of the frame
* @param height height of the frame
* @param pel_format pixel format index (always use PixelFormats enum)
*
*/
* Common constructor function of a frame
*
* @param width width of the frame
* @param height height of the frame
* @param pel_format pixel format index (always use PixelFormats enum)
*
*/
Void init( UInt width, UInt height, Int pel_format, Int bitsPixel )
{
m_bInit = false;
m_bHasRGBPel = false;
m_pppcInputPel = NULL;
m_pcARGB32 = NULL;
m_uiWidth = width;
m_uiHeight = height;
m_iPixelFormat = pel_format;
m_iNumberChannels = 3;
m_uiBitsPel = bitsPixel < 8 ? 8 : bitsPixel;
m_uiHalfPelValue = 1 << ( m_uiBitsPel - 1 );
@@ -414,17 +371,39 @@ struct PlaYUVerFramePrivate
}
m_pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsMap.at( pel_format ) );
Int iNumberChannels = m_pcPelFormat->numberChannels;
m_bHasRGBPel = false;
if( m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_GRAY )
std::size_t mem_size = 0;
std::size_t num_of_ptrs = 0;
for( Int ch = 0; ch < iNumberChannels; ch++ )
{
getImgMemory( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 1 );
Int ratioW = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0;
Int ratioH = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0;
// Add pointers mem
num_of_ptrs += CHROMASHIFT( m_uiHeight, ratioH );
// Add pixel mem
mem_size += CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ) * sizeof( Pel );
}
else
mem_size += num_of_ptrs * sizeof( Pel* ) + sizeof( Pel** ) * iNumberChannels;
m_pppcInputPel = (Pel***)xMallocMem( mem_size );
Pel** pelPtrMem = (Pel**)( m_pppcInputPel + iNumberChannels );
Pel* pelMem = (Pel*)( pelPtrMem + num_of_ptrs );
for( Int ch = 0; ch < iNumberChannels; ch++ )
{
getImgMemory( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->log2ChromaHeight,
m_pcPelFormat->log2ChromaWidth );
Int ratioW = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0;
Int ratioH = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0;
m_pppcInputPel[ch] = pelPtrMem;
for( UInt h = 0; h < CHROMASHIFT( m_uiHeight, ratioH ); h++ )
{
*pelPtrMem = pelMem;
pelPtrMem++;
pelMem += CHROMASHIFT( m_uiWidth, ratioW );
}
}
/* Alloc ARGB memory */
getMem1D( &m_pcARGB32, m_uiHeight * m_uiWidth * 4 );
m_puiHistogram = NULL;
@@ -434,7 +413,7 @@ struct PlaYUVerFramePrivate
m_uiHistoSegments = 1 << m_uiBitsPel;
if( m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_RGB ||
m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_ARGB )
m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_RGBA )
m_uiHistoChannels = m_pcPelFormat->numberChannels + 1;
else
m_uiHistoChannels = m_pcPelFormat->numberChannels;
@@ -455,7 +434,7 @@ struct PlaYUVerFramePrivate
m_bHasHistogram = false;
if( m_pppcInputPel )
freeImgMemory( m_pppcInputPel );
xFreeMem( m_pppcInputPel );
if( m_pcARGB32 )
freeMem1D( m_pcARGB32 );
@@ -902,6 +881,8 @@ Void PlaYUVerFrame::frameToBuffer( Byte* output_buffer, Int iEndianness )
Void PlaYUVerFrame::fillRGBBuffer()
{
#define PEL_ARGB( a, r, g, b ) ( ( a & 0xff ) << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff )
#define PEL_RGB( r, g, b ) PEL_ARGB( 0xffu, r, g, b )
#define CLAMP_YUV2RGB( X ) X = X < 0 ? 0 : X > 255 ? 255 : X;
#define YUV2RGB( iY, iU, iV, iR, iG, iB ) \
iR = iY + ( ( 1436 * ( iV - 128 ) ) >> 10 ); \
@@ -913,21 +894,15 @@ Void PlaYUVerFrame::fillRGBBuffer()
if( d->m_bHasRGBPel )
return;
Int iR, iG, iB;
Int shiftBits = d->m_uiBitsPel - 8;
UInt* pARGB = (UInt*)d->m_pcARGB32;
if( d->m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_GRAY )
{
Pel* pY = d->m_pppcInputPel[LUMA][0];
Int iY;
for( UInt i = 0; i < d->m_uiHeight * d->m_uiWidth; i++ )
{
iY = *pY++;
iY >>= shiftBits;
iR = iY;
iG = iY;
iB = iY;
*pARGB++ = PEL_RGB( iR, iG, iB );
*pARGB++ = PEL_RGB( *pY, *pY, *pY );
pY++;
}
}
else if( d->m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_RGB )
@@ -935,14 +910,17 @@ Void PlaYUVerFrame::fillRGBBuffer()
Pel* pR = d->m_pppcInputPel[COLOR_R][0];
Pel* pG = d->m_pppcInputPel[COLOR_G][0];
Pel* pB = d->m_pppcInputPel[COLOR_B][0];
for( UInt i = 0; i < d->m_uiHeight * d->m_uiWidth; i++ )
{
iR = *pR++;
iG = *pG++;
iB = *pB++;
*pARGB++ = PEL_RGB( ( iR >> shiftBits ), ( iG >> shiftBits ), ( iB >> shiftBits ) );
}
*pARGB++ = PEL_RGB( ( *pR++ ) >> shiftBits, ( *pG++ ) >> shiftBits, ( *pB++ ) >> shiftBits );
}
else if( d->m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_RGBA )
{
Pel* pR = d->m_pppcInputPel[COLOR_R][0];
Pel* pG = d->m_pppcInputPel[COLOR_G][0];
Pel* pB = d->m_pppcInputPel[COLOR_B][0];
Pel* pA = d->m_pppcInputPel[COLOR_A][0];
for( UInt i = 0; i < d->m_uiHeight * d->m_uiWidth; i++ )
*pARGB++ = PEL_ARGB( ( *pA++ ) >> shiftBits, ( *pR++ ) >> shiftBits, ( *pG++ ) >> shiftBits, ( *pB++ ) >> shiftBits );
}
else if( d->m_pcPelFormat->colorSpace == PlaYUVerPixel::COLOR_YUV )
{
@@ -959,7 +937,7 @@ Void PlaYUVerFrame::fillRGBBuffer()
UInt y, x;
Int i, j;
for( y = 0; y<d->m_uiHeight>> d->m_pcPelFormat->log2ChromaHeight; y++ )
for( y = 0; y < CHROMASHIFT( d->m_uiHeight, d->m_pcPelFormat->log2ChromaHeight ); y++ )
{
for( i = 0; i < 1 << d->m_pcPelFormat->log2ChromaHeight; i++ )
{
@@ -967,7 +945,7 @@ Void PlaYUVerFrame::fillRGBBuffer()
pU = pLineU;
pV = pLineV;
pARGB = pARGBLine;
for( x = 0; x<d->m_uiWidth>> d->m_pcPelFormat->log2ChromaWidth; x++ )
for( x = 0; x < CHROMASHIFT( d->m_uiWidth, d->m_pcPelFormat->log2ChromaWidth ); x++ )
{
iU = *pU++;
iU >>= shiftBits;
@@ -1041,7 +1019,7 @@ Void PlaYUVerFrame::calcHistogram()
{
d->m_puiHistogram[*( data[j] ) + j * d->m_uiHistoSegments]++;
}
if( ( colorSpace == PlaYUVerPixel::COLOR_RGB || colorSpace == PlaYUVerPixel::COLOR_ARGB ) )
if( ( colorSpace == PlaYUVerPixel::COLOR_RGB || colorSpace == PlaYUVerPixel::COLOR_RGBA ) )
{
PlaYUVerPixel currPixel( colorSpace, *( data[COLOR_R] ), *( data[COLOR_G] ), *( data[COLOR_B] ) );
luma = currPixel.ConvertPixel( PlaYUVerPixel::COLOR_YUV ).Y();
@@ -1090,7 +1068,7 @@ Int getRealHistoChannel( Int colorSpace, Int channel )
}
}
break;
case PlaYUVerPixel::COLOR_ARGB:
case PlaYUVerPixel::COLOR_RGBA:
if( channel != COLOR_R && channel != COLOR_G && channel != COLOR_B && channel != COLOR_A && channel != LUMA )
{
return -1;
@@ -1309,14 +1287,14 @@ Double PlaYUVerFrame::getStdDev( Int channel, UInt start, UInt end )
/*------------ original
for ( i = start ; i <= end ; i++ )
{
dev += ( i - mean ) * ( i - mean ) * d->m_puiHistogram[indexStart +i];
}
for ( i = start ; i <= end ; i++ )
{
dev += ( i - mean ) * ( i - mean ) * d->m_puiHistogram[indexStart +i];
}
return sqrt( dev / count );
return sqrt( dev / count );
-----------------------*/
-----------------------*/
for( UInt i = start; i <= end; i++ )
{
+5 -2
View File
@@ -55,7 +55,7 @@ public:
COLOR_YUV = 0, //!< YUV
COLOR_RGB = 1, //!< RGB
COLOR_GRAY = 2, //!< Grayscale
COLOR_ARGB = 3, //!< RGB + Alpha
COLOR_RGBA = 3, //!< RGB + Alpha
COLOR_MAX = 255, //!< Accouunt for future formats
};
@@ -130,7 +130,9 @@ public:
RGBp,
RGB24,
BGR24,
NUMBER_PEL_FORMATS
RGBA,
BGRA,
PEL_FMT_MAX = 255,
};
/**
@@ -147,6 +149,7 @@ public:
*/
static std::vector<String> supportedPixelFormatListNames();
static std::vector<String> supportedPixelFormatListNames( Int colorSpace );
static Int numberOfFormats();
static Int findPixelFormat( const String& name );
/**
+169 -116
View File
@@ -53,148 +53,148 @@
Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height, UInt depth )
{
#ifdef USE_SSE
if( ( width % 16 ) == 0 )
{
uint8_t *yp = in[LUMA][0];
uint8_t *up = in[CHROMA_U][0];
uint8_t *vp = in[CHROMA_V][0];
uint32_t suv = width >> 1;
uint32_t *rgb = ( uint32_t* )out;
if( ( width % 16 ) == 0 )
{
uint8_t *yp = in[LUMA][0];
uint8_t *up = in[CHROMA_U][0];
uint8_t *vp = in[CHROMA_V][0];
uint32_t suv = width >> 1;
uint32_t *rgb = ( uint32_t* )out;
__m128i y0r0, y0r1, u0, v0;
__m128i y00r0, y01r0, y00r1, y01r1;
__m128i u00, u01, v00, v01;
__m128i rv00, rv01, gu00, gu01, gv00, gv01, bu00, bu01;
__m128i r00, r01, g00, g01, b00, b01;
__m128i rgb0123, rgb4567, rgb89ab, rgbcdef;
__m128i gbgb;
__m128i ysub, uvsub;
__m128i zero, facy, facrv, facgu, facgv, facbu;
__m128i *srcy128r0, *srcy128r1;
__m128i *dstrgb128r0, *dstrgb128r1;
__m64 *srcu64, *srcv64;
UInt x, y;
__m128i y0r0, y0r1, u0, v0;
__m128i y00r0, y01r0, y00r1, y01r1;
__m128i u00, u01, v00, v01;
__m128i rv00, rv01, gu00, gu01, gv00, gv01, bu00, bu01;
__m128i r00, r01, g00, g01, b00, b01;
__m128i rgb0123, rgb4567, rgb89ab, rgbcdef;
__m128i gbgb;
__m128i ysub, uvsub;
__m128i zero, facy, facrv, facgu, facgv, facbu;
__m128i *srcy128r0, *srcy128r1;
__m128i *dstrgb128r0, *dstrgb128r1;
__m64 *srcu64, *srcv64;
UInt x, y;
ysub = _mm_set1_epi32( 0x00100010 );
uvsub = _mm_set1_epi32( 0x00800080 );
ysub = _mm_set1_epi32( 0x00100010 );
uvsub = _mm_set1_epi32( 0x00800080 );
facy = _mm_set1_epi32( 0x004a004a );
facrv = _mm_set1_epi32( 0x00660066 );
facgu = _mm_set1_epi32( 0x00190019 );
facgv = _mm_set1_epi32( 0x00340034 );
facbu = _mm_set1_epi32( 0x00810081 );
facy = _mm_set1_epi32( 0x004a004a );
facrv = _mm_set1_epi32( 0x00660066 );
facgu = _mm_set1_epi32( 0x00190019 );
facgv = _mm_set1_epi32( 0x00340034 );
facbu = _mm_set1_epi32( 0x00810081 );
zero = _mm_set1_epi32( 0x00000000 );
zero = _mm_set1_epi32( 0x00000000 );
for( y = 0; y < height; y += 2 )
{
for( y = 0; y < height; y += 2 )
{
srcy128r0 = ( __m128i * )( yp + width * y );
srcy128r1 = ( __m128i * )( yp + width * y + width );
srcu64 = ( __m64 * )( up + suv * ( y / 2 ) );
srcv64 = ( __m64 * )( vp + suv * ( y / 2 ) );
srcy128r0 = ( __m128i * )( yp + width * y );
srcy128r1 = ( __m128i * )( yp + width * y + width );
srcu64 = ( __m64 * )( up + suv * ( y / 2 ) );
srcv64 = ( __m64 * )( vp + suv * ( y / 2 ) );
dstrgb128r0 = ( __m128i * )( rgb + width * y );
dstrgb128r1 = ( __m128i * )( rgb + width * y + width );
dstrgb128r0 = ( __m128i * )( rgb + width * y );
dstrgb128r1 = ( __m128i * )( rgb + width * y + width );
for( x = 0; x < width; x += 16 )
{
for( x = 0; x < width; x += 16 )
{
u0 = _mm_loadl_epi64( ( __m128i * )srcu64 );
srcu64++;
v0 = _mm_loadl_epi64( ( __m128i * )srcv64 );
srcv64++;
u0 = _mm_loadl_epi64( ( __m128i * )srcu64 );
srcu64++;
v0 = _mm_loadl_epi64( ( __m128i * )srcv64 );
srcv64++;
y0r0 = _mm_load_si128( srcy128r0++ );
y0r1 = _mm_load_si128( srcy128r1++ );
y0r0 = _mm_load_si128( srcy128r0++ );
y0r1 = _mm_load_si128( srcy128r1++ );
// constant y factors
y00r0 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpacklo_epi8( y0r0, zero ), ysub ), facy );
y01r0 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpackhi_epi8( y0r0, zero ), ysub ), facy );
y00r1 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpacklo_epi8( y0r1, zero ), ysub ), facy );
y01r1 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpackhi_epi8( y0r1, zero ), ysub ), facy );
// constant y factors
y00r0 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpacklo_epi8( y0r0, zero ), ysub ), facy );
y01r0 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpackhi_epi8( y0r0, zero ), ysub ), facy );
y00r1 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpacklo_epi8( y0r1, zero ), ysub ), facy );
y01r1 = _mm_mullo_epi16( _mm_sub_epi16( _mm_unpackhi_epi8( y0r1, zero ), ysub ), facy );
// expand u and v so they're aligned with y values
u0 = _mm_unpacklo_epi8( u0, zero );
u00 = _mm_sub_epi16( _mm_unpacklo_epi16( u0, u0 ), uvsub );
u01 = _mm_sub_epi16( _mm_unpackhi_epi16( u0, u0 ), uvsub );
// expand u and v so they're aligned with y values
u0 = _mm_unpacklo_epi8( u0, zero );
u00 = _mm_sub_epi16( _mm_unpacklo_epi16( u0, u0 ), uvsub );
u01 = _mm_sub_epi16( _mm_unpackhi_epi16( u0, u0 ), uvsub );
v0 = _mm_unpacklo_epi8( v0, zero );
v00 = _mm_sub_epi16( _mm_unpacklo_epi16( v0, v0 ), uvsub );
v01 = _mm_sub_epi16( _mm_unpackhi_epi16( v0, v0 ), uvsub );
v0 = _mm_unpacklo_epi8( v0, zero );
v00 = _mm_sub_epi16( _mm_unpacklo_epi16( v0, v0 ), uvsub );
v01 = _mm_sub_epi16( _mm_unpackhi_epi16( v0, v0 ), uvsub );
// common factors on both rows.
rv00 = _mm_mullo_epi16( facrv, v00 );
rv01 = _mm_mullo_epi16( facrv, v01 );
gu00 = _mm_mullo_epi16( facgu, u00 );
gu01 = _mm_mullo_epi16( facgu, u01 );
gv00 = _mm_mullo_epi16( facgv, v00 );
gv01 = _mm_mullo_epi16( facgv, v01 );
bu00 = _mm_mullo_epi16( facbu, u00 );
bu01 = _mm_mullo_epi16( facbu, u01 );
// common factors on both rows.
rv00 = _mm_mullo_epi16( facrv, v00 );
rv01 = _mm_mullo_epi16( facrv, v01 );
gu00 = _mm_mullo_epi16( facgu, u00 );
gu01 = _mm_mullo_epi16( facgu, u01 );
gv00 = _mm_mullo_epi16( facgv, v00 );
gv01 = _mm_mullo_epi16( facgv, v01 );
bu00 = _mm_mullo_epi16( facbu, u00 );
bu01 = _mm_mullo_epi16( facbu, u01 );
// row 0
r00 = _mm_srai_epi16( _mm_add_epi16( y00r0, rv00 ), 6 );
r01 = _mm_srai_epi16( _mm_add_epi16( y01r0, rv01 ), 6 );
g00 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y00r0, gu00 ), gv00 ), 6 );
g01 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y01r0, gu01 ), gv01 ), 6 );
b00 = _mm_srai_epi16( _mm_add_epi16( y00r0, bu00 ), 6 );
b01 = _mm_srai_epi16( _mm_add_epi16( y01r0, bu01 ), 6 );
// row 0
r00 = _mm_srai_epi16( _mm_add_epi16( y00r0, rv00 ), 6 );
r01 = _mm_srai_epi16( _mm_add_epi16( y01r0, rv01 ), 6 );
g00 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y00r0, gu00 ), gv00 ), 6 );
g01 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y01r0, gu01 ), gv01 ), 6 );
b00 = _mm_srai_epi16( _mm_add_epi16( y00r0, bu00 ), 6 );
b01 = _mm_srai_epi16( _mm_add_epi16( y01r0, bu01 ), 6 );
r00 = _mm_packus_epi16( r00, r01 );// rrrr.. saturated
g00 = _mm_packus_epi16( g00, g01 );// gggg.. saturated
b00 = _mm_packus_epi16( b00, b01 );// bbbb.. saturated
r00 = _mm_packus_epi16( r00, r01 );// rrrr.. saturated
g00 = _mm_packus_epi16( g00, g01 );// gggg.. saturated
b00 = _mm_packus_epi16( b00, b01 );// bbbb.. saturated
r01 = _mm_unpacklo_epi8( r00, zero );// 0r0r..
gbgb = _mm_unpacklo_epi8( b00, g00 );// gbgb..
rgb0123 = _mm_unpacklo_epi16( gbgb, r01 );// 0rgb0rgb..
rgb4567 = _mm_unpackhi_epi16( gbgb, r01 );// 0rgb0rgb..
r01 = _mm_unpacklo_epi8( r00, zero );// 0r0r..
gbgb = _mm_unpacklo_epi8( b00, g00 );// gbgb..
rgb0123 = _mm_unpacklo_epi16( gbgb, r01 );// 0rgb0rgb..
rgb4567 = _mm_unpackhi_epi16( gbgb, r01 );// 0rgb0rgb..
r01 = _mm_unpackhi_epi8( r00, zero );
gbgb = _mm_unpackhi_epi8( b00, g00 );
rgb89ab = _mm_unpacklo_epi16( gbgb, r01 );
rgbcdef = _mm_unpackhi_epi16( gbgb, r01 );
r01 = _mm_unpackhi_epi8( r00, zero );
gbgb = _mm_unpackhi_epi8( b00, g00 );
rgb89ab = _mm_unpacklo_epi16( gbgb, r01 );
rgbcdef = _mm_unpackhi_epi16( gbgb, r01 );
_mm_store_si128( dstrgb128r0++, rgb0123 );
_mm_store_si128( dstrgb128r0++, rgb4567 );
_mm_store_si128( dstrgb128r0++, rgb89ab );
_mm_store_si128( dstrgb128r0++, rgbcdef );
_mm_store_si128( dstrgb128r0++, rgb0123 );
_mm_store_si128( dstrgb128r0++, rgb4567 );
_mm_store_si128( dstrgb128r0++, rgb89ab );
_mm_store_si128( dstrgb128r0++, rgbcdef );
// row 1
r00 = _mm_srai_epi16( _mm_add_epi16( y00r1, rv00 ), 6 );
r01 = _mm_srai_epi16( _mm_add_epi16( y01r1, rv01 ), 6 );
g00 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y00r1, gu00 ), gv00 ), 6 );
g01 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y01r1, gu01 ), gv01 ), 6 );
b00 = _mm_srai_epi16( _mm_add_epi16( y00r1, bu00 ), 6 );
b01 = _mm_srai_epi16( _mm_add_epi16( y01r1, bu01 ), 6 );
// row 1
r00 = _mm_srai_epi16( _mm_add_epi16( y00r1, rv00 ), 6 );
r01 = _mm_srai_epi16( _mm_add_epi16( y01r1, rv01 ), 6 );
g00 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y00r1, gu00 ), gv00 ), 6 );
g01 = _mm_srai_epi16( _mm_sub_epi16( _mm_sub_epi16( y01r1, gu01 ), gv01 ), 6 );
b00 = _mm_srai_epi16( _mm_add_epi16( y00r1, bu00 ), 6 );
b01 = _mm_srai_epi16( _mm_add_epi16( y01r1, bu01 ), 6 );
r00 = _mm_packus_epi16( r00, r01 );// rrrr.. saturated
g00 = _mm_packus_epi16( g00, g01 );// gggg.. saturated
b00 = _mm_packus_epi16( b00, b01 );// bbbb.. saturated
r00 = _mm_packus_epi16( r00, r01 );// rrrr.. saturated
g00 = _mm_packus_epi16( g00, g01 );// gggg.. saturated
b00 = _mm_packus_epi16( b00, b01 );// bbbb.. saturated
r01 = _mm_unpacklo_epi8( r00, zero );// 0r0r..
gbgb = _mm_unpacklo_epi8( b00, g00 );// gbgb..
rgb0123 = _mm_unpacklo_epi16( gbgb, r01 );// 0rgb0rgb..
rgb4567 = _mm_unpackhi_epi16( gbgb, r01 );// 0rgb0rgb..
r01 = _mm_unpacklo_epi8( r00, zero );// 0r0r..
gbgb = _mm_unpacklo_epi8( b00, g00 );// gbgb..
rgb0123 = _mm_unpacklo_epi16( gbgb, r01 );// 0rgb0rgb..
rgb4567 = _mm_unpackhi_epi16( gbgb, r01 );// 0rgb0rgb..
r01 = _mm_unpackhi_epi8( r00, zero );
gbgb = _mm_unpackhi_epi8( b00, g00 );
rgb89ab = _mm_unpacklo_epi16( gbgb, r01 );
rgbcdef = _mm_unpackhi_epi16( gbgb, r01 );
r01 = _mm_unpackhi_epi8( r00, zero );
gbgb = _mm_unpackhi_epi8( b00, g00 );
rgb89ab = _mm_unpacklo_epi16( gbgb, r01 );
rgbcdef = _mm_unpackhi_epi16( gbgb, r01 );
_mm_store_si128( dstrgb128r1++, rgb0123 );
_mm_store_si128( dstrgb128r1++, rgb4567 );
_mm_store_si128( dstrgb128r1++, rgb89ab );
_mm_store_si128( dstrgb128r1++, rgbcdef );
_mm_store_si128( dstrgb128r1++, rgb0123 );
_mm_store_si128( dstrgb128r1++, rgb4567 );
_mm_store_si128( dstrgb128r1++, rgb89ab );
_mm_store_si128( dstrgb128r1++, rgbcdef );
}
}
}
else
}
}
}
else
#endif
{
fillARGB32bufferYUV( in, out, width, height, depth, 1, 1 );
}
{
fillARGB32bufferYUV( in, out, width, height, depth, 1, 1 );
}
}
#endif
@@ -331,4 +331,57 @@ const std::map<int, PlaYUVerPixFmtDescriptor> g_PlaYUVerPixFmtDescriptorsMap = {
},
},
},
{
PlaYUVerFrame::BGR24,
{
"BGR",
PlaYUVerPixel::COLOR_RGB,
3,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ),
{
{0, 2, 3}, /* R */
{0, 2, 2}, /* G */
{0, 2, 1}, /* B */
},
},
},
{
PlaYUVerFrame::RGBA,
{
"RGBA",
PlaYUVerPixel::COLOR_RGBA,
4,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGBA ),
{
{0, 3, 1}, /* R */
{0, 3, 2}, /* G */
{0, 3, 3}, /* B */
{0, 3, 4}, /* A */
},
},
},
{
PlaYUVerFrame::BGRA,
{
"BGRA",
PlaYUVerPixel::COLOR_RGBA,
4,
1,
0,
0,
ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGRA ),
{
{0, 3, 3}, /* R */
{0, 3, 2}, /* G */
{0, 3, 1}, /* B */
{0, 3, 4}, /* A */
},
},
},
};
-2
View File
@@ -34,8 +34,6 @@
#define CHROMARATIO( SIZE, RATIO ) ( RATIO > 1 ? ( ( SIZE + 1 ) / RATIO ) : SIZE )
#define PEL_RGB( r, g, b ) ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff )
typedef struct PlaYUVerComponentDescriptor
{
/**
+1 -1
View File
@@ -199,7 +199,7 @@ Bool StreamHandlerLibav::openHandler( String strFilename, Bool bInput )
}
m_iPixelFormat = PlaYUVerFrame::NO_FMT;
for( Int i = 0; i < PlaYUVerFrame::NUMBER_PEL_FORMATS; i++ )
for( Int i = 0; i < PlaYUVerFrame::numberOfFormats(); i++ )
{
if( g_PlaYUVerPixFmtDescriptorsMap.at( i ).ffmpegPelFormat == auxPixFmt )
{