Newer
Older

Karsten Suehring
committed
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2010-2025, ITU/ISO/IEC

Karsten Suehring
committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \file UnitPartitioner.h
* \brief Provides a class for partitioning management
*/
#ifndef __UNITPARTITIONER__
#define __UNITPARTITIONER__
#include "Unit.h"
#include "CommonDef.h"
static_assert( MAX_CU_TILING_PARTITIONS >= 4, "Minimum required number of partitions for the Partitioning type is 4!" );
typedef std::vector <UnitArea> Partitioning;

Karsten Suehring
committed
//////////////////////////////////////////////////////////////////////////
// PartManager class - manages the partitioning tree
//
// contains the currently processed partitioning area (currArea)
// as well as the all partitioning decisions that led to this area
// being processed (in m_partStack).
//////////////////////////////////////////////////////////////////////////
enum PartSplit
{
CTU_LEVEL = 0,
CU_QUAD_SPLIT,
CU_HORZ_SPLIT,
CU_VERT_SPLIT,
CU_TRIH_SPLIT,
CU_TRIV_SPLIT,
TU_MAX_TR_SPLIT,
TU_NO_ISP,
TU_1D_HORZ_SPLIT,
TU_1D_VERT_SPLIT,
SBT_VER_HALF_POS0_SPLIT,
SBT_VER_HALF_POS1_SPLIT,
SBT_HOR_HALF_POS0_SPLIT,
SBT_HOR_HALF_POS1_SPLIT,
SBT_VER_QUAD_POS0_SPLIT,
SBT_VER_QUAD_POS1_SPLIT,
SBT_HOR_QUAD_POS0_SPLIT,
SBT_HOR_QUAD_POS1_SPLIT,

Karsten Suehring
committed
NUM_PART_SPLIT,
CU_MT_SPLIT = 1000, ///< dummy element to indicate the MT (multi-type-tree) split
CU_BT_SPLIT = 1001, ///< dummy element to indicate the BT split
CU_DONT_SPLIT = 2000 ///< dummy element to indicate no splitting
};
struct PartLevel
{
PartSplit split;
Partitioning parts;
unsigned idx;
bool checkdIfImplicit;
bool isImplicit;
PartSplit implicitSplit;
PartSplit firstSubPartSplit;
bool canQtSplit;
bool qgEnable;
bool qgChromaEnable;

Karsten Suehring
committed
PartLevel();
PartLevel( const PartSplit _split, const Partitioning& _parts );
PartLevel( const PartSplit _split, Partitioning&& _parts );
};
// set depending on max QT / BT possibilities
typedef static_vector<PartLevel, 2 * MAX_CU_DEPTH + 1> PartitioningStack;
class Partitioner
{
protected:
PartitioningStack m_partStack;
#if _DEBUG
UnitArea m_currArea;
#endif
public:
unsigned currDepth;
unsigned currQtDepth;
unsigned currTrDepth;
unsigned currBtDepth;
unsigned currMtDepth;
unsigned currSubdiv;
Position currQgPos;
Position currQgChromaPos;

Karsten Suehring
committed
unsigned currImplicitBtDepth;
ChannelType chType;
TreeType treeType;
ModeType modeType;

Karsten Suehring
committed
virtual ~Partitioner () { }
const PartLevel& currPartLevel () const { return m_partStack.back(); }
const UnitArea& currArea () const { return currPartLevel().parts[currPartIdx()]; }
const unsigned currPartIdx () const { return currPartLevel().idx; }
const PartitioningStack& getPartStack () const { return m_partStack; }
const bool currQgEnable () const { return currPartLevel().qgEnable; }
const bool currQgChromaEnable () const { return currPartLevel().qgChromaEnable; }

Karsten Suehring
committed
SplitSeries getSplitSeries () const;
ModeTypeSeries getModeTypeSeries () const;

Karsten Suehring
committed
virtual void initCtu ( const UnitArea& ctuArea, const ChannelType _chType, const Slice& slice ) = 0;
virtual void splitCurrArea ( const PartSplit split, const CodingStructure &cs ) = 0;
virtual void exitCurrSplit () = 0;
virtual bool nextPart ( const CodingStructure &cs, bool autoPop = false ) = 0;
virtual bool hasNextPart () = 0;
virtual void setCUData ( CodingUnit& cu );
virtual void copyState ( const Partitioner& other );
public:
virtual void canSplit ( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv ) = 0;

Karsten Suehring
committed
virtual bool canSplit ( const PartSplit split, const CodingStructure &cs ) = 0;
virtual bool isSplitImplicit ( const PartSplit split, const CodingStructure &cs ) = 0;
virtual PartSplit getImplicitSplit ( const CodingStructure &cs ) = 0;
bool isSepTree ( const CodingStructure &cs );
bool isLocalSepTree ( const CodingStructure &cs );
bool isConsInter () { return modeType == MODE_TYPE_INTER; }
bool isConsIntra () { return modeType == MODE_TYPE_INTRA; }

Karsten Suehring
committed
};
class AdaptiveDepthPartitioner : public Partitioner
{
public:
void setMaxMinDepth( unsigned& minDepth, unsigned& maxDepth, const CodingStructure& cs ) const;
};
class QTBTPartitioner : public AdaptiveDepthPartitioner
{
public:
void initCtu ( const UnitArea& ctuArea, const ChannelType _chType, const Slice& slice );
void splitCurrArea ( const PartSplit split, const CodingStructure &cs );
void exitCurrSplit ();
bool nextPart ( const CodingStructure &cs, bool autoPop = false );
bool hasNextPart ();
void canSplit ( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv );

Karsten Suehring
committed
bool canSplit ( const PartSplit split, const CodingStructure &cs );
bool isSplitImplicit ( const PartSplit split, const CodingStructure &cs );
PartSplit getImplicitSplit ( const CodingStructure &cs );
};
class TUIntraSubPartitioner : public Partitioner
{
public:
TUIntraSubPartitioner(Partitioner& _initialState)
{
//we copy the input partitioner data
m_partStack.push_back(PartLevel(TU_NO_ISP, { _initialState.currArea() }));
currDepth = _initialState.currDepth;
currQtDepth = _initialState.currQtDepth;
currTrDepth = _initialState.currTrDepth;
currBtDepth = _initialState.currBtDepth;
currMtDepth = _initialState.currMtDepth;
chType = _initialState.chType;
#if _DEBUG
m_currArea = _initialState.currArea();
#endif
treeType = _initialState.treeType;
modeType = _initialState.modeType;
}
void initCtu (const UnitArea& ctuArea, const ChannelType chType, const Slice& slice) {}; // not needed
void splitCurrArea (const PartSplit split, const CodingStructure &cs);
void exitCurrSplit ();
bool nextPart (const CodingStructure &cs, bool autoPop = false);
bool hasNextPart ();
void canSplit (const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv) {};
bool canSplit (const PartSplit split, const CodingStructure &cs);
bool isSplitImplicit (const PartSplit split, const CodingStructure &cs) { return false; }; //not needed
PartSplit getImplicitSplit (const CodingStructure &cs) { return CU_DONT_SPLIT; }; //not needed
};

Karsten Suehring
committed
//////////////////////////////////////////////////////////////////////////
// Partitioner namespace - contains methods calculating the actual splits
//////////////////////////////////////////////////////////////////////////
namespace PartitionerImpl
{
Partitioning getCUSubPartitions( const UnitArea &cuArea, const CodingStructure &cs, const PartSplit splitType = CU_QUAD_SPLIT );
Partitioning getMaxTuTiling ( const UnitArea& curArea, const CodingStructure &cs );
void getTUIntraSubPartitions( Partitioning &sub, const UnitArea &tuArea, const CodingStructure &cs, const PartSplit splitType );
Partitioning getSbtTuTiling ( const UnitArea& curArea, const CodingStructure &cs, const PartSplit splitType );