TComPicYuv::create

本文讨论了VoidTComPicYuv类在初始化过程中如何根据给定的图像宽度、高度和最大块大小来创建缓冲区,并设置必要的偏移量以支持运动补偿边界处理。重点在于理解图像和视频编码中块布局的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Void TComPicYuv::create( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
{
  m_iPicWidth       = iPicWidth;
  m_iPicHeight      = iPicHeight;
  
  // --> After config finished!
  m_iCuWidth        = uiMaxCUWidth;
  m_iCuHeight       = uiMaxCUHeight;


  Int numCuInWidth  = m_iPicWidth  / m_iCuWidth  + (m_iPicWidth  % m_iCuWidth  != 0);
  Int numCuInHeight = m_iPicHeight / m_iCuHeight + (m_iPicHeight % m_iCuHeight != 0);
  
  m_iLumaMarginX    = g_uiMaxCUWidth  + 16; // for 16-byte alignment
  m_iLumaMarginY    = g_uiMaxCUHeight + 16;  // margin for 8-tap filter and infinite padding
  
  m_iChromaMarginX  = m_iLumaMarginX>>1;
  m_iChromaMarginY  = m_iLumaMarginY>>1;
  
  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
  m_apiPicBufU      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
  m_apiPicBufV      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
  
  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
  m_piPicOrgU       = m_apiPicBufU + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
  m_piPicOrgV       = m_apiPicBufV + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
  
  m_bIsBorderExtended = false;
  
  m_cuOffsetY = new Int[numCuInWidth * numCuInHeight];
  m_cuOffsetC = new Int[numCuInWidth * numCuInHeight];
  for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
  {
    for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
    {
      m_cuOffsetY[cuRow * numCuInWidth + cuCol] = getStride() * cuRow * m_iCuHeight + cuCol * m_iCuWidth;
      m_cuOffsetC[cuRow * numCuInWidth + cuCol] = getCStride() * cuRow * (m_iCuHeight / 2) + cuCol * (m_iCuWidth / 2);
    }
  }
  
  m_buOffsetY = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
  m_buOffsetC = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
  for (Int buRow = 0; buRow < (1 << uiMaxCUDepth); buRow++)
  {
    for (Int buCol = 0; buCol < (1 << uiMaxCUDepth); buCol++)
    {
      m_buOffsetY[(buRow << uiMaxCUDepth) + buCol] = getStride() * buRow * (uiMaxCUHeight >> uiMaxCUDepth) + buCol * (uiMaxCUWidth  >> uiMaxCUDepth);
      m_buOffsetC[(buRow << uiMaxCUDepth) + buCol] = getCStride() * buRow * (uiMaxCUHeight / 2 >> uiMaxCUDepth) + buCol * (uiMaxCUWidth / 2 >> uiMaxCUDepth);
    }
  }
  return;
}


开辟的空间比原来的大,主要是运动补偿边界的时候,特殊情况的处理

解释这段代码 #include <stdlib.h> #include <stdio.h> #include <string.h> typedef void Void; typedef bool Bool; typedef int Int; typedef unsigned char UChar; typedef UChar Pel; ///< 16-bit pixel type class TComPicYuv { private: // ------------------------------------------------------------------------------------------------ // YUV buffer // ------------------------------------------------------------------------------------------------ Pel* m_apiPicBufY; ///< Buffer (including margin) Pel* m_apiPicBufU; Pel* m_apiPicBufV; // ------------------------------------------------------------------------------------------------ // Parameter for general YUV buffer usage // ------------------------------------------------------------------------------------------------ Int m_iPicWidth; ///< Width of picture Int m_iPicHeight; ///< Height of picture public: TComPicYuv (); virtual ~TComPicYuv(); // ------------------------------------------------------------------------------------------------ // Memory management // ------------------------------------------------------------------------------------------------ Bool create ( Int iPicWidth, Int iPicHeight ); Void destroy (); Void setYuv (Pel pixelY,Pel pixelU,Pel pixelV); Void setPixel (int posX, int posY, int width, Pel pixelY,Pel pixelU,Pel pixelV); // ------------------------------------------------------------------------------------------------ // Get information of picture // ------------------------------------------------------------------------------------------------ Pel* getPicBufY () { return m_apiPicBufY ; } Pel* getPicBufU () { return m_apiPicBufU ; } Pel* getPicBufV () { return m_apiPicBufV ; } Int getWidth () { return m_iPicWidth; } Int getHeight () { return m_iPicHeight; } Int getStride () { return m_iPicWidth ; } Int getCStride () { return (m_iPicWidth >> 1); } };// END CLASS DEFINITION TComPicYuv TComPicYuv::TComPicYuv() { m_apiPicBufY = NULL; // Buffer (including margin) m_apiPicBufU = NULL; m_apiPicBufV = NULL; } TComPicYuv::~TComPicYuv() { } Bool TComPicYuv::create( Int iPicWidth, Int iPicHeight ) { m_iPicWidth = iPicWidth; m_iPicHeight = iPicHeight; m_apiPicBufY = (Pel*)malloc(m_iPicWidth * m_iPicHeight * sizeof(Pel)); m_apiPicBufU = (Pel*)malloc((m_iPicWidth >>1) * (m_iPicHeight>>1) * sizeof(Pel)); m_apiPicBufV = (Pel*)malloc((m_iPicWidth >>1) * (m_iPicHeight>>1) * sizeof(Pel)); return true; } Void TComPicYuv::destroy() { if( m_apiPicBufY ){ free( m_apiPicBufY ); m_apiPicBufY = NULL; } if( m_apiPicBufU ){ free( m_apiPicBufU ); m_apiPicBufU = NULL; } if( m_apiPicBufV ){ free( m_apiPicBufV ); m_apiPicBufV = NULL; } } Void TComPicYuv::setYuv(Pel pixelY,Pel pixelU,Pel pixelV) { if( m_apiPicBufY ){ memset(m_apiPicBufY, pixelY,m_iPicWidth * m_iPicHeight * sizeof(Pel)) ; } if( m_apiPicBufU ){ memset(m_apiPicBufU, pixelU,(m_iPicWidth >>1) * (m_iPicHeight>>1) * sizeof(Pel)) ; } if( m_apiPicBufV ){ memset(m_apiPicBufV, pixelV,(m_iPicWidth >>1) * (m_iPicHeight>>1) * sizeof(Pel)) ; } } Void TComPicYuv::setPixel(int posX, int posY, int width, Pel pixelY,Pel pixelU,Pel pixelV) { Pel *Y = m_apiPicBufY + posY*m_iPicWidth+posX; for(int h = 0; h<width; h++) { for(int w = 0; w<width;w++) { Y[h*m_iPicWidth + w] = pixelY; } } Pel *U = m_apiPicBufU + (posY>>1)*(m_iPicWidth>>1)+(posX>>1); Pel *V = m_apiPicBufV + (posY>>1)*(m_iPicWidth>>1)+(posX>>1); for(int h = 0; h<(width>>1); h++) { for(int w = 0; w<(width>>1);w++) { U[h*(m_iPicWidth>>1) + w] = pixelU; V[h*(m_iPicWidth>>1) + w] = pixelV; } } } int main() { TComPicYuv *frame = new TComPicYuv; TComPicYuv *clourMap = new TComPicYuv; frame->create(8,8); clourMap->create(512,512); FILE *FrameFile = fopen("D:\\clourFrame_8x8.yuv","wb"); FILE *clourFile = fopen("D:\\clourMap_512x512.yuv","wb"); for(int Y = 0; Y<256; Y++) { for(int U = 0; U<256; U++) { for(int V = 0; V<256; V++) { frame->setYuv((Pel)Y,(Pel)U,(Pel)V); fwrite(frame->getPicBufY(),1,frame->getWidth()*frame->getHeight(),FrameFile); fwrite(frame->getPicBufU(),1,(frame->getWidth()*frame->getHeight())>>2,FrameFile); fwrite(frame->getPicBufV(),1,(frame->getWidth()*frame->getHeight())>>2,FrameFile); int count = Y*256*256 + U*256 + V; if(count%1000000==0) { printf("="); } } } } for(int Y = 0; Y<256; Y++) { for(int U = 0; U<256; U++) { for(int V = 0; V<256; V++) { clourMap->setPixel(U*2,V*2,2,Y,U,V); } } fwrite(clourMap->getPicBufY(),1,clourMap->getWidth()*clourMap->getHeight(),clourFile); fwrite(clourMap->getPicBufU(),1,(clourMap->getWidth()*clourMap->getHeight())>>2,clourFile); fwrite(clourMap->getPicBufV(),1,(clourMap->getWidth()*clourMap->getHeight())>>2,clourFile); printf("*"); } fclose(clourFile); fclose(FrameFile); frame->destroy(); clourMap->destroy(); }
最新发布
07-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值