[x265] [PATCH 1 of 3] entropy: disable signaling of CABAC init state

Steve Borho steve at borho.org
Fri Aug 8 04:22:29 CEST 2014


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1407459507 18000
#      Thu Aug 07 19:58:27 2014 -0500
# Node ID cb8e33adbfa8a59fc40ee8ee09ca604e277cf722
# Parent  8e45fc7c55217f26537a4300b96e12727428abc2
entropy: disable signaling of CABAC init state

This flag, which was already disabled when frame parallelism is in use (which
is nearly always) was of limited utility. It did not improve compression
efficiency by any measurable amount, and it was expensive to compute.  But the
quality which made it expendable was that it was the only user of the bBinsCoded
flag in the ContextModel; forcing us to copy twice as much data every time we
copy a context.

With this feature removed, the context model can be reduced to a single uint8_t
state variable.

diff -r 8e45fc7c5521 -r cb8e33adbfa8 source/common/slice.h
--- a/source/common/slice.h	Thu Aug 07 19:49:42 2014 +0530
+++ b/source/common/slice.h	Thu Aug 07 19:58:27 2014 -0500
@@ -234,9 +234,6 @@
     bool     bEntropyCodingSyncEnabled; // use param
     bool     bSignHideEnabled;          // use param
 
-    bool     bCabacInitPresent;
-    uint32_t encCABACTableIdx;          // Used to transmit table selection across slices
-
     bool     bDeblockingFilterControlPresent;
     bool     bPicDisableDeblockingFilter;
     int      deblockingFilterBetaOffsetDiv2;
diff -r 8e45fc7c5521 -r cb8e33adbfa8 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Thu Aug 07 19:49:42 2014 +0530
+++ b/source/encoder/encoder.cpp	Thu Aug 07 19:58:27 2014 -0500
@@ -1196,10 +1196,7 @@
     pps->deblockingFilterBetaOffsetDiv2 = 0;
     pps->deblockingFilterTcOffsetDiv2 = 0;
 
-    // options affected by parallelization
     pps->bEntropyCodingSyncEnabled = m_param->bEnableWavefront;
-    pps->bCabacInitPresent = m_param->frameNumThreads == 1; // only deterministic with one frame thread
-    pps->encCABACTableIdx = I_SLICE;
 }
 
 void Encoder::configure(x265_param *p)
diff -r 8e45fc7c5521 -r cb8e33adbfa8 source/encoder/entropy.cpp
--- a/source/encoder/entropy.cpp	Thu Aug 07 19:49:42 2014 +0530
+++ b/source/encoder/entropy.cpp	Thu Aug 07 19:58:27 2014 -0500
@@ -134,7 +134,7 @@
     WRITE_FLAG(0,                          "output_flag_present_flag");
     WRITE_CODE(0, 3,                       "num_extra_slice_header_bits");
     WRITE_FLAG(pps->bSignHideEnabled,      "sign_data_hiding_flag");
-    WRITE_FLAG(pps->bCabacInitPresent,     "cabac_init_present_flag");
+    WRITE_FLAG(0,                          "cabac_init_present_flag");
     WRITE_UVLC(0,                          "num_ref_idx_l0_default_active_minus1");
     WRITE_UVLC(0,                          "num_ref_idx_l1_default_active_minus1");
 
@@ -412,14 +412,6 @@
     if (slice->isInterB())
         WRITE_FLAG(0, "mvd_l1_zero_flag");
 
-    if (!slice->isIntra() && slice->m_pps->bCabacInitPresent)
-    {
-        SliceType sliceType   = slice->m_sliceType;
-        int  encCABACTableIdx = slice->m_pps->encCABACTableIdx;
-        bool encCabacInitFlag = (sliceType != encCABACTableIdx && encCABACTableIdx != I_SLICE) ? true : false;
-        WRITE_FLAG(encCabacInitFlag, "cabac_init_flag");
-    }
-
     // TMVP always enabled
     {
         if (slice->m_sliceType == B_SLICE)
@@ -908,11 +900,6 @@
     int  qp              = slice->m_sliceQp;
     SliceType sliceType  = slice->m_sliceType;
 
-    int encCABACTableIdx = slice->m_pps->encCABACTableIdx;
-
-    if (!slice->isIntra() && (encCABACTableIdx == B_SLICE || encCABACTableIdx == P_SLICE) && slice->m_pps->bCabacInitPresent)
-        sliceType = (SliceType)encCABACTableIdx;
-
     initBuffer(&m_contextModels[OFF_SPLIT_FLAG_CTX], sliceType, qp, (uint8_t*)INIT_SPLIT_FLAG, NUM_SPLIT_FLAG_CTX);
     initBuffer(&m_contextModels[OFF_SKIP_FLAG_CTX], sliceType, qp, (uint8_t*)INIT_SKIP_FLAG, NUM_SKIP_FLAG_CTX);
     initBuffer(&m_contextModels[OFF_MERGE_FLAG_EXT_CTX], sliceType, qp, (uint8_t*)INIT_MERGE_FLAG_EXT, NUM_MERGE_FLAG_EXT_CTX);
@@ -944,66 +931,6 @@
     start();
 }
 
-/* If current slice type is P/B then it determines the distance of
- * initialization type 1 and 2 from the current CABAC states and stores the
- * index of the closest table.  This index is used for the next P/B slice when
- * cabac_init_present_flag is true.
- */
-void Entropy::determineCabacInitIdx(Slice *slice, PPS *pps)
-{
-    int qp = slice->m_sliceQp;
-
-    if (!slice->isIntra())
-    {
-        SliceType aSliceTypeChoices[] = { B_SLICE, P_SLICE };
-
-        uint32_t bestCost       = MAX_UINT;
-        SliceType bestSliceType = aSliceTypeChoices[0];
-        for (uint32_t idx = 0; idx < 2; idx++)
-        {
-            uint32_t curCost = 0;
-            SliceType curSliceType = aSliceTypeChoices[idx];
-
-            x265_emms();
-            curCost  = calcCost(&m_contextModels[OFF_SPLIT_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_SPLIT_FLAG, NUM_SPLIT_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_SKIP_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_SKIP_FLAG, NUM_SKIP_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_MERGE_FLAG_EXT_CTX], curSliceType, qp, (uint8_t*)INIT_MERGE_FLAG_EXT, NUM_MERGE_FLAG_EXT_CTX);
-            curCost += calcCost(&m_contextModels[OFF_MERGE_IDX_EXT_CTX], curSliceType, qp, (uint8_t*)INIT_MERGE_IDX_EXT, NUM_MERGE_IDX_EXT_CTX);
-            curCost += calcCost(&m_contextModels[OFF_PART_SIZE_CTX], curSliceType, qp, (uint8_t*)INIT_PART_SIZE, NUM_PART_SIZE_CTX);
-            curCost += calcCost(&m_contextModels[OFF_PRED_MODE_CTX], curSliceType, qp, (uint8_t*)INIT_PRED_MODE, NUM_PRED_MODE_CTX);
-            curCost += calcCost(&m_contextModels[OFF_ADI_CTX], curSliceType, qp, (uint8_t*)INIT_INTRA_PRED_MODE, NUM_ADI_CTX);
-            curCost += calcCost(&m_contextModels[OFF_CHROMA_PRED_CTX], curSliceType, qp, (uint8_t*)INIT_CHROMA_PRED_MODE, NUM_CHROMA_PRED_CTX);
-            curCost += calcCost(&m_contextModels[OFF_DELTA_QP_CTX], curSliceType, qp, (uint8_t*)INIT_DQP, NUM_DELTA_QP_CTX);
-            curCost += calcCost(&m_contextModels[OFF_INTER_DIR_CTX], curSliceType, qp, (uint8_t*)INIT_INTER_DIR, NUM_INTER_DIR_CTX);
-            curCost += calcCost(&m_contextModels[OFF_REF_NO_CTX], curSliceType, qp, (uint8_t*)INIT_REF_PIC, NUM_REF_NO_CTX);
-            curCost += calcCost(&m_contextModels[OFF_MV_RES_CTX], curSliceType, qp, (uint8_t*)INIT_MVD, NUM_MV_RES_CTX);
-            curCost += calcCost(&m_contextModels[OFF_QT_CBF_CTX], curSliceType, qp, (uint8_t*)INIT_QT_CBF, NUM_QT_CBF_CTX);
-            curCost += calcCost(&m_contextModels[OFF_TRANS_SUBDIV_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_TRANS_SUBDIV_FLAG, NUM_TRANS_SUBDIV_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_QT_ROOT_CBF_CTX], curSliceType, qp, (uint8_t*)INIT_QT_ROOT_CBF, NUM_QT_ROOT_CBF_CTX);
-            curCost += calcCost(&m_contextModels[OFF_SIG_CG_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_SIG_CG_FLAG, 2 * NUM_SIG_CG_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_SIG_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_SIG_FLAG, NUM_SIG_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_CTX_LAST_FLAG_X], curSliceType, qp, (uint8_t*)INIT_LAST, NUM_CTX_LAST_FLAG_XY);
-            curCost += calcCost(&m_contextModels[OFF_CTX_LAST_FLAG_Y], curSliceType, qp, (uint8_t*)INIT_LAST, NUM_CTX_LAST_FLAG_XY);
-            curCost += calcCost(&m_contextModels[OFF_ONE_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_ONE_FLAG, NUM_ONE_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_ABS_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_ABS_FLAG, NUM_ABS_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_MVP_IDX_CTX], curSliceType, qp, (uint8_t*)INIT_MVP_IDX, NUM_MVP_IDX_CTX);
-            curCost += calcCost(&m_contextModels[OFF_SAO_MERGE_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_SAO_MERGE_FLAG, NUM_SAO_MERGE_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_SAO_TYPE_IDX_CTX], curSliceType, qp, (uint8_t*)INIT_SAO_TYPE_IDX, NUM_SAO_TYPE_IDX_CTX);
-            curCost += calcCost(&m_contextModels[OFF_TRANSFORMSKIP_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_TRANSFORMSKIP_FLAG, 2 * NUM_TRANSFORMSKIP_FLAG_CTX);
-            curCost += calcCost(&m_contextModels[OFF_CU_TRANSQUANT_BYPASS_FLAG_CTX], curSliceType, qp, (uint8_t*)INIT_CU_TRANSQUANT_BYPASS_FLAG, NUM_CU_TRANSQUANT_BYPASS_FLAG_CTX);
-            if (curCost < bestCost)
-            {
-                bestSliceType = curSliceType;
-                bestCost      = curCost;
-            }
-        }
-
-        pps->encCABACTableIdx = bestSliceType;
-    }
-    else
-        pps->encCABACTableIdx = I_SLICE;
-}
-
 /* code explicit wp tables */
 void Entropy::codePredWeightTable(Slice* slice)
 {
diff -r 8e45fc7c5521 -r cb8e33adbfa8 source/encoder/entropy.h
--- a/source/encoder/entropy.h	Thu Aug 07 19:49:42 2014 +0530
+++ b/source/encoder/entropy.h	Thu Aug 07 19:58:27 2014 -0500
@@ -133,7 +133,6 @@
     void codeShortTermRefPicSet(RPS* rps);
     void codeSliceFinish()                   { finish(); }
     void codeTerminatingBit(uint32_t lsLast) { encodeBinTrm(lsLast); }
-    void determineCabacInitIdx(Slice *slice, PPS *pps);
 
     void codeSaoOffset(SaoLcuParam* saoLcuParam, uint32_t compIdx);
     void codeSaoUnitInterleaving(int compIdx, bool saoFlag, int rx, int ry, SaoLcuParam* saoLcuParam, int cuAddrInSlice, int cuAddrUpInSlice, int allowMergeLeft, int allowMergeUp);
diff -r 8e45fc7c5521 -r cb8e33adbfa8 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Thu Aug 07 19:49:42 2014 +0530
+++ b/source/encoder/frameencoder.cpp	Thu Aug 07 19:58:27 2014 -0500
@@ -487,14 +487,6 @@
         m_frameStats.miscBits += cu->m_totalBits - (cu->m_mvBits + cu->m_coeffBits);
     }
 
-    // when frame parallelism is disabled, we can tweak the initial CABAC state of P and B frames
-    if (slice->m_pps->bCabacInitPresent)
-    {
-        X265_CHECK(m_param->frameNumThreads == 1, "bCabacInitPresent enabled with frame parallelism\n");
-        // we pass m_top's m_pps instance because this function will modify it
-        m_entropyCoder.determineCabacInitIdx(slice, &m_top->m_pps);
-    }
-
     // flush lines
     for (int i = 0; i < numSubstreams; i++)
     {


More information about the x265-devel mailing list