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