Changeset 56 in 3DVCSoftware for trunk/source/Lib/TLibEncoder/TEncBinCoderCABAC.cpp
- Timestamp:
- 11 May 2012, 21:20:17 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/Lib/TLibEncoder/TEncBinCoderCABAC.cpp
r5 r56 2 2 * License, included below. This software may be subject to other third party 3 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 5 * 6 * Copyright (c) 2010-201 1,ISO/IEC4 * granted under this license. 5 * 6 * Copyright (c) 2010-2012, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 15 15 * this list of conditions and the following disclaimer in the documentation 16 16 * and/or other materials provided with the distribution. 17 * * Neither the name of the I SO/IEC nor the names of its contributors may17 * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may 18 18 * be used to endorse or promote products derived from this software without 19 19 * specific prior written permission. … … 32 32 */ 33 33 34 35 36 34 /** \file TEncBinCoderCABAC.cpp 37 35 \brief binary entropy encoder of CABAC … … 39 37 40 38 #include "TEncBinCoderCABAC.h" 39 #include "TLibCommon/TComRom.h" 40 41 42 //! \ingroup TLibEncoder 43 //! \{ 41 44 42 45 43 46 TEncBinCABAC::TEncBinCABAC() 44 47 : m_pcTComBitIf( 0 ) 45 , m_bBinCountingEnabled(0) 48 , m_binCountIncrement( 0 ) 49 #if FAST_BIT_EST 50 , m_fracBits( 0 ) 51 #endif 46 52 { 47 53 } … … 51 57 } 52 58 53 Void 54 TEncBinCABAC::init( TComBitIf* pcTComBitIf ) 59 Void TEncBinCABAC::init( TComBitIf* pcTComBitIf ) 55 60 { 56 61 m_pcTComBitIf = pcTComBitIf; 57 62 } 58 63 59 Void 60 TEncBinCABAC::uninit() 64 Void TEncBinCABAC::uninit() 61 65 { 62 66 m_pcTComBitIf = 0; 63 67 } 64 68 65 Void 66 TEncBinCABAC::start() 67 { 68 m_uiLow = 0; 69 m_uiRange = 510; 70 m_uiBitsToFollow = 0; 71 m_uiByte = 0; 72 m_uiBitsLeft = 9; 73 } 74 75 Void 76 TEncBinCABAC::finish() 77 { 78 xWriteBitAndBitsToFollow( ( m_uiLow >> 9 ) & 1 ); 79 xWriteBit ( ( m_uiLow >> 8 ) & 1 ); 80 // xWriteBit ( 1 ); // stop bit, already written in TEncGOP::compressGOP 81 if( 8 - m_uiBitsLeft != 0 ) 82 { 83 m_pcTComBitIf->write ( m_uiByte, 8 - m_uiBitsLeft ); 84 } 85 } 86 87 Void 88 TEncBinCABAC::copyState( TEncBinIf* pcTEncBinIf ) 69 Void TEncBinCABAC::start() 70 { 71 m_uiLow = 0; 72 m_uiRange = 510; 73 m_bitsLeft = 23; 74 m_numBufferedBytes = 0; 75 m_bufferedByte = 0xff; 76 } 77 78 Void TEncBinCABAC::finish() 79 { 80 if ( m_uiLow >> ( 32 - m_bitsLeft ) ) 81 { 82 //assert( m_numBufferedBytes > 0 ); 83 //assert( m_bufferedByte != 0xff ); 84 m_pcTComBitIf->write( m_bufferedByte + 1, 8 ); 85 while ( m_numBufferedBytes > 1 ) 86 { 87 m_pcTComBitIf->write( 0x00, 8 ); 88 m_numBufferedBytes--; 89 } 90 m_uiLow -= 1 << ( 32 - m_bitsLeft ); 91 } 92 else 93 { 94 if ( m_numBufferedBytes > 0 ) 95 { 96 m_pcTComBitIf->write( m_bufferedByte, 8 ); 97 } 98 while ( m_numBufferedBytes > 1 ) 99 { 100 m_pcTComBitIf->write( 0xff, 8 ); 101 m_numBufferedBytes--; 102 } 103 } 104 m_pcTComBitIf->write( m_uiLow >> 8, 24 - m_bitsLeft ); 105 } 106 107 #if OL_FLUSH 108 Void TEncBinCABAC::flush() 109 { 110 encodeBinTrm(1); 111 finish(); 112 m_pcTComBitIf->write(1, 1); 113 #if OL_FLUSH_ALIGN 114 m_pcTComBitIf->writeAlignZero(); 115 #endif 116 117 start(); 118 } 119 #endif 120 121 /** Reset BAC register and counter values. 122 * \returns Void 123 */ 124 Void TEncBinCABAC::resetBac() 125 { 126 start(); 127 } 128 129 #if BURST_IPCM 130 /** Encode # of subsequent IPCM blocks. 131 * \param numSubseqIPCM 132 * \returns Void 133 */ 134 Void TEncBinCABAC::encodeNumSubseqIPCM( Int numSubseqIPCM ) 135 { 136 finish(); 137 m_pcTComBitIf->write( 1, 1 ); // stop bit 138 139 m_pcTComBitIf->write( numSubseqIPCM ? 1 : 0, 1); 140 141 if ( numSubseqIPCM > 0) 142 { 143 Bool bCodeLast = ( 3 > numSubseqIPCM ); 144 145 while( --numSubseqIPCM ) 146 { 147 m_pcTComBitIf->write( 1, 1 ); 148 } 149 if( bCodeLast ) 150 { 151 m_pcTComBitIf->write( 0, 1 ); 152 } 153 } 154 } 155 #endif 156 157 /** Encode PCM alignment zero bits. 158 * \returns Void 159 */ 160 Void TEncBinCABAC::encodePCMAlignBits() 161 { 162 #if !BURST_IPCM 163 finish(); 164 m_pcTComBitIf->write( 1, 1 ); // stop bit 165 #endif 166 m_pcTComBitIf->writeAlignZero(); // pcm align zero 167 } 168 169 /** Write a PCM code. 170 * \param uiCode code value 171 * \param uiLength code bit-depth 172 * \returns Void 173 */ 174 Void TEncBinCABAC::xWritePCMCode(UInt uiCode, UInt uiLength) 175 { 176 m_pcTComBitIf->write(uiCode, uiLength); 177 } 178 179 Void TEncBinCABAC::copyState( TEncBinIf* pcTEncBinIf ) 89 180 { 90 181 TEncBinCABAC* pcTEncBinCABAC = pcTEncBinIf->getTEncBinCABAC(); 91 182 m_uiLow = pcTEncBinCABAC->m_uiLow; 92 183 m_uiRange = pcTEncBinCABAC->m_uiRange; 93 m_uiBitsToFollow = pcTEncBinCABAC->m_uiBitsToFollow; 94 m_uiByte = pcTEncBinCABAC->m_uiByte; 95 m_uiBitsLeft = pcTEncBinCABAC->m_uiBitsLeft; 96 } 97 98 Void 99 TEncBinCABAC::resetBits() 100 { 101 m_uiLow &= 255; 102 m_uiBitsToFollow = 0; 103 m_uiByte = 0; 104 m_uiBitsLeft = 9; 105 } 106 107 UInt 108 TEncBinCABAC::getNumWrittenBits() 109 { 110 return m_pcTComBitIf->getNumberOfWrittenBits() + 8 + m_uiBitsToFollow - m_uiBitsLeft + 1; 111 } 112 113 Void 114 TEncBinCABAC::encodeBin( UInt uiBin, ContextModel &rcCtxModel ) 115 { 116 { 117 DTRACE_CABAC_V( g_nSymbolCounter++ ) 184 m_bitsLeft = pcTEncBinCABAC->m_bitsLeft; 185 m_bufferedByte = pcTEncBinCABAC->m_bufferedByte; 186 m_numBufferedBytes = pcTEncBinCABAC->m_numBufferedBytes; 187 #if FAST_BIT_EST 188 m_fracBits = pcTEncBinCABAC->m_fracBits; 189 #endif 190 } 191 192 Void TEncBinCABAC::resetBits() 193 { 194 m_uiLow = 0; 195 m_bitsLeft = 23; 196 m_numBufferedBytes = 0; 197 m_bufferedByte = 0xff; 198 if ( m_binCountIncrement ) 199 { 200 m_uiBinsCoded = 0; 201 } 202 #if FAST_BIT_EST 203 m_fracBits &= 32767; 204 #endif 205 } 206 207 UInt TEncBinCABAC::getNumWrittenBits() 208 { 209 return m_pcTComBitIf->getNumberOfWrittenBits() + 8 * m_numBufferedBytes + 23 - m_bitsLeft; 210 } 211 212 /** 213 * \brief Encode bin 214 * 215 * \param binValue bin value 216 * \param rcCtxModel context model 217 */ 218 Void TEncBinCABAC::encodeBin( UInt binValue, ContextModel &rcCtxModel ) 219 { 220 { 221 DTRACE_CABAC_VL( g_nSymbolCounter++ ) 118 222 DTRACE_CABAC_T( "\tstate=" ) 119 223 DTRACE_CABAC_V( ( rcCtxModel.getState() << 1 ) + rcCtxModel.getMps() ) 120 224 DTRACE_CABAC_T( "\tsymbol=" ) 121 DTRACE_CABAC_V( uiBin)225 DTRACE_CABAC_V( binValue ) 122 226 DTRACE_CABAC_T( "\n" ) 123 227 } 124 if (m_bBinCountingEnabled) 125 { 126 m_uiBinsCoded++; 127 } 228 m_uiBinsCoded += m_binCountIncrement; 229 #if CABAC_INIT_FLAG 230 rcCtxModel.setBinsCoded( 1 ); 231 #endif 232 128 233 UInt uiLPS = TComCABACTables::sm_aucLPSTable[ rcCtxModel.getState() ][ ( m_uiRange >> 6 ) & 3 ]; 129 234 m_uiRange -= uiLPS; 130 if( uiBin != rcCtxModel.getMps() ) 131 { 132 m_uiLow += m_uiRange; 133 m_uiRange = uiLPS; 235 236 if( binValue != rcCtxModel.getMps() ) 237 { 238 Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 3 ]; 239 m_uiLow = ( m_uiLow + m_uiRange ) << numBits; 240 m_uiRange = uiLPS << numBits; 134 241 rcCtxModel.updateLPS(); 242 243 m_bitsLeft -= numBits; 135 244 } 136 245 else 137 246 { 138 247 rcCtxModel.updateMPS(); 139 } 140 while( m_uiRange < 256 ) 141 { 142 if( m_uiLow >= 512 ) 143 { 144 xWriteBitAndBitsToFollow( 1 ); 145 m_uiLow -= 512; 146 } 147 else if( m_uiLow < 256 ) 148 { 149 xWriteBitAndBitsToFollow( 0 ); 150 } 151 else 152 { 153 m_uiBitsToFollow++; 154 m_uiLow -= 256; 155 } 248 if ( m_uiRange >= 256 ) 249 { 250 return; 251 } 252 253 m_uiLow <<= 1; 254 m_uiRange <<= 1; 255 m_bitsLeft--; 256 } 257 258 testAndWriteOut(); 259 } 260 261 /** 262 * \brief Encode equiprobable bin 263 * 264 * \param binValue bin value 265 */ 266 Void TEncBinCABAC::encodeBinEP( UInt binValue ) 267 { 268 { 269 DTRACE_CABAC_VL( g_nSymbolCounter++ ) 270 DTRACE_CABAC_T( "\tEPsymbol=" ) 271 DTRACE_CABAC_V( binValue ) 272 DTRACE_CABAC_T( "\n" ) 273 } 274 m_uiBinsCoded += m_binCountIncrement; 275 m_uiLow <<= 1; 276 if( binValue ) 277 { 278 m_uiLow += m_uiRange; 279 } 280 m_bitsLeft--; 281 282 testAndWriteOut(); 283 } 284 285 /** 286 * \brief Encode equiprobable bins 287 * 288 * \param binValues bin values 289 * \param numBins number of bins 290 */ 291 Void TEncBinCABAC::encodeBinsEP( UInt binValues, Int numBins ) 292 { 293 m_uiBinsCoded += numBins & -m_binCountIncrement; 294 295 for ( Int i = 0; i < numBins; i++ ) 296 { 297 DTRACE_CABAC_VL( g_nSymbolCounter++ ) 298 DTRACE_CABAC_T( "\tEPsymbol=" ) 299 DTRACE_CABAC_V( ( binValues >> ( numBins - 1 - i ) ) & 1 ) 300 DTRACE_CABAC_T( "\n" ) 301 } 302 303 while ( numBins > 8 ) 304 { 305 numBins -= 8; 306 UInt pattern = binValues >> numBins; 307 m_uiLow <<= 8; 308 m_uiLow += m_uiRange * pattern; 309 binValues -= pattern << numBins; 310 m_bitsLeft -= 8; 311 312 testAndWriteOut(); 313 } 314 315 m_uiLow <<= numBins; 316 m_uiLow += m_uiRange * binValues; 317 m_bitsLeft -= numBins; 318 319 testAndWriteOut(); 320 } 321 322 /** 323 * \brief Encode terminating bin 324 * 325 * \param binValue bin value 326 */ 327 Void TEncBinCABAC::encodeBinTrm( UInt binValue ) 328 { 329 m_uiBinsCoded += m_binCountIncrement; 330 m_uiRange -= 2; 331 if( binValue ) 332 { 333 m_uiLow += m_uiRange; 334 m_uiLow <<= 7; 335 m_uiRange = 2 << 7; 336 m_bitsLeft -= 7; 337 } 338 else if ( m_uiRange >= 256 ) 339 { 340 return; 341 } 342 else 343 { 156 344 m_uiLow <<= 1; 157 345 m_uiRange <<= 1; 158 } 159 } 160 161 Void 162 TEncBinCABAC::encodeBinEP( UInt uiBin ) 163 { 164 { 165 DTRACE_CABAC_V( g_nSymbolCounter++ ) 166 DTRACE_CABAC_T( "\tEPsymbol=" ) 167 DTRACE_CABAC_V( uiBin ) 168 DTRACE_CABAC_T( "\n" ) 169 } 170 if (m_bBinCountingEnabled) 171 { 172 m_uiBinsCoded++; 173 } 174 m_uiLow <<= 1; 175 if( uiBin ) 176 { 177 m_uiLow += m_uiRange; 178 } 179 if( m_uiLow >= 1024 ) 180 { 181 xWriteBitAndBitsToFollow( 1 ); 182 m_uiLow -= 1024; 183 } 184 else if( m_uiLow < 512 ) 185 { 186 xWriteBitAndBitsToFollow( 0 ); 346 m_bitsLeft--; 347 } 348 349 testAndWriteOut(); 350 } 351 352 Void TEncBinCABAC::testAndWriteOut() 353 { 354 if ( m_bitsLeft < 12 ) 355 { 356 writeOut(); 357 } 358 } 359 360 /** 361 * \brief Move bits from register into bitstream 362 */ 363 Void TEncBinCABAC::writeOut() 364 { 365 UInt leadByte = m_uiLow >> (24 - m_bitsLeft); 366 m_bitsLeft += 8; 367 m_uiLow &= 0xffffffffu >> m_bitsLeft; 368 369 if ( leadByte == 0xff ) 370 { 371 m_numBufferedBytes++; 187 372 } 188 373 else 189 374 { 190 m_uiBitsToFollow++; 191 m_uiLow -= 512; 192 } 193 } 194 195 Void 196 TEncBinCABAC::encodeBinTrm( UInt uiBin ) 197 { 198 if (m_bBinCountingEnabled) 199 { 200 m_uiBinsCoded++; 201 } 202 m_uiRange -= 2; 203 if( uiBin ) 204 { 205 m_uiLow += m_uiRange; 206 m_uiRange = 2; 207 } 208 while( m_uiRange < 256 ) 209 { 210 if( m_uiLow >= 512 ) 211 { 212 xWriteBitAndBitsToFollow( 1 ); 213 m_uiLow -= 512; 214 } 215 else if( m_uiLow < 256 ) 216 { 217 xWriteBitAndBitsToFollow( 0 ); 375 if ( m_numBufferedBytes > 0 ) 376 { 377 UInt carry = leadByte >> 8; 378 UInt byte = m_bufferedByte + carry; 379 m_bufferedByte = leadByte & 0xff; 380 m_pcTComBitIf->write( byte, 8 ); 381 382 byte = ( 0xff + carry ) & 0xff; 383 while ( m_numBufferedBytes > 1 ) 384 { 385 m_pcTComBitIf->write( byte, 8 ); 386 m_numBufferedBytes--; 387 } 218 388 } 219 389 else 220 390 { 221 m_uiBitsToFollow++; 222 m_uiLow -= 256; 223 } 224 m_uiLow <<= 1; 225 m_uiRange <<= 1; 226 } 227 } 228 229 Void 230 TEncBinCABAC::xWriteBit( UInt uiBit ) 231 { 232 m_uiByte += m_uiByte + uiBit; 233 if( ! --m_uiBitsLeft ) 234 { 235 m_pcTComBitIf->write( m_uiByte, 8 ); 236 m_uiBitsLeft = 8; 237 m_uiByte = 0; 238 } 239 } 240 241 Void 242 TEncBinCABAC::xWriteBitAndBitsToFollow( UInt uiBit ) 243 { 244 xWriteBit( uiBit ); 245 uiBit = 1 - uiBit; 246 while( m_uiBitsToFollow > 0 ) 247 { 248 m_uiBitsToFollow--; 249 xWriteBit( uiBit ); 250 } 251 } 391 m_numBufferedBytes = 1; 392 m_bufferedByte = leadByte; 393 } 394 } 395 } 396 397 /** flush bits when CABAC termination 398 * \param [in] bEnd true means this flushing happens at the end of RBSP. No need to encode stop bit 399 */ 400 Void TEncBinCABAC::encodeFlush(Bool bEnd) 401 { 402 m_uiRange = 2; 403 404 m_uiLow += 2; 405 m_uiLow <<= 7; 406 m_uiRange = 2 << 7; 407 m_bitsLeft -= 7; 408 testAndWriteOut(); 409 finish(); 410 411 if(!bEnd) 412 { 413 m_pcTComBitIf->write( 1, 1 ); // stop bit 414 } 415 } 416 417 //! \}
Note: See TracChangeset for help on using the changeset viewer.