[x265] [PATCH 2 of 2] analysis: include CU mode signaling overhead in sa8d costs [CHANGES OUTPUTS]
Steve Borho
steve at borho.org
Thu Dec 11 22:43:32 CET 2014
On 12/11, Steve Borho wrote:
> # HG changeset patch
> # User Steve Borho <steve at borho.org>
> # Date 1418327875 21600
> # Thu Dec 11 13:57:55 2014 -0600
> # Node ID ef4587c47e0f27a71c92f5b4e2595d16093c311f
> # Parent a0bf346f31760598e327c218ef2b81c5cfad3f55
> analysis: include CU mode signaling overhead in sa8d costs [CHANGES OUTPUTS]
>
> At RD levels 0..4, some mode decisions are made based on just the residual cost
> using the formula: sa8d(prediction, source) + lambda * bits. This avoids
> the expensive residual coding operations required to generate the reconstructed
> pixels necessary to measure the final distortion (for real RDO).
>
> checkIntraInInter(), predInterSearch(), and checkMerge2Nx2N_rd0_4() were not
> including the cost of the mode decision fields in that bit count (aka: signaling
> not-skip, pred mode, part size, etc). This resulted in less compression
> efficiency (spending more bits than required for quality).
I've pushed a fixed version of these two commits (see below) to
https://bitbucket.org/sborho/x265
They haven't been pushed to the main repo yet because while these
changes are "correct" as far as I can tell the results are
underwhelming.
> diff -r a0bf346f3176 -r ef4587c47e0f source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp Thu Dec 11 13:52:34 2014 -0600
> +++ b/source/encoder/analysis.cpp Thu Dec 11 13:57:55 2014 -0600
> @@ -1303,7 +1303,13 @@
> md.bestMode = tempPred->rdCost < bestPred->rdCost ? tempPred : bestPred;
> }
> else
> + {
> + /* at rdLevel 0, all mode decisions are made via sa8d residual cost, add merge mode signal cost */
> + bestPred->sa8dBits += m_entropyCoder.bitsInterMode(bestPred->cu, 0, depth); /* inter 2Nx2N cost */
> + bestPred->sa8dBits += 1; /* merge flag */
> + bestPred->sa8dCost = m_rdCost.calcRdSADCost(bestPred->distortion, bestPred->sa8dBits);
> md.bestMode = bestPred;
> + }
>
> /* broadcast sets of MV field data */
> bestPred->cu.setPUInterDir(interDirNeighbours[bestSadCand], 0, 0);
> @@ -1458,6 +1464,7 @@
> interMode.distortion += primitives.sa8d_inter[cpart](fencYuv.m_buf[1], fencYuv.m_csize, predYuv.m_buf[1], predYuv.m_csize);
> interMode.distortion += primitives.sa8d_inter[cpart](fencYuv.m_buf[2], fencYuv.m_csize, predYuv.m_buf[2], predYuv.m_csize);
> }
> + interMode.sa8dBits += m_entropyCoder.bitsInterMode(interMode.cu, 0, cuGeom.depth);
> interMode.sa8dCost = m_rdCost.calcRdSADCost(interMode.distortion, interMode.sa8dBits);
>
> if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_reuseInterDataCTU)
> @@ -1669,6 +1676,10 @@
> cu.m_mv[1][0] = bestME[1].mv;
> }
> }
> +
> + uint32_t modeBits = m_entropyCoder.bitsIntraMode(bidir2Nx2N.cu, 0);
> + bidir2Nx2N.sa8dBits += modeBits;
> + bidir2Nx2N.sa8dCost += m_rdCost.getCost(modeBits);
> }
>
> void Analysis::encodeResidue(const CUData& ctu, const CUGeom& cuGeom)
> diff -r a0bf346f3176 -r ef4587c47e0f source/encoder/search.cpp
> --- a/source/encoder/search.cpp Thu Dec 11 13:52:34 2014 -0600
> +++ b/source/encoder/search.cpp Thu Dec 11 13:57:55 2014 -0600
> @@ -1325,10 +1325,9 @@
>
> cu.setLumaIntraDirSubParts((uint8_t)bmode, absPartIdx, depth + initTuDepth);
> intraMode.initCosts();
> - intraMode.totalBits = bbits;
> intraMode.distortion = bsad;
> - intraMode.sa8dCost = bcost;
> - intraMode.sa8dBits = bbits;
> + intraMode.sa8dBits = bbits + m_entropyCoder.bitsIntraMode(intraMode.cu, absPartIdx);
> + intraMode.sa8dCost = m_rdCost.calcRdSADCost(intraMode.sa8dBits, intraMode.sa8dBits);
this should have been: calcRdSADCost(intraMode.distortion, intraMode.sa8dBits)
> }
>
> void Search::encodeIntraInInter(Mode& intraMode, const CUGeom& cuGeom)
--
Steve Borho
More information about the x265-devel
mailing list