diff --git a/source/app/ConfigureFormatDialog.cpp b/source/app/ConfigureFormatDialog.cpp index d33a51b..a5bc019 100644 --- a/source/app/ConfigureFormatDialog.cpp +++ b/source/app/ConfigureFormatDialog.cpp @@ -150,7 +150,7 @@ ConfigureFormatDialog::ConfigureFormatDialog( QWidget *parent ) : m_comboBoxPixelFormat->setSizePolicy( sizePolicyPixelFormat ); m_comboBoxPixelFormat->setAcceptDrops( true ); m_comboBoxPixelFormat->clear(); - m_comboBoxPixelFormat->insertItems( 0, PlaYUVerFrame::supportedPixelFormatList() ); + m_comboBoxPixelFormat->insertItems( 0, PlaYUVerFrame::supportedPixelFormatListNames() ); m_comboBoxPixelFormat->setCurrentIndex( 1 ); MainLayout->addItem( new QSpacerItem( 10, 20, QSizePolicy::Minimum ) ); diff --git a/source/app/PropertiesSidebar.cpp b/source/app/PropertiesSidebar.cpp index 69d7a03..c80f398 100644 --- a/source/app/PropertiesSidebar.cpp +++ b/source/app/PropertiesSidebar.cpp @@ -169,7 +169,7 @@ Void StreamPropertiesSideBar::setData( PlaYUVerStream* pcStream ) UInt fps = m_pcStream->getFrameRate(); value = QString( tr( "%1 x %2 @ %3 Hz" ) ).arg( width ).arg( height ).arg( fps ); labelSizeValue->setText( value ); - value = QString( PlaYUVerFrame::supportedPixelFormatList().at( m_pcStream->getCurrFrame()->getPelFormat() ) ); + value = QString( PlaYUVerFrame::supportedPixelFormatListNames().at( m_pcStream->getCurrFrame()->getPelFormat() ) ); labelColorSpaceValue->setText( value ); } } diff --git a/source/lib/PlaYUVerFrame.cpp b/source/lib/PlaYUVerFrame.cpp index d88e765..d9d2ca8 100644 --- a/source/lib/PlaYUVerFrame.cpp +++ b/source/lib/PlaYUVerFrame.cpp @@ -26,6 +26,10 @@ #include #include "LibMemory.h" #include "PlaYUVerFrame.h" +#include "PlaYUVerFramePixelFormats.h" +#ifdef USE_FFMPEG +#include "LibAvContextHandle.h" +#endif #ifdef USE_OPENCV #include #endif @@ -36,6 +40,9 @@ namespace plaYUVer { + + + Int PlaYUVerFrame::isRGBorYUVorGray( Int pixel_format ) { switch( pixel_format ) @@ -56,7 +63,7 @@ Int PlaYUVerFrame::isRGBorYUVorGray( Int pixel_format ) return COLOR_INVALID; } -QStringList PlaYUVerFrame::supportedPixelFormatList() +QStringList PlaYUVerFrame::supportedPixelFormatListNames() { QStringList formats; Int numberFormats = PLAYUVER_NUMBER_FORMATS; @@ -253,51 +260,15 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame, UInt xPos, UInt yPos ) if( m_iPixelFormat != input_frame->getPelFormat() ) return; m_bHasRGBPel = false; - - switch( m_iPixelFormat ) + Pel ***pInput = input_frame->getPelBufferYUV(); + for( Int ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) { - case YUV420p: - for( UInt i = 0; i < m_uiHeight / 2; i++ ) + 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++ ) { - memcpy( m_pppcInputPel[LUMA][( i << 1 )], &( input_frame->getPelBufferYUV()[LUMA][yPos + ( i << 1 )][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[LUMA][( i << 1 ) + 1], &( input_frame->getPelBufferYUV()[LUMA][yPos + ( i << 1 ) + 1][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[CHROMA_U][i], &( input_frame->getPelBufferYUV()[CHROMA_U][yPos / 2 + i][xPos / 2] ), m_uiWidth / 2 * sizeof(Pel) ); - memcpy( m_pppcInputPel[CHROMA_V][i], &( input_frame->getPelBufferYUV()[CHROMA_V][yPos / 2 + i][xPos / 2] ), m_uiWidth / 2 * sizeof(Pel) ); + memcpy( m_pppcInputPel[ch][i], &( pInput[ch][yPos / ratioH + i][xPos / ratioW] ), m_uiWidth / ratioW * sizeof(Pel) ); } - break; - case YUV444p: - for( UInt i = 0; i < m_uiHeight; i++ ) - { - memcpy( m_pppcInputPel[LUMA][i], &( input_frame->getPelBufferYUV()[LUMA][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[CHROMA_U][i], &( input_frame->getPelBufferYUV()[CHROMA_U][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[CHROMA_V][i], &( input_frame->getPelBufferYUV()[CHROMA_V][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - } - break; - case YUV422p: - case YUYV422: - for( UInt i = 0; i < m_uiHeight; i++ ) - { - memcpy( m_pppcInputPel[LUMA][i], &( input_frame->getPelBufferYUV()[LUMA][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[CHROMA_U][i], &( input_frame->getPelBufferYUV()[CHROMA_U][yPos + i][xPos / 2] ), m_uiWidth / 2 * sizeof(Pel) ); - memcpy( m_pppcInputPel[CHROMA_V][i], &( input_frame->getPelBufferYUV()[CHROMA_V][yPos + i][xPos / 2] ), m_uiWidth / 2 * sizeof(Pel) ); - } - break; - case GRAY: - for( UInt i = 0; i < m_uiHeight; i++ ) - { - memcpy( m_pppcInputPel[LUMA][i], &( input_frame->getPelBufferYUV()[LUMA][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - } - break; - case RGB8: - for( UInt i = 0; i < m_uiHeight; i++ ) - { - memcpy( m_pppcInputPel[COLOR_R][i], &( input_frame->getPelBufferYUV()[LUMA][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[COLOR_G][i], &( input_frame->getPelBufferYUV()[CHROMA_U][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - memcpy( m_pppcInputPel[COLOR_B][i], &( input_frame->getPelBufferYUV()[CHROMA_V][yPos + i][xPos] ), m_uiWidth * sizeof(Pel) ); - } - break; - default: - Q_ASSERT( 0 ); } } @@ -338,6 +309,12 @@ Pixel PlaYUVerFrame::ConvertPixel( Pixel sInputPixel, Int eOutputSpace ) return sOutputPixel; } +/* + ************************************************************** + * Interface to other libs + ************************************************************** + */ + Void PlaYUVerFrame::openPixfc() { #ifdef USE_PIXFC @@ -456,9 +433,9 @@ Void PlaYUVerFrame::copyFrom( cv::Mat* opencvFrame ) UInt* buff = (UInt*)pcRGBPelInterlaced; for( UInt i = 0; i < m_uiHeight * m_uiWidth; i++ ) { - *pInputPelY++ = qRed( *buff ); - *pInputPelU++ = qGreen( *buff ); - *pInputPelV++ = qBlue( *buff++ ); + *pInputPelY++ = pelRed( *buff ); + *pInputPelU++ = pelGreen( *buff ); + *pInputPelV++ = pelBlue( *buff++ ); } m_bHasRGBPel = true; } @@ -469,10 +446,14 @@ Void PlaYUVerFrame::copyFrom( cv::Mat* opencvFrame ) } #endif -/** + +/* + ************************************************************** * Quality Related Function API + ************************************************************** */ + Double PlaYUVerFrame::getQuality( Int Metric, PlaYUVerFrame* Org, Int component ) { switch( Metric ) diff --git a/source/lib/PlaYUVerFrame.h b/source/lib/PlaYUVerFrame.h index 1820d1f..13ed8e6 100644 --- a/source/lib/PlaYUVerFrame.h +++ b/source/lib/PlaYUVerFrame.h @@ -39,73 +39,12 @@ #endif class PixFcSSE; +struct AVFrame; + namespace plaYUVer { -typedef struct -{ - const Char* name; - Int colorSpace; - UInt numberChannels; - Int ratioChromaWidth; - Int ratioChromaHeight; - Pixel (*getPixelValue)( Pel ***Img, Int xPos, Int yPos ); - Void (*frameFromBuffer)( Pel *in, Pel*** out, UInt width, UInt height ); - Void (*bufferFromFrame)( Pel ***in, Pel* out, UInt width, UInt height ); - Void (*fillRGBbuffer)( Pel*** in, UChar* out, UInt width, UInt height ); - Int ffmpegPelFormat; -} PlaYUVerFramePelFormat; - -#define PLAYUVER_NUMBER_FORMATS 6 - -extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS]; - -template -Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) -{ - iR = iY + 1402 * iV / 1000; - iG = iY - ( 101004 * iU + 209599 * iV ) / 293500; - iB = iY + 1772 * iU / 1000; - - 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; -} - -template -Void rgbToYuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) -{ - iY = ( 299 * iR + 587 * iG + 114 * iB + 500 ) / 1000; - iU = ( 1000 * ( iB - iY ) + 226816 ) / 1772; - iV = ( 1000 * ( iR - iY ) + 179456 ) / 1402; -} - -inline Q_DECL_CONSTEXPR Int qRed(UInt rgb) // get red part of RGB -{ return ((rgb >> 16) & 0xff); } - -inline Q_DECL_CONSTEXPR Int qGreen(UInt rgb) // get green part of RGB -{ return ((rgb >> 8) & 0xff); } - -inline Q_DECL_CONSTEXPR Int qBlue(UInt rgb) // get blue part of RGB -{ return (rgb & 0xff); } - -inline Q_DECL_CONSTEXPR Int qAlpha(UInt rgb) // get alpha part of RGBA -{ return rgb >> 24; } - -inline Q_DECL_CONSTEXPR UInt qRgb(Int r, Int g, Int b) // set RGB value -{ return (0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } - class PlaYUVerFrame { @@ -132,7 +71,7 @@ public: }; static Int isRGBorYUVorGray( Int pixel_format ); - static QStringList supportedPixelFormatList(); + static QStringList supportedPixelFormatListNames(); PlaYUVerFrame( UInt width = 0, UInt height = 0, Int pel_format = 0 ); PlaYUVerFrame( PlaYUVerFrame *other ); @@ -198,11 +137,20 @@ public: return m_pcRGB32; } + /** + * Interface to other libs + */ + Void copyFrom( struct AVFrame * ); + #ifdef USE_OPENCV cv::Mat getCvMat(); Void copyFrom( cv::Mat* ); #endif + /** + * Quality metrics interface + */ + enum QualityMetrics { NO_METRIC = -1, @@ -230,7 +178,7 @@ public: private: - PlaYUVerFramePelFormat* m_pcPelFormat; + struct structPlaYUVerFramePelFormat* m_pcPelFormat; UInt m_uiWidth; UInt m_uiHeight; diff --git a/source/lib/PlaYUVerFramePixelFormats.cpp b/source/lib/PlaYUVerFramePixelFormats.cpp index bb69063..2cf154b 100644 --- a/source/lib/PlaYUVerFramePixelFormats.cpp +++ b/source/lib/PlaYUVerFramePixelFormats.cpp @@ -18,21 +18,28 @@ */ /** - * \file PlaYUVerFrame.cpp - * \brief Video Frame handling + * \file PlaYUVerFramePixelFormats.cpp + * \brief Handling the pixel formats definition */ #include "config.h" #include #include "LibMemory.h" -#include "PlaYUVerFrame.h" #ifdef USE_FFMPEG #include "LibAvContextHandle.h" #endif +#include "PlaYUVerFramePixelFormats.h" namespace plaYUVer { +/* + ************************************************************** + * Handle different pel formats + * Interface to generalise into one struct the pixel formats + ************************************************************** + */ + #ifdef USE_FFMPEG #define ADD_FFMPEG_PEL_FMT( fmt ) fmt #else @@ -75,7 +82,7 @@ Void fillRGBbufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt rati iU = pU[y >> ratioChromaVer][x >> ratioChromaHor] - 128; iV = pV[y >> ratioChromaVer][x >> ratioChromaHor] - 128; yuvToRgb( iY, iU, iV, iR, iG, iB ); - *buff = qRgb( iR, iG, iB ); + *buff = pelRgb( iR, iG, iB ); buff++; } } @@ -259,10 +266,13 @@ Void bufferFromFrameGray( Pel ***in, Pel* out, UInt width, UInt height ) Void fillRGBbufferGray( Pel*** in, UChar* out, UInt width, UInt height ) { Pel *inPel = in[0][0]; + Pel iY; UInt* buff = ( UInt* )out; for( UInt i = 0; i < height * width; i++ ) { - *buff++ = qRgb( *inPel, *inPel, *inPel++ ); + iY = *inPel; + *buff++ = pelRgb( iY, iY, iY ); + inPel++; } } PlaYUVerFramePelFormat gray = @@ -329,7 +339,7 @@ Void fillRGBbufferRGB24( Pel*** in, UChar* out, UInt width, UInt height ) iR = *pR++; iG = *pG++; iB = *pB++; - *buff++ = qRgb( iR, iG, iB ); + *buff++ = pelRgb( iR, iG, iB ); } } PlaYUVerFramePelFormat rgb24 = @@ -345,7 +355,7 @@ PlaYUVerFramePelFormat rgb24 = fillRGBbufferRGB24, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), }; -extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = +PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = { yuv420p, yuv444p, @@ -354,4 +364,5 @@ extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORM gray, rgb24, }; + } // NAMESPACE diff --git a/source/lib/PlaYUVerFramePixelFormats.h b/source/lib/PlaYUVerFramePixelFormats.h new file mode 100644 index 0000000..a3c98a3 --- /dev/null +++ b/source/lib/PlaYUVerFramePixelFormats.h @@ -0,0 +1,111 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com) + * Joao Carreira (jfmcarreira@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file PlaYUVerFramePixelFormats.h + * \brief Handling the pixel formats definition + */ + + +#ifndef __PLAYUVERFRAMEPIXELFORMATS_H__ +#define __PLAYUVERFRAMEPIXELFORMATS_H__ + +#include "PlaYUVerDefs.h" +#include "PlaYUVerFrame.h" + +namespace plaYUVer +{ + +template +Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) +{ + iR = iY + 1402 * iV / 1000; + iG = iY - ( 101004 * iU + 209599 * iV ) / 293500; + iB = iY + 1772 * iU / 1000; + + 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; +} + +template +Void rgbToYuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) +{ + iY = ( 299 * iR + 587 * iG + 114 * iB + 500 ) / 1000; + iU = ( 1000 * ( iB - iY ) + 226816 ) / 1772; + iV = ( 1000 * ( iR - iY ) + 179456 ) / 1402; +} + +inline Int pelRed( UInt rgb ) // get red part of RGB +{ + return ( ( rgb >> 16 ) & 0xff ); +} + +inline Int pelGreen( UInt rgb ) // get green part of RGB +{ + return ( ( rgb >> 8 ) & 0xff ); +} + +inline Int pelBlue( UInt rgb ) // get blue part of RGB +{ + return ( rgb & 0xff ); +} + +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 ); +} + +struct structPlaYUVerFramePelFormat +{ + const Char* name; + Int colorSpace; + UInt numberChannels; + Int ratioChromaWidth; + Int ratioChromaHeight; + Pixel (*getPixelValue)( Pel ***Img, Int xPos, Int yPos ); + Void (*frameFromBuffer)( Pel *in, Pel*** out, UInt width, UInt height ); + Void (*bufferFromFrame)( Pel ***in, Pel* out, UInt width, UInt height ); + Void (*fillRGBbuffer)( Pel*** in, UChar* out, UInt width, UInt height ); + Int ffmpegPelFormat; +}; + +typedef struct structPlaYUVerFramePelFormat PlaYUVerFramePelFormat; + +#define PLAYUVER_NUMBER_FORMATS 6 +extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS]; + +} // NAMESPACE + +#endif // __PLAYUVERFRAMEPIXELFORMATS_H__ diff --git a/source/lib/PlaYUVerStream.cpp b/source/lib/PlaYUVerStream.cpp index 8980c90..f4f5769 100644 --- a/source/lib/PlaYUVerStream.cpp +++ b/source/lib/PlaYUVerStream.cpp @@ -243,7 +243,7 @@ Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_ m_cStreamInformationString.append( QString( " / " ) ); m_cStreamInformationString.append( m_cCodedName ); m_cStreamInformationString.append( QString( " / " ) ); - m_cStreamInformationString.append( PlaYUVerFrame::supportedPixelFormatList().at( m_iPixelFormat ) ); + m_cStreamInformationString.append( PlaYUVerFrame::supportedPixelFormatListNames().at( m_iPixelFormat ) ); m_cStreamInformationString.append( "] " ); m_cStreamInformationString.append( QFileInfo( m_cFilename ).fileName() ); @@ -348,7 +348,7 @@ Bool PlaYUVerStream::guessFormat( QString filename, UInt& rWidth, UInt& rHeight, { bRet = true; // Guess pixel format - QStringList formats_list = PlaYUVerFrame::supportedPixelFormatList(); + QStringList formats_list = PlaYUVerFrame::supportedPixelFormatListNames(); for( Int i = 0; i < formats_list.size(); i++ ) { if( FilenameShort.contains( formats_list.at( i ), Qt::CaseInsensitive ) ) @@ -609,7 +609,7 @@ Bool PlaYUVerStream::saveFrame( const QString& filename, PlaYUVerFrame *saveFram else { saveFrame->fillRGBBuffer(); - QImage qimg = QImage( saveFrame->getRGBBuffer(), saveFrame->getWidth(), saveFrame->getHeight(), QImage::Format_RGB888 ); + QImage qimg = QImage( saveFrame->getRGBBuffer(), saveFrame->getWidth(), saveFrame->getHeight(), QImage::Format_RGB32 ); return qimg.save( filename ); } return false; diff --git a/source/lib/ffmpeg/LibAvContextHandle.cpp b/source/lib/ffmpeg/LibAvContextHandle.cpp index a6a2eea..0b0ce21 100644 --- a/source/lib/ffmpeg/LibAvContextHandle.cpp +++ b/source/lib/ffmpeg/LibAvContextHandle.cpp @@ -25,6 +25,7 @@ #include #include "LibAvContextHandle.h" #include "PlaYUVerFrame.h" +#include "PlaYUVerFramePixelFormats.h" namespace plaYUVer {