1 /*****************************************************************************
2 * Copyright (C) 2013-2020 MulticoreWare, Inc
3 *
4 * Authors: Steve Borho <steve@borho.org>
5 *          Min Chen <chenm003@163.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
20 *
21 * This program is also available under a commercial proprietary license.
22 * For more information, contact us at license @ x265.com.
23 *****************************************************************************/
24 
25 #ifndef X265_ENTROPY_H
26 #define X265_ENTROPY_H
27 
28 #include "common.h"
29 #include "bitstream.h"
30 #include "frame.h"
31 #include "cudata.h"
32 #include "contexts.h"
33 #include "slice.h"
34 
35 namespace X265_NS {
36 // private namespace
37 
38 struct SaoCtuParam;
39 struct EstBitsSbac;
40 class ScalingList;
41 
42 enum SplitType
43 {
44     DONT_SPLIT            = 0,
45     VERTICAL_SPLIT        = 1,
46     QUAD_SPLIT            = 2,
47     NUMBER_OF_SPLIT_MODES = 3
48 };
49 
50 struct TURecurse
51 {
52     uint32_t section;
53     uint32_t splitMode;
54     uint32_t absPartIdxTURelCU;
55     uint32_t absPartIdxStep;
56 
TURecurseTURecurse57     TURecurse(SplitType splitType, uint32_t _absPartIdxStep, uint32_t _absPartIdxTU)
58     {
59         static const uint32_t partIdxStepShift[NUMBER_OF_SPLIT_MODES] = { 0, 1, 2 };
60         section           = 0;
61         absPartIdxTURelCU = _absPartIdxTU;
62         splitMode         = (uint32_t)splitType;
63         absPartIdxStep    = _absPartIdxStep >> partIdxStepShift[splitMode];
64     }
65 
isNextSectionTURecurse66     bool isNextSection()
67     {
68         if (splitMode == DONT_SPLIT)
69         {
70             section++;
71             return false;
72         }
73         else
74         {
75             absPartIdxTURelCU += absPartIdxStep;
76 
77             section++;
78             return section < (uint32_t)(1 << splitMode);
79         }
80     }
81 
isLastSectionTURecurse82     bool isLastSection() const
83     {
84         return (section + 1) >= (uint32_t)(1 << splitMode);
85     }
86 };
87 
88 struct EstBitsSbac
89 {
90     int significantCoeffGroupBits[NUM_SIG_CG_FLAG_CTX][2];
91     int significantBits[2][NUM_SIG_FLAG_CTX];
92     int lastBits[2][10];
93     int greaterOneBits[NUM_ONE_FLAG_CTX][2];
94     int levelAbsBits[NUM_ABS_FLAG_CTX][2];
95     int blockCbpBits[NUM_QT_CBF_CTX][2];
96     int blockRootCbpBits[2];
97 };
98 
99 class Entropy : public SyntaxElementWriter
100 {
101 public:
102 
103     uint64_t      m_pad;
104     uint8_t       m_contextState[160]; // MAX_OFF_CTX_MOD + padding
105 
106     /* CABAC state */
107     uint32_t      m_low;
108     uint32_t      m_range;
109     uint32_t      m_bufferedByte;
110     int           m_numBufferedBytes;
111     int           m_bitsLeft;
112     uint64_t      m_fracBits;
113     EstBitsSbac   m_estBitsSbac;
114     double        m_meanQP;
115 
116     Entropy();
117 
setBitstream(Bitstream * p)118     void setBitstream(Bitstream* p)    { m_bitIf = p; }
119 
getNumberOfWrittenBits()120     uint32_t getNumberOfWrittenBits()
121     {
122         X265_CHECK(!m_bitIf, "bit counting mode expected\n");
123         return (uint32_t)(m_fracBits >> 15);
124     }
125 
126 #if CHECKED_BUILD || _DEBUG
127     bool m_valid;
markInvalid()128     void markInvalid()                 { m_valid = false; }
markValid()129     void markValid()                   { m_valid = true; }
130 #else
markValid()131     void markValid()                   { }
132 #endif
zeroFract()133     void zeroFract()                   { m_fracBits = 0; }
134     void resetBits();
135     void resetEntropy(const Slice& slice);
136 
137     // SBAC RD
load(const Entropy & src)138     void load(const Entropy& src)            { copyFrom(src); }
store(Entropy & dest)139     void store(Entropy& dest) const          { dest.copyFrom(*this); }
loadContexts(const Entropy & src)140     void loadContexts(const Entropy& src)    { copyContextsFrom(src); }
141     void loadIntraDirModeLuma(const Entropy& src);
142     void copyState(const Entropy& other);
143 
144     void codeVPS(const VPS& vps);
145     void codeSPS(const SPS& sps, const ScalingList& scalingList, const ProfileTierLevel& ptl);
146     void codePPS( const PPS& pps, bool filerAcross, int iPPSInitQpMinus26 );
147     void codeVUI(const VUI& vui, int maxSubTLayers, bool bEmitVUITimingInfo, bool bEmitVUIHRDInfo);
148     void codeAUD(const Slice& slice);
149     void codeHrdParameters(const HRDInfo& hrd, int maxSubTLayers);
150 
151     void codeSliceHeader(const Slice& slice, FrameData& encData, uint32_t slice_addr, uint32_t slice_addr_bits, int sliceQp);
152     void codeSliceHeaderWPPEntryPoints(const uint32_t *substreamSizes, uint32_t numSubStreams, uint32_t maxOffset);
153     void codeShortTermRefPicSet(const RPS& rps, int idx);
finishSlice()154     void finishSlice()                 { encodeBinTrm(1); finish(); dynamic_cast<Bitstream*>(m_bitIf)->writeByteAlignment(); }
155 
156     void encodeCTU(const CUData& cu, const CUGeom& cuGeom);
157 
158     void codeIntraDirLumaAng(const CUData& cu, uint32_t absPartIdx, bool isMultiple);
159     void codeIntraDirChroma(const CUData& cu, uint32_t absPartIdx, uint32_t *chromaDirMode);
160 
161     void codeMergeIndex(const CUData& cu, uint32_t absPartIdx);
162     void codeMvd(const CUData& cu, uint32_t absPartIdx, int list);
163 
164     void codePartSize(const CUData& cu, uint32_t absPartIdx, uint32_t depth);
165     void codePredInfo(const CUData& cu, uint32_t absPartIdx);
166 
167     void codeQtCbfChroma(const CUData& cu, uint32_t absPartIdx, TextType ttype, uint32_t tuDepth, bool lowestLevel);
168     void codeCoeff(const CUData& cu, uint32_t absPartIdx, bool& bCodeDQP, const uint32_t depthRange[2]);
169     void codeCoeffNxN(const CUData& cu, const coeff_t* coef, uint32_t absPartIdx, uint32_t log2TrSize, TextType ttype);
170 
codeSaoMerge(uint32_t code)171     inline void codeSaoMerge(uint32_t code)                          { encodeBin(code, m_contextState[OFF_SAO_MERGE_FLAG_CTX]); }
codeSaoType(uint32_t code)172     inline void codeSaoType(uint32_t code)                           { encodeBin(code, m_contextState[OFF_SAO_TYPE_IDX_CTX]); }
codeMVPIdx(uint32_t symbol)173     inline void codeMVPIdx(uint32_t symbol)                          { encodeBin(symbol, m_contextState[OFF_MVP_IDX_CTX]); }
codeMergeFlag(const CUData & cu,uint32_t absPartIdx)174     inline void codeMergeFlag(const CUData& cu, uint32_t absPartIdx) { encodeBin(cu.m_mergeFlag[absPartIdx], m_contextState[OFF_MERGE_FLAG_EXT_CTX]); }
codeSkipFlag(const CUData & cu,uint32_t absPartIdx)175     inline void codeSkipFlag(const CUData& cu, uint32_t absPartIdx)  { encodeBin(cu.isSkipped(absPartIdx), m_contextState[OFF_SKIP_FLAG_CTX + cu.getCtxSkipFlag(absPartIdx)]); }
codeSplitFlag(const CUData & cu,uint32_t absPartIdx,uint32_t depth)176     inline void codeSplitFlag(const CUData& cu, uint32_t absPartIdx, uint32_t depth) { encodeBin(cu.m_cuDepth[absPartIdx] > depth, m_contextState[OFF_SPLIT_FLAG_CTX + cu.getCtxSplitFlag(absPartIdx, depth)]); }
codeTransformSubdivFlag(uint32_t symbol,uint32_t ctx)177     inline void codeTransformSubdivFlag(uint32_t symbol, uint32_t ctx)    { encodeBin(symbol, m_contextState[OFF_TRANS_SUBDIV_FLAG_CTX + ctx]); }
codePredMode(int predMode)178     inline void codePredMode(int predMode)                                { encodeBin(predMode == MODE_INTRA ? 1 : 0, m_contextState[OFF_PRED_MODE_CTX]); }
codeCUTransquantBypassFlag(uint32_t symbol)179     inline void codeCUTransquantBypassFlag(uint32_t symbol)               { encodeBin(symbol, m_contextState[OFF_TQUANT_BYPASS_FLAG_CTX]); }
codeQtCbfLuma(uint32_t cbf,uint32_t tuDepth)180     inline void codeQtCbfLuma(uint32_t cbf, uint32_t tuDepth)             { encodeBin(cbf, m_contextState[OFF_QT_CBF_CTX + !tuDepth]); }
codeQtCbfChroma(uint32_t cbf,uint32_t tuDepth)181     inline void codeQtCbfChroma(uint32_t cbf, uint32_t tuDepth)           { encodeBin(cbf, m_contextState[OFF_QT_CBF_CTX + 2 + tuDepth]); }
codeQtRootCbf(uint32_t cbf)182     inline void codeQtRootCbf(uint32_t cbf)                               { encodeBin(cbf, m_contextState[OFF_QT_ROOT_CBF_CTX]); }
codeTransformSkipFlags(uint32_t transformSkip,TextType ttype)183     inline void codeTransformSkipFlags(uint32_t transformSkip, TextType ttype) { encodeBin(transformSkip, m_contextState[OFF_TRANSFORMSKIP_FLAG_CTX + (ttype ? NUM_TRANSFORMSKIP_FLAG_CTX : 0)]); }
184     void codeDeltaQP(const CUData& cu, uint32_t absPartIdx);
185     void codeSaoOffset(const SaoCtuParam& ctuParam, int plane);
186     void codeSaoOffsetEO(int *offset, int typeIdx, int plane);
187     void codeSaoOffsetBO(int *offset, int bandPos, int plane);
188 
189     /* RDO functions */
190     void estBit(EstBitsSbac& estBitsSbac, uint32_t log2TrSize, bool bIsLuma) const;
191     void estCBFBit(EstBitsSbac& estBitsSbac) const;
192     void estSignificantCoeffGroupMapBit(EstBitsSbac& estBitsSbac, bool bIsLuma) const;
193     void estSignificantMapBit(EstBitsSbac& estBitsSbac, uint32_t log2TrSize, bool bIsLuma) const;
194     void estSignificantCoefficientsBit(EstBitsSbac& estBitsSbac, bool bIsLuma) const;
195 
bitsIntraModeNonMPM()196     inline uint32_t bitsIntraModeNonMPM() const { return bitsCodeBin(0, m_contextState[OFF_ADI_CTX]) + 5; }
bitsIntraModeMPM(const uint32_t preds[3],uint32_t dir)197     inline uint32_t bitsIntraModeMPM(const uint32_t preds[3], uint32_t dir) const { return bitsCodeBin(1, m_contextState[OFF_ADI_CTX]) + (dir == preds[0] ? 1 : 2); }
estimateCbfBits(uint32_t cbf,TextType ttype,uint32_t tuDepth)198     inline uint32_t estimateCbfBits(uint32_t cbf, TextType ttype, uint32_t tuDepth) const { return bitsCodeBin(cbf, m_contextState[OFF_QT_CBF_CTX + ctxCbf[ttype][tuDepth]]); }
199     uint32_t bitsInterMode(const CUData& cu, uint32_t absPartIdx, uint32_t depth) const;
bitsIntraMode(const CUData & cu,uint32_t absPartIdx)200     uint32_t bitsIntraMode(const CUData& cu, uint32_t absPartIdx) const
201     {
202         return bitsCodeBin(0, m_contextState[OFF_SKIP_FLAG_CTX + cu.getCtxSkipFlag(absPartIdx)]) + /* not skip */
203                bitsCodeBin(1, m_contextState[OFF_PRED_MODE_CTX]); /* intra */
204     }
205 
206     /* these functions are only used to estimate the bits when cbf is 0 and will never be called when writing the bistream. */
codeQtRootCbfZero()207     inline void codeQtRootCbfZero() { encodeBin(0, m_contextState[OFF_QT_ROOT_CBF_CTX]); }
208 
209 private:
210 
211     /* CABAC private methods */
212     void start();
213     void finish();
214 
215     void encodeBin(uint32_t binValue, uint8_t& ctxModel);
216     void encodeBinEP(uint32_t binValue);
217     void encodeBinsEP(uint32_t binValues, int numBins);
218     void encodeBinTrm(uint32_t binValue);
219 
220     /* return the bits of encoding the context bin without updating */
bitsCodeBin(uint32_t binValue,uint32_t ctxModel)221     inline uint32_t bitsCodeBin(uint32_t binValue, uint32_t ctxModel) const
222     {
223         uint64_t fracBits = (m_fracBits & 32767) + sbacGetEntropyBits(ctxModel, binValue);
224         return (uint32_t)(fracBits >> 15);
225     }
226 
227     void encodeCU(const CUData& ctu, const CUGeom &cuGeom, uint32_t absPartIdx, uint32_t depth, bool& bEncodeDQP);
228     void finishCU(const CUData& ctu, uint32_t absPartIdx, uint32_t depth, bool bEncodeDQP);
229 
230     void writeOut();
231 
232     /* SBac private methods */
233     void writeUnaryMaxSymbol(uint32_t symbol, uint8_t* scmModel, int offset, uint32_t maxSymbol);
234     void writeEpExGolomb(uint32_t symbol, uint32_t count);
235     void writeCoefRemainExGolomb(uint32_t symbol, const uint32_t absGoRice);
236 
237     void codeProfileTier(const ProfileTierLevel& ptl, int maxTempSubLayers);
238     void codeScalingList(const ScalingList&);
239     void codeScalingList(const ScalingList& scalingList, uint32_t sizeId, uint32_t listId);
240 
241     void codePredWeightTable(const Slice& slice);
242     void codeInterDir(const CUData& cu, uint32_t absPartIdx);
243     void codePUWise(const CUData& cu, uint32_t absPartIdx);
244     void codeRefFrmIdxPU(const CUData& cu, uint32_t absPartIdx, int list);
245     void codeRefFrmIdx(const CUData& cu, uint32_t absPartIdx, int list);
246 
247     void codeSaoMaxUvlc(uint32_t code, uint32_t maxSymbol);
248 
249     void codeLastSignificantXY(uint32_t posx, uint32_t posy, uint32_t log2TrSize, bool bIsLuma, uint32_t scanIdx);
250 
251     void encodeTransform(const CUData& cu, uint32_t absPartIdx, uint32_t tuDepth, uint32_t log2TrSize,
252                          bool& bCodeDQP, const uint32_t depthRange[2]);
253     void encodeTransformLuma(const CUData& cu, uint32_t absPartIdx, uint32_t tuDepth, uint32_t log2TrSize,
254                          bool& bCodeDQP, const uint32_t depthRange[2]);
255 
256     void copyFrom(const Entropy& src);
257     void copyContextsFrom(const Entropy& src);
258 };
259 }
260 
261 #endif // ifndef X265_ENTROPY_H
262