在学习1中我们看到了CompArea这个类,他继承了Area中的size和position两个属性,并且给这两个补充了他们的chromaFormat和compnentID两个属性。今天我们继续看下一个类。
struct UnitArea
这个类中有两个成员变量,分别是chromaFormat和blocks,chromaFormat存储的当前单元的编码格式(420,400...)blocks是类似于vector容器的一个数组,存放的数据类型为CompArea,其分别代表Y,Cb,Cr三个通道的分量
调用Y(),Cb(),Cr()三个成员函数可以分别返回三个代表该通道的CompArea类型的值,其余的方法类似于前面的介绍。
typedef static_vector<CompArea, MAX_NUM_TBLOCKS> UnitBlocksType;
struct UnitArea
{
ChromaFormat chromaFormat;
UnitBlocksType blocks;
UnitArea() : chromaFormat(NUM_CHROMA_FORMAT) { }
UnitArea(const ChromaFormat _chromaFormat);
UnitArea(const ChromaFormat _chromaFormat, const Area &area);
UnitArea(const ChromaFormat _chromaFormat, const CompArea &blkY);
UnitArea(const ChromaFormat _chromaFormat, CompArea &&blkY);
UnitArea(const ChromaFormat _chromaFormat, const CompArea &blkY, const CompArea &blkCb, const CompArea &blkCr);
UnitArea(const ChromaFormat _chromaFormat, CompArea &&blkY, CompArea &&blkCb, CompArea &&blkCr);
CompArea& Y() { return blocks[COMPONENT_Y]; }
const CompArea& Y() const { return blocks[COMPONENT_Y]; }
CompArea& Cb() { return blocks[COMPONENT_Cb]; }
const CompArea& Cb() const { return blocks[COMPONENT_Cb]; }
CompArea& Cr() { return blocks[COMPONENT_Cr]; }
const CompArea& Cr() const { return blocks[COMPONENT_Cr]; }
CompArea& block(const ComponentID comp) { return blocks[comp]; }
const CompArea& block(const ComponentID comp) const { return blocks[comp]; }
bool contains(const UnitArea& other) const;
bool contains(const UnitArea& other, const ChannelType chType) const;
CompArea& operator[]( const int n ) { return blocks[n]; }
const CompArea& operator[]( const int n ) const { return blocks[n]; }
const bool operator==(const UnitArea &other) const
{
if (chromaFormat != other.chromaFormat) return false;
if (blocks.size() != other.blocks.size()) return false;
for (uint32_t i = 0; i < blocks.size(); i++)
{
if (blocks[i] != other.blocks[i]) return false;
}
return true;
}
#if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
void resizeTo (const UnitArea& unit);
#endif
void repositionTo(const UnitArea& unit);
const bool operator!=(const UnitArea &other) const { return !(*this == other); }
const Position& lumaPos () const { return Y(); }
const Size& lumaSize() const { return Y(); }
const Position& chromaPos () const { return Cb(); }
const Size& chromaSize() const { return Cb(); }
const UnitArea singleComp(const ComponentID compID) const;
const UnitArea singleChan(const ChannelType chType) const;
const SizeType lwidth() const { return Y().width; } /*! luma width */
const SizeType lheight() const { return Y().height; } /*! luma height */
const PosType lx() const { return Y().x; } /*! luma x-pos */
const PosType ly() const { return Y().y; } /*! luma y-pos */
bool valid() const { return chromaFormat != NUM_CHROMA_FORMAT && blocks.size() > 0; }
};
template struct AreaBuf
这是一个模板类,其成员函数有一个模板指针,以及int型整数stride,根据具体的类型定义的不同,它可以作为不同数据的缓存,可以缓存像素的信息,变换的信息,运动向量的信息等等。同时它的基类是Size,在先前的结构中,已经有个坐标,大小,通道,编码格式等信息,所以我们就可以凭借这些信息在AreaBuf中拿出我们想要的具体的值。
类中定义了许多的成员函数,大多数的作用顾名思义,at()方法与大多数容器一样返回一个值,bufat()返回当前位置的指针,subbuf()返回一个子AreaBuf
template<typename T>
struct AreaBuf : public Size
{
T* buf;
int stride;
// the proper type causes awful lot of errors
//ptrdiff_t stride;
AreaBuf() : Size(), buf( NULL ), stride( 0 ) { }
AreaBuf( T *_buf, const Size &size ) : Size( size ), buf( _buf ), stride( size.width ) { }
AreaBuf( T *_buf, const int &_stride, const Size &size ) : Size( size ), buf( _buf ), stride( _stride ) { }
AreaBuf( T *_buf, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _width ) { }
AreaBuf( T *_buf, const int &_stride, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _stride ) { }
operator AreaBuf<const T>() const { return AreaBuf<const T>( buf, stride, width, height ); }
void fill ( const T &val );
void memset ( const int val );
void copyFrom ( const AreaBuf<const T> &other );
void roundToOutputBitdepth(const AreaBuf<const T> &src, const ClpRng& clpRng);
void reconstruct ( const AreaBuf<const T> &pred, const AreaBuf<const T> &resi, const ClpRng& clpRng);
void copyClip ( const AreaBuf<const T> &src, const ClpRng& clpRng);
void subtract ( const AreaBuf<const T> &other );
void extendSingleBorderPel();
void extendBorderPel ( unsigned margin );
void extendBorderPel(unsigned marginX, unsigned marginY);
void padBorderPel ( unsigned marginX, unsigned marginY, int dir );
void addWeightedAvg ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng, const int8_t bcwIdx);
void removeWeightHighFreq ( const AreaBuf<T>& other, const bool bClip, const ClpRng& clpRng, const int8_t iBcwWeight);
void addAvg ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng );
void removeHighFreq ( const AreaBuf<T>& other, const bool bClip, const ClpRng& clpRng);
void updateHistogram ( std::vector<int32_t>& hist ) const;
T meanDiff ( const AreaBuf<const T> &other ) const;
void subtract ( const T val );
void linearTransform ( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng );
void transposedFrom ( const AreaBuf<const T> &other );
void toLast ( const ClpRng& clpRng );
void rspSignal ( std::vector<Pel>& pLUT );
void scaleSignal ( const int scale, const bool dir , const ClpRng& clpRng);
T computeAvg ( ) const;
T& at( const int &x, const int &y ) { return buf[y * stride + x]; }
const T& at( const int &x, const int &y ) const { return buf[y * stride + x]; }
T& at( const Position &pos ) { return buf[pos.y * stride + pos.x]; }
const T& at( const Position &pos ) const { return buf[pos.y * stride + pos.x]; }
T* bufAt( const int &x, const int &y ) { return &at( x, y ); }
const T* bufAt( const int &x, const int &y ) const { return &at( x, y ); }
T* bufAt( const Position& pos ) { return &at( pos ); }
const T* bufAt( const Position& pos ) const { return &at( pos ); }
AreaBuf< T> subBuf( const Position &pos, const Size &size ) { return AreaBuf< T>( bufAt( pos ), stride, size ); }
AreaBuf<const T> subBuf( const Position &pos, const Size &size ) const { return AreaBuf<const T>( bufAt( pos ), stride, size ); }
AreaBuf< T> subBuf( const int &x, const int &y, const unsigned &_w, const unsigned &_h ) { return AreaBuf< T>( bufAt( x, y ), stride, _w, _h ); }
AreaBuf<const T> subBuf( const int &x, const int &y, const unsigned &_w, const unsigned &_h ) const { return AreaBuf<const T>( bufAt( x, y ), stride, _w, _h ); }
};
typedef AreaBuf< Pel> PelBuf;
typedef AreaBuf<const Pel> CPelBuf;
typedef AreaBuf< TCoeff> CoeffBuf;
typedef AreaBuf<const TCoeff> CCoeffBuf;
typedef AreaBuf< MotionInfo> MotionBuf;
typedef AreaBuf<const MotionInfo> CMotionBuf;
typedef AreaBuf< TCoeff> PLTescapeBuf;
typedef AreaBuf<const TCoeff> CPLTescapeBuf;
typedef AreaBuf< bool> PLTtypeBuf;
typedef AreaBuf<const bool> CPLTtypeBu
template struct UnitBuf
就目前所看到带有unit的数据结构,都是将之前的单通道的结构,整合成为了一个更全面的结构,是一种层层包含的关系,在AreaBuf中只存在Y,Cb或者Cr一个通道,而在UnitBuf中,它将分别代表Y,Cb,Cr的AreaBuf当作一个数组元素,存放进了static_vector中。
struct UnitArea;
template<typename T>
struct UnitBuf
{
typedef static_vector<AreaBuf<T>, MAX_NUM_COMPONENT> UnitBufBuffers;
typedef static_vector<AreaBuf<const T>, MAX_NUM_COMPONENT> ConstUnitBufBuffers;
ChromaFormat chromaFormat;
UnitBufBuffers bufs;
UnitBuf() : chromaFormat( NUM_CHROMA_FORMAT ) { }
UnitBuf( const ChromaFormat &_chromaFormat, const UnitBufBuffers& _bufs ) : chromaFormat( _chromaFormat ), bufs( _bufs ) { }
UnitBuf( const ChromaFormat &_chromaFormat, UnitBufBuffers&& _bufs ) : chromaFormat( _chromaFormat ), bufs( std::forward<UnitBufBuffers>( _bufs ) ) { }
UnitBuf( const ChromaFormat &_chromaFormat, const AreaBuf<T> &blkY ) : chromaFormat( _chromaFormat ), bufs{ blkY } { }
UnitBuf( const ChromaFormat &_chromaFormat, AreaBuf<T> &&blkY ) : chromaFormat( _chromaFormat ), bufs{ std::forward<AreaBuf<T> >(blkY) } { }
UnitBuf( const ChromaFormat &_chromaFormat, const AreaBuf<T> &blkY, const AreaBuf<T> &blkCb, const AreaBuf<T> &blkCr ) : chromaFormat( _chromaFormat ), bufs{ blkY, blkCb, blkCr } { }
UnitBuf( const ChromaFormat &_chromaFormat, AreaBuf<T> &&blkY, AreaBuf<T> &&blkCb, AreaBuf<T> &&blkCr ) : chromaFormat( _chromaFormat ), bufs{ std::forward<AreaBuf<T> >(blkY), std::forward<AreaBuf<T> >(blkCb), std::forward<AreaBuf<T> >(blkCr) } { }
operator UnitBuf<const T>() const
{
return UnitBuf<const T>( chromaFormat, ConstUnitBufBuffers( bufs.begin(), bufs.end() ) );
}
AreaBuf<T>& get( const ComponentID comp ) { return bufs[comp]; }
const AreaBuf<T>& get( const ComponentID comp ) const { return bufs[comp]; }
AreaBuf<T>& Y() { return bufs[0]; }
const AreaBuf<T>& Y() const { return bufs[0]; }
AreaBuf<T>& Cb() { return bufs[1]; }
const AreaBuf<T>& Cb() const { return bufs[1]; }
AreaBuf<T>& Cr() { return bufs[2]; }
const AreaBuf<T>& Cr() const { return bufs[2]; }
void fill ( const T &val );
void copyFrom ( const UnitBuf<const T> &other, const bool lumaOnly = false, const bool chromaOnly = false );
void roundToOutputBitdepth(const UnitBuf<const T> &src, const ClpRngs& clpRngs);
void reconstruct ( const UnitBuf<const T> &pred, const UnitBuf<const T> &resi, const ClpRngs& clpRngs );
void copyClip ( const UnitBuf<const T> &src, const ClpRngs& clpRngs, const bool lumaOnly = false, const bool chromaOnly = false );
void subtract ( const UnitBuf<const T> &other );
void addWeightedAvg ( const UnitBuf<const T> &other1, const UnitBuf<const T> &other2, const ClpRngs& clpRngs, const uint8_t bcwIdx = BCW_DEFAULT, const bool chromaOnly = false, const bool lumaOnly = false);
void addAvg ( const UnitBuf<const T> &other1, const UnitBuf<const T> &other2, const ClpRngs& clpRngs, const bool chromaOnly = false, const bool lumaOnly = false);
void extendSingleBorderPel();
void extendBorderPel(unsigned marginX, unsigned marginY);
void padBorderPel ( unsigned margin, int dir );
void extendBorderPel ( unsigned margin );
void removeHighFreq ( const UnitBuf<T>& other, const bool bClip, const ClpRngs& clpRngs
, const int8_t bcwWeight = g_BcwWeights[BCW_DEFAULT]
);
UnitBuf< T> subBuf (const UnitArea& subArea);
const UnitBuf<const T> subBuf (const UnitArea& subArea) const;
void colorSpaceConvert(const UnitBuf<T> &other, const bool forward, const ClpRng& clpRng);
};
typedef UnitBuf< Pel> PelUnitBuf;
typedef UnitBuf<const Pel> CPelUnitBuf;
typedef UnitBuf< TCoeff> CoeffUnitBuf;
typedef UnitBuf<const TCoeff> CCoeffUnitBuf;
struct PelStorage:public PelUnitBuf
这个类简单来说就是开辟内存使用的,为缓存器开闭对应的内存存储数据,主要使用create成员函数为其分配相应大小的内存空间。
//Buffer.h
struct UnitArea;
struct CompArea;
struct PelStorage : public PelUnitBuf
{
PelStorage();
~PelStorage();
void swap( PelStorage& other );
void createFromBuf( PelUnitBuf buf );
void create( const UnitArea &_unit );
void create( const ChromaFormat &_chromaFormat, const Area& _area, const unsigned _maxCUSize = 0,
const unsigned _margin = 0, const unsigned _alignment = 0, const bool _scaleChromaMargin = true );
void destroy();
PelBuf getBuf( const CompArea &blk );
const CPelBuf getBuf( const CompArea &blk ) const;
PelBuf getBuf( const ComponentID CompID );
const CPelBuf getBuf( const ComponentID CompID ) const;
PelUnitBuf getBuf( const UnitArea &unit );
const CPelUnitBuf getBuf( const UnitArea &unit ) const;
Pel *getOrigin( const int id ) const { return m_origin[id]; }
private:
Pel *m_origin[MAX_NUM_COMPONENT];
};
//Buffer.cpp
void PelStorage::create( const UnitArea &_UnitArea )
{
create( _UnitArea.chromaFormat, _UnitArea.blocks[0] );
}
void PelStorage::create( const ChromaFormat &_chromaFormat, const Area& _area, const unsigned _maxCUSize, const unsigned _margin, const unsigned _alignment, const bool _scaleChromaMargin )
{
CHECK( !bufs.empty(), "Trying to re-create an already initialized buffer" );
chromaFormat = _chromaFormat;
const uint32_t numCh = getNumberValidComponents( _chromaFormat );
unsigned extHeight = _area.height;
unsigned extWidth = _area.width;
if( _maxCUSize )
{
extHeight = ( ( _area.height + _maxCUSize - 1 ) / _maxCUSize ) * _maxCUSize;
extWidth = ( ( _area.width + _maxCUSize - 1 ) / _maxCUSize ) * _maxCUSize;
}
for( uint32_t i = 0; i < numCh; i++ )
{
const ComponentID compID = ComponentID( i );
const unsigned scaleX = ::getComponentScaleX( compID, _chromaFormat );
const unsigned scaleY = ::getComponentScaleY( compID, _chromaFormat );
unsigned scaledHeight = extHeight >> scaleY;
unsigned scaledWidth = extWidth >> scaleX;
unsigned ymargin = _margin >> (_scaleChromaMargin?scaleY:0);
unsigned xmargin = _margin >> (_scaleChromaMargin?scaleX:0);
unsigned totalWidth = scaledWidth + 2*xmargin;
unsigned totalHeight = scaledHeight +2*ymargin;
if( _alignment )
{
// make sure buffer lines are align
CHECK( _alignment != MEMORY_ALIGN_DEF_SIZE, "Unsupported alignment" );
totalWidth = ( ( totalWidth + _alignment - 1 ) / _alignment ) * _alignment;
}
uint32_t area = totalWidth * totalHeight;
CHECK( !area, "Trying to create a buffer with zero area" );
m_origin[i] = ( Pel* ) xMalloc( Pel, area );
Pel* topLeft = m_origin[i] + totalWidth * ymargin + xmargin;
bufs.push_back( PelBuf( topLeft, totalWidth, _area.width >> scaleX, _area.height >> scaleY ) );
}
}