1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Steve Borho <steve@borho.org>
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.
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.
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.
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
24 #ifndef X265_ENTROPY_H
25 #define X265_ENTROPY_H
28 #include "bitstream.h"
46 NUMBER_OF_SPLIT_MODES
= 3
53 uint32_t absPartIdxTURelCU
;
54 uint32_t absPartIdxStep
;
56 TURecurse(SplitType splitType
, uint32_t _absPartIdxStep
, uint32_t _absPartIdxTU
)
58 static const uint32_t partIdxStepShift
[NUMBER_OF_SPLIT_MODES
] = { 0, 1, 2 };
60 absPartIdxTURelCU
= _absPartIdxTU
;
61 splitMode
= (uint32_t)splitType
;
62 absPartIdxStep
= _absPartIdxStep
>> partIdxStepShift
[splitMode
];
67 if (splitMode
== DONT_SPLIT
)
74 absPartIdxTURelCU
+= absPartIdxStep
;
77 return section
< (uint32_t)(1 << splitMode
);
81 bool isLastSection() const
83 return (section
+ 1) >= (uint32_t)(1 << splitMode
);
89 int significantCoeffGroupBits
[NUM_SIG_CG_FLAG_CTX
][2];
90 int significantBits
[NUM_SIG_FLAG_CTX
][2];
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];
99 class Entropy
: public SyntaxElementWriter
104 uint8_t m_contextState
[160]; // MAX_OFF_CTX_MOD + padding
109 uint32_t m_bufferedByte
;
110 int m_numBufferedBytes
;
113 EstBitsSbac m_estBitsSbac
;
117 void setBitstream(Bitstream
* p
) { m_bitIf
= p
; }
119 uint32_t getNumberOfWrittenBits()
121 X265_CHECK(!m_bitIf
, "bit counting mode expected\n");
122 return (uint32_t)(m_fracBits
>> 15);
125 #if CHECKED_BUILD || _DEBUG
127 void markInvalid() { m_valid
= false; }
128 void markValid() { m_valid
= true; }
132 void zeroFract() { m_fracBits
= 0; }
134 void resetEntropy(const Slice
& slice
);
137 void load(const Entropy
& src
) { copyFrom(src
); }
138 void store(Entropy
& dest
) const { dest
.copyFrom(*this); }
139 void loadContexts(const Entropy
& src
) { copyContextsFrom(src
); }
140 void loadIntraDirModeLuma(const Entropy
& src
);
141 void copyState(const Entropy
& other
);
143 void codeVPS(const VPS
& vps
);
144 void codeSPS(const SPS
& sps
, const ScalingList
& scalingList
, const ProfileTierLevel
& ptl
);
145 void codePPS(const PPS
& pps
);
146 void codeVUI(const VUI
& vui
);
147 void codeAUD(const Slice
& slice
);
148 void codeHrdParameters(const HRDInfo
& hrd
);
150 void codeSliceHeader(const Slice
& slice
, FrameData
& encData
);
151 void codeSliceHeaderWPPEntryPoints(const Slice
& slice
, const uint32_t *substreamSizes
, uint32_t maxOffset
);
152 void codeShortTermRefPicSet(const RPS
& rps
);
153 void finishSlice() { encodeBinTrm(1); finish(); dynamic_cast<Bitstream
*>(m_bitIf
)->writeByteAlignment(); }
155 void encodeCTU(const CUData
& cu
, const CUGeom
& cuGeom
);
157 void codeIntraDirLumaAng(const CUData
& cu
, uint32_t absPartIdx
, bool isMultiple
);
158 void codeIntraDirChroma(const CUData
& cu
, uint32_t absPartIdx
, uint32_t *chromaDirMode
);
160 void codeMergeIndex(const CUData
& cu
, uint32_t absPartIdx
);
161 void codeMvd(const CUData
& cu
, uint32_t absPartIdx
, int list
);
163 void codePartSize(const CUData
& cu
, uint32_t absPartIdx
, uint32_t depth
);
164 void codePredInfo(const CUData
& cu
, uint32_t absPartIdx
);
165 inline void codeQtCbfLuma(const CUData
& cu
, uint32_t absPartIdx
, uint32_t tuDepth
) { codeQtCbfLuma(cu
.getCbf(absPartIdx
, TEXT_LUMA
, tuDepth
), tuDepth
); }
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
);
171 inline void codeSaoMerge(uint32_t code
) { encodeBin(code
, m_contextState
[OFF_SAO_MERGE_FLAG_CTX
]); }
172 inline void codeMVPIdx(uint32_t symbol
) { encodeBin(symbol
, m_contextState
[OFF_MVP_IDX_CTX
]); }
173 inline void codeMergeFlag(const CUData
& cu
, uint32_t absPartIdx
) { encodeBin(cu
.m_mergeFlag
[absPartIdx
], m_contextState
[OFF_MERGE_FLAG_EXT_CTX
]); }
174 inline void codeSkipFlag(const CUData
& cu
, uint32_t absPartIdx
) { encodeBin(cu
.isSkipped(absPartIdx
), m_contextState
[OFF_SKIP_FLAG_CTX
+ cu
.getCtxSkipFlag(absPartIdx
)]); }
175 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
)]); }
176 inline void codeTransformSubdivFlag(uint32_t symbol
, uint32_t ctx
) { encodeBin(symbol
, m_contextState
[OFF_TRANS_SUBDIV_FLAG_CTX
+ ctx
]); }
177 inline void codePredMode(int predMode
) { encodeBin(predMode
== MODE_INTRA
? 1 : 0, m_contextState
[OFF_PRED_MODE_CTX
]); }
178 inline void codeCUTransquantBypassFlag(uint32_t symbol
) { encodeBin(symbol
, m_contextState
[OFF_TQUANT_BYPASS_FLAG_CTX
]); }
179 inline void codeQtCbfLuma(uint32_t cbf
, uint32_t tuDepth
) { encodeBin(cbf
, m_contextState
[OFF_QT_CBF_CTX
+ !tuDepth
]); }
180 inline void codeQtCbfChroma(uint32_t cbf
, uint32_t tuDepth
) { encodeBin(cbf
, m_contextState
[OFF_QT_CBF_CTX
+ 2 + tuDepth
]); }
181 inline void codeQtRootCbf(uint32_t cbf
) { encodeBin(cbf
, m_contextState
[OFF_QT_ROOT_CBF_CTX
]); }
183 void codeSaoOffset(const SaoCtuParam
& ctuParam
, int plane
);
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;
192 inline uint32_t bitsIntraModeNonMPM() const { return bitsCodeBin(0, m_contextState
[OFF_ADI_CTX
]) + 5; }
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); }
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;
196 uint32_t bitsIntraMode(const CUData
& cu
, uint32_t absPartIdx
) const
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 */
202 /* these functions are only used to estimate the bits when cbf is 0 and will never be called when writing the bistream. */
203 inline void codeQtRootCbfZero() { encodeBin(0, m_contextState
[OFF_QT_ROOT_CBF_CTX
]); }
207 /* CABAC private methods */
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
);
216 /* return the bits of encoding the context bin without updating */
217 inline uint32_t bitsCodeBin(uint32_t binValue
, uint32_t ctxModel
) const
219 uint64_t fracBits
= (m_fracBits
& 32767) + sbacGetEntropyBits(ctxModel
, binValue
);
220 return (uint32_t)(fracBits
>> 15);
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
);
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
);
233 void codeProfileTier(const ProfileTierLevel
& ptl
);
234 void codeScalingList(const ScalingList
&);
235 void codeScalingList(const ScalingList
& scalingList
, uint32_t sizeId
, uint32_t listId
);
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
);
243 void codeSaoMaxUvlc(uint32_t code
, uint32_t maxSymbol
);
245 void codeDeltaQP(const CUData
& cu
, uint32_t absPartIdx
);
246 void codeLastSignificantXY(uint32_t posx
, uint32_t posy
, uint32_t log2TrSize
, bool bIsLuma
, uint32_t scanIdx
);
247 void codeTransformSkipFlags(const CUData
& cu
, uint32_t absPartIdx
, uint32_t trSize
, TextType ttype
);
249 void encodeTransform(const CUData
& cu
, uint32_t absPartIdx
, uint32_t tuDepth
, uint32_t log2TrSize
,
250 bool& bCodeDQP
, const uint32_t depthRange
[2]);
252 void copyFrom(const Entropy
& src
);
253 void copyContextsFrom(const Entropy
& src
);
257 #endif // ifndef X265_ENTROPY_H