-
Vadim Seregin authoredVadim Seregin authored
AlfParameters.h 16.32 KiB
/* 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-2022, ITU/ISO/IEC
* 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 AlfParameters.h
\brief Define types for storing ALF parameters
*/
#ifndef __ALFPARAMETERS__
#define __ALFPARAMETERS__
#include <vector>
#include "CommonDef.h"
//! \ingroup AlfParameters
//! \{
enum AlfFilterType
{
ALF_FILTER_5,
ALF_FILTER_7,
CC_ALF,
#if ALF_IMPROVEMENT
ALF_FILTER_9,
ALF_FILTER_9_EXT,
ALF_FILTER_EXT,
#endif
ALF_NUM_OF_FILTER_TYPES
};
static const int size_CC_ALF = -1;
#if ALF_IMPROVEMENT
static const int size_ALF_FILTER_9_EXT = -2;
static const int size_ALF_FILTER_EXT = -3;
#endif
struct AlfFilterShape
{
AlfFilterShape( int size )
: filterLength( size ),
numCoeff( size * size / 4 + 1 ),
filterSize( size * size / 2 + 1 )
#if ALF_IMPROVEMENT
, numOrder( 0 )
, indexSecOrder( 0 )
, offset0( 0 )
#endif
{
if( size == 5 )
{
pattern = {
0,
1, 2, 3,
4, 5, 6, 5, 4,
3, 2, 1,
0
};
weights = {
2,
2, 2, 2,
2, 2, 1, 1
};
filterType = ALF_FILTER_5;
#if ALF_IMPROVEMENT
numOrder = 1;
indexSecOrder = numCoeff - 1;
offset0 = 0;
#endif
}
else if( size == 7 )
{
pattern = {
0,
1, 2, 3,
4, 5, 6, 7, 8,
9, 10, 11, 12, 11, 10, 9,
8, 7, 6, 5, 4,
3, 2, 1,
0
};
weights = {
2,
2, 2, 2,
2, 2, 2, 2, 2,
2, 2, 2, 1, 1
};
filterType = ALF_FILTER_7;
#if ALF_IMPROVEMENT
numOrder = 1;
indexSecOrder = numCoeff - 1;
offset0 = 0;
#endif
}
#if ALF_IMPROVEMENT
else if( size == 9 )
{
pattern = {
0,
1, 2, 3,
4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 19, 18, 17, 16,
15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4,
3, 2, 1,
0
};
weights = {
2,
2, 2, 2,
2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 1
};
filterType = ALF_FILTER_9;
#if ALF_IMPROVEMENT
numOrder = 1;
indexSecOrder = numCoeff - 1;
offset0 = 0;
#endif
}
else if( size == size_ALF_FILTER_EXT )
{
size = filterLength = 0;
numCoeff = filterSize = EXT_LENGTH;
filterType = ALF_FILTER_EXT;
#if ALF_IMPROVEMENT
numOrder = 1;
indexSecOrder = numCoeff - 1;
offset0 = ALF_ORDER;
#endif
}
else if( size == size_ALF_FILTER_9_EXT )
{
size = 9;
numCoeff = MAX_NUM_ALF_LUMA_COEFF;
filterSize = MAX_NUM_ALF_LUMA_COEFF;
filterLength = 9;
filterType = ALF_FILTER_9_EXT;
pattern = {
0,
1, 2, 3,
4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 19, 18, 17, 16,
15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4,
3, 2, 1,
0
};
#if ALF_IMPROVEMENT
numOrder = 2;
indexSecOrder = 20;
offset0 = 0;
#endif
}
#endif
else if( size == size_CC_ALF )
{
size = 4;
#if JVET_X0071_LONGER_CCALF
filterLength = MAX_NUM_CC_ALF_CHROMA_COEFF;
numCoeff = MAX_NUM_CC_ALF_CHROMA_COEFF;
filterSize = MAX_NUM_CC_ALF_CHROMA_COEFF;
#else
filterLength = 8;
numCoeff = 8;
filterSize = 8;
#endif
filterType = CC_ALF;
}
else
{
filterType = ALF_NUM_OF_FILTER_TYPES;
CHECK( 0, "Wrong ALF filter shape" );
}
}
AlfFilterType filterType;
int filterLength;
int numCoeff; //TO DO: check whether we need both numCoeff and filterSize
int filterSize;
std::vector<int> pattern;
std::vector<int> weights;
#if ALF_IMPROVEMENT
int numOrder;
int indexSecOrder;
int offset0;
#endif
};
struct AlfParam
{
bool enabledFlag[MAX_NUM_COMPONENT]; // alf_slice_enable_flag, alf_chroma_idc
#if ALF_IMPROVEMENT
#if JVET_X0071_ALF_BAND_CLASSIFIER
char lumaClassifierIdx[MAX_NUM_ALF_ALTERNATIVES_LUMA];
#endif
AlfFilterType filterType[MAX_NUM_CHANNEL_TYPE];
bool nonLinearFlag[MAX_NUM_CHANNEL_TYPE][32]; // alf_[luma/chroma]_clip_flag
int numAlternativesLuma;
short lumaCoeff[MAX_NUM_ALF_ALTERNATIVES_LUMA][MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_coeff_luma_delta[i][j]
#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
Pel lumaClipp[MAX_NUM_ALF_ALTERNATIVES_LUMA][MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_clipp_luma_[i][j]
#else
short lumaClipp[MAX_NUM_ALF_ALTERNATIVES_LUMA][MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_clipp_luma_[i][j]
#endif
int numLumaFilters[MAX_NUM_ALF_ALTERNATIVES_LUMA]; // number_of_filters_minus1 + 1
short filterCoeffDeltaIdx[MAX_NUM_ALF_ALTERNATIVES_LUMA][MAX_NUM_ALF_CLASSES]; // filter_coeff_delta[i]// number_of_filters_minus1 + 1
#else
bool nonLinearFlag[MAX_NUM_CHANNEL_TYPE]; // alf_[luma/chroma]_clip_flag
short lumaCoeff[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_coeff_luma_delta[i][j]
#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
Pel lumaClipp[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_clipp_luma_[i][j]
#else
short lumaClipp[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_clipp_luma_[i][j]
#endif
int numLumaFilters; // number_of_filters_minus1 + 1
short filterCoeffDeltaIdx[MAX_NUM_ALF_CLASSES]; // filter_coeff_delta[i]
#endif
int numAlternativesChroma; // alf_chroma_num_alts_minus_one + 1
short chromaCoeff[MAX_NUM_ALF_ALTERNATIVES_CHROMA][MAX_NUM_ALF_CHROMA_COEFF]; // alf_coeff_chroma[i]
#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
Pel chromaClipp[MAX_NUM_ALF_ALTERNATIVES_CHROMA][MAX_NUM_ALF_CHROMA_COEFF]; // alf_clipp_chroma[i]
#else
short chromaClipp[MAX_NUM_ALF_ALTERNATIVES_CHROMA][MAX_NUM_ALF_CHROMA_COEFF]; // alf_clipp_chroma[i]
#endif
bool alfLumaCoeffFlag[MAX_NUM_ALF_CLASSES]; // alf_luma_coeff_flag[i]
bool alfLumaCoeffDeltaFlag; // alf_luma_coeff_delta_flag
std::vector<AlfFilterShape>* filterShapes;
bool newFilterFlag[MAX_NUM_CHANNEL_TYPE];
AlfParam()
{
reset();
}
void reset()
{
std::memset( enabledFlag, false, sizeof( enabledFlag ) );
std::memset( nonLinearFlag, false, sizeof( nonLinearFlag ) );
#if JVET_X0071_ALF_BAND_CLASSIFIER
std::memset( lumaClassifierIdx, 0, sizeof( lumaClassifierIdx ) );
#endif
std::memset( lumaCoeff, 0, sizeof( lumaCoeff ) );
std::memset( lumaClipp, 0, sizeof( lumaClipp ) );
numAlternativesChroma = 1;
std::memset( chromaCoeff, 0, sizeof( chromaCoeff ) );
std::memset( chromaClipp, 0, sizeof( chromaClipp ) );
std::memset( filterCoeffDeltaIdx, 0, sizeof( filterCoeffDeltaIdx ) );
std::memset( alfLumaCoeffFlag, true, sizeof( alfLumaCoeffFlag ) );
#if ALF_IMPROVEMENT
std::memset(filterType, false, sizeof(filterType));
numAlternativesLuma = 1;
for (int i = 0; i < MAX_NUM_ALF_ALTERNATIVES_LUMA; i++)
{
numLumaFilters[i] = 1;
}
#else
numLumaFilters = 1;
#endif
alfLumaCoeffDeltaFlag = false;
memset(newFilterFlag, 0, sizeof(newFilterFlag));
}
const AlfParam& operator = ( const AlfParam& src )
{
std::memcpy( enabledFlag, src.enabledFlag, sizeof( enabledFlag ) );
std::memcpy( nonLinearFlag, src.nonLinearFlag, sizeof( nonLinearFlag ) );
#if JVET_X0071_ALF_BAND_CLASSIFIER
std::memcpy( lumaClassifierIdx, src.lumaClassifierIdx, sizeof( lumaClassifierIdx ) );
#endif
std::memcpy( lumaCoeff, src.lumaCoeff, sizeof( lumaCoeff ) );
std::memcpy( lumaClipp, src.lumaClipp, sizeof( lumaClipp ) );
numAlternativesChroma = src.numAlternativesChroma;
std::memcpy( chromaCoeff, src.chromaCoeff, sizeof( chromaCoeff ) );
std::memcpy( chromaClipp, src.chromaClipp, sizeof( chromaClipp ) );
std::memcpy( filterCoeffDeltaIdx, src.filterCoeffDeltaIdx, sizeof( filterCoeffDeltaIdx ) );
std::memcpy( alfLumaCoeffFlag, src.alfLumaCoeffFlag, sizeof( alfLumaCoeffFlag ) );
#if ALF_IMPROVEMENT
std::memcpy(filterType, src.filterType, sizeof(filterType));
numAlternativesLuma = src.numAlternativesLuma;
std::memcpy(numLumaFilters, src.numLumaFilters, sizeof(numLumaFilters));
#else
numLumaFilters = src.numLumaFilters;
#endif
alfLumaCoeffDeltaFlag = src.alfLumaCoeffDeltaFlag;
filterShapes = src.filterShapes;
std::memcpy(newFilterFlag, src.newFilterFlag, sizeof(newFilterFlag));
return *this;
}
bool operator==( const AlfParam& other )
{
if( memcmp( enabledFlag, other.enabledFlag, sizeof( enabledFlag ) ) )
{
return false;
}
if( memcmp( nonLinearFlag, other.nonLinearFlag, sizeof( nonLinearFlag ) ) )
{
return false;
}
#if ALF_IMPROVEMENT
if( memcmp( filterType, other.filterType, sizeof( filterType ) ) )
{
return false;
}
#if JVET_X0071_ALF_BAND_CLASSIFIER
if( memcmp( lumaClassifierIdx, other.lumaClassifierIdx, sizeof( lumaClassifierIdx ) ) )
{
return false;
}
#endif
#endif
if( memcmp( lumaCoeff, other.lumaCoeff, sizeof( lumaCoeff ) ) )
{
return false;
}
if( memcmp( lumaClipp, other.lumaClipp, sizeof( lumaClipp ) ) )
{
return false;
}
if( memcmp( chromaCoeff, other.chromaCoeff, sizeof( chromaCoeff ) ) )
{
return false;
}
if( memcmp( chromaClipp, other.chromaClipp, sizeof( chromaClipp ) ) )
{
return false;
}
if( memcmp( filterCoeffDeltaIdx, other.filterCoeffDeltaIdx, sizeof( filterCoeffDeltaIdx ) ) )
{
return false;
}
if( memcmp( alfLumaCoeffFlag, other.alfLumaCoeffFlag, sizeof( alfLumaCoeffFlag ) ) )
{
return false;
}
if( memcmp( newFilterFlag, other.newFilterFlag, sizeof( newFilterFlag ) ) )
{
return false;
}
if( numAlternativesChroma != other.numAlternativesChroma )
{
return false;
}
#if ALF_IMPROVEMENT
if (numAlternativesLuma != other.numAlternativesLuma)
{
return false;
}
if (memcmp(numLumaFilters, other.numLumaFilters, sizeof(numLumaFilters)))
{
return false;
}
#else
if( numLumaFilters != other.numLumaFilters )
{
return false;
}
#endif
if( alfLumaCoeffDeltaFlag != other.alfLumaCoeffDeltaFlag )
{
return false;
}
return true;
}
bool operator!=( const AlfParam& other )
{
return !( *this == other );
}
};
struct CcAlfFilterParam
{
bool ccAlfFilterEnabled[2];
bool ccAlfFilterIdxEnabled[2][MAX_NUM_CC_ALF_FILTERS];
uint8_t ccAlfFilterCount[2];
short ccAlfCoeff[2][MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF];
int newCcAlfFilter[2];
int numberValidComponents;
CcAlfFilterParam()
{
reset();
}
void reset()
{
std::memset( ccAlfFilterEnabled, false, sizeof( ccAlfFilterEnabled ) );
std::memset( ccAlfFilterIdxEnabled, false, sizeof( ccAlfFilterIdxEnabled ) );
std::memset( ccAlfCoeff, 0, sizeof( ccAlfCoeff ) );
ccAlfFilterCount[0] = ccAlfFilterCount[1] = MAX_NUM_CC_ALF_FILTERS;
numberValidComponents = 3;
newCcAlfFilter[0] = newCcAlfFilter[1] = 0;
}
const CcAlfFilterParam& operator = ( const CcAlfFilterParam& src )
{
std::memcpy( ccAlfFilterEnabled, src.ccAlfFilterEnabled, sizeof( ccAlfFilterEnabled ) );
std::memcpy( ccAlfFilterIdxEnabled, src.ccAlfFilterIdxEnabled, sizeof( ccAlfFilterIdxEnabled ) );
std::memcpy( ccAlfCoeff, src.ccAlfCoeff, sizeof( ccAlfCoeff ) );
ccAlfFilterCount[0] = src.ccAlfFilterCount[0];
ccAlfFilterCount[1] = src.ccAlfFilterCount[1];
numberValidComponents = src.numberValidComponents;
newCcAlfFilter[0] = src.newCcAlfFilter[0];
newCcAlfFilter[1] = src.newCcAlfFilter[1];
return *this;
}
};
#if JVET_W0066_CCSAO
struct CcSaoComParam
{
bool enabled [MAX_NUM_COMPONENT];
uint8_t setNum [MAX_NUM_COMPONENT];
bool setEnabled[MAX_NUM_COMPONENT][MAX_CCSAO_SET_NUM];
#if JVET_Y0106_CCSAO_EDGE_CLASSIFIER
bool setType[MAX_NUM_COMPONENT][MAX_CCSAO_SET_NUM];
#endif
uint16_t candPos [MAX_NUM_COMPONENT][MAX_CCSAO_SET_NUM][MAX_NUM_LUMA_COMP];
uint16_t bandNum [MAX_NUM_COMPONENT][MAX_CCSAO_SET_NUM][MAX_NUM_COMPONENT];
short offset [MAX_NUM_COMPONENT][MAX_CCSAO_SET_NUM][MAX_CCSAO_CLASS_NUM];
CcSaoComParam()
{
reset();
}
void reset()
{
std::memset( enabled, false, sizeof( enabled ) );
std::memset( setNum, 0, sizeof( setNum ) );
std::memset( setEnabled, false, sizeof( setEnabled ) );
#if JVET_Y0106_CCSAO_EDGE_CLASSIFIER
std::memset(setType, 0, sizeof(setType));
#endif
std::memset( candPos, 0, sizeof( candPos ) );
std::memset( bandNum, 0, sizeof( bandNum ) );
std::memset( offset, 0, sizeof( offset ) );
}
void reset(ComponentID compID)
{
enabled[compID] = false;
setNum [compID] = 0;
std::memset( setEnabled[compID], false, sizeof( setEnabled[compID]) );
#if JVET_Y0106_CCSAO_EDGE_CLASSIFIER
std::memset(setType[compID], 0, sizeof(setType[compID]));
#endif
std::memset( candPos [compID], 0, sizeof( candPos [compID]) );
std::memset( bandNum [compID], 0, sizeof( bandNum [compID]) );
std::memset( offset [compID], 0, sizeof( offset [compID]) );
}
const CcSaoComParam& operator = ( const CcSaoComParam& src )
{
std::memcpy( enabled, src.enabled, sizeof( enabled ) );
std::memcpy( setNum, src.setNum, sizeof( setNum ) );
std::memcpy( setEnabled, src.setEnabled, sizeof( setEnabled ) );
#if JVET_Y0106_CCSAO_EDGE_CLASSIFIER
std::memcpy(setType, src.setType, sizeof(setType));
#endif
std::memcpy( candPos, src.candPos, sizeof( candPos ) );
std::memcpy( bandNum, src.bandNum, sizeof( bandNum ) );
std::memcpy( offset, src.offset, sizeof( offset ) );
return *this;
}
};
#endif
//! \}
#endif // end of #ifndef __ALFPARAMETERS__