VTM数据结构2
文章目录
前言
学习CompArea,UnitArea前参考VTM数据结构1
VTM数据结构1
VTM数据结构:CompArea,UnitArea
这两种自定义的数据类型继承于Area
提示:以下是本篇文章正文内容,下面案例可供参考
这两种自定义数据类型在CommonLib/Unit.h中定义
一、CompArea
简介:CopArea继承自Area,用来表示特定分量的二维信息
注意:CompArea作为子类,添加了ChromaFormat型的成员,以及ComponentID型的成员,这两种都是美剧类型的变量。
ChromaFormat和ComponentID枚举类型的定义
enum ChromaFormat
{
CHROMA_400 = 0,
CHROMA_420 = 1,
CHROMA_422 = 2,
CHROMA_444 = 3,
NUM_CHROMA_FORMAT = 4
};
enum ComponentID
{
COMPONENT_Y = 0,
COMPONENT_Cb = 1,
COMPONENT_Cr = 2,
MAX_NUM_COMPONENT = 3,
MAX_NUM_TBLOCKS = MAX_NUM_COMPONENT
};
VTM对CompArea的定义:
struct CompArea : public Area
{
CompArea() : Area(), chromaFormat(NUM_CHROMA_FORMAT), compID(MAX_NUM_TBLOCKS) { } //参数初始化列表
//以给出了
CompArea(const ComponentID _compID, const ChromaFormat _cf, const Area &_area, const bool isLuma = false) : Area(_area), chromaFormat(_cf), compID(_compID) { if (isLuma) xRecalcLumaToChroma(); }
CompArea(const ComponentID _compID, const ChromaFormat _cf, const Position& _pos, const Size& _size, const bool isLuma = false) : Area(_pos, _size), chromaFormat(_cf), compID(_compID) { if (isLuma) xRecalcLumaToChroma(); }
CompArea(const ComponentID _compID, const ChromaFormat _cf, const uint32_t _x, const uint32_t _y, const uint32_t _w, const uint32_t _h, const bool isLuma = false) : Area(_x, _y, _w, _h), chromaFormat(_cf), compID(_compID) { if (isLuma) xRecalcLumaToChroma(); }
ChromaFormat chromaFormat; //新增的成员变量
ComponentID compID; //新增的成员变量
Position chromaPos() const;
Position lumaPos() const;
Size chromaSize() const;
Size lumaSize() const;
Position compPos( const ComponentID compID ) const;
Position chanPos( const ChannelType chType ) const;
Position topLeftComp (const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, *this); }
Position topRightComp (const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, { (PosType) (x + width - 1), y }); }
Position bottomLeftComp (const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, { x , (PosType) (y + height - 1 )}); }
Position bottomRightComp(const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, { (PosType) (x + width - 1), (PosType) (y + height - 1 )}); }
bool valid() const { return chromaFormat < NUM_CHROMA_FORMAT && compID < MAX_NUM_TBLOCKS && width != 0 && height != 0; } //校验数据有效
const bool operator==(const CompArea &other) const //重载==,
{
if (chromaFormat != other.chromaFormat) return false;
if (compID != other.compID) return false;
return Position::operator==(other) && Size::operator==(other); //利用父类的重载,
}
const bool operator!=(const CompArea &other) const { return !(operator==(other)); } //重载!=
#if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
void resizeTo (const Size& newSize) { Size::resizeTo(newSize); }
#endif
void repositionTo (const Position& newPos) { Position::repositionTo(newPos); }
void positionRelativeTo(const CompArea& origCompArea) { Position::relativeTo(origCompArea); }
private:
void xRecalcLumaToChroma();
};
二、UnitArea
简介:UnitArea中存放了ChromaFormat型以及CompArea型的数据
1.static_vector的封装
类模板static_vector
template<typename T, size_t N>
class static_vector
{
T _arr[ N ];
size_t _size;
public:
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T& reference;
typedef T const& const_reference;
typedef T* pointer;
typedef T const* const_pointer;
typedef T* iterator;
typedef T const* const_iterator;
static const size_type max_num_elements = N;
static_vector() : _size( 0 ) { }
static_vector( size_t N_ ) : _size( N_ ) { }
static_vector( size_t N_, const T& _val ) : _size( 0 ) { resize( N_, _val ); }
template<typename It>
static_vector( It _it1, It _it2 ) : _size( 0 ) { while( _it1 < _it2 ) _arr[ _size++ ] = *_it1++; }
static_vector( std::initializer_list<T> _il ) : _size( 0 )
{
typename std::initializer_list<T>::iterator _src1 = _il.begin();
typename std::initializer_list<T>::iterator _src2 = _il.end();
while( _src1 < _src2 ) _arr[ _size++ ] = *_src1++;
CHECKD( _size > N, "capacity exceeded" );
}
static_vector& operator=( std::initializer_list<T> _il )
{
_size = 0;
typename std::initializer_list<T>::iterator _src1 = _il.begin();
typename std::initializer_list<T>::iterator _src2 = _il.end();
while( _src1 < _src2 ) _arr[ _size++ ] = *_src1++;
CHECKD( _size > N, "capacity exceeded" );
}
void resize( size_t N_ ) { CHECKD( N_ > N, "capacity exceeded" ); while(_size < N_) _arr[ _size++ ] = T() ; _size = N_; }
void resize( size_t N_, const T& _val ) { CHECKD( N_ > N, "capacity exceeded" ); while(_size < N_) _arr[ _size++ ] = _val; _size = N_; }
void reserve( size_t N_ ) { CHECKD( N_ > N, "capacity exceeded" ); }
void push_back( const T& _val ) { CHECKD( _size >= N, "capacity exceeded" ); _arr[ _size++ ] = _val; }
void push_back( T&& val ) { CHECKD( _size >= N, "capacity exceeded" ); _arr[ _size++ ] = std::forward<T>( val ); }
void pop_back() { CHECKD( _size == 0, "calling pop_back on an empty vector" ); _size--; }
void pop_front() { CHECKD( _size == 0, "calling pop_front on an empty vector" ); _size--; for( int i = 0; i < _size; i++ ) _arr[i] = _arr[i + 1]; }
void clear() { _size = 0; }
reference at( size_t _i ) { CHECKD( _i >= _size, "Trying to access an out-of-bound-element" ); return _arr[ _i ]; }
const_reference at( size_t _i ) const { CHECKD( _i >= _size, "Trying to access an out-of-bound-element" ); return _arr[ _i ]; }
reference operator[]( size_t _i ) { CHECKD( _i >= _size, "Trying to access an out-of-bound-element" ); return _arr[ _i ]; }
const_reference operator[]( size_t _i ) const { CHECKD( _i >= _size, "Trying to access an out-of-bound-element" ); return _arr[ _i ]; }
reference front() { CHECKD( _size == 0, "Trying to access the first element of an empty vector" ); return _arr[ 0 ]; }
const_reference front() const { CHECKD( _size == 0, "Trying to access the first element of an empty vector" ); return _arr[ 0 ]; }
reference back() { CHECKD( _size == 0, "Trying to access the last element of an empty vector" ); return _arr[ _size - 1 ]; }
const_reference back() const { CHECKD( _size == 0, "Trying to access the last element of an empty vector" ); return _arr[ _size - 1 ]; }
pointer data() { return _arr; }
const_pointer data() const { return _arr; }
iterator begin() { return _arr; }
const_iterator begin() const { return _arr; }
const_iterator cbegin() const { return _arr; }
iterator end() { return _arr + _size; }
const_iterator end() const { return _arr + _size; };
const_iterator cend() const { return _arr + _size; };
size_type size() const { return _size; };
size_type byte_size() const { return _size * sizeof( T ); }
bool empty() const { return _size == 0; }
size_type capacity() const { return N; }
size_type max_size() const { return N; }
size_type byte_capacity() const { return sizeof(_arr); }
iterator insert( const_iterator _pos, const T& _val )
{ CHECKD( _size >= N, "capacity exceeded" );
for( difference_type i = _size - 1; i >= _pos - _arr; i-- ) _arr[i + 1] = _arr[i];
*const_cast<iterator>( _pos ) = _val;
_size++;
return const_cast<iterator>( _pos ); }
iterator insert( const_iterator _pos, T&& _val )
{ CHECKD( _size >= N, "capacity exceeded" );
for( difference_type i = _size - 1; i >= _pos - _arr; i-- ) _arr[i + 1] = _arr[i];
*const_cast<iterator>( _pos ) = std::forward<T>( _val );
_size++; return const_cast<iterator>( _pos ); }
template<class InputIt>
iterator insert( const_iterator _pos, InputIt first, InputIt last )
{ const difference_type numEl = last - first;
CHECKD( _size + numEl >= N, "capacity exceeded" );
for( difference_type i = _size - 1; i >= _pos - _arr; i-- ) _arr[i + numEl] = _arr[i];
iterator it = const_cast<iterator>( _pos ); _size += numEl;
while( first != last ) *it++ = *first++;
return const_cast<iterator>( _pos ); }
};
UnitArea定义:
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);
//在static_vector中重载了[],实际上就是返回对应
CompArea& Y() { return blocks[COMPONENT_Y]; }//这里重载了[],返回的时_arr数组中对应的分量
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; }
};
总结
CompArea提供了单个分量的信息,UnitArea相当于是CompArea类型的数组,存储多个分量的信号。
static_vector这个类模板的设计很巧妙,相当于设计了一个类似vector容器的结构,相比于vector容器有了长度的限定。