From d735df75fdb0ac7fb6e029400eee18d50a5bfa4e Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sun, 4 Feb 2018 19:32:00 +0000 Subject: [PATCH] Fix bug with PlaYUVerPixel --- app/VideoSubWindow.cpp | 12 ++- lib/PlaYUVerFrame.cpp | 144 +++++++++++++++++++++++---------- lib/PlaYUVerFrame.h | 176 +++++++++++++++++++++-------------------- 3 files changed, 199 insertions(+), 133 deletions(-) diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index 2440860..4ca0e50 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -999,15 +999,19 @@ Void VideoSubWindow::updatePixelValueStatusBar( const QPoint& pos ) if( ColorSpace == PlaYUVerPixel::COLOR_YUV ) { sPixelValue = m_pcCurrFrame->getPixelValue( pos.x(), pos.y() ); - strStatus.append( - QString( "Y: %1 U: %2 V: %3" ).arg( sPixelValue.Y() ).arg( sPixelValue.Cb() ).arg( sPixelValue.Cr() ) ); + 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() ); - strStatus.append( - QString( "R: %1 G: %2 B: %3" ).arg( sPixelValue.R() ).arg( sPixelValue.G() ).arg( sPixelValue.B() ) ); + strStatus.append( QString( "R: %1 G: %2 B: %3" ) + .arg( sPixelValue.R() ) + .arg( sPixelValue.G() ) + .arg( sPixelValue.B() ) ); } emit updateStatusBar( strStatus ); } diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index c0f704d..34a879a 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -35,10 +35,6 @@ #define MAX_NUMBER_COMPONENTS 4 -/*! \brief Supported formats - * - * List of supported pixels formats - */ std::vector PlaYUVerFrame::supportedColorSpacesListNames() { return std::vector{ @@ -79,7 +75,24 @@ Int PlaYUVerFrame::findPixelFormat( const String& name ) return -1; } -static inline Void YuvToRgb( const Int& iY, const Int& iU, const Int& iV, Int& iR, Int& iG, Int& iB ) +struct PlaYUVerPixelPrivate +{ + PlaYUVerPixelPrivate( const Int& ColorSpace ) + { + iColorSpace = ColorSpace == PlaYUVerPixel::COLOR_GRAY ? + PlaYUVerPixel::COLOR_YUV : + ColorSpace; + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + PixelComponents[i] = 0; + } + } + + Int iColorSpace; + Pel PixelComponents[MAX_NUMBER_COMPONENTS]; +}; + +static inline Void yuvToRgb( const Int& iY, const Int& iU, const Int& iV, Int& iR, Int& iG, Int& iB ) { iR = iY + ( ( 1436 * ( iV - 128 ) ) >> 10 ); iG = iY - ( ( 352 * ( iU - 128 ) + 731 * ( iV - 128 ) ) >> 10 ); @@ -96,64 +109,56 @@ static inline Void rgbToYuv( const Int& iR, const Int& iG, const Int& iB, Int& i iV = ( 1000 * ( iR - iY ) + 179456 ) / 1402; } -struct PlaYUVerPixelPrivate -{ - Int iColorSpace; - Pel PixelComponents[MAX_NUMBER_COMPONENTS]; -}; - Int PlaYUVerPixel::getMaxNumberOfComponents() { return MAX_NUMBER_COMPONENTS; } -PlaYUVerPixel::PlaYUVerPixel() - : d( new PlaYUVerPixelPrivate ) +PlaYUVerPixel::PlaYUVerPixel( const Int& ColorSpace ) + : d( new PlaYUVerPixelPrivate( ColorSpace ) ) { - d->iColorSpace = COLOR_INVALID; - d->PixelComponents[0] = 0; - d->PixelComponents[1] = 0; - d->PixelComponents[2] = 0; - d->PixelComponents[3] = 0; } -PlaYUVerPixel::PlaYUVerPixel( const Int& ColorSpace ) +PlaYUVerPixel::PlaYUVerPixel( const Int& ColorSpace, const Pel& c0 ) + : d( new PlaYUVerPixelPrivate( ColorSpace ) ) { - d->iColorSpace = ColorSpace == COLOR_GRAY ? COLOR_YUV : ColorSpace; - d->PixelComponents[0] = 0; - d->PixelComponents[1] = 0; - d->PixelComponents[2] = 0; - d->PixelComponents[3] = 0; + d->PixelComponents[0] = c0; } PlaYUVerPixel::PlaYUVerPixel( const Int& ColorSpace, const Pel& c0, const Pel& c1, const Pel& c2 ) + : d( new PlaYUVerPixelPrivate( ColorSpace ) ) { - d->iColorSpace = ColorSpace == COLOR_GRAY ? COLOR_YUV : ColorSpace; d->PixelComponents[0] = c0; d->PixelComponents[1] = c1; d->PixelComponents[2] = c2; - d->PixelComponents[3] = 0; } PlaYUVerPixel::PlaYUVerPixel( const Int& ColorSpace, const Pel& c0, const Pel& c1, const Pel& c2, const Pel& c3 ) + : d( new PlaYUVerPixelPrivate( ColorSpace ) ) { - d->iColorSpace = ColorSpace == COLOR_GRAY ? COLOR_YUV : ColorSpace; d->PixelComponents[0] = c0; d->PixelComponents[1] = c1; d->PixelComponents[2] = c2; d->PixelComponents[3] = c3; } -PlaYUVerPixel::~PlaYUVerPixel() {} - -Int PlaYUVerPixel::ColorSpaceType() +PlaYUVerPixel::PlaYUVerPixel( const PlaYUVerPixel& other ) + : d( new PlaYUVerPixelPrivate( other.colorSpace() ) ) { - return d->iColorSpace; + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + d->PixelComponents[i] = other[i]; + } } -Pel* PlaYUVerPixel::Components() +PlaYUVerPixel::~PlaYUVerPixel() { - return d->PixelComponents; + delete d; +} + +Int PlaYUVerPixel::colorSpace() const +{ + return d->iColorSpace; } Pel PlaYUVerPixel::Y() const @@ -168,6 +173,22 @@ Pel PlaYUVerPixel::Cr() const { return d->PixelComponents[2]; } +Pel PlaYUVerPixel::R() const +{ + return d->PixelComponents[0]; +} +Pel PlaYUVerPixel::G() const +{ + return d->PixelComponents[1]; +} +Pel PlaYUVerPixel::B() const +{ + return d->PixelComponents[2]; +} +Pel PlaYUVerPixel::A() const +{ + return d->PixelComponents[3]; +} Pel& PlaYUVerPixel::Y() { @@ -193,6 +214,10 @@ Pel& PlaYUVerPixel::B() { return d->PixelComponents[2]; } +Pel& PlaYUVerPixel::A() +{ + return d->PixelComponents[3]; +} Pel PlaYUVerPixel::operator[]( const Int& channel ) const { @@ -203,6 +228,15 @@ Pel& PlaYUVerPixel::operator[]( const Int& channel ) return d->PixelComponents[channel]; } +PlaYUVerPixel PlaYUVerPixel::operator=( const PlaYUVerPixel& other ) +{ + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + d->PixelComponents[i] = other[i]; + } + return *this; +} + PlaYUVerPixel PlaYUVerPixel::operator+( const PlaYUVerPixel& in ) { PlaYUVerPixel result; @@ -210,20 +244,45 @@ PlaYUVerPixel PlaYUVerPixel::operator+( const PlaYUVerPixel& in ) { result[i] = d->PixelComponents[i] + in[i]; } - PlaYUVerPixel out( d->iColorSpace, Y() + in.Y(), Cb() + in.Cb(), Cr() + in.Cr() ); - return out; + return result; +} + +PlaYUVerPixel PlaYUVerPixel::operator+=( const PlaYUVerPixel& in ) +{ + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + d->PixelComponents[i] += in[i]; + } + return *this; } PlaYUVerPixel PlaYUVerPixel::operator-( const PlaYUVerPixel& in ) { - PlaYUVerPixel out( d->iColorSpace, Y() - in.Y(), Cb() - in.Cb(), Cr() - in.Cr() ); - return out; + PlaYUVerPixel result; + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + result[i] = d->PixelComponents[i] - in[i]; + } + return result; +} + +PlaYUVerPixel PlaYUVerPixel::operator-=( const PlaYUVerPixel& in ) +{ + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + d->PixelComponents[i] -= in[i]; + } + return *this; } PlaYUVerPixel PlaYUVerPixel::operator*( const Double& op ) { - PlaYUVerPixel out( d->iColorSpace, Y() * op, Cb() * op, Cr() * op ); - return out; + PlaYUVerPixel result; + for( Int i = 0; i < MAX_NUMBER_COMPONENTS; i++ ) + { + result[i] = d->PixelComponents[i] * op; + } + return result; } PlaYUVerPixel PlaYUVerPixel::ConvertPixel( ColorSpace eOutputSpace ) @@ -236,7 +295,7 @@ PlaYUVerPixel PlaYUVerPixel::ConvertPixel( ColorSpace eOutputSpace ) if( eOutputSpace == COLOR_RGB ) { - YuvToRgb( Y(), Cb(), Cr(), outA, outB, outC ); + yuvToRgb( Y(), Cb(), Cr(), outA, outB, outC ); outPixel.R() = outA; outPixel.G() = outB; outPixel.B() = outC; @@ -649,8 +708,7 @@ UChar* PlaYUVerFrame::getRGBBuffer() PlaYUVerPixel PlaYUVerFrame::getPixelValue( Int xPos, Int yPos ) { - PlaYUVerPixel PixelValue( d->m_pcPelFormat->colorSpace, d->m_uiHalfPelValue, d->m_uiHalfPelValue, - d->m_uiHalfPelValue ); + PlaYUVerPixel PixelValue( d->m_pcPelFormat->colorSpace ); for( UInt ch = 0; ch < d->m_pcPelFormat->numberChannels; ch++ ) { Int ratioH = ch > 0 ? d->m_pcPelFormat->log2ChromaWidth : 0; @@ -679,7 +737,7 @@ Void PlaYUVerFrame::setPixelValue( Int xPos, Int yPos, PlaYUVerPixel pixel ) { Int ratioH = ch > 0 ? d->m_pcPelFormat->log2ChromaWidth : 0; Int ratioW = ch > 0 ? d->m_pcPelFormat->log2ChromaHeight : 0; - d->m_pppcInputPel[ch][( yPos >> ratioH )][( xPos >> ratioW )] = pixel.Components()[ch]; + d->m_pppcInputPel[ch][( yPos >> ratioH )][( xPos >> ratioW )] = pixel[ch]; } d->m_bHasHistogram = false; d->m_bHasRGBPel = false; diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index 842122b..c604432 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -61,15 +61,14 @@ public: static Int getMaxNumberOfComponents(); - PlaYUVerPixel(); - PlaYUVerPixel( const Int& ColorSpace ); + PlaYUVerPixel( const Int& ColorSpace = COLOR_INVALID ); + PlaYUVerPixel( const Int& ColorSpace, const Pel& c0 ); PlaYUVerPixel( const Int& ColorSpace, const Pel& c0, const Pel& c1, const Pel& c2 ); PlaYUVerPixel( const Int& ColorSpace, const Pel& c0, const Pel& c1, const Pel& c2, const Pel& c3 ); + PlaYUVerPixel( const PlaYUVerPixel& other ); ~PlaYUVerPixel(); - Int ColorSpaceType(); - - Pel* Components(); + Int colorSpace() const; Pel Y() const; Pel Cb() const; @@ -77,6 +76,7 @@ public: Pel R() const; Pel G() const; Pel B() const; + Pel A() const; Pel& Y(); Pel& Cb(); @@ -84,12 +84,16 @@ public: Pel& R(); Pel& G(); Pel& B(); + Pel& A(); Pel operator[]( const Int& channel ) const; Pel& operator[]( const Int& channel ); + PlaYUVerPixel operator=( const PlaYUVerPixel& ); PlaYUVerPixel operator+( const PlaYUVerPixel& ); + PlaYUVerPixel operator+=( const PlaYUVerPixel& ); PlaYUVerPixel operator-( const PlaYUVerPixel& ); + PlaYUVerPixel operator-=( const PlaYUVerPixel& ); PlaYUVerPixel operator*( const Double& ); /** @@ -113,8 +117,8 @@ class PlaYUVerFrame { public: /** ColorSpace Enum - * List of supported pixel formats - do not change order - */ + * List of supported pixel formats - do not change order + */ enum PixelFormats { NO_FMT = -1, @@ -130,58 +134,58 @@ public: }; /** - * Function that handles the supported color space - * of PlaYUVerFrame - * @return vector of strings with pixel formats names - */ + * Function that handles the supported color space + * of PlaYUVerFrame + * @return vector of strings with pixel formats names + */ static std::vector supportedColorSpacesListNames(); /** - * Function that handles the supported pixel formats - * of PlaYUVerFrame - * @return vector of strings with pixel formats names - */ + * Function that handles the supported pixel formats + * of PlaYUVerFrame + * @return vector of strings with pixel formats names + */ static std::vector supportedPixelFormatListNames(); static std::vector supportedPixelFormatListNames( Int colorSpace ); static Int findPixelFormat( const String& name ); /** - * Creates a new frame using the following configuration - * - * @param width width of the frame - * @param height height of the frame - * @param pel_format pixel format index (always use PixelFormats enum) - * - * @note this function might misbehave if the pixel format enum is not correct - */ + * Creates a new frame using the following configuration + * + * @param width width of the frame + * @param height height of the frame + * @param pel_format pixel format index (always use PixelFormats enum) + * + * @note this function might misbehave if the pixel format enum is not correct + */ PlaYUVerFrame( UInt width, UInt height, Int pelFormat, Int bitsPixel = 8 ); /** - * Copy contructor - * - * @param other existing frame to copy from - */ + * Copy contructor + * + * @param other existing frame to copy from + */ PlaYUVerFrame( const PlaYUVerFrame& other ); PlaYUVerFrame( const PlaYUVerFrame* other ); /** - * Creates and new frame with the configuration of an existing one and copy - * its contents. This function only copies a specific region from the existing - * frame - * - * @param other existing frame to copy from - * @param posX position X to crop from - * @param posY position Y to crop from - * @param areaWidth crop width - * @param areaHeight crop height - */ + * Creates and new frame with the configuration of an existing one and copy + * its contents. This function only copies a specific region from the existing + * frame + * + * @param other existing frame to copy from + * @param posX position X to crop from + * @param posY position Y to crop from + * @param areaWidth crop width + * @param areaHeight crop height + */ PlaYUVerFrame( const PlaYUVerFrame& other, UInt x, UInt y, UInt width, UInt height ); PlaYUVerFrame( const PlaYUVerFrame* other, UInt x, UInt y, UInt width, UInt height ); ~PlaYUVerFrame(); /** Format match opts - */ + */ enum FormatMatching { MATCH_COLOR_SPACE = 1, @@ -193,57 +197,57 @@ public: }; /** - * Check if two PlaYUVerFrames have the same fmt - * @param other frame to compare with - * @param match matching conditions (use enum FormatMatching) - * @return true if format matches - */ + * Check if two PlaYUVerFrames have the same fmt + * @param other frame to compare with + * @param match matching conditions (use enum FormatMatching) + * @return true if format matches + */ Bool haveSameFmt( const PlaYUVerFrame& other, UInt match = MATCH_ALL ) const; Bool haveSameFmt( const PlaYUVerFrame* other, UInt match = MATCH_ALL ) const; /** - * Get pixel format information - * @return pixel format index - */ + * Get pixel format information + * @return pixel format index + */ Int getPelFormat() const; /** - * Get pixel format information - * @return pixel format name - */ + * Get pixel format information + * @return pixel format name + */ String getPelFmtName(); /** - * Get color space information - * @return get color space index - */ + * Get color space information + * @return get color space index + */ Int getColorSpace() const; /** - * Get the number of channels - * @return number of channels - */ + * Get the number of channels + * @return number of channels + */ UInt getNumberChannels() const; /** - * Get width of the frame - * @param channel/component - * @return number of pixels - */ + * Get width of the frame + * @param channel/component + * @return number of pixels + */ UInt getWidth( Int channel = 0 ) const; /** - * Get height of the frame - * @param channel/component - * @return number of pixels - */ + * Get height of the frame + * @param channel/component + * @return number of pixels + */ UInt getHeight( Int channel = 0 ) const; /** - * Get number of pixels of the frame - * @param channel/component - * @return number of pixels - */ + * Get number of pixels of the frame + * @param channel/component + * @return number of pixels + */ UInt getPixels( Int channel = 0 ) const; UInt8 getChromaWidthRatio() const; @@ -254,26 +258,26 @@ public: UInt getChromaSize() const; /** - * Get number of bits per pixel - * @return number of bits - */ + * Get number of bits per pixel + * @return number of bits + */ UInt getBitsPel() const; /** - * Get number of bytes per frame of an existing frame - * @return number of bytes per frame - */ + * Get number of bytes per frame of an existing frame + * @return number of bytes per frame + */ UInt64 getBytesPerFrame(); /** - * Get number of bytes per frame of a specific pixel format - * @return number of bytes per frame - */ + * Get number of bytes per frame of a specific pixel format + * @return number of bytes per frame + */ static UInt64 getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelFormat, UInt bitsPixel ); /** - * Reset frame pixels to zero - */ + * Reset frame pixels to zero + */ Void clear(); Pel*** getPelBufferYUV() const; @@ -297,8 +301,8 @@ public: Void fillRGBBuffer(); /** - * Histogram - */ + * Histogram + */ Void calcHistogram(); UInt getMin( Int channel ); @@ -313,18 +317,18 @@ public: Int getHistogramSegment(); /** - * Interface with OpenCV lib - */ + * Interface with OpenCV lib + */ Bool toMat( cv::Mat& cvMat, Bool convertToGray = false ); Bool fromMat( cv::Mat& cvMat ); /** * \ingroup PlaYUVerLibFrame * @defgroup PlaYUVerLibFrameQualityMetrics Quality Metrics Interface - * @{ - * Quality metrics interface - * - */ + * @{ + * Quality metrics interface + * + */ enum QualityMetrics {