Mercurial > hg > forks > libbpg
comparison jctvc/TLibEncoder/TEncSbac.cpp @ 0:772086c29cc7
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 16 Nov 2016 11:16:33 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:772086c29cc7 |
---|---|
1 /* The copyright in this software is being made available under the BSD | |
2 * License, included below. This software may be subject to other third party | |
3 * and contributor rights, including patent rights, and no such rights are | |
4 * granted under this license. | |
5 * | |
6 * Copyright (c) 2010-2014, ITU/ISO/IEC | |
7 * All rights reserved. | |
8 * | |
9 * Redistribution and use in source and binary forms, with or without | |
10 * modification, are permitted provided that the following conditions are met: | |
11 * | |
12 * * Redistributions of source code must retain the above copyright notice, | |
13 * this list of conditions and the following disclaimer. | |
14 * * Redistributions in binary form must reproduce the above copyright notice, | |
15 * this list of conditions and the following disclaimer in the documentation | |
16 * and/or other materials provided with the distribution. | |
17 * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may | |
18 * be used to endorse or promote products derived from this software without | |
19 * specific prior written permission. | |
20 * | |
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS | |
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
31 * THE POSSIBILITY OF SUCH DAMAGE. | |
32 */ | |
33 | |
34 /** \file TEncSbac.cpp | |
35 \brief SBAC encoder class | |
36 */ | |
37 | |
38 #include "TEncTop.h" | |
39 #include "TEncSbac.h" | |
40 #include "TLibCommon/TComTU.h" | |
41 | |
42 #include <map> | |
43 #include <algorithm> | |
44 | |
45 #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST | |
46 #include "../TLibCommon/Debug.h" | |
47 #endif | |
48 | |
49 | |
50 //! \ingroup TLibEncoder | |
51 //! \{ | |
52 | |
53 // ==================================================================================================================== | |
54 // Constructor / destructor / create / destroy | |
55 // ==================================================================================================================== | |
56 | |
57 TEncSbac::TEncSbac() | |
58 // new structure here | |
59 : m_pcBitIf ( NULL ) | |
60 , m_pcSlice ( NULL ) | |
61 , m_pcBinIf ( NULL ) | |
62 , m_numContextModels ( 0 ) | |
63 , m_cCUSplitFlagSCModel ( 1, 1, NUM_SPLIT_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
64 , m_cCUSkipFlagSCModel ( 1, 1, NUM_SKIP_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
65 , m_cCUMergeFlagExtSCModel ( 1, 1, NUM_MERGE_FLAG_EXT_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
66 , m_cCUMergeIdxExtSCModel ( 1, 1, NUM_MERGE_IDX_EXT_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
67 , m_cCUPartSizeSCModel ( 1, 1, NUM_PART_SIZE_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
68 , m_cCUPredModeSCModel ( 1, 1, NUM_PRED_MODE_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
69 , m_cCUIntraPredSCModel ( 1, 1, NUM_ADI_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
70 , m_cCUChromaPredSCModel ( 1, 1, NUM_CHROMA_PRED_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
71 , m_cCUDeltaQpSCModel ( 1, 1, NUM_DELTA_QP_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
72 , m_cCUInterDirSCModel ( 1, 1, NUM_INTER_DIR_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
73 , m_cCURefPicSCModel ( 1, 1, NUM_REF_NO_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
74 , m_cCUMvdSCModel ( 1, 1, NUM_MV_RES_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
75 , m_cCUQtCbfSCModel ( 1, NUM_QT_CBF_CTX_SETS, NUM_QT_CBF_CTX_PER_SET , m_contextModels + m_numContextModels, m_numContextModels) | |
76 , m_cCUTransSubdivFlagSCModel ( 1, 1, NUM_TRANS_SUBDIV_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
77 , m_cCUQtRootCbfSCModel ( 1, 1, NUM_QT_ROOT_CBF_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
78 , m_cCUSigCoeffGroupSCModel ( 1, 2, NUM_SIG_CG_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
79 , m_cCUSigSCModel ( 1, 1, NUM_SIG_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
80 , m_cCuCtxLastX ( 1, NUM_CTX_LAST_FLAG_SETS, NUM_CTX_LAST_FLAG_XY , m_contextModels + m_numContextModels, m_numContextModels) | |
81 , m_cCuCtxLastY ( 1, NUM_CTX_LAST_FLAG_SETS, NUM_CTX_LAST_FLAG_XY , m_contextModels + m_numContextModels, m_numContextModels) | |
82 , m_cCUOneSCModel ( 1, 1, NUM_ONE_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
83 , m_cCUAbsSCModel ( 1, 1, NUM_ABS_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
84 , m_cMVPIdxSCModel ( 1, 1, NUM_MVP_IDX_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
85 , m_cSaoMergeSCModel ( 1, 1, NUM_SAO_MERGE_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
86 , m_cSaoTypeIdxSCModel ( 1, 1, NUM_SAO_TYPE_IDX_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
87 , m_cTransformSkipSCModel ( 1, MAX_NUM_CHANNEL_TYPE, NUM_TRANSFORMSKIP_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
88 , m_CUTransquantBypassFlagSCModel ( 1, 1, NUM_CU_TRANSQUANT_BYPASS_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
89 , m_explicitRdpcmFlagSCModel ( 1, MAX_NUM_CHANNEL_TYPE, NUM_EXPLICIT_RDPCM_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
90 , m_explicitRdpcmDirSCModel ( 1, MAX_NUM_CHANNEL_TYPE, NUM_EXPLICIT_RDPCM_DIR_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
91 , m_cCrossComponentPredictionSCModel ( 1, 1, NUM_CROSS_COMPONENT_PREDICTION_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
92 , m_ChromaQpAdjFlagSCModel ( 1, 1, NUM_CHROMA_QP_ADJ_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
93 , m_ChromaQpAdjIdcSCModel ( 1, 1, NUM_CHROMA_QP_ADJ_IDC_CTX , m_contextModels + m_numContextModels, m_numContextModels) | |
94 { | |
95 assert( m_numContextModels <= MAX_NUM_CTX_MOD ); | |
96 } | |
97 | |
98 TEncSbac::~TEncSbac() | |
99 { | |
100 } | |
101 | |
102 // ==================================================================================================================== | |
103 // Public member functions | |
104 // ==================================================================================================================== | |
105 | |
106 Void TEncSbac::resetEntropy () | |
107 { | |
108 Int iQp = m_pcSlice->getSliceQp(); | |
109 SliceType eSliceType = m_pcSlice->getSliceType(); | |
110 | |
111 Int encCABACTableIdx = m_pcSlice->getPPS()->getEncCABACTableIdx(); | |
112 if (!m_pcSlice->isIntra() && (encCABACTableIdx==B_SLICE || encCABACTableIdx==P_SLICE) && m_pcSlice->getPPS()->getCabacInitPresentFlag()) | |
113 { | |
114 eSliceType = (SliceType) encCABACTableIdx; | |
115 } | |
116 | |
117 m_cCUSplitFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SPLIT_FLAG ); | |
118 m_cCUSkipFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SKIP_FLAG ); | |
119 m_cCUMergeFlagExtSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_MERGE_FLAG_EXT); | |
120 m_cCUMergeIdxExtSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_MERGE_IDX_EXT); | |
121 m_cCUPartSizeSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_PART_SIZE ); | |
122 m_cCUPredModeSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_PRED_MODE ); | |
123 m_cCUIntraPredSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_INTRA_PRED_MODE ); | |
124 m_cCUChromaPredSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_CHROMA_PRED_MODE ); | |
125 m_cCUInterDirSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_INTER_DIR ); | |
126 m_cCUMvdSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_MVD ); | |
127 m_cCURefPicSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_REF_PIC ); | |
128 m_cCUDeltaQpSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_DQP ); | |
129 m_cCUQtCbfSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_QT_CBF ); | |
130 m_cCUQtRootCbfSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_QT_ROOT_CBF ); | |
131 m_cCUSigCoeffGroupSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SIG_CG_FLAG ); | |
132 m_cCUSigSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SIG_FLAG ); | |
133 m_cCuCtxLastX.initBuffer ( eSliceType, iQp, (UChar*)INIT_LAST ); | |
134 m_cCuCtxLastY.initBuffer ( eSliceType, iQp, (UChar*)INIT_LAST ); | |
135 m_cCUOneSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_ONE_FLAG ); | |
136 m_cCUAbsSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_ABS_FLAG ); | |
137 m_cMVPIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_MVP_IDX ); | |
138 m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); | |
139 m_cSaoMergeSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG ); | |
140 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); | |
141 m_cTransformSkipSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANSFORMSKIP_FLAG ); | |
142 m_CUTransquantBypassFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_CU_TRANSQUANT_BYPASS_FLAG ); | |
143 m_explicitRdpcmFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_EXPLICIT_RDPCM_FLAG); | |
144 m_explicitRdpcmDirSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_EXPLICIT_RDPCM_DIR); | |
145 m_cCrossComponentPredictionSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_CROSS_COMPONENT_PREDICTION ); | |
146 m_ChromaQpAdjFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_CHROMA_QP_ADJ_FLAG ); | |
147 m_ChromaQpAdjIdcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_CHROMA_QP_ADJ_IDC ); | |
148 | |
149 for (UInt statisticIndex = 0; statisticIndex < RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS ; statisticIndex++) | |
150 { | |
151 m_golombRiceAdaptationStatistics[statisticIndex] = 0; | |
152 } | |
153 | |
154 m_pcBinIf->start(); | |
155 | |
156 return; | |
157 } | |
158 | |
159 /** The function does the following: | |
160 * If current slice type is P/B then it determines the distance of initialisation type 1 and 2 from the current CABAC states and | |
161 * stores the index of the closest table. This index is used for the next P/B slice when cabac_init_present_flag is true. | |
162 */ | |
163 Void TEncSbac::determineCabacInitIdx() | |
164 { | |
165 Int qp = m_pcSlice->getSliceQp(); | |
166 | |
167 if (!m_pcSlice->isIntra()) | |
168 { | |
169 SliceType aSliceTypeChoices[] = {B_SLICE, P_SLICE}; | |
170 | |
171 UInt bestCost = MAX_UINT; | |
172 SliceType bestSliceType = aSliceTypeChoices[0]; | |
173 for (UInt idx=0; idx<2; idx++) | |
174 { | |
175 UInt curCost = 0; | |
176 SliceType curSliceType = aSliceTypeChoices[idx]; | |
177 | |
178 curCost = m_cCUSplitFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SPLIT_FLAG ); | |
179 curCost += m_cCUSkipFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SKIP_FLAG ); | |
180 curCost += m_cCUMergeFlagExtSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_MERGE_FLAG_EXT); | |
181 curCost += m_cCUMergeIdxExtSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_MERGE_IDX_EXT); | |
182 curCost += m_cCUPartSizeSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_PART_SIZE ); | |
183 curCost += m_cCUPredModeSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_PRED_MODE ); | |
184 curCost += m_cCUIntraPredSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_INTRA_PRED_MODE ); | |
185 curCost += m_cCUChromaPredSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_CHROMA_PRED_MODE ); | |
186 curCost += m_cCUInterDirSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_INTER_DIR ); | |
187 curCost += m_cCUMvdSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_MVD ); | |
188 curCost += m_cCURefPicSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_REF_PIC ); | |
189 curCost += m_cCUDeltaQpSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_DQP ); | |
190 curCost += m_cCUQtCbfSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_QT_CBF ); | |
191 curCost += m_cCUQtRootCbfSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_QT_ROOT_CBF ); | |
192 curCost += m_cCUSigCoeffGroupSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SIG_CG_FLAG ); | |
193 curCost += m_cCUSigSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SIG_FLAG ); | |
194 curCost += m_cCuCtxLastX.calcCost ( curSliceType, qp, (UChar*)INIT_LAST ); | |
195 curCost += m_cCuCtxLastY.calcCost ( curSliceType, qp, (UChar*)INIT_LAST ); | |
196 curCost += m_cCUOneSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_ONE_FLAG ); | |
197 curCost += m_cCUAbsSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_ABS_FLAG ); | |
198 curCost += m_cMVPIdxSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_MVP_IDX ); | |
199 curCost += m_cCUTransSubdivFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); | |
200 curCost += m_cSaoMergeSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_MERGE_FLAG ); | |
201 curCost += m_cSaoTypeIdxSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_TYPE_IDX ); | |
202 curCost += m_cTransformSkipSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_TRANSFORMSKIP_FLAG ); | |
203 curCost += m_CUTransquantBypassFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_CU_TRANSQUANT_BYPASS_FLAG ); | |
204 curCost += m_explicitRdpcmFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_EXPLICIT_RDPCM_FLAG); | |
205 curCost += m_explicitRdpcmDirSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_EXPLICIT_RDPCM_DIR); | |
206 curCost += m_cCrossComponentPredictionSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_CROSS_COMPONENT_PREDICTION ); | |
207 curCost += m_ChromaQpAdjFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_CHROMA_QP_ADJ_FLAG ); | |
208 curCost += m_ChromaQpAdjIdcSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_CHROMA_QP_ADJ_IDC ); | |
209 | |
210 if (curCost < bestCost) | |
211 { | |
212 bestSliceType = curSliceType; | |
213 bestCost = curCost; | |
214 } | |
215 } | |
216 m_pcSlice->getPPS()->setEncCABACTableIdx( bestSliceType ); | |
217 } | |
218 else | |
219 { | |
220 m_pcSlice->getPPS()->setEncCABACTableIdx( I_SLICE ); | |
221 } | |
222 } | |
223 | |
224 Void TEncSbac::codeVPS( TComVPS* pcVPS ) | |
225 { | |
226 assert (0); | |
227 return; | |
228 } | |
229 | |
230 Void TEncSbac::codeSPS( TComSPS* pcSPS ) | |
231 { | |
232 assert (0); | |
233 return; | |
234 } | |
235 | |
236 Void TEncSbac::codePPS( TComPPS* pcPPS ) | |
237 { | |
238 assert (0); | |
239 return; | |
240 } | |
241 | |
242 Void TEncSbac::codeSliceHeader( TComSlice* pcSlice ) | |
243 { | |
244 assert (0); | |
245 return; | |
246 } | |
247 | |
248 Void TEncSbac::codeTilesWPPEntryPoint( TComSlice* pSlice ) | |
249 { | |
250 assert (0); | |
251 return; | |
252 } | |
253 | |
254 Void TEncSbac::codeTerminatingBit( UInt uilsLast ) | |
255 { | |
256 m_pcBinIf->encodeBinTrm( uilsLast ); | |
257 } | |
258 | |
259 Void TEncSbac::codeSliceFinish() | |
260 { | |
261 m_pcBinIf->finish(); | |
262 } | |
263 | |
264 Void TEncSbac::xWriteUnarySymbol( UInt uiSymbol, ContextModel* pcSCModel, Int iOffset ) | |
265 { | |
266 m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[0] ); | |
267 | |
268 if( 0 == uiSymbol) | |
269 { | |
270 return; | |
271 } | |
272 | |
273 while( uiSymbol-- ) | |
274 { | |
275 m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[ iOffset ] ); | |
276 } | |
277 | |
278 return; | |
279 } | |
280 | |
281 Void TEncSbac::xWriteUnaryMaxSymbol( UInt uiSymbol, ContextModel* pcSCModel, Int iOffset, UInt uiMaxSymbol ) | |
282 { | |
283 if (uiMaxSymbol == 0) | |
284 { | |
285 return; | |
286 } | |
287 | |
288 m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[ 0 ] ); | |
289 | |
290 if ( uiSymbol == 0 ) | |
291 { | |
292 return; | |
293 } | |
294 | |
295 Bool bCodeLast = ( uiMaxSymbol > uiSymbol ); | |
296 | |
297 while( --uiSymbol ) | |
298 { | |
299 m_pcBinIf->encodeBin( 1, pcSCModel[ iOffset ] ); | |
300 } | |
301 if( bCodeLast ) | |
302 { | |
303 m_pcBinIf->encodeBin( 0, pcSCModel[ iOffset ] ); | |
304 } | |
305 | |
306 return; | |
307 } | |
308 | |
309 Void TEncSbac::xWriteEpExGolomb( UInt uiSymbol, UInt uiCount ) | |
310 { | |
311 UInt bins = 0; | |
312 Int numBins = 0; | |
313 | |
314 while( uiSymbol >= (UInt)(1<<uiCount) ) | |
315 { | |
316 bins = 2 * bins + 1; | |
317 numBins++; | |
318 uiSymbol -= 1 << uiCount; | |
319 uiCount ++; | |
320 } | |
321 bins = 2 * bins + 0; | |
322 numBins++; | |
323 | |
324 bins = (bins << uiCount) | uiSymbol; | |
325 numBins += uiCount; | |
326 | |
327 assert( numBins <= 32 ); | |
328 m_pcBinIf->encodeBinsEP( bins, numBins ); | |
329 } | |
330 | |
331 | |
332 /** Coding of coeff_abs_level_minus3 | |
333 * \param uiSymbol value of coeff_abs_level_minus3 | |
334 * \param ruiGoRiceParam reference to Rice parameter | |
335 * \returns Void | |
336 */ | |
337 Void TEncSbac::xWriteCoefRemainExGolomb ( UInt symbol, UInt &rParam, const Bool useLimitedPrefixLength, const ChannelType channelType ) | |
338 { | |
339 Int codeNumber = (Int)symbol; | |
340 UInt length; | |
341 | |
342 if (codeNumber < (COEF_REMAIN_BIN_REDUCTION << rParam)) | |
343 { | |
344 length = codeNumber>>rParam; | |
345 m_pcBinIf->encodeBinsEP( (1<<(length+1))-2 , length+1); | |
346 m_pcBinIf->encodeBinsEP((codeNumber%(1<<rParam)),rParam); | |
347 } | |
348 else if (useLimitedPrefixLength) | |
349 { | |
350 const UInt maximumPrefixLength = (32 - (COEF_REMAIN_BIN_REDUCTION + g_maxTrDynamicRange[channelType])); | |
351 | |
352 UInt prefixLength = 0; | |
353 UInt suffixLength = MAX_UINT; | |
354 UInt codeValue = (symbol >> rParam) - COEF_REMAIN_BIN_REDUCTION; | |
355 | |
356 if (codeValue >= ((1 << maximumPrefixLength) - 1)) | |
357 { | |
358 prefixLength = maximumPrefixLength; | |
359 suffixLength = g_maxTrDynamicRange[channelType] - rParam; | |
360 } | |
361 else | |
362 { | |
363 while (codeValue > ((2 << prefixLength) - 2)) | |
364 { | |
365 prefixLength++; | |
366 } | |
367 | |
368 suffixLength = prefixLength + 1; //+1 for the separator bit | |
369 } | |
370 | |
371 const UInt suffix = codeValue - ((1 << prefixLength) - 1); | |
372 | |
373 const UInt totalPrefixLength = prefixLength + COEF_REMAIN_BIN_REDUCTION; | |
374 const UInt prefix = (1 << totalPrefixLength) - 1; | |
375 const UInt rParamBitMask = (1 << rParam) - 1; | |
376 | |
377 m_pcBinIf->encodeBinsEP( prefix, totalPrefixLength ); //prefix | |
378 m_pcBinIf->encodeBinsEP(((suffix << rParam) | (symbol & rParamBitMask)), (suffixLength + rParam)); //separator, suffix, and rParam bits | |
379 } | |
380 else | |
381 { | |
382 length = rParam; | |
383 codeNumber = codeNumber - ( COEF_REMAIN_BIN_REDUCTION << rParam); | |
384 | |
385 while (codeNumber >= (1<<length)) | |
386 { | |
387 codeNumber -= (1<<(length++)); | |
388 } | |
389 | |
390 m_pcBinIf->encodeBinsEP((1<<(COEF_REMAIN_BIN_REDUCTION+length+1-rParam))-2,COEF_REMAIN_BIN_REDUCTION+length+1-rParam); | |
391 m_pcBinIf->encodeBinsEP(codeNumber,length); | |
392 } | |
393 } | |
394 | |
395 // SBAC RD | |
396 Void TEncSbac::load ( const TEncSbac* pSrc) | |
397 { | |
398 this->xCopyFrom(pSrc); | |
399 } | |
400 | |
401 Void TEncSbac::loadIntraDirMode( const TEncSbac* pSrc, const ChannelType chType ) | |
402 { | |
403 m_pcBinIf->copyState( pSrc->m_pcBinIf ); | |
404 if (isLuma(chType)) | |
405 this->m_cCUIntraPredSCModel .copyFrom( &pSrc->m_cCUIntraPredSCModel ); | |
406 else | |
407 this->m_cCUChromaPredSCModel .copyFrom( &pSrc->m_cCUChromaPredSCModel ); | |
408 } | |
409 | |
410 | |
411 Void TEncSbac::store( TEncSbac* pDest) const | |
412 { | |
413 pDest->xCopyFrom( this ); | |
414 } | |
415 | |
416 | |
417 Void TEncSbac::xCopyFrom( const TEncSbac* pSrc ) | |
418 { | |
419 m_pcBinIf->copyState( pSrc->m_pcBinIf ); | |
420 xCopyContextsFrom(pSrc); | |
421 } | |
422 | |
423 Void TEncSbac::codeMVPIdx ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) | |
424 { | |
425 Int iSymbol = pcCU->getMVPIdx(eRefList, uiAbsPartIdx); | |
426 Int iNum = AMVP_MAX_NUM_CANDS; | |
427 | |
428 xWriteUnaryMaxSymbol(iSymbol, m_cMVPIdxSCModel.get(0), 1, iNum-1); | |
429 } | |
430 | |
431 Void TEncSbac::codePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) | |
432 { | |
433 PartSize eSize = pcCU->getPartitionSize( uiAbsPartIdx ); | |
434 | |
435 if ( pcCU->isIntra( uiAbsPartIdx ) ) | |
436 { | |
437 if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) | |
438 { | |
439 m_pcBinIf->encodeBin( eSize == SIZE_2Nx2N? 1 : 0, m_cCUPartSizeSCModel.get( 0, 0, 0 ) ); | |
440 } | |
441 return; | |
442 } | |
443 | |
444 switch(eSize) | |
445 { | |
446 case SIZE_2Nx2N: | |
447 { | |
448 m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 0) ); | |
449 break; | |
450 } | |
451 case SIZE_2NxN: | |
452 case SIZE_2NxnU: | |
453 case SIZE_2NxnD: | |
454 { | |
455 m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); | |
456 m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 1) ); | |
457 if ( pcCU->getSlice()->getSPS()->getAMPAcc( uiDepth ) ) | |
458 { | |
459 if (eSize == SIZE_2NxN) | |
460 { | |
461 m_pcBinIf->encodeBin(1, m_cCUPartSizeSCModel.get( 0, 0, 3 )); | |
462 } | |
463 else | |
464 { | |
465 m_pcBinIf->encodeBin(0, m_cCUPartSizeSCModel.get( 0, 0, 3 )); | |
466 m_pcBinIf->encodeBinEP((eSize == SIZE_2NxnU? 0: 1)); | |
467 } | |
468 } | |
469 break; | |
470 } | |
471 case SIZE_Nx2N: | |
472 case SIZE_nLx2N: | |
473 case SIZE_nRx2N: | |
474 { | |
475 m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); | |
476 m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) ); | |
477 | |
478 if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth && !( pcCU->getWidth(uiAbsPartIdx) == 8 && pcCU->getHeight(uiAbsPartIdx) == 8 ) ) | |
479 { | |
480 m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 2) ); | |
481 } | |
482 | |
483 if ( pcCU->getSlice()->getSPS()->getAMPAcc( uiDepth ) ) | |
484 { | |
485 if (eSize == SIZE_Nx2N) | |
486 { | |
487 m_pcBinIf->encodeBin(1, m_cCUPartSizeSCModel.get( 0, 0, 3 )); | |
488 } | |
489 else | |
490 { | |
491 m_pcBinIf->encodeBin(0, m_cCUPartSizeSCModel.get( 0, 0, 3 )); | |
492 m_pcBinIf->encodeBinEP((eSize == SIZE_nLx2N? 0: 1)); | |
493 } | |
494 } | |
495 break; | |
496 } | |
497 case SIZE_NxN: | |
498 { | |
499 if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth && !( pcCU->getWidth(uiAbsPartIdx) == 8 && pcCU->getHeight(uiAbsPartIdx) == 8 ) ) | |
500 { | |
501 m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); | |
502 m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) ); | |
503 m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 2) ); | |
504 } | |
505 break; | |
506 } | |
507 default: | |
508 { | |
509 assert(0); | |
510 break; | |
511 } | |
512 } | |
513 } | |
514 | |
515 | |
516 /** code prediction mode | |
517 * \param pcCU | |
518 * \param uiAbsPartIdx | |
519 * \returns Void | |
520 */ | |
521 Void TEncSbac::codePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
522 { | |
523 // get context function is here | |
524 m_pcBinIf->encodeBin( pcCU->isIntra( uiAbsPartIdx ) ? 1 : 0, m_cCUPredModeSCModel.get( 0, 0, 0 ) ); | |
525 } | |
526 | |
527 Void TEncSbac::codeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
528 { | |
529 UInt uiSymbol = pcCU->getCUTransquantBypass(uiAbsPartIdx); | |
530 m_pcBinIf->encodeBin( uiSymbol, m_CUTransquantBypassFlagSCModel.get( 0, 0, 0 ) ); | |
531 } | |
532 | |
533 /** code skip flag | |
534 * \param pcCU | |
535 * \param uiAbsPartIdx | |
536 * \returns Void | |
537 */ | |
538 Void TEncSbac::codeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
539 { | |
540 // get context function is here | |
541 UInt uiSymbol = pcCU->isSkipped( uiAbsPartIdx ) ? 1 : 0; | |
542 UInt uiCtxSkip = pcCU->getCtxSkipFlag( uiAbsPartIdx ) ; | |
543 m_pcBinIf->encodeBin( uiSymbol, m_cCUSkipFlagSCModel.get( 0, 0, uiCtxSkip ) ); | |
544 DTRACE_CABAC_VL( g_nSymbolCounter++ ); | |
545 DTRACE_CABAC_T( "\tSkipFlag" ); | |
546 DTRACE_CABAC_T( "\tuiCtxSkip: "); | |
547 DTRACE_CABAC_V( uiCtxSkip ); | |
548 DTRACE_CABAC_T( "\tuiSymbol: "); | |
549 DTRACE_CABAC_V( uiSymbol ); | |
550 DTRACE_CABAC_T( "\n"); | |
551 } | |
552 | |
553 /** code merge flag | |
554 * \param pcCU | |
555 * \param uiAbsPartIdx | |
556 * \returns Void | |
557 */ | |
558 Void TEncSbac::codeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
559 { | |
560 const UInt uiSymbol = pcCU->getMergeFlag( uiAbsPartIdx ) ? 1 : 0; | |
561 m_pcBinIf->encodeBin( uiSymbol, *m_cCUMergeFlagExtSCModel.get( 0 ) ); | |
562 | |
563 DTRACE_CABAC_VL( g_nSymbolCounter++ ); | |
564 DTRACE_CABAC_T( "\tMergeFlag: " ); | |
565 DTRACE_CABAC_V( uiSymbol ); | |
566 DTRACE_CABAC_T( "\tAddress: " ); | |
567 DTRACE_CABAC_V( pcCU->getCtuRsAddr() ); | |
568 DTRACE_CABAC_T( "\tuiAbsPartIdx: " ); | |
569 DTRACE_CABAC_V( uiAbsPartIdx ); | |
570 DTRACE_CABAC_T( "\n" ); | |
571 } | |
572 | |
573 /** code merge index | |
574 * \param pcCU | |
575 * \param uiAbsPartIdx | |
576 * \returns Void | |
577 */ | |
578 Void TEncSbac::codeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
579 { | |
580 UInt uiUnaryIdx = pcCU->getMergeIndex( uiAbsPartIdx ); | |
581 UInt uiNumCand = pcCU->getSlice()->getMaxNumMergeCand(); | |
582 if ( uiNumCand > 1 ) | |
583 { | |
584 for( UInt ui = 0; ui < uiNumCand - 1; ++ui ) | |
585 { | |
586 const UInt uiSymbol = ui == uiUnaryIdx ? 0 : 1; | |
587 if ( ui==0 ) | |
588 { | |
589 m_pcBinIf->encodeBin( uiSymbol, m_cCUMergeIdxExtSCModel.get( 0, 0, 0 ) ); | |
590 } | |
591 else | |
592 { | |
593 m_pcBinIf->encodeBinEP( uiSymbol ); | |
594 } | |
595 if( uiSymbol == 0 ) | |
596 { | |
597 break; | |
598 } | |
599 } | |
600 } | |
601 DTRACE_CABAC_VL( g_nSymbolCounter++ ); | |
602 DTRACE_CABAC_T( "\tparseMergeIndex()" ); | |
603 DTRACE_CABAC_T( "\tuiMRGIdx= " ); | |
604 DTRACE_CABAC_V( pcCU->getMergeIndex( uiAbsPartIdx ) ); | |
605 DTRACE_CABAC_T( "\n" ); | |
606 } | |
607 | |
608 Void TEncSbac::codeSplitFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) | |
609 { | |
610 if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) | |
611 return; | |
612 | |
613 UInt uiCtx = pcCU->getCtxSplitFlag( uiAbsPartIdx, uiDepth ); | |
614 UInt uiCurrSplitFlag = ( pcCU->getDepth( uiAbsPartIdx ) > uiDepth ) ? 1 : 0; | |
615 | |
616 assert( uiCtx < 3 ); | |
617 m_pcBinIf->encodeBin( uiCurrSplitFlag, m_cCUSplitFlagSCModel.get( 0, 0, uiCtx ) ); | |
618 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
619 DTRACE_CABAC_T( "\tSplitFlag\n" ) | |
620 return; | |
621 } | |
622 | |
623 Void TEncSbac::codeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx ) | |
624 { | |
625 m_pcBinIf->encodeBin( uiSymbol, m_cCUTransSubdivFlagSCModel.get( 0, 0, uiCtx ) ); | |
626 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
627 DTRACE_CABAC_T( "\tparseTransformSubdivFlag()" ) | |
628 DTRACE_CABAC_T( "\tsymbol=" ) | |
629 DTRACE_CABAC_V( uiSymbol ) | |
630 DTRACE_CABAC_T( "\tctx=" ) | |
631 DTRACE_CABAC_V( uiCtx ) | |
632 DTRACE_CABAC_T( "\n" ) | |
633 } | |
634 | |
635 | |
636 Void TEncSbac::codeIntraDirLumaAng( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiple) | |
637 { | |
638 UInt dir[4],j; | |
639 Int preds[4][NUM_MOST_PROBABLE_MODES] = {{-1, -1, -1},{-1, -1, -1},{-1, -1, -1},{-1, -1, -1}}; | |
640 Int predNum[4], predIdx[4] ={ -1,-1,-1,-1}; | |
641 PartSize mode = pcCU->getPartitionSize( absPartIdx ); | |
642 UInt partNum = isMultiple?(mode==SIZE_NxN?4:1):1; | |
643 UInt partOffset = ( pcCU->getPic()->getNumPartitionsInCtu() >> ( pcCU->getDepth(absPartIdx) << 1 ) ) >> 2; | |
644 for (j=0;j<partNum;j++) | |
645 { | |
646 dir[j] = pcCU->getIntraDir( CHANNEL_TYPE_LUMA, absPartIdx+partOffset*j ); | |
647 predNum[j] = pcCU->getIntraDirPredictor(absPartIdx+partOffset*j, preds[j], COMPONENT_Y); | |
648 for(UInt i = 0; i < predNum[j]; i++) | |
649 { | |
650 if(dir[j] == preds[j][i]) | |
651 { | |
652 predIdx[j] = i; | |
653 } | |
654 } | |
655 m_pcBinIf->encodeBin((predIdx[j] != -1)? 1 : 0, m_cCUIntraPredSCModel.get( 0, 0, 0 ) ); | |
656 } | |
657 for (j=0;j<partNum;j++) | |
658 { | |
659 if(predIdx[j] != -1) | |
660 { | |
661 m_pcBinIf->encodeBinEP( predIdx[j] ? 1 : 0 ); | |
662 if (predIdx[j]) | |
663 { | |
664 m_pcBinIf->encodeBinEP( predIdx[j]-1 ); | |
665 } | |
666 } | |
667 else | |
668 { | |
669 assert(predNum[j]>=3); // It is currently always 3! | |
670 if (preds[j][0] > preds[j][1]) | |
671 { | |
672 std::swap(preds[j][0], preds[j][1]); | |
673 } | |
674 if (preds[j][0] > preds[j][2]) | |
675 { | |
676 std::swap(preds[j][0], preds[j][2]); | |
677 } | |
678 if (preds[j][1] > preds[j][2]) | |
679 { | |
680 std::swap(preds[j][1], preds[j][2]); | |
681 } | |
682 for(Int i = (predNum[j] - 1); i >= 0; i--) | |
683 { | |
684 dir[j] = dir[j] > preds[j][i] ? dir[j] - 1 : dir[j]; | |
685 } | |
686 m_pcBinIf->encodeBinsEP( dir[j], 5 ); | |
687 } | |
688 } | |
689 return; | |
690 } | |
691 | |
692 Void TEncSbac::codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
693 { | |
694 UInt uiIntraDirChroma = pcCU->getIntraDir( CHANNEL_TYPE_CHROMA, uiAbsPartIdx ); | |
695 | |
696 if( uiIntraDirChroma == DM_CHROMA_IDX ) | |
697 { | |
698 m_pcBinIf->encodeBin( 0, m_cCUChromaPredSCModel.get( 0, 0, 0 ) ); | |
699 } | |
700 else | |
701 { | |
702 m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, 0 ) ); | |
703 | |
704 UInt uiAllowedChromaDir[ NUM_CHROMA_MODE ]; | |
705 pcCU->getAllowedChromaDir( uiAbsPartIdx, uiAllowedChromaDir ); | |
706 | |
707 for( Int i = 0; i < NUM_CHROMA_MODE - 1; i++ ) | |
708 { | |
709 if( uiIntraDirChroma == uiAllowedChromaDir[i] ) | |
710 { | |
711 uiIntraDirChroma = i; | |
712 break; | |
713 } | |
714 } | |
715 | |
716 m_pcBinIf->encodeBinsEP( uiIntraDirChroma, 2 ); | |
717 } | |
718 | |
719 return; | |
720 } | |
721 | |
722 | |
723 Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
724 { | |
725 const UInt uiInterDir = pcCU->getInterDir( uiAbsPartIdx ) - 1; | |
726 const UInt uiCtx = pcCU->getCtxInterDir( uiAbsPartIdx ); | |
727 ContextModel *pCtx = m_cCUInterDirSCModel.get( 0 ); | |
728 | |
729 if (pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N || pcCU->getHeight(uiAbsPartIdx) != 8 ) | |
730 { | |
731 m_pcBinIf->encodeBin( uiInterDir == 2 ? 1 : 0, *( pCtx + uiCtx ) ); | |
732 } | |
733 | |
734 if (uiInterDir < 2) | |
735 { | |
736 m_pcBinIf->encodeBin( uiInterDir, *( pCtx + 4 ) ); | |
737 } | |
738 | |
739 return; | |
740 } | |
741 | |
742 Void TEncSbac::codeRefFrmIdx( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) | |
743 { | |
744 Int iRefFrame = pcCU->getCUMvField( eRefList )->getRefIdx( uiAbsPartIdx ); | |
745 ContextModel *pCtx = m_cCURefPicSCModel.get( 0 ); | |
746 m_pcBinIf->encodeBin( ( iRefFrame == 0 ? 0 : 1 ), *pCtx ); | |
747 | |
748 if( iRefFrame > 0 ) | |
749 { | |
750 UInt uiRefNum = pcCU->getSlice()->getNumRefIdx( eRefList ) - 2; | |
751 pCtx++; | |
752 iRefFrame--; | |
753 for( UInt ui = 0; ui < uiRefNum; ++ui ) | |
754 { | |
755 const UInt uiSymbol = ui == iRefFrame ? 0 : 1; | |
756 if( ui == 0 ) | |
757 { | |
758 m_pcBinIf->encodeBin( uiSymbol, *pCtx ); | |
759 } | |
760 else | |
761 { | |
762 m_pcBinIf->encodeBinEP( uiSymbol ); | |
763 } | |
764 if( uiSymbol == 0 ) | |
765 { | |
766 break; | |
767 } | |
768 } | |
769 } | |
770 return; | |
771 } | |
772 | |
773 Void TEncSbac::codeMvd( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) | |
774 { | |
775 if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefList == REF_PIC_LIST_1 && pcCU->getInterDir(uiAbsPartIdx)==3) | |
776 { | |
777 return; | |
778 } | |
779 | |
780 const TComCUMvField* pcCUMvField = pcCU->getCUMvField( eRefList ); | |
781 const Int iHor = pcCUMvField->getMvd( uiAbsPartIdx ).getHor(); | |
782 const Int iVer = pcCUMvField->getMvd( uiAbsPartIdx ).getVer(); | |
783 ContextModel* pCtx = m_cCUMvdSCModel.get( 0 ); | |
784 | |
785 m_pcBinIf->encodeBin( iHor != 0 ? 1 : 0, *pCtx ); | |
786 m_pcBinIf->encodeBin( iVer != 0 ? 1 : 0, *pCtx ); | |
787 | |
788 const Bool bHorAbsGr0 = iHor != 0; | |
789 const Bool bVerAbsGr0 = iVer != 0; | |
790 const UInt uiHorAbs = 0 > iHor ? -iHor : iHor; | |
791 const UInt uiVerAbs = 0 > iVer ? -iVer : iVer; | |
792 pCtx++; | |
793 | |
794 if( bHorAbsGr0 ) | |
795 { | |
796 m_pcBinIf->encodeBin( uiHorAbs > 1 ? 1 : 0, *pCtx ); | |
797 } | |
798 | |
799 if( bVerAbsGr0 ) | |
800 { | |
801 m_pcBinIf->encodeBin( uiVerAbs > 1 ? 1 : 0, *pCtx ); | |
802 } | |
803 | |
804 if( bHorAbsGr0 ) | |
805 { | |
806 if( uiHorAbs > 1 ) | |
807 { | |
808 xWriteEpExGolomb( uiHorAbs-2, 1 ); | |
809 } | |
810 | |
811 m_pcBinIf->encodeBinEP( 0 > iHor ? 1 : 0 ); | |
812 } | |
813 | |
814 if( bVerAbsGr0 ) | |
815 { | |
816 if( uiVerAbs > 1 ) | |
817 { | |
818 xWriteEpExGolomb( uiVerAbs-2, 1 ); | |
819 } | |
820 | |
821 m_pcBinIf->encodeBinEP( 0 > iVer ? 1 : 0 ); | |
822 } | |
823 | |
824 return; | |
825 } | |
826 | |
827 Void TEncSbac::codeCrossComponentPrediction( TComTU &rTu, ComponentID compID ) | |
828 { | |
829 TComDataCU *pcCU = rTu.getCU(); | |
830 | |
831 if( isLuma(compID) || !pcCU->getSlice()->getPPS()->getUseCrossComponentPrediction() ) return; | |
832 | |
833 const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU(); | |
834 | |
835 if (!pcCU->isIntra(uiAbsPartIdx) || (pcCU->getIntraDir( CHANNEL_TYPE_CHROMA, uiAbsPartIdx ) == DM_CHROMA_IDX)) | |
836 { | |
837 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
838 DTRACE_CABAC_T("\tparseCrossComponentPrediction()") | |
839 DTRACE_CABAC_T( "\tAddr=" ) | |
840 DTRACE_CABAC_V( compID ) | |
841 DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) | |
842 DTRACE_CABAC_V( uiAbsPartIdx ) | |
843 | |
844 Int alpha = pcCU->getCrossComponentPredictionAlpha( uiAbsPartIdx, compID ); | |
845 ContextModel *pCtx = m_cCrossComponentPredictionSCModel.get(0, 0) + ((compID == COMPONENT_Cr) ? (NUM_CROSS_COMPONENT_PREDICTION_CTX >> 1) : 0); | |
846 m_pcBinIf->encodeBin(((alpha != 0) ? 1 : 0), pCtx[0]); | |
847 | |
848 if (alpha != 0) | |
849 { | |
850 static const Int log2AbsAlphaMinus1Table[8] = { 0, 1, 1, 2, 2, 2, 3, 3 }; | |
851 assert(abs(alpha) <= 8); | |
852 | |
853 if (abs(alpha)>1) | |
854 { | |
855 m_pcBinIf->encodeBin(1, pCtx[1]); | |
856 xWriteUnaryMaxSymbol( log2AbsAlphaMinus1Table[abs(alpha) - 1] - 1, (pCtx + 2), 1, 2 ); | |
857 } | |
858 else | |
859 { | |
860 m_pcBinIf->encodeBin(0, pCtx[1]); | |
861 } | |
862 m_pcBinIf->encodeBin( ((alpha < 0) ? 1 : 0), pCtx[4] ); | |
863 } | |
864 DTRACE_CABAC_T( "\tAlpha=" ) | |
865 DTRACE_CABAC_V( pcCU->getCrossComponentPredictionAlpha( uiAbsPartIdx, compID ) ) | |
866 DTRACE_CABAC_T( "\n" ) | |
867 } | |
868 } | |
869 | |
870 Void TEncSbac::codeDeltaQP( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
871 { | |
872 Int iDQp = pcCU->getQP( uiAbsPartIdx ) - pcCU->getRefQP( uiAbsPartIdx ); | |
873 | |
874 Int qpBdOffsetY = pcCU->getSlice()->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA); | |
875 iDQp = (iDQp + 78 + qpBdOffsetY + (qpBdOffsetY/2)) % (52 + qpBdOffsetY) - 26 - (qpBdOffsetY/2); | |
876 | |
877 UInt uiAbsDQp = (UInt)((iDQp > 0)? iDQp : (-iDQp)); | |
878 UInt TUValue = min((Int)uiAbsDQp, CU_DQP_TU_CMAX); | |
879 xWriteUnaryMaxSymbol( TUValue, &m_cCUDeltaQpSCModel.get( 0, 0, 0 ), 1, CU_DQP_TU_CMAX); | |
880 if( uiAbsDQp >= CU_DQP_TU_CMAX ) | |
881 { | |
882 xWriteEpExGolomb( uiAbsDQp - CU_DQP_TU_CMAX, CU_DQP_EG_k ); | |
883 } | |
884 | |
885 if ( uiAbsDQp > 0) | |
886 { | |
887 UInt uiSign = (iDQp > 0 ? 0 : 1); | |
888 m_pcBinIf->encodeBinEP(uiSign); | |
889 } | |
890 | |
891 return; | |
892 } | |
893 | |
894 /** code chroma qp adjustment, converting from the internal table representation | |
895 * \returns Void | |
896 */ | |
897 Void TEncSbac::codeChromaQpAdjustment( TComDataCU* cu, UInt absPartIdx ) | |
898 { | |
899 Int internalIdc = cu->getChromaQpAdj( absPartIdx ); | |
900 Int tableSize = cu->getSlice()->getPPS()->getChromaQpAdjTableSize(); | |
901 /* internal_idc == 0 => flag = 0 | |
902 * internal_idc > 1 => code idc value (if table size warrents) */ | |
903 m_pcBinIf->encodeBin( internalIdc > 0, m_ChromaQpAdjFlagSCModel.get( 0, 0, 0 ) ); | |
904 | |
905 if (internalIdc > 0 && tableSize > 1) | |
906 { | |
907 xWriteUnaryMaxSymbol( internalIdc - 1, &m_ChromaQpAdjIdcSCModel.get( 0, 0, 0 ), 0, tableSize - 1 ); | |
908 } | |
909 } | |
910 | |
911 Void TEncSbac::codeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel ) | |
912 { | |
913 TComDataCU* pcCU = rTu.getCU(); | |
914 | |
915 const UInt absPartIdx = rTu.GetAbsPartIdxTU(compID); | |
916 const UInt TUDepth = rTu.GetTransformDepthRel(); | |
917 UInt uiCtx = pcCU->getCtxQtCbf( rTu, toChannelType(compID) ); | |
918 const UInt contextSet = toChannelType(compID); | |
919 | |
920 const UInt width = rTu.getRect(compID).width; | |
921 const UInt height = rTu.getRect(compID).height; | |
922 const Bool canQuadSplit = (width >= (MIN_TU_SIZE * 2)) && (height >= (MIN_TU_SIZE * 2)); | |
923 | |
924 // Since the CBF for chroma is coded at the highest level possible, if sub-TUs are | |
925 // to be coded for a 4x8 chroma TU, their CBFs must be coded at the highest 4x8 level | |
926 // (i.e. where luma TUs are 8x8 rather than 4x4) | |
927 // ___ ___ | |
928 // | | | <- 4 x (8x8 luma + 4x8 4:2:2 chroma) | |
929 // |___|___| each quadrant has its own chroma CBF | |
930 // | | | _ _ _ _ | |
931 // |___|___| | | |
932 // <--16---> V | |
933 // _ _ | |
934 // |_|_| <- 4 x 4x4 luma + 1 x 4x8 4:2:2 chroma | |
935 // |_|_| no chroma CBF is coded - instead the parent CBF is inherited | |
936 // <-8-> if sub-TUs are present, their CBFs had to be coded at the parent level | |
937 | |
938 const UInt lowestTUDepth = TUDepth + ((!lowestLevel && !canQuadSplit) ? 1 : 0); //unsplittable TUs inherit their parent's CBF | |
939 | |
940 if ((width != height) && (lowestLevel || !canQuadSplit)) //if sub-TUs are present | |
941 { | |
942 const UInt subTUDepth = lowestTUDepth + 1; //if this is the lowest level of the TU-tree, the sub-TUs are directly below. Otherwise, this must be the level above the lowest level (as specified above) | |
943 const UInt partIdxesPerSubTU = rTu.GetAbsPartIdxNumParts(compID) >> 1; | |
944 | |
945 for (UInt subTU = 0; subTU < 2; subTU++) | |
946 { | |
947 const UInt subTUAbsPartIdx = absPartIdx + (subTU * partIdxesPerSubTU); | |
948 const UInt uiCbf = pcCU->getCbf(subTUAbsPartIdx, compID, subTUDepth); | |
949 | |
950 m_pcBinIf->encodeBin(uiCbf, m_cCUQtCbfSCModel.get(0, contextSet, uiCtx)); | |
951 | |
952 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
953 DTRACE_CABAC_T( "\tparseQtCbf()" ) | |
954 DTRACE_CABAC_T( "\tsub-TU=" ) | |
955 DTRACE_CABAC_V( subTU ) | |
956 DTRACE_CABAC_T( "\tsymbol=" ) | |
957 DTRACE_CABAC_V( uiCbf ) | |
958 DTRACE_CABAC_T( "\tctx=" ) | |
959 DTRACE_CABAC_V( uiCtx ) | |
960 DTRACE_CABAC_T( "\tetype=" ) | |
961 DTRACE_CABAC_V( compID ) | |
962 DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) | |
963 DTRACE_CABAC_V( subTUAbsPartIdx ) | |
964 DTRACE_CABAC_T( "\n" ) | |
965 } | |
966 } | |
967 else | |
968 { | |
969 const UInt uiCbf = pcCU->getCbf( absPartIdx, compID, lowestTUDepth ); | |
970 m_pcBinIf->encodeBin( uiCbf , m_cCUQtCbfSCModel.get( 0, contextSet, uiCtx ) ); | |
971 | |
972 | |
973 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
974 DTRACE_CABAC_T( "\tparseQtCbf()" ) | |
975 DTRACE_CABAC_T( "\tsymbol=" ) | |
976 DTRACE_CABAC_V( uiCbf ) | |
977 DTRACE_CABAC_T( "\tctx=" ) | |
978 DTRACE_CABAC_V( uiCtx ) | |
979 DTRACE_CABAC_T( "\tetype=" ) | |
980 DTRACE_CABAC_V( compID ) | |
981 DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) | |
982 DTRACE_CABAC_V( rTu.GetAbsPartIdxTU(compID) ) | |
983 DTRACE_CABAC_T( "\n" ) | |
984 } | |
985 } | |
986 | |
987 | |
988 Void TEncSbac::codeTransformSkipFlags (TComTU &rTu, ComponentID component ) | |
989 { | |
990 TComDataCU* pcCU=rTu.getCU(); | |
991 const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU(); | |
992 | |
993 if (pcCU->getCUTransquantBypass(uiAbsPartIdx)) | |
994 { | |
995 return; | |
996 } | |
997 | |
998 if (!TUCompRectHasAssociatedTransformSkipFlag(rTu.getRect(component), pcCU->getSlice()->getPPS()->getTransformSkipLog2MaxSize())) | |
999 { | |
1000 return; | |
1001 } | |
1002 | |
1003 UInt useTransformSkip = pcCU->getTransformSkip( uiAbsPartIdx,component); | |
1004 m_pcBinIf->encodeBin( useTransformSkip, m_cTransformSkipSCModel.get( 0, toChannelType(component), 0 ) ); | |
1005 | |
1006 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
1007 DTRACE_CABAC_T("\tparseTransformSkip()"); | |
1008 DTRACE_CABAC_T( "\tsymbol=" ) | |
1009 DTRACE_CABAC_V( useTransformSkip ) | |
1010 DTRACE_CABAC_T( "\tAddr=" ) | |
1011 DTRACE_CABAC_V( pcCU->getCtuRsAddr() ) | |
1012 DTRACE_CABAC_T( "\tetype=" ) | |
1013 DTRACE_CABAC_V( component ) | |
1014 DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) | |
1015 DTRACE_CABAC_V( rTu.GetAbsPartIdxTU() ) | |
1016 DTRACE_CABAC_T( "\n" ) | |
1017 } | |
1018 | |
1019 | |
1020 /** Code I_PCM information. | |
1021 * \param pcCU pointer to CU | |
1022 * \param uiAbsPartIdx CU index | |
1023 * \returns Void | |
1024 */ | |
1025 Void TEncSbac::codeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1026 { | |
1027 UInt uiIPCM = (pcCU->getIPCMFlag(uiAbsPartIdx) == true)? 1 : 0; | |
1028 | |
1029 Bool writePCMSampleFlag = pcCU->getIPCMFlag(uiAbsPartIdx); | |
1030 | |
1031 m_pcBinIf->encodeBinTrm (uiIPCM); | |
1032 | |
1033 if (writePCMSampleFlag) | |
1034 { | |
1035 m_pcBinIf->encodePCMAlignBits(); | |
1036 | |
1037 const UInt minCoeffSizeY = pcCU->getPic()->getMinCUWidth() * pcCU->getPic()->getMinCUHeight(); | |
1038 const UInt offsetY = minCoeffSizeY * uiAbsPartIdx; | |
1039 for (UInt ch=0; ch < pcCU->getPic()->getNumberValidComponents(); ch++) | |
1040 { | |
1041 const ComponentID compID = ComponentID(ch); | |
1042 const UInt offset = offsetY >> (pcCU->getPic()->getComponentScaleX(compID) + pcCU->getPic()->getComponentScaleY(compID)); | |
1043 Pel * pPCMSample = pcCU->getPCMSample(compID) + offset; | |
1044 const UInt width = pcCU->getWidth (uiAbsPartIdx) >> pcCU->getPic()->getComponentScaleX(compID); | |
1045 const UInt height = pcCU->getHeight(uiAbsPartIdx) >> pcCU->getPic()->getComponentScaleY(compID); | |
1046 const UInt sampleBits = pcCU->getSlice()->getSPS()->getPCMBitDepth(toChannelType(compID)); | |
1047 for (UInt y=0; y<height; y++) | |
1048 { | |
1049 for (UInt x=0; x<width; x++) | |
1050 { | |
1051 UInt sample = pPCMSample[x]; | |
1052 m_pcBinIf->xWritePCMCode(sample, sampleBits); | |
1053 } | |
1054 pPCMSample += width; | |
1055 } | |
1056 } | |
1057 | |
1058 m_pcBinIf->resetBac(); | |
1059 } | |
1060 } | |
1061 | |
1062 Void TEncSbac::codeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1063 { | |
1064 UInt uiCbf = pcCU->getQtRootCbf( uiAbsPartIdx ); | |
1065 UInt uiCtx = 0; | |
1066 m_pcBinIf->encodeBin( uiCbf , m_cCUQtRootCbfSCModel.get( 0, 0, uiCtx ) ); | |
1067 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
1068 DTRACE_CABAC_T( "\tparseQtRootCbf()" ) | |
1069 DTRACE_CABAC_T( "\tsymbol=" ) | |
1070 DTRACE_CABAC_V( uiCbf ) | |
1071 DTRACE_CABAC_T( "\tctx=" ) | |
1072 DTRACE_CABAC_V( uiCtx ) | |
1073 DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) | |
1074 DTRACE_CABAC_V( uiAbsPartIdx ) | |
1075 DTRACE_CABAC_T( "\n" ) | |
1076 } | |
1077 | |
1078 Void TEncSbac::codeQtCbfZero( TComTU & rTu, const ChannelType chType ) | |
1079 { | |
1080 // this function is only used to estimate the bits when cbf is 0 | |
1081 // and will never be called when writing the bistream. do not need to write log | |
1082 UInt uiCbf = 0; | |
1083 UInt uiCtx = rTu.getCU()->getCtxQtCbf( rTu, chType ); | |
1084 | |
1085 m_pcBinIf->encodeBin( uiCbf , m_cCUQtCbfSCModel.get( 0, chType, uiCtx ) ); | |
1086 } | |
1087 | |
1088 Void TEncSbac::codeQtRootCbfZero( TComDataCU* pcCU ) | |
1089 { | |
1090 // this function is only used to estimate the bits when cbf is 0 | |
1091 // and will never be called when writing the bistream. do not need to write log | |
1092 UInt uiCbf = 0; | |
1093 UInt uiCtx = 0; | |
1094 m_pcBinIf->encodeBin( uiCbf , m_cCUQtRootCbfSCModel.get( 0, 0, uiCtx ) ); | |
1095 } | |
1096 | |
1097 /** Encode (X,Y) position of the last significant coefficient | |
1098 * \param uiPosX X component of last coefficient | |
1099 * \param uiPosY Y component of last coefficient | |
1100 * \param width Block width | |
1101 * \param height Block height | |
1102 * \param eTType plane type / luminance or chrominance | |
1103 * \param uiScanIdx scan type (zig-zag, hor, ver) | |
1104 * This method encodes the X and Y component within a block of the last significant coefficient. | |
1105 */ | |
1106 Void TEncSbac::codeLastSignificantXY( UInt uiPosX, UInt uiPosY, Int width, Int height, ComponentID component, UInt uiScanIdx ) | |
1107 { | |
1108 // swap | |
1109 if( uiScanIdx == SCAN_VER ) | |
1110 { | |
1111 swap( uiPosX, uiPosY ); | |
1112 swap( width, height ); | |
1113 } | |
1114 | |
1115 UInt uiCtxLast; | |
1116 UInt uiGroupIdxX = g_uiGroupIdx[ uiPosX ]; | |
1117 UInt uiGroupIdxY = g_uiGroupIdx[ uiPosY ]; | |
1118 | |
1119 ContextModel *pCtxX = m_cCuCtxLastX.get( 0, toChannelType(component) ); | |
1120 ContextModel *pCtxY = m_cCuCtxLastY.get( 0, toChannelType(component) ); | |
1121 | |
1122 Int blkSizeOffsetX, blkSizeOffsetY, shiftX, shiftY; | |
1123 getLastSignificantContextParameters(component, width, height, blkSizeOffsetX, blkSizeOffsetY, shiftX, shiftY); | |
1124 | |
1125 //------------------ | |
1126 | |
1127 // posX | |
1128 | |
1129 for( uiCtxLast = 0; uiCtxLast < uiGroupIdxX; uiCtxLast++ ) | |
1130 { | |
1131 m_pcBinIf->encodeBin( 1, *( pCtxX + blkSizeOffsetX + (uiCtxLast >>shiftX) ) ); | |
1132 } | |
1133 if( uiGroupIdxX < g_uiGroupIdx[ width - 1 ]) | |
1134 { | |
1135 m_pcBinIf->encodeBin( 0, *( pCtxX + blkSizeOffsetX + (uiCtxLast >>shiftX) ) ); | |
1136 } | |
1137 | |
1138 // posY | |
1139 | |
1140 for( uiCtxLast = 0; uiCtxLast < uiGroupIdxY; uiCtxLast++ ) | |
1141 { | |
1142 m_pcBinIf->encodeBin( 1, *( pCtxY + blkSizeOffsetY + (uiCtxLast >>shiftY) ) ); | |
1143 } | |
1144 if( uiGroupIdxY < g_uiGroupIdx[ height - 1 ]) | |
1145 { | |
1146 m_pcBinIf->encodeBin( 0, *( pCtxY + blkSizeOffsetY + (uiCtxLast >>shiftY) ) ); | |
1147 } | |
1148 | |
1149 // EP-coded part | |
1150 | |
1151 if ( uiGroupIdxX > 3 ) | |
1152 { | |
1153 UInt uiCount = ( uiGroupIdxX - 2 ) >> 1; | |
1154 uiPosX = uiPosX - g_uiMinInGroup[ uiGroupIdxX ]; | |
1155 for (Int i = uiCount - 1 ; i >= 0; i-- ) | |
1156 { | |
1157 m_pcBinIf->encodeBinEP( ( uiPosX >> i ) & 1 ); | |
1158 } | |
1159 } | |
1160 if ( uiGroupIdxY > 3 ) | |
1161 { | |
1162 UInt uiCount = ( uiGroupIdxY - 2 ) >> 1; | |
1163 uiPosY = uiPosY - g_uiMinInGroup[ uiGroupIdxY ]; | |
1164 for ( Int i = uiCount - 1 ; i >= 0; i-- ) | |
1165 { | |
1166 m_pcBinIf->encodeBinEP( ( uiPosY >> i ) & 1 ); | |
1167 } | |
1168 } | |
1169 } | |
1170 | |
1171 | |
1172 Void TEncSbac::codeCoeffNxN( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID ) | |
1173 { | |
1174 TComDataCU* pcCU=rTu.getCU(); | |
1175 const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU(compID); | |
1176 const TComRectangle &tuRect=rTu.getRect(compID); | |
1177 const UInt uiWidth=tuRect.width; | |
1178 const UInt uiHeight=tuRect.height; | |
1179 | |
1180 DTRACE_CABAC_VL( g_nSymbolCounter++ ) | |
1181 DTRACE_CABAC_T( "\tparseCoeffNxN()\teType=" ) | |
1182 DTRACE_CABAC_V( compID ) | |
1183 DTRACE_CABAC_T( "\twidth=" ) | |
1184 DTRACE_CABAC_V( uiWidth ) | |
1185 DTRACE_CABAC_T( "\theight=" ) | |
1186 DTRACE_CABAC_V( uiHeight ) | |
1187 DTRACE_CABAC_T( "\tdepth=" ) | |
1188 // DTRACE_CABAC_V( rTu.GetTransformDepthTotalAdj(compID) ) | |
1189 DTRACE_CABAC_V( rTu.GetTransformDepthTotal() ) | |
1190 DTRACE_CABAC_T( "\tabspartidx=" ) | |
1191 DTRACE_CABAC_V( uiAbsPartIdx ) | |
1192 DTRACE_CABAC_T( "\ttoCU-X=" ) | |
1193 DTRACE_CABAC_V( pcCU->getCUPelX() ) | |
1194 DTRACE_CABAC_T( "\ttoCU-Y=" ) | |
1195 DTRACE_CABAC_V( pcCU->getCUPelY() ) | |
1196 DTRACE_CABAC_T( "\tCU-addr=" ) | |
1197 DTRACE_CABAC_V( pcCU->getCtuRsAddr() ) | |
1198 DTRACE_CABAC_T( "\tinCU-X=" ) | |
1199 // DTRACE_CABAC_V( g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ] ) | |
1200 DTRACE_CABAC_V( g_auiRasterToPelX[ g_auiZscanToRaster[rTu.GetAbsPartIdxTU(compID)] ] ) | |
1201 DTRACE_CABAC_T( "\tinCU-Y=" ) | |
1202 // DTRACE_CABAC_V( g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ] ) | |
1203 DTRACE_CABAC_V( g_auiRasterToPelY[ g_auiZscanToRaster[rTu.GetAbsPartIdxTU(compID)] ] ) | |
1204 DTRACE_CABAC_T( "\tpredmode=" ) | |
1205 DTRACE_CABAC_V( pcCU->getPredictionMode( uiAbsPartIdx ) ) | |
1206 DTRACE_CABAC_T( "\n" ) | |
1207 | |
1208 //-------------------------------------------------------------------------------------------------- | |
1209 | |
1210 if( uiWidth > m_pcSlice->getSPS()->getMaxTrSize() ) | |
1211 { | |
1212 std::cerr << "ERROR: codeCoeffNxN was passed a TU with dimensions larger than the maximum allowed size" << std::endl; | |
1213 assert(false); | |
1214 exit(1); | |
1215 } | |
1216 | |
1217 // compute number of significant coefficients | |
1218 UInt uiNumSig = TEncEntropy::countNonZeroCoeffs(pcCoef, uiWidth * uiHeight); | |
1219 | |
1220 if ( uiNumSig == 0 ) | |
1221 { | |
1222 std::cerr << "ERROR: codeCoeffNxN called for empty TU!" << std::endl; | |
1223 assert(false); | |
1224 exit(1); | |
1225 } | |
1226 | |
1227 //-------------------------------------------------------------------------------------------------- | |
1228 | |
1229 //set parameters | |
1230 | |
1231 const ChannelType chType = toChannelType(compID); | |
1232 const UInt uiLog2BlockWidth = g_aucConvertToBit[ uiWidth ] + 2; | |
1233 const UInt uiLog2BlockHeight = g_aucConvertToBit[ uiHeight ] + 2; | |
1234 | |
1235 const ChannelType channelType = toChannelType(compID); | |
1236 const Bool extendedPrecision = pcCU->getSlice()->getSPS()->getUseExtendedPrecision(); | |
1237 | |
1238 const Bool alignCABACBeforeBypass = pcCU->getSlice()->getSPS()->getAlignCABACBeforeBypass(); | |
1239 | |
1240 Bool beValid; | |
1241 | |
1242 { | |
1243 Int uiIntraMode = -1; | |
1244 const Bool bIsLuma = isLuma(compID); | |
1245 Int isIntra = pcCU->isIntra(uiAbsPartIdx) ? 1 : 0; | |
1246 if ( isIntra ) | |
1247 { | |
1248 uiIntraMode = pcCU->getIntraDir( toChannelType(compID), uiAbsPartIdx ); | |
1249 | |
1250 uiIntraMode = (uiIntraMode==DM_CHROMA_IDX && !bIsLuma) ? pcCU->getIntraDir(CHANNEL_TYPE_LUMA, getChromasCorrespondingPULumaIdx(uiAbsPartIdx, rTu.GetChromaFormat())) : uiIntraMode; | |
1251 uiIntraMode = ((rTu.GetChromaFormat() == CHROMA_422) && !bIsLuma) ? g_chroma422IntraAngleMappingTable[uiIntraMode] : uiIntraMode; | |
1252 } | |
1253 | |
1254 Int transformSkip = pcCU->getTransformSkip( uiAbsPartIdx,compID) ? 1 : 0; | |
1255 Bool rdpcm_lossy = ( transformSkip && isIntra && ( (uiIntraMode == HOR_IDX) || (uiIntraMode == VER_IDX) ) ) && pcCU->isRDPCMEnabled(uiAbsPartIdx); | |
1256 | |
1257 if ( (pcCU->getCUTransquantBypass(uiAbsPartIdx)) || rdpcm_lossy ) | |
1258 { | |
1259 beValid = false; | |
1260 if ( (!pcCU->isIntra(uiAbsPartIdx)) && pcCU->isRDPCMEnabled(uiAbsPartIdx)) | |
1261 codeExplicitRdpcmMode( rTu, compID); | |
1262 } | |
1263 else | |
1264 { | |
1265 beValid = pcCU->getSlice()->getPPS()->getSignHideFlag() > 0; | |
1266 } | |
1267 } | |
1268 | |
1269 //-------------------------------------------------------------------------------------------------- | |
1270 | |
1271 if(pcCU->getSlice()->getPPS()->getUseTransformSkip()) | |
1272 { | |
1273 codeTransformSkipFlags(rTu, compID); | |
1274 if(pcCU->getTransformSkip(uiAbsPartIdx, compID) && !pcCU->isIntra(uiAbsPartIdx) && pcCU->isRDPCMEnabled(uiAbsPartIdx)) | |
1275 { | |
1276 // This TU has coefficients and is transform skipped. Check whether is inter coded and if yes encode the explicit RDPCM mode | |
1277 codeExplicitRdpcmMode( rTu, compID); | |
1278 | |
1279 if(pcCU->getExplicitRdpcmMode(compID, uiAbsPartIdx) != RDPCM_OFF) | |
1280 { | |
1281 // Sign data hiding is avoided for horizontal and vertical explicit RDPCM modes | |
1282 beValid = false; | |
1283 } | |
1284 } | |
1285 } | |
1286 | |
1287 //-------------------------------------------------------------------------------------------------- | |
1288 | |
1289 const Bool bUseGolombRiceParameterAdaptation = pcCU->getSlice()->getSPS()->getUseGolombRiceParameterAdaptation(); | |
1290 UInt ¤tGolombRiceStatistic = m_golombRiceAdaptationStatistics[rTu.getGolombRiceStatisticsIndex(compID)]; | |
1291 | |
1292 //select scans | |
1293 TUEntropyCodingParameters codingParameters; | |
1294 getTUEntropyCodingParameters(codingParameters, rTu, compID); | |
1295 | |
1296 //----- encode significance map ----- | |
1297 | |
1298 // Find position of last coefficient | |
1299 Int scanPosLast = -1; | |
1300 Int posLast; | |
1301 | |
1302 | |
1303 UInt uiSigCoeffGroupFlag[ MLS_GRP_NUM ]; | |
1304 | |
1305 memset( uiSigCoeffGroupFlag, 0, sizeof(UInt) * MLS_GRP_NUM ); | |
1306 do | |
1307 { | |
1308 posLast = codingParameters.scan[ ++scanPosLast ]; | |
1309 | |
1310 if( pcCoef[ posLast ] != 0 ) | |
1311 { | |
1312 // get L1 sig map | |
1313 UInt uiPosY = posLast >> uiLog2BlockWidth; | |
1314 UInt uiPosX = posLast - ( uiPosY << uiLog2BlockWidth ); | |
1315 | |
1316 UInt uiBlkIdx = (codingParameters.widthInGroups * (uiPosY >> MLS_CG_LOG2_HEIGHT)) + (uiPosX >> MLS_CG_LOG2_WIDTH); | |
1317 uiSigCoeffGroupFlag[ uiBlkIdx ] = 1; | |
1318 | |
1319 uiNumSig--; | |
1320 } | |
1321 } | |
1322 while ( uiNumSig > 0 ); | |
1323 | |
1324 // Code position of last coefficient | |
1325 Int posLastY = posLast >> uiLog2BlockWidth; | |
1326 Int posLastX = posLast - ( posLastY << uiLog2BlockWidth ); | |
1327 codeLastSignificantXY(posLastX, posLastY, uiWidth, uiHeight, compID, codingParameters.scanType); | |
1328 | |
1329 //===== code significance flag ===== | |
1330 ContextModel * const baseCoeffGroupCtx = m_cCUSigCoeffGroupSCModel.get( 0, chType ); | |
1331 ContextModel * const baseCtx = m_cCUSigSCModel.get( 0, 0 ) + getSignificanceMapContextOffset(compID); | |
1332 | |
1333 const Int iLastScanSet = scanPosLast >> MLS_CG_SIZE; | |
1334 | |
1335 UInt c1 = 1; | |
1336 UInt uiGoRiceParam = 0; | |
1337 Int iScanPosSig = scanPosLast; | |
1338 | |
1339 for( Int iSubSet = iLastScanSet; iSubSet >= 0; iSubSet-- ) | |
1340 { | |
1341 Int numNonZero = 0; | |
1342 Int iSubPos = iSubSet << MLS_CG_SIZE; | |
1343 uiGoRiceParam = currentGolombRiceStatistic / RExt__GOLOMB_RICE_INCREMENT_DIVISOR; | |
1344 Bool updateGolombRiceStatistics = bUseGolombRiceParameterAdaptation; //leave the statistics at 0 when not using the adaptation system | |
1345 UInt coeffSigns = 0; | |
1346 | |
1347 Int absCoeff[1 << MLS_CG_SIZE]; | |
1348 | |
1349 Int lastNZPosInCG = -1; | |
1350 Int firstNZPosInCG = 1 << MLS_CG_SIZE; | |
1351 | |
1352 Bool escapeDataPresentInGroup = false; | |
1353 | |
1354 if( iScanPosSig == scanPosLast ) | |
1355 { | |
1356 absCoeff[ 0 ] = Int(abs( pcCoef[ posLast ] )); | |
1357 coeffSigns = ( pcCoef[ posLast ] < 0 ); | |
1358 numNonZero = 1; | |
1359 lastNZPosInCG = iScanPosSig; | |
1360 firstNZPosInCG = iScanPosSig; | |
1361 iScanPosSig--; | |
1362 } | |
1363 | |
1364 // encode significant_coeffgroup_flag | |
1365 Int iCGBlkPos = codingParameters.scanCG[ iSubSet ]; | |
1366 Int iCGPosY = iCGBlkPos / codingParameters.widthInGroups; | |
1367 Int iCGPosX = iCGBlkPos - (iCGPosY * codingParameters.widthInGroups); | |
1368 | |
1369 if( iSubSet == iLastScanSet || iSubSet == 0) | |
1370 { | |
1371 uiSigCoeffGroupFlag[ iCGBlkPos ] = 1; | |
1372 } | |
1373 else | |
1374 { | |
1375 UInt uiSigCoeffGroup = (uiSigCoeffGroupFlag[ iCGBlkPos ] != 0); | |
1376 UInt uiCtxSig = TComTrQuant::getSigCoeffGroupCtxInc( uiSigCoeffGroupFlag, iCGPosX, iCGPosY, codingParameters.widthInGroups, codingParameters.heightInGroups ); | |
1377 m_pcBinIf->encodeBin( uiSigCoeffGroup, baseCoeffGroupCtx[ uiCtxSig ] ); | |
1378 } | |
1379 | |
1380 // encode significant_coeff_flag | |
1381 if( uiSigCoeffGroupFlag[ iCGBlkPos ] ) | |
1382 { | |
1383 const Int patternSigCtx = TComTrQuant::calcPatternSigCtx(uiSigCoeffGroupFlag, iCGPosX, iCGPosY, codingParameters.widthInGroups, codingParameters.heightInGroups); | |
1384 | |
1385 UInt uiBlkPos, uiSig, uiCtxSig; | |
1386 for( ; iScanPosSig >= iSubPos; iScanPosSig-- ) | |
1387 { | |
1388 uiBlkPos = codingParameters.scan[ iScanPosSig ]; | |
1389 uiSig = (pcCoef[ uiBlkPos ] != 0); | |
1390 if( iScanPosSig > iSubPos || iSubSet == 0 || numNonZero ) | |
1391 { | |
1392 uiCtxSig = TComTrQuant::getSigCtxInc( patternSigCtx, codingParameters, iScanPosSig, uiLog2BlockWidth, uiLog2BlockHeight, chType ); | |
1393 m_pcBinIf->encodeBin( uiSig, baseCtx[ uiCtxSig ] ); | |
1394 } | |
1395 if( uiSig ) | |
1396 { | |
1397 absCoeff[ numNonZero ] = Int(abs( pcCoef[ uiBlkPos ] )); | |
1398 coeffSigns = 2 * coeffSigns + ( pcCoef[ uiBlkPos ] < 0 ); | |
1399 numNonZero++; | |
1400 if( lastNZPosInCG == -1 ) | |
1401 { | |
1402 lastNZPosInCG = iScanPosSig; | |
1403 } | |
1404 firstNZPosInCG = iScanPosSig; | |
1405 } | |
1406 } | |
1407 } | |
1408 else | |
1409 { | |
1410 iScanPosSig = iSubPos - 1; | |
1411 } | |
1412 | |
1413 if( numNonZero > 0 ) | |
1414 { | |
1415 Bool signHidden = ( lastNZPosInCG - firstNZPosInCG >= SBH_THRESHOLD ); | |
1416 | |
1417 const UInt uiCtxSet = getContextSetIndex(compID, iSubSet, (c1 == 0)); | |
1418 c1 = 1; | |
1419 | |
1420 ContextModel *baseCtxMod = m_cCUOneSCModel.get( 0, 0 ) + (NUM_ONE_FLAG_CTX_PER_SET * uiCtxSet); | |
1421 | |
1422 Int numC1Flag = min(numNonZero, C1FLAG_NUMBER); | |
1423 Int firstC2FlagIdx = -1; | |
1424 for( Int idx = 0; idx < numC1Flag; idx++ ) | |
1425 { | |
1426 UInt uiSymbol = absCoeff[ idx ] > 1; | |
1427 m_pcBinIf->encodeBin( uiSymbol, baseCtxMod[c1] ); | |
1428 if( uiSymbol ) | |
1429 { | |
1430 c1 = 0; | |
1431 | |
1432 if (firstC2FlagIdx == -1) | |
1433 { | |
1434 firstC2FlagIdx = idx; | |
1435 } | |
1436 else //if a greater-than-one has been encountered already this group | |
1437 { | |
1438 escapeDataPresentInGroup = true; | |
1439 } | |
1440 } | |
1441 else if( (c1 < 3) && (c1 > 0) ) | |
1442 { | |
1443 c1++; | |
1444 } | |
1445 } | |
1446 | |
1447 if (c1 == 0) | |
1448 { | |
1449 baseCtxMod = m_cCUAbsSCModel.get( 0, 0 ) + (NUM_ABS_FLAG_CTX_PER_SET * uiCtxSet); | |
1450 if ( firstC2FlagIdx != -1) | |
1451 { | |
1452 UInt symbol = absCoeff[ firstC2FlagIdx ] > 2; | |
1453 m_pcBinIf->encodeBin( symbol, baseCtxMod[0] ); | |
1454 if (symbol != 0) | |
1455 { | |
1456 escapeDataPresentInGroup = true; | |
1457 } | |
1458 } | |
1459 } | |
1460 | |
1461 escapeDataPresentInGroup = escapeDataPresentInGroup || (numNonZero > C1FLAG_NUMBER); | |
1462 | |
1463 if (escapeDataPresentInGroup && alignCABACBeforeBypass) | |
1464 { | |
1465 m_pcBinIf->align(); | |
1466 } | |
1467 | |
1468 if( beValid && signHidden ) | |
1469 { | |
1470 m_pcBinIf->encodeBinsEP( (coeffSigns >> 1), numNonZero-1 ); | |
1471 } | |
1472 else | |
1473 { | |
1474 m_pcBinIf->encodeBinsEP( coeffSigns, numNonZero ); | |
1475 } | |
1476 | |
1477 Int iFirstCoeff2 = 1; | |
1478 if (escapeDataPresentInGroup) | |
1479 { | |
1480 for ( Int idx = 0; idx < numNonZero; idx++ ) | |
1481 { | |
1482 UInt baseLevel = (idx < C1FLAG_NUMBER)? (2 + iFirstCoeff2 ) : 1; | |
1483 | |
1484 if( absCoeff[ idx ] >= baseLevel) | |
1485 { | |
1486 const UInt escapeCodeValue = absCoeff[idx] - baseLevel; | |
1487 | |
1488 xWriteCoefRemainExGolomb( escapeCodeValue, uiGoRiceParam, extendedPrecision, channelType ); | |
1489 | |
1490 if (absCoeff[idx] > (3 << uiGoRiceParam)) | |
1491 { | |
1492 uiGoRiceParam = bUseGolombRiceParameterAdaptation ? (uiGoRiceParam + 1) : (std::min<UInt>((uiGoRiceParam + 1), 4)); | |
1493 } | |
1494 | |
1495 if (updateGolombRiceStatistics) | |
1496 { | |
1497 const UInt initialGolombRiceParameter = currentGolombRiceStatistic / RExt__GOLOMB_RICE_INCREMENT_DIVISOR; | |
1498 | |
1499 if (escapeCodeValue >= (3 << initialGolombRiceParameter)) | |
1500 { | |
1501 currentGolombRiceStatistic++; | |
1502 } | |
1503 else if (((escapeCodeValue * 2) < (1 << initialGolombRiceParameter)) && (currentGolombRiceStatistic > 0)) | |
1504 { | |
1505 currentGolombRiceStatistic--; | |
1506 } | |
1507 | |
1508 updateGolombRiceStatistics = false; | |
1509 } | |
1510 } | |
1511 | |
1512 if(absCoeff[ idx ] >= 2) | |
1513 { | |
1514 iFirstCoeff2 = 0; | |
1515 } | |
1516 } | |
1517 } | |
1518 } | |
1519 } | |
1520 #if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST | |
1521 printSBACCoeffData(posLastX, posLastY, uiWidth, uiHeight, compID, uiAbsPartIdx, codingParameters.scanType, pcCoef, g_bFinalEncode); | |
1522 #endif | |
1523 | |
1524 return; | |
1525 } | |
1526 | |
1527 /** code SAO offset sign | |
1528 * \param code sign value | |
1529 */ | |
1530 Void TEncSbac::codeSAOSign( UInt code ) | |
1531 { | |
1532 m_pcBinIf->encodeBinEP( code ); | |
1533 } | |
1534 | |
1535 Void TEncSbac::codeSaoMaxUvlc ( UInt code, UInt maxSymbol ) | |
1536 { | |
1537 if (maxSymbol == 0) | |
1538 { | |
1539 return; | |
1540 } | |
1541 | |
1542 Int i; | |
1543 Bool bCodeLast = ( maxSymbol > code ); | |
1544 | |
1545 if ( code == 0 ) | |
1546 { | |
1547 m_pcBinIf->encodeBinEP( 0 ); | |
1548 } | |
1549 else | |
1550 { | |
1551 m_pcBinIf->encodeBinEP( 1 ); | |
1552 for ( i=0; i<code-1; i++ ) | |
1553 { | |
1554 m_pcBinIf->encodeBinEP( 1 ); | |
1555 } | |
1556 if( bCodeLast ) | |
1557 { | |
1558 m_pcBinIf->encodeBinEP( 0 ); | |
1559 } | |
1560 } | |
1561 } | |
1562 | |
1563 /** Code SAO EO class or BO band position | |
1564 * \param uiLength | |
1565 * \param uiCode | |
1566 */ | |
1567 Void TEncSbac::codeSaoUflc ( UInt uiLength, UInt uiCode ) | |
1568 { | |
1569 m_pcBinIf->encodeBinsEP ( uiCode, uiLength ); | |
1570 } | |
1571 | |
1572 /** Code SAO merge flags | |
1573 * \param uiCode | |
1574 * \param uiCompIdx | |
1575 */ | |
1576 Void TEncSbac::codeSaoMerge ( UInt uiCode ) | |
1577 { | |
1578 m_pcBinIf->encodeBin(((uiCode == 0) ? 0 : 1), m_cSaoMergeSCModel.get( 0, 0, 0 )); | |
1579 } | |
1580 | |
1581 /** Code SAO type index | |
1582 * \param uiCode | |
1583 */ | |
1584 Void TEncSbac::codeSaoTypeIdx ( UInt uiCode) | |
1585 { | |
1586 if (uiCode == 0) | |
1587 { | |
1588 m_pcBinIf->encodeBin( 0, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) ); | |
1589 } | |
1590 else | |
1591 { | |
1592 m_pcBinIf->encodeBin( 1, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) ); | |
1593 m_pcBinIf->encodeBinEP( uiCode == 1 ? 0 : 1 ); | |
1594 } | |
1595 } | |
1596 | |
1597 Void TEncSbac::codeSAOOffsetParam(ComponentID compIdx, SAOOffset& ctbParam, Bool sliceEnabled) | |
1598 { | |
1599 UInt uiSymbol; | |
1600 if(!sliceEnabled) | |
1601 { | |
1602 assert(ctbParam.modeIdc == SAO_MODE_OFF); | |
1603 return; | |
1604 } | |
1605 const Bool bIsFirstCompOfChType = (getFirstComponentOfChannel(toChannelType(compIdx)) == compIdx); | |
1606 | |
1607 //type | |
1608 if(bIsFirstCompOfChType) | |
1609 { | |
1610 //sao_type_idx_luma or sao_type_idx_chroma | |
1611 if(ctbParam.modeIdc == SAO_MODE_OFF) | |
1612 { | |
1613 uiSymbol =0; | |
1614 } | |
1615 else if(ctbParam.typeIdc == SAO_TYPE_BO) //BO | |
1616 { | |
1617 uiSymbol = 1; | |
1618 } | |
1619 else | |
1620 { | |
1621 assert(ctbParam.typeIdc < SAO_TYPE_START_BO); //EO | |
1622 uiSymbol = 2; | |
1623 } | |
1624 codeSaoTypeIdx(uiSymbol); | |
1625 } | |
1626 | |
1627 if(ctbParam.modeIdc == SAO_MODE_NEW) | |
1628 { | |
1629 Int numClasses = (ctbParam.typeIdc == SAO_TYPE_BO)?4:NUM_SAO_EO_CLASSES; | |
1630 Int offset[4]; | |
1631 Int k=0; | |
1632 for(Int i=0; i< numClasses; i++) | |
1633 { | |
1634 if(ctbParam.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN) | |
1635 { | |
1636 continue; | |
1637 } | |
1638 Int classIdx = (ctbParam.typeIdc == SAO_TYPE_BO)?( (ctbParam.typeAuxInfo+i)% NUM_SAO_BO_CLASSES ):i; | |
1639 offset[k] = ctbParam.offset[classIdx]; | |
1640 k++; | |
1641 } | |
1642 | |
1643 for(Int i=0; i< 4; i++) | |
1644 { | |
1645 codeSaoMaxUvlc((offset[i]<0)?(-offset[i]):(offset[i]), g_saoMaxOffsetQVal[compIdx] ); //sao_offset_abs | |
1646 } | |
1647 | |
1648 | |
1649 if(ctbParam.typeIdc == SAO_TYPE_BO) | |
1650 { | |
1651 for(Int i=0; i< 4; i++) | |
1652 { | |
1653 if(offset[i] != 0) | |
1654 { | |
1655 codeSAOSign((offset[i]< 0)?1:0); | |
1656 } | |
1657 } | |
1658 | |
1659 codeSaoUflc(NUM_SAO_BO_CLASSES_LOG2, ctbParam.typeAuxInfo ); //sao_band_position | |
1660 } | |
1661 else //EO | |
1662 { | |
1663 if(bIsFirstCompOfChType) | |
1664 { | |
1665 assert(ctbParam.typeIdc - SAO_TYPE_START_EO >=0); | |
1666 codeSaoUflc(NUM_SAO_EO_TYPES_LOG2, ctbParam.typeIdc - SAO_TYPE_START_EO ); //sao_eo_class_luma or sao_eo_class_chroma | |
1667 } | |
1668 } | |
1669 | |
1670 } | |
1671 } | |
1672 | |
1673 | |
1674 Void TEncSbac::codeSAOBlkParam(SAOBlkParam& saoBlkParam | |
1675 , Bool* sliceEnabled | |
1676 , Bool leftMergeAvail | |
1677 , Bool aboveMergeAvail | |
1678 , Bool onlyEstMergeInfo // = false | |
1679 ) | |
1680 { | |
1681 | |
1682 Bool isLeftMerge = false; | |
1683 Bool isAboveMerge= false; | |
1684 | |
1685 if(leftMergeAvail) | |
1686 { | |
1687 isLeftMerge = ((saoBlkParam[COMPONENT_Y].modeIdc == SAO_MODE_MERGE) && (saoBlkParam[COMPONENT_Y].typeIdc == SAO_MERGE_LEFT)); | |
1688 codeSaoMerge( isLeftMerge?1:0 ); //sao_merge_left_flag | |
1689 } | |
1690 | |
1691 if( aboveMergeAvail && !isLeftMerge) | |
1692 { | |
1693 isAboveMerge = ((saoBlkParam[COMPONENT_Y].modeIdc == SAO_MODE_MERGE) && (saoBlkParam[COMPONENT_Y].typeIdc == SAO_MERGE_ABOVE)); | |
1694 codeSaoMerge( isAboveMerge?1:0 ); //sao_merge_left_flag | |
1695 } | |
1696 | |
1697 if(onlyEstMergeInfo) | |
1698 { | |
1699 return; //only for RDO | |
1700 } | |
1701 | |
1702 if(!isLeftMerge && !isAboveMerge) //not merge mode | |
1703 { | |
1704 for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++) | |
1705 { | |
1706 codeSAOOffsetParam(ComponentID(compIdx), saoBlkParam[compIdx], sliceEnabled[compIdx]); | |
1707 } | |
1708 } | |
1709 } | |
1710 | |
1711 /*! | |
1712 **************************************************************************** | |
1713 * \brief | |
1714 * estimate bit cost for CBP, significant map and significant coefficients | |
1715 **************************************************************************** | |
1716 */ | |
1717 Void TEncSbac::estBit( estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, ChannelType chType ) | |
1718 { | |
1719 estCBFBit( pcEstBitsSbac ); | |
1720 | |
1721 estSignificantCoeffGroupMapBit( pcEstBitsSbac, chType ); | |
1722 | |
1723 // encode significance map | |
1724 estSignificantMapBit( pcEstBitsSbac, width, height, chType ); | |
1725 | |
1726 // encode last significant position | |
1727 estLastSignificantPositionBit( pcEstBitsSbac, width, height, chType ); | |
1728 | |
1729 // encode significant coefficients | |
1730 estSignificantCoefficientsBit( pcEstBitsSbac, chType ); | |
1731 | |
1732 memcpy(pcEstBitsSbac->golombRiceAdaptationStatistics, m_golombRiceAdaptationStatistics, (sizeof(UInt) * RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS)); | |
1733 } | |
1734 | |
1735 /*! | |
1736 **************************************************************************** | |
1737 * \brief | |
1738 * estimate bit cost for each CBP bit | |
1739 **************************************************************************** | |
1740 */ | |
1741 Void TEncSbac::estCBFBit( estBitsSbacStruct* pcEstBitsSbac ) | |
1742 { | |
1743 ContextModel *pCtx = m_cCUQtCbfSCModel.get( 0 ); | |
1744 | |
1745 for( UInt uiCtxInc = 0; uiCtxInc < (NUM_QT_CBF_CTX_SETS * NUM_QT_CBF_CTX_PER_SET); uiCtxInc++ ) | |
1746 { | |
1747 pcEstBitsSbac->blockCbpBits[ uiCtxInc ][ 0 ] = pCtx[ uiCtxInc ].getEntropyBits( 0 ); | |
1748 pcEstBitsSbac->blockCbpBits[ uiCtxInc ][ 1 ] = pCtx[ uiCtxInc ].getEntropyBits( 1 ); | |
1749 } | |
1750 | |
1751 pCtx = m_cCUQtRootCbfSCModel.get( 0 ); | |
1752 | |
1753 for( UInt uiCtxInc = 0; uiCtxInc < 4; uiCtxInc++ ) | |
1754 { | |
1755 pcEstBitsSbac->blockRootCbpBits[ uiCtxInc ][ 0 ] = pCtx[ uiCtxInc ].getEntropyBits( 0 ); | |
1756 pcEstBitsSbac->blockRootCbpBits[ uiCtxInc ][ 1 ] = pCtx[ uiCtxInc ].getEntropyBits( 1 ); | |
1757 } | |
1758 } | |
1759 | |
1760 | |
1761 /*! | |
1762 **************************************************************************** | |
1763 * \brief | |
1764 * estimate SAMBAC bit cost for significant coefficient group map | |
1765 **************************************************************************** | |
1766 */ | |
1767 Void TEncSbac::estSignificantCoeffGroupMapBit( estBitsSbacStruct* pcEstBitsSbac, ChannelType chType ) | |
1768 { | |
1769 Int firstCtx = 0, numCtx = NUM_SIG_CG_FLAG_CTX; | |
1770 | |
1771 for ( Int ctxIdx = firstCtx; ctxIdx < firstCtx + numCtx; ctxIdx++ ) | |
1772 { | |
1773 for( UInt uiBin = 0; uiBin < 2; uiBin++ ) | |
1774 { | |
1775 pcEstBitsSbac->significantCoeffGroupBits[ ctxIdx ][ uiBin ] = m_cCUSigCoeffGroupSCModel.get( 0, chType, ctxIdx ).getEntropyBits( uiBin ); | |
1776 } | |
1777 } | |
1778 } | |
1779 | |
1780 | |
1781 /*! | |
1782 **************************************************************************** | |
1783 * \brief | |
1784 * estimate SAMBAC bit cost for significant coefficient map | |
1785 **************************************************************************** | |
1786 */ | |
1787 Void TEncSbac::estSignificantMapBit( estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, ChannelType chType ) | |
1788 { | |
1789 //-------------------------------------------------------------------------------------------------- | |
1790 | |
1791 //set up the number of channels and context variables | |
1792 | |
1793 const UInt firstComponent = ((isLuma(chType)) ? (COMPONENT_Y) : (COMPONENT_Cb)); | |
1794 const UInt lastComponent = ((isLuma(chType)) ? (COMPONENT_Y) : (COMPONENT_Cb)); | |
1795 | |
1796 //---------------------------------------------------------- | |
1797 | |
1798 Int firstCtx = MAX_INT; | |
1799 Int numCtx = MAX_INT; | |
1800 | |
1801 if ((width == 4) && (height == 4)) | |
1802 { | |
1803 firstCtx = significanceMapContextSetStart[chType][CONTEXT_TYPE_4x4]; | |
1804 numCtx = significanceMapContextSetSize [chType][CONTEXT_TYPE_4x4]; | |
1805 } | |
1806 else if ((width == 8) && (height == 8)) | |
1807 { | |
1808 firstCtx = significanceMapContextSetStart[chType][CONTEXT_TYPE_8x8]; | |
1809 numCtx = significanceMapContextSetSize [chType][CONTEXT_TYPE_8x8]; | |
1810 } | |
1811 else | |
1812 { | |
1813 firstCtx = significanceMapContextSetStart[chType][CONTEXT_TYPE_NxN]; | |
1814 numCtx = significanceMapContextSetSize [chType][CONTEXT_TYPE_NxN]; | |
1815 } | |
1816 | |
1817 //-------------------------------------------------------------------------------------------------- | |
1818 | |
1819 //fill the data for the significace map | |
1820 | |
1821 for (UInt component = firstComponent; component <= lastComponent; component++) | |
1822 { | |
1823 const UInt contextOffset = getSignificanceMapContextOffset(ComponentID(component)); | |
1824 | |
1825 if (firstCtx > 0) | |
1826 { | |
1827 for( UInt bin = 0; bin < 2; bin++ ) //always get the DC | |
1828 { | |
1829 pcEstBitsSbac->significantBits[ contextOffset ][ bin ] = m_cCUSigSCModel.get( 0, 0, contextOffset ).getEntropyBits( bin ); | |
1830 } | |
1831 } | |
1832 | |
1833 // This could be made optional, but would require this function to have knowledge of whether the | |
1834 // TU is transform-skipped or transquant-bypassed and whether the SPS flag is set | |
1835 for( UInt bin = 0; bin < 2; bin++ ) | |
1836 { | |
1837 const Int ctxIdx = significanceMapContextSetStart[chType][CONTEXT_TYPE_SINGLE]; | |
1838 pcEstBitsSbac->significantBits[ contextOffset + ctxIdx ][ bin ] = m_cCUSigSCModel.get( 0, 0, (contextOffset + ctxIdx) ).getEntropyBits( bin ); | |
1839 } | |
1840 | |
1841 for ( Int ctxIdx = firstCtx; ctxIdx < firstCtx + numCtx; ctxIdx++ ) | |
1842 { | |
1843 for( UInt uiBin = 0; uiBin < 2; uiBin++ ) | |
1844 { | |
1845 pcEstBitsSbac->significantBits[ contextOffset + ctxIdx ][ uiBin ] = m_cCUSigSCModel.get( 0, 0, (contextOffset + ctxIdx) ).getEntropyBits( uiBin ); | |
1846 } | |
1847 } | |
1848 } | |
1849 | |
1850 //-------------------------------------------------------------------------------------------------- | |
1851 } | |
1852 | |
1853 | |
1854 /*! | |
1855 **************************************************************************** | |
1856 * \brief | |
1857 * estimate bit cost of significant coefficient | |
1858 **************************************************************************** | |
1859 */ | |
1860 | |
1861 Void TEncSbac::estLastSignificantPositionBit( estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, ChannelType chType ) | |
1862 { | |
1863 //--------------------------------------------------------------------------------------------------. | |
1864 | |
1865 //set up the number of channels | |
1866 | |
1867 const UInt firstComponent = ((isLuma(chType)) ? (COMPONENT_Y) : (COMPONENT_Cb)); | |
1868 const UInt lastComponent = ((isLuma(chType)) ? (COMPONENT_Y) : (COMPONENT_Cb)); | |
1869 | |
1870 //-------------------------------------------------------------------------------------------------- | |
1871 | |
1872 //fill the data for the last-significant-coefficient position | |
1873 | |
1874 for (UInt componentIndex = firstComponent; componentIndex <= lastComponent; componentIndex++) | |
1875 { | |
1876 const ComponentID component = ComponentID(componentIndex); | |
1877 | |
1878 Int iBitsX = 0, iBitsY = 0; | |
1879 | |
1880 Int blkSizeOffsetX, blkSizeOffsetY, shiftX, shiftY; | |
1881 getLastSignificantContextParameters(ComponentID(component), width, height, blkSizeOffsetX, blkSizeOffsetY, shiftX, shiftY); | |
1882 | |
1883 Int ctx; | |
1884 | |
1885 const ChannelType channelType = toChannelType(ComponentID(component)); | |
1886 | |
1887 ContextModel *const pCtxX = m_cCuCtxLastX.get( 0, channelType ); | |
1888 ContextModel *const pCtxY = m_cCuCtxLastY.get( 0, channelType ); | |
1889 Int *const lastXBitsArray = pcEstBitsSbac->lastXBits[channelType]; | |
1890 Int *const lastYBitsArray = pcEstBitsSbac->lastYBits[channelType]; | |
1891 | |
1892 //------------------------------------------------ | |
1893 | |
1894 //X-coordinate | |
1895 | |
1896 for (ctx = 0; ctx < g_uiGroupIdx[ width - 1 ]; ctx++) | |
1897 { | |
1898 Int ctxOffset = blkSizeOffsetX + (ctx >>shiftX); | |
1899 lastXBitsArray[ ctx ] = iBitsX + pCtxX[ ctxOffset ].getEntropyBits( 0 ); | |
1900 iBitsX += pCtxX[ ctxOffset ].getEntropyBits( 1 ); | |
1901 } | |
1902 | |
1903 lastXBitsArray[ctx] = iBitsX; | |
1904 | |
1905 //------------------------------------------------ | |
1906 | |
1907 //Y-coordinate | |
1908 | |
1909 for (ctx = 0; ctx < g_uiGroupIdx[ height - 1 ]; ctx++) | |
1910 { | |
1911 Int ctxOffset = blkSizeOffsetY + (ctx >>shiftY); | |
1912 lastYBitsArray[ ctx ] = iBitsY + pCtxY[ ctxOffset ].getEntropyBits( 0 ); | |
1913 iBitsY += pCtxY[ ctxOffset ].getEntropyBits( 1 ); | |
1914 } | |
1915 | |
1916 lastYBitsArray[ctx] = iBitsY; | |
1917 | |
1918 } //end of component loop | |
1919 | |
1920 //-------------------------------------------------------------------------------------------------- | |
1921 } | |
1922 | |
1923 | |
1924 /*! | |
1925 **************************************************************************** | |
1926 * \brief | |
1927 * estimate bit cost of significant coefficient | |
1928 **************************************************************************** | |
1929 */ | |
1930 Void TEncSbac::estSignificantCoefficientsBit( estBitsSbacStruct* pcEstBitsSbac, ChannelType chType ) | |
1931 { | |
1932 ContextModel *ctxOne = m_cCUOneSCModel.get(0, 0); | |
1933 ContextModel *ctxAbs = m_cCUAbsSCModel.get(0, 0); | |
1934 | |
1935 const UInt oneStartIndex = ((isLuma(chType)) ? (0) : (NUM_ONE_FLAG_CTX_LUMA)); | |
1936 const UInt oneStopIndex = ((isLuma(chType)) ? (NUM_ONE_FLAG_CTX_LUMA) : (NUM_ONE_FLAG_CTX)); | |
1937 const UInt absStartIndex = ((isLuma(chType)) ? (0) : (NUM_ABS_FLAG_CTX_LUMA)); | |
1938 const UInt absStopIndex = ((isLuma(chType)) ? (NUM_ABS_FLAG_CTX_LUMA) : (NUM_ABS_FLAG_CTX)); | |
1939 | |
1940 for (Int ctxIdx = oneStartIndex; ctxIdx < oneStopIndex; ctxIdx++) | |
1941 { | |
1942 pcEstBitsSbac->m_greaterOneBits[ ctxIdx ][ 0 ] = ctxOne[ ctxIdx ].getEntropyBits( 0 ); | |
1943 pcEstBitsSbac->m_greaterOneBits[ ctxIdx ][ 1 ] = ctxOne[ ctxIdx ].getEntropyBits( 1 ); | |
1944 } | |
1945 | |
1946 for (Int ctxIdx = absStartIndex; ctxIdx < absStopIndex; ctxIdx++) | |
1947 { | |
1948 pcEstBitsSbac->m_levelAbsBits[ ctxIdx ][ 0 ] = ctxAbs[ ctxIdx ].getEntropyBits( 0 ); | |
1949 pcEstBitsSbac->m_levelAbsBits[ ctxIdx ][ 1 ] = ctxAbs[ ctxIdx ].getEntropyBits( 1 ); | |
1950 } | |
1951 } | |
1952 | |
1953 /** | |
1954 - Initialize our context information from the nominated source. | |
1955 . | |
1956 \param pSrc From where to copy context information. | |
1957 */ | |
1958 Void TEncSbac::xCopyContextsFrom( const TEncSbac* pSrc ) | |
1959 { | |
1960 memcpy(m_contextModels, pSrc->m_contextModels, m_numContextModels*sizeof(m_contextModels[0])); | |
1961 memcpy(m_golombRiceAdaptationStatistics, pSrc->m_golombRiceAdaptationStatistics, (sizeof(UInt) * RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS)); | |
1962 } | |
1963 | |
1964 Void TEncSbac::loadContexts ( const TEncSbac* pSrc) | |
1965 { | |
1966 xCopyContextsFrom(pSrc); | |
1967 } | |
1968 | |
1969 /** Performs CABAC encoding of the explicit RDPCM mode | |
1970 * \param rTu current TU data structure | |
1971 * \param compID component identifier | |
1972 */ | |
1973 Void TEncSbac::codeExplicitRdpcmMode( TComTU &rTu, const ComponentID compID ) | |
1974 { | |
1975 TComDataCU *cu = rTu.getCU(); | |
1976 const TComRectangle &rect = rTu.getRect(compID); | |
1977 const UInt absPartIdx = rTu.GetAbsPartIdxTU(compID); | |
1978 const UInt tuHeight = g_aucConvertToBit[rect.height]; | |
1979 const UInt tuWidth = g_aucConvertToBit[rect.width]; | |
1980 | |
1981 assert(tuHeight == tuWidth); | |
1982 assert(tuHeight < 4); | |
1983 | |
1984 UInt explicitRdpcmMode = cu->getExplicitRdpcmMode(compID, absPartIdx); | |
1985 | |
1986 if( explicitRdpcmMode == RDPCM_OFF ) | |
1987 { | |
1988 m_pcBinIf->encodeBin (0, m_explicitRdpcmFlagSCModel.get (0, toChannelType(compID), 0)); | |
1989 } | |
1990 else if( explicitRdpcmMode == RDPCM_HOR || explicitRdpcmMode == RDPCM_VER ) | |
1991 { | |
1992 m_pcBinIf->encodeBin (1, m_explicitRdpcmFlagSCModel.get (0, toChannelType(compID), 0)); | |
1993 if(explicitRdpcmMode == RDPCM_HOR) | |
1994 { | |
1995 m_pcBinIf->encodeBin ( 0, m_explicitRdpcmDirSCModel.get(0, toChannelType(compID), 0)); | |
1996 } | |
1997 else | |
1998 { | |
1999 m_pcBinIf->encodeBin ( 1, m_explicitRdpcmDirSCModel.get(0, toChannelType(compID), 0)); | |
2000 } | |
2001 } | |
2002 else | |
2003 { | |
2004 assert(0); | |
2005 } | |
2006 } | |
2007 | |
2008 //! \} |