From 83df007fad76c667f8793a0e4c0bb476561dfd3d Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sun, 23 Mar 2014 19:47:14 +0000 Subject: [PATCH] Add new YUV formats --- source/InputStream.cpp | 3 +- source/PlaYUVerFrame.cpp | 209 ++++++++++++++--------- source/PlaYUVerFrame.h | 2 +- source/SubWindowHandle.cpp | 2 +- source/TypeDef.h | 9 +- source/lib/ffmpeg/LibAvContextHandle.cpp | 4 +- 6 files changed, 146 insertions(+), 83 deletions(-) diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 24a115a..0bd4aec 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -246,7 +246,6 @@ Void InputStream::readFrame() return; } m_cCurrFrame->FrameFromBuffer( m_pInputBuffer, m_iPixelFormat ); - return; } @@ -289,7 +288,7 @@ Void InputStream::seekInput( Int new_frame_num ) else #endif { - UInt64 frame_bytes_input = m_uiWidth * m_uiHeight * 1.5; + UInt64 frame_bytes_input = m_cCurrFrame->getBytesPerFrame(); UInt64 nbytes_seek = frame_bytes_input * new_frame_num; fseek( m_pFile, nbytes_seek, SEEK_SET ); m_iCurrFrameNum = new_frame_num - 1; diff --git a/source/PlaYUVerFrame.cpp b/source/PlaYUVerFrame.cpp index d7d9ecd..34a8627 100755 --- a/source/PlaYUVerFrame.cpp +++ b/source/PlaYUVerFrame.cpp @@ -33,7 +33,13 @@ namespace plaYUVer QStringList PlaYUVerFrame::supportedPixelFormatList() { QStringList formats; - formats << "yuv420" << "yuv400"; + formats << "yuv420p" + << "yuv444p"; + /* << "yuv422p" + << "yuv410p" + << "yuv411p" + << "gray" + << "rgb8"; */ return formats; } @@ -50,24 +56,35 @@ PlaYUVerFrame::PlaYUVerFrame( UInt width, UInt height, Int pel_format ) switch( m_iPixelFormat ) { - case YUV420: + case YUV420p: get_mem2Dpel( &( m_pppcInputPel[0] ), m_uiHeight, m_uiWidth ); get_mem2Dpel( &( m_pppcInputPel[1] ), m_uiHeight / 2, m_uiWidth / 2 ); get_mem2Dpel( &( m_pppcInputPel[2] ), m_uiHeight / 2, m_uiWidth / 2 ); break; - case YUV422: + case YUV444p: + get_mem2Dpel( &( m_pppcInputPel[0] ), m_uiHeight, m_uiWidth ); + get_mem2Dpel( &( m_pppcInputPel[1] ), m_uiHeight, m_uiWidth ); + get_mem2Dpel( &( m_pppcInputPel[2] ), m_uiHeight, m_uiWidth ); + break; + case YUV422p: get_mem2Dpel( &( m_pppcInputPel[0] ), m_uiHeight, m_uiWidth ); get_mem2Dpel( &( m_pppcInputPel[1] ), m_uiHeight / 2, m_uiWidth ); get_mem2Dpel( &( m_pppcInputPel[2] ), m_uiHeight / 2, m_uiWidth ); break; - case YUV400: + case YUV410p: + case YUV411p: + get_mem2Dpel( &( m_pppcInputPel[0] ), m_uiHeight, m_uiWidth ); + get_mem2Dpel( &( m_pppcInputPel[1] ), m_uiHeight, m_uiWidth ); + get_mem2Dpel( &( m_pppcInputPel[2] ), m_uiHeight, m_uiWidth ); + break; + case GRAY: get_mem2Dpel( &( m_pppcInputPel[0] ), m_uiHeight, m_uiWidth ); break; - case RGB: + case RGB8: get_mem3Dpel( &m_pppcRGBPel, 3, m_uiHeight, m_uiWidth ); break; } - if( m_iPixelFormat != RGB ) + if( m_iPixelFormat != RGB8 ) get_mem3Dpel( &m_pppcRGBPel, 3, m_uiHeight, m_uiWidth ); } @@ -116,58 +133,77 @@ Void rgbToyuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) iV = 0; } -Void PlaYUVerFrame::YUV420toRGB() +Void PlaYUVerFrame::FrametoRGB8() { Int iY, iU, iV, iR, iG, iB; - for( UInt y = 0; y < m_uiHeight; y += 2 ) + + Pel** ppInputPelY = m_pppcInputPel[0]; + Pel* pInputPelY = &(m_pppcInputPel[0][0][0]); + Pel* pInputPelU = &(m_pppcInputPel[1][0][0]); + Pel* pInputPelV = &(m_pppcInputPel[2][0][0]); + Pel* pRGBPelR = &(m_pppcRGBPel[0][0][0]); + Pel* pRGBPelG = &(m_pppcRGBPel[1][0][0]); + Pel* pRGBPelB = &(m_pppcRGBPel[2][0][0]); + + switch( m_iPixelFormat ) { - for( UInt x = 0; x < m_uiWidth; x += 2 ) - { - // Pixel (x, y). - - iY = m_pppcInputPel[0][y][x]; - iU = m_pppcInputPel[1][y >> 1][x >> 1]; - iV = m_pppcInputPel[2][y >> 1][x >> 1]; - iU -= 128; - iV -= 128; - - yuvToRgb( iY, iU, iV, iR, iG, iB ); - - m_pppcRGBPel[0][y][x] = iR; - m_pppcRGBPel[1][y][x] = iG; - m_pppcRGBPel[2][y][x] = iB; - - // Pixel (x+1, y) - - iY = m_pppcInputPel[0][y][x + 1]; - - yuvToRgb( iY, iU, iV, iR, iG, iB ); - - m_pppcRGBPel[0][y][x + 1] = iR; - m_pppcRGBPel[1][y][x + 1] = iG; - m_pppcRGBPel[2][y][x + 1] = iB; - - // Pixel (x, y+1) - - iY = m_pppcInputPel[0][y + 1][x]; - - yuvToRgb( iY, iU, iV, iR, iG, iB ); - - m_pppcRGBPel[0][y + 1][x] = iR; - m_pppcRGBPel[1][y + 1][x] = iG; - m_pppcRGBPel[2][y + 1][x] = iB; - - // Pixel (x+1, y+1) - - iY = m_pppcInputPel[0][y + 1][x + 1]; - - yuvToRgb( iY, iU, iV, iR, iG, iB ); - - m_pppcRGBPel[0][y + 1][x + 1] = iR; - m_pppcRGBPel[1][y + 1][x + 1] = iG; - m_pppcRGBPel[2][y + 1][x + 1] = iB; - - } + 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++; + iV = *pInputPelV++; + iU -= 128; + iV -= 128; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[0][y][x] = iR; + m_pppcRGBPel[1][y][x] = iG; + m_pppcRGBPel[2][y][x] = iB; + // Pixel (x+1, y) + iY = ppInputPelY[y][x+1]; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[0][y][x + 1] = iR; + m_pppcRGBPel[1][y][x + 1] = iG; + m_pppcRGBPel[2][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[1][y + 1][x] = iG; + m_pppcRGBPel[2][y + 1][x] = iB; + // Pixel (x+1, y+1) + iY = ppInputPelY[y+1][x+1]; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + m_pppcRGBPel[0][y + 1][x + 1] = iR; + m_pppcRGBPel[1][y + 1][x + 1] = iG; + m_pppcRGBPel[2][y + 1][x + 1] = iB; + } + break; + case YUV444p: + for( UInt y = 0; y < m_uiHeight; y++ ) + for( UInt x = 0; x < m_uiWidth; x++ ) + { + iY = *pInputPelY++; + iU = *pInputPelU++; + iV = *pInputPelV++; + iU -= 128; + iV -= 128; + yuvToRgb( iY, iU, iV, iR, iG, iB ); + *pRGBPelR++ = iR; + *pRGBPelG++ = iG; + *pRGBPelB++ = iB; + } + break; + case YUV422p: + case YUV410p: + case YUV411p: + case GRAY: + case RGB8: + default: + // No action. + break; } } @@ -180,16 +216,21 @@ Void PlaYUVerFrame::FrameFromBuffer( Pel *input_buffer, Int pel_format ) UInt64 frame_bytes_input = m_uiWidth * m_uiHeight; switch( m_iPixelFormat ) { - case YUV420: - memcpy( &m_pppcInputPel[0][0][0], input_buffer, frame_bytes_input * sizeof(Pel) ); - memcpy( &m_pppcInputPel[1][0][0], input_buffer + frame_bytes_input, frame_bytes_input / 4 * sizeof(Pel) ); + case YUV420p: + memcpy( &m_pppcInputPel[0][0][0], input_buffer + frame_bytes_input * 0, frame_bytes_input * sizeof(Pel) ); + memcpy( &m_pppcInputPel[1][0][0], input_buffer + frame_bytes_input * 1, frame_bytes_input / 4 * sizeof(Pel) ); memcpy( &m_pppcInputPel[2][0][0], input_buffer + frame_bytes_input * 5 / 4, frame_bytes_input / 4 * sizeof(Pel) ); break; - case YUV422: + case YUV444p: + memcpy( &m_pppcInputPel[0][0][0], input_buffer + frame_bytes_input * 0, frame_bytes_input * sizeof(Pel) ); + memcpy( &m_pppcInputPel[1][0][0], input_buffer + frame_bytes_input * 1, frame_bytes_input * sizeof(Pel) ); + memcpy( &m_pppcInputPel[2][0][0], input_buffer + frame_bytes_input * 2, frame_bytes_input * sizeof(Pel) ); break; - case YUV400: - break; - case RGB: + case YUV422p: + case YUV410p: + case YUV411p: + case GRAY: + case RGB8: break; } } @@ -203,17 +244,21 @@ Void PlaYUVerFrame::CopyFrom( PlaYUVerFrame* input_frame ) UInt64 num_bytes = m_uiWidth * m_uiHeight; switch( m_iPixelFormat ) { - case YUV420: + case YUV420p: memcpy( &m_pppcInputPel[0][0][0], &( input_frame->getPelBufferYUV()[0][0][0] ), num_bytes * sizeof(Pel) ); memcpy( &m_pppcInputPel[1][0][0], &( input_frame->getPelBufferYUV()[1][0][0] ), num_bytes / 4 * sizeof(Pel) ); memcpy( &m_pppcInputPel[2][0][0], &( input_frame->getPelBufferYUV()[2][0][0] ), num_bytes / 4 * sizeof(Pel) ); - //YUV420toRGB(); break; - case YUV422: + case YUV444p: + memcpy( &m_pppcInputPel[0][0][0], &( input_frame->getPelBufferYUV()[0][0][0] ), num_bytes * sizeof(Pel) ); + memcpy( &m_pppcInputPel[1][0][0], &( input_frame->getPelBufferYUV()[1][0][0] ), num_bytes * sizeof(Pel) ); + memcpy( &m_pppcInputPel[2][0][0], &( input_frame->getPelBufferYUV()[2][0][0] ), num_bytes * sizeof(Pel) ); break; - case YUV400: - break; - case RGB: + case YUV422p: + case YUV410p: + case YUV411p: + case GRAY: + case RGB8: break; } } @@ -244,16 +289,23 @@ UInt64 PlaYUVerFrame::getBytesPerFrame() { switch( m_iPixelFormat ) { - case YUV420: + case YUV420p: return m_uiWidth * m_uiHeight * 1.5; break; - case YUV422: + case YUV444p: + return m_uiWidth * m_uiHeight * 3; + break; + case YUV422p: return m_uiWidth * m_uiHeight * 2; break; - case YUV400: + case YUV410p: + case YUV411p: + return 0; + break; + case GRAY: return m_uiWidth * m_uiHeight; break; - case RGB: + case RGB8: return m_uiWidth * m_uiHeight * 3; break; default: @@ -288,25 +340,30 @@ Pixel PlaYUVerFrame::getPixelValue(const QPoint &pos, ColorSpace space) Pixel pixel_value; switch( m_iPixelFormat ) { - case YUV420: + case YUV420p: pixel_value.color_space = COLOR_YUV; pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; pixel_value.ChromaU = m_pppcInputPel[CHROMA_U][pos.y()>>1][pos.x()>>1]; pixel_value.ChromaV = m_pppcInputPel[CHROMA_V][pos.y()>>1][pos.x()>>1]; break; - case YUV422: + case YUV444p: + pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; + pixel_value.ChromaU = m_pppcInputPel[CHROMA_U][pos.y()][pos.x()]; + pixel_value.ChromaV = m_pppcInputPel[CHROMA_V][pos.y()][pos.x()]; + break; + case YUV422p: pixel_value.color_space = COLOR_YUV; pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; pixel_value.ChromaU = m_pppcInputPel[CHROMA_U][pos.y()][pos.x()>>1]; pixel_value.ChromaV = m_pppcInputPel[CHROMA_V][pos.y()][pos.x()>>1]; break; - case YUV400: + case GRAY: pixel_value.color_space = COLOR_YUV; pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; pixel_value.ChromaU = 0; pixel_value.ChromaV = 0; break; - case RGB: + case RGB8: pixel_value.color_space = COLOR_RGB; pixel_value.ColorR = m_pppcInputPel[COLOR_R][pos.y()][pos.x()]; pixel_value.ColorG = m_pppcInputPel[COLOR_G][pos.y()][pos.x()]; diff --git a/source/PlaYUVerFrame.h b/source/PlaYUVerFrame.h index 4275be9..5e663b8 100755 --- a/source/PlaYUVerFrame.h +++ b/source/PlaYUVerFrame.h @@ -46,7 +46,7 @@ public: static QStringList supportedPixelFormatList(); - Void YUV420toRGB(); + Void FrametoRGB8(); Void FrameFromBuffer( Pel *input_buffer, Int pel_format ); Void CopyFrom( PlaYUVerFrame* ); diff --git a/source/SubWindowHandle.cpp b/source/SubWindowHandle.cpp index 09e1996..d13ea58 100644 --- a/source/SubWindowHandle.cpp +++ b/source/SubWindowHandle.cpp @@ -152,7 +152,7 @@ QImage* SubWindowHandle::FrameToQImage( PlaYUVerFrame* curr_frame ) { Pel*** bufferRGB = curr_frame->getPelBufferRGB(); - curr_frame->YUV420toRGB(); + curr_frame->FrametoRGB8(); for( UInt y = 0; y < curr_frame->getHeight(); y++ ) { diff --git a/source/TypeDef.h b/source/TypeDef.h index 5c76860..c6b0b06 100644 --- a/source/TypeDef.h +++ b/source/TypeDef.h @@ -112,7 +112,14 @@ typedef UChar Pel; ///< 8-bit pixel type enum InputStreamColorSpace { - NO_FMT = -1, YUV420, YUV400, YUV422, RGB, + NO_FMT = -1, + YUV420p, + YUV444p, + YUV422p, + YUV410p, + YUV411p, + GRAY, + RGB8, }; enum ColorSpace diff --git a/source/lib/ffmpeg/LibAvContextHandle.cpp b/source/lib/ffmpeg/LibAvContextHandle.cpp index 5118182..dad618b 100755 --- a/source/lib/ffmpeg/LibAvContextHandle.cpp +++ b/source/lib/ffmpeg/LibAvContextHandle.cpp @@ -110,7 +110,7 @@ Bool LibAvContextHandle::initAvFormat( char* filename, UInt& width, UInt& height { case NO_FMT: break; - case YUV420: + case YUV420p: av_dict_set( &format_opts, "pixel_format", av_get_pix_fmt_name( AV_PIX_FMT_YUV420P ), 0 ); break; case YUV400: @@ -174,7 +174,7 @@ Bool LibAvContextHandle::initAvFormat( char* filename, UInt& width, UInt& height switch( video_dec_ctx->pix_fmt ) { case AV_PIX_FMT_YUV420P: - pixel_format = YUV420; + pixel_format = YUV420p; break; case AV_PIX_FMT_GRAY8: pixel_format = YUV400;