ETRI_HEVC_define.h 의 Line 606:638
// ========================================================================
// ETRI_Fast PU Mode Decision
// ========================================================================
#define ETRI_FASTPUProcessing 1
#if ETRI_FASTPUProcessing
#define ETRI_FFESD 1 ///< Fast ESD when SKLevel <= (Threshold = ETRI_FFESD ; Default= 1 @ 2015 11 19 by Seok
#define ETRI_FastIntraSKIP 1 ///< Fast INTRA SKIP on Prediction Stage (Chroma Prediction SKIP @ 2015 11 19 by Seok : <MD5 Error>
#define ETRI_TEST_FASTINPRED 1 /// 2015 11 9 by Seok : For Test When this procesdure would be stable it should be equal to ETRI_FASTPUProcessing
#define ETRI_TEST_FASTITPRED 1 /// 2015 11 9 by Seok : For Test When this procesdure would be stable it should be equal to ETRI_FASTPUProcessing
#define ETRI_FAST_MGITRDOQ 1 /// Merge/INTRA RDOQ SKIP @ 2015 11 21 by Seok : [OK FIX]
#define ETRI_FAST_MGINRDOQ 1 /// Merge/INTER RDOQ SKIP @ 2015 11 21 by Seok
#define ETRI_FAST_INITRDOQ 1 /// INTER/INTRA RDOQ SKIP @ 2015 11 21 by Seok
#if ETRI_FFESD
#define ETRI_FFESDLEVEL 1 /// FFESD Activation Threshold @ 2015 12 3 by Seok
#endif
#define ETRI_TEST_1201 1 ///< Test CU Decision
#define ETRI_TEST_1202 1 ///< Test CU Decision :: GOOD
#define ETRI_TEST_1203 0 ///< ALL CU Prediction Mode is SKIP For Ultimate Speed Test @ 2015 12 21 by Seok
#define ETRI_TEST_1204 0 ///< ALL CU Depth is only 1 For Ultimate Speed Test @ 2015 12 21 by Seok
#define ETRI_FPU_STATISTICS (0 && !ETRI_MULTITHREAD_2) ///< For Debug, Look at the TencSlice.cpp @ 2015 11 16 by Seok
#if ETRI_CU_INTRA_MODE_INHERITANCE ///< Avoid the Corruption of algorithm @ 2015 12 15 by Seok
#undef ETRI_CU_INTRA_MODE_INHERITANCE
#define ETRI_CU_INTRA_MODE_INHERITANCE 0
#endif
#else
#define ETRI_FFESD 0
#endif
전처리문 | 설명 |
---|---|
ETRI_FFESD | FFESD Activation 여부이다. 이것이 1이면 동작하고 0이면 동작하지 않는다. |
ETRI_FFESDLEVEL | FFESD Activation시 FFESD Activation을 위한 Threshold 값 |
ETRI_FastIntraSKIP | Fast Intra SKip 동작 여부 결정 |
ETRI_TEST_FASTINPRED | Pass Inter Prediction 동작 여부 결정 |
ETRI_TEST_FASTITPRED | Pass Intra Prediction 동작 여부 결정 |
ETRI_FAST_MGITRDOQ | Pass Merge/Intra RDOQ 동작 여부 결정 |
ETRI_FAST_MGINRDOQ | Pass Merge/Inter RDOQ 동작 여부 결정 |
ETRI_FAST_INITRDOQ | Pass Inter/Intra RDOQ 동작 여부 결정 |
ETRI_TEST_1201 | Fast CU Decision을 위한 전처리기 다음의 1202와 통합할 예정이다. |
ETRI_TEST_1202 | Fast CU Decision을 위한 전처리기 위의 1201과 통합할 예정이다. |
ETRI_TEST_1203 | Ultimate test to SKIP을 위한 전처리기 위의 1201과 통합할 예정이다. |
ETRI_TEST_1204 | Ultimate test to Top Depth를 위한 전처리기 위의 1201과 통합할 예정이다. |
ETRI_FPU_STATISTICS | 알고리즘 개발을 위한 Statistics를 계산할 때, 사용되는 전처리기, 각 Tile 별 결과를 Slice 별로 출력한다. 단, ETRI_MULTITHREAD_2가 Activation이면 동작하지 못한다. |
Intra Prediction은 Luma Prediction과 Chroma Prediction으로 나누어진다. 그리고 Intra Prediction 까지 오게 될 떄는 최소한 SKIP/Merge 혹은 Inter Prediction을 거치게 된다.
따라서, Intra Prediction for LUMA를 수행하게 되면 최소한, SKIP/Merge 혹은 Inter Prediction에서의 Hadamard 값과 Intra Luma에서의 Hadamard 값이 나오게 된다.
그런데 SKIP/Merge 혹은 Inter Prediction에서의 Hadamard 값은 Luma Hadamard 와 Chroma Hadamard를 합친 값이다. 그러므로 Intra Luma의 Hadamard 값이 Skip/Merge 혹은 Inter Hadamrd 값중 작은 값보다 큰 값이라면 Intra Mode로 선택될 가능성은 매우 낮다. 따라서 이 경우에는 Intra Chroma Prediction 및 Intra RDOQ를 모두 Pass 해 버려도 된다. 즉,
where
경우에 따라, 보다 화질 손실을 줄이기 위해 5~10% 정도의 Margine을 두어 다음과 같이 놓아서, Fast Intra Skip 의 손실을 줄일 수도 있다.
R21 Candidate에서는 그렇게 하지 않았다.
FFESD는 원래 Hadamard Transform/Qunatization을 중심으로 SKIP/MERGE를 선택하는 것에 대하여 정확하게 RD-Cost를 구하여 SKIP/Merge를 선택하도록 하는 방식이다. 이때, Hadamard Transform/Qunatization을 통해 SKIP/Merge RDOQ를 수행하기 위한 조건을
해당 코드는 다음과 같다.
/// Condition of FFESD ACTIVATION of Early SKIP/Merge @ 2015 11 22 by Seok
#if ETRI_FFESD
/// 단순 FFESD 조건 : 실험 결과 가장 성적이 좋다
em_bControlParam[ETRI_IdEarlyMerge] = em_uiSKLevel[uhDepth] <= ETRI_FFESDLEVEL;
#else
em_bControlParam[ETRI_IdEarlyMerge] = (RIGHTContInRange(0, em_uiSKLevel[uhDepth], ETRI_FFESD, true) && !em_bSkipMode[ETRI_IdAxTempCU_Merge]);
#endif
여기에서 em_bControlParam[ETRI_IdEarlyMerge] 가 TRUE 가 되면 다음의 함수가 불리면서 FFESD가 동작한다.
//--------------------------------------------------------------------------------
// If ESD = 0 and the configuration of ESD is fixed, I recommend the following simple code.
// Jinwuk Seok 2015 0801
//--------------------------------------------------------------------------------
// SKIP Prediction : Instead of xCheckRDCostMerge2Nx2N : by Merge for inter_2Nx2N
ETRI_xCheckSkipMerge_PRED( rpcBestCU, rpcTempCU, uiDepth);
ETRI_xControlPUProcessing(rpcTempCU, uiDepth, ETRI_IdAxTempCU_Merge, ETRI_PRED); /// Check no ValidMergeCandidates for ETRI_SliceEncoder_MVClip, yhee
ETRI_xEarlyCheckSkipMerge_RDOQ(rpcBestCU, rpcTempCU, uiDepth, iQP, bIsLosslessMode, ETRI_FFESD);
ETRI_xCheckEarlySkipDecision(rpcBestCU, &earlyDetectionSkipMode, uiFastESDId); /// It requires REVISION @ 2015 9 3 by Seok uiFastESDId
해당 코드는 다음과 같다
if (SubStage == ETRI_PRED)
{
em_bSkipMode[ETRI_IdAxTempCU_Inter] |= em_bESD[uhDepth];
//--------------------------------------------------------------------------------------------------
// Inter Prediction SKIP :
// [1] Slice Depth 혹은 QP 에 에 따른 UpperBound를 놓고 이보다 크면 Inter Prediction을 하지 않는다
// [2] MVClip의 경우, Inter Prediction중에 Check가 이루어지므로 여기서 할 필요가 없다
// [3] ETRI_CU_INTRA_MODE_INHERITANCE 를 여기에 구현한다
// @ Fast PU Test Code 2015 10 27 by Seok
//--------------------------------------------------------------------------------------------------
#if ETRI_TEST_FASTINPRED
UInt uiUpperBound = em_ucFPUInterSkipLevel[(pcSlice->getDepth() > 0)];
em_bSkipMode[ETRI_IdAxTempCU_Inter] |= (em_uiSKLevel[uhDepth] > uiUpperBound);
em_uiINHADDistortion = (em_bSkipMode[ETRI_IdAxTempCU_Inter])? MAX_INT : em_uiINHADDistortion;
#endif