1/* 2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * Context Adaptive Binary Arithmetic Coder. 25 */ 26 27#ifndef AVCODEC_CABAC_H 28#define AVCODEC_CABAC_H 29 30#include "put_bits.h" 31 32//#undef NDEBUG 33#include <assert.h> 34#include "libavutil/x86_cpu.h" 35 36#define CABAC_BITS 16 37#define CABAC_MASK ((1<<CABAC_BITS)-1) 38#define BRANCHLESS_CABAC_DECODER 1 39//#define ARCH_X86_DISABLED 1 40 41typedef struct CABACContext{ 42 int low; 43 int range; 44 int outstanding_count; 45#ifdef STRICT_LIMITS 46 int symCount; 47#endif 48 const uint8_t *bytestream_start; 49 const uint8_t *bytestream; 50 const uint8_t *bytestream_end; 51 PutBitContext pb; 52}CABACContext; 53 54extern uint8_t ff_h264_mlps_state[4*64]; 55extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS 56extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS 57extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS 58extern const uint8_t ff_h264_norm_shift[512]; 59 60 61void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); 62void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); 63void ff_init_cabac_states(CABACContext *c); 64 65 66static inline void put_cabac_bit(CABACContext *c, int b){ 67 put_bits(&c->pb, 1, b); 68 for(;c->outstanding_count; c->outstanding_count--){ 69 put_bits(&c->pb, 1, 1-b); 70 } 71} 72 73static inline void renorm_cabac_encoder(CABACContext *c){ 74 while(c->range < 0x100){ 75 //FIXME optimize 76 if(c->low<0x100){ 77 put_cabac_bit(c, 0); 78 }else if(c->low<0x200){ 79 c->outstanding_count++; 80 c->low -= 0x100; 81 }else{ 82 put_cabac_bit(c, 1); 83 c->low -= 0x200; 84 } 85 86 c->range+= c->range; 87 c->low += c->low; 88 } 89} 90 91#ifdef TEST 92static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ 93 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state]; 94 95 if(bit == ((*state)&1)){ 96 c->range -= RangeLPS; 97 *state= ff_h264_mps_state[*state]; 98 }else{ 99 c->low += c->range - RangeLPS; 100 c->range = RangeLPS; 101 *state= ff_h264_lps_state[*state]; 102 } 103 104 renorm_cabac_encoder(c); 105 106#ifdef STRICT_LIMITS 107 c->symCount++; 108#endif 109} 110 111static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){ 112 assert(c->range > RangeLPS); 113 114 if(!bit){ 115 c->range -= RangeLPS; 116 }else{ 117 c->low += c->range - RangeLPS; 118 c->range = RangeLPS; 119 } 120 121 renorm_cabac_encoder(c); 122 123#ifdef STRICT_LIMITS 124 c->symCount++; 125#endif 126} 127 128/** 129 * @param bit 0 -> write zero bit, !=0 write one bit 130 */ 131static void put_cabac_bypass(CABACContext *c, int bit){ 132 c->low += c->low; 133 134 if(bit){ 135 c->low += c->range; 136 } 137//FIXME optimize 138 if(c->low<0x200){ 139 put_cabac_bit(c, 0); 140 }else if(c->low<0x400){ 141 c->outstanding_count++; 142 c->low -= 0x200; 143 }else{ 144 put_cabac_bit(c, 1); 145 c->low -= 0x400; 146 } 147 148#ifdef STRICT_LIMITS 149 c->symCount++; 150#endif 151} 152 153/** 154 * 155 * @return the number of bytes written 156 */ 157static int put_cabac_terminate(CABACContext *c, int bit){ 158 c->range -= 2; 159 160 if(!bit){ 161 renorm_cabac_encoder(c); 162 }else{ 163 c->low += c->range; 164 c->range= 2; 165 166 renorm_cabac_encoder(c); 167 168 assert(c->low <= 0x1FF); 169 put_cabac_bit(c, c->low>>9); 170 put_bits(&c->pb, 2, ((c->low>>7)&3)|1); 171 172 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong 173 } 174 175#ifdef STRICT_LIMITS 176 c->symCount++; 177#endif 178 179 return (put_bits_count(&c->pb)+7)>>3; 180} 181 182/** 183 * put (truncated) unary binarization. 184 */ 185static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){ 186 int i; 187 188 assert(v <= max); 189 190#if 1 191 for(i=0; i<v; i++){ 192 put_cabac(c, state, 1); 193 if(i < max_index) state++; 194 } 195 if(truncated==0 || v<max) 196 put_cabac(c, state, 0); 197#else 198 if(v <= max_index){ 199 for(i=0; i<v; i++){ 200 put_cabac(c, state+i, 1); 201 } 202 if(truncated==0 || v<max) 203 put_cabac(c, state+i, 0); 204 }else{ 205 for(i=0; i<=max_index; i++){ 206 put_cabac(c, state+i, 1); 207 } 208 for(; i<v; i++){ 209 put_cabac(c, state+max_index, 1); 210 } 211 if(truncated==0 || v<max) 212 put_cabac(c, state+max_index, 0); 213 } 214#endif 215} 216 217/** 218 * put unary exp golomb k-th order binarization. 219 */ 220static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){ 221 int i; 222 223 if(v==0) 224 put_cabac(c, state, 0); 225 else{ 226 const int sign= v < 0; 227 228 if(is_signed) v= FFABS(v); 229 230 if(v<max){ 231 for(i=0; i<v; i++){ 232 put_cabac(c, state, 1); 233 if(i < max_index) state++; 234 } 235 236 put_cabac(c, state, 0); 237 }else{ 238 int m= 1<<k; 239 240 for(i=0; i<max; i++){ 241 put_cabac(c, state, 1); 242 if(i < max_index) state++; 243 } 244 245 v -= max; 246 while(v >= m){ //FIXME optimize 247 put_cabac_bypass(c, 1); 248 v-= m; 249 m+= m; 250 } 251 put_cabac_bypass(c, 0); 252 while(m>>=1){ 253 put_cabac_bypass(c, v&m); 254 } 255 } 256 257 if(is_signed) 258 put_cabac_bypass(c, sign); 259 } 260} 261#endif /* TEST */ 262 263static void refill(CABACContext *c){ 264#if CABAC_BITS == 16 265 c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 266#else 267 c->low+= c->bytestream[0]<<1; 268#endif 269 c->low -= CABAC_MASK; 270 c->bytestream+= CABAC_BITS/8; 271} 272 273#if ! ( ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) ) 274static void refill2(CABACContext *c){ 275 int i, x; 276 277 x= c->low ^ (c->low-1); 278 i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; 279 280 x= -CABAC_MASK; 281 282#if CABAC_BITS == 16 283 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 284#else 285 x+= c->bytestream[0]<<1; 286#endif 287 288 c->low += x<<i; 289 c->bytestream+= CABAC_BITS/8; 290} 291#endif 292 293static inline void renorm_cabac_decoder(CABACContext *c){ 294 while(c->range < 0x100){ 295 c->range+= c->range; 296 c->low+= c->low; 297 if(!(c->low & CABAC_MASK)) 298 refill(c); 299 } 300} 301 302static inline void renorm_cabac_decoder_once(CABACContext *c){ 303#ifdef ARCH_X86_DISABLED 304 int temp; 305#if 0 306 //P3:683 athlon:475 307 __asm__( 308 "lea -0x100(%0), %2 \n\t" 309 "shr $31, %2 \n\t" //FIXME 31->63 for x86-64 310 "shl %%cl, %0 \n\t" 311 "shl %%cl, %1 \n\t" 312 : "+r"(c->range), "+r"(c->low), "+c"(temp) 313 ); 314#elif 0 315 //P3:680 athlon:474 316 __asm__( 317 "cmp $0x100, %0 \n\t" 318 "setb %%cl \n\t" //FIXME 31->63 for x86-64 319 "shl %%cl, %0 \n\t" 320 "shl %%cl, %1 \n\t" 321 : "+r"(c->range), "+r"(c->low), "+c"(temp) 322 ); 323#elif 1 324 int temp2; 325 //P3:665 athlon:517 326 __asm__( 327 "lea -0x100(%0), %%eax \n\t" 328 "cltd \n\t" 329 "mov %0, %%eax \n\t" 330 "and %%edx, %0 \n\t" 331 "and %1, %%edx \n\t" 332 "add %%eax, %0 \n\t" 333 "add %%edx, %1 \n\t" 334 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) 335 ); 336#elif 0 337 int temp2; 338 //P3:673 athlon:509 339 __asm__( 340 "cmp $0x100, %0 \n\t" 341 "sbb %%edx, %%edx \n\t" 342 "mov %0, %%eax \n\t" 343 "and %%edx, %0 \n\t" 344 "and %1, %%edx \n\t" 345 "add %%eax, %0 \n\t" 346 "add %%edx, %1 \n\t" 347 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) 348 ); 349#else 350 int temp2; 351 //P3:677 athlon:511 352 __asm__( 353 "cmp $0x100, %0 \n\t" 354 "lea (%0, %0), %%eax \n\t" 355 "lea (%1, %1), %%edx \n\t" 356 "cmovb %%eax, %0 \n\t" 357 "cmovb %%edx, %1 \n\t" 358 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) 359 ); 360#endif 361#else 362 //P3:675 athlon:476 363 int shift= (uint32_t)(c->range - 0x100)>>31; 364 c->range<<= shift; 365 c->low <<= shift; 366#endif 367 if(!(c->low & CABAC_MASK)) 368 refill(c); 369} 370 371static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ 372 //FIXME gcc generates duplicate load/stores for c->low and c->range 373#define LOW "0" 374#define RANGE "4" 375#if ARCH_X86_64 376#define BYTESTART "16" 377#define BYTE "24" 378#define BYTEEND "32" 379#else 380#define BYTESTART "12" 381#define BYTE "16" 382#define BYTEEND "20" 383#endif 384#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) 385 int bit; 386 387#ifndef BRANCHLESS_CABAC_DECODER 388 __asm__ volatile( 389 "movzbl (%1), %0 \n\t" 390 "movl "RANGE "(%2), %%ebx \n\t" 391 "movl "RANGE "(%2), %%edx \n\t" 392 "andl $0xC0, %%ebx \n\t" 393 "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t" 394 "movl "LOW "(%2), %%ebx \n\t" 395//eax:state ebx:low, edx:range, esi:RangeLPS 396 "subl %%esi, %%edx \n\t" 397 "movl %%edx, %%ecx \n\t" 398 "shll $17, %%ecx \n\t" 399 "cmpl %%ecx, %%ebx \n\t" 400 " ja 1f \n\t" 401 402#if 1 403 //athlon:4067 P3:4110 404 "lea -0x100(%%edx), %%ecx \n\t" 405 "shr $31, %%ecx \n\t" 406 "shl %%cl, %%edx \n\t" 407 "shl %%cl, %%ebx \n\t" 408#else 409 //athlon:4057 P3:4130 410 "cmp $0x100, %%edx \n\t" //FIXME avoidable 411 "setb %%cl \n\t" 412 "shl %%cl, %%edx \n\t" 413 "shl %%cl, %%ebx \n\t" 414#endif 415 "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t" 416 "movb %%cl, (%1) \n\t" 417//eax:state ebx:low, edx:range, esi:RangeLPS 418 "test %%bx, %%bx \n\t" 419 " jnz 2f \n\t" 420 "mov "BYTE "(%2), %%"REG_S" \n\t" 421 "subl $0xFFFF, %%ebx \n\t" 422 "movzwl (%%"REG_S"), %%ecx \n\t" 423 "bswap %%ecx \n\t" 424 "shrl $15, %%ecx \n\t" 425 "add $2, %%"REG_S" \n\t" 426 "addl %%ecx, %%ebx \n\t" 427 "mov %%"REG_S", "BYTE "(%2) \n\t" 428 "jmp 2f \n\t" 429 "1: \n\t" 430//eax:state ebx:low, edx:range, esi:RangeLPS 431 "subl %%ecx, %%ebx \n\t" 432 "movl %%esi, %%edx \n\t" 433 "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t" 434 "shll %%cl, %%ebx \n\t" 435 "shll %%cl, %%edx \n\t" 436 "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t" 437 "movb %%cl, (%1) \n\t" 438 "add $1, %0 \n\t" 439 "test %%bx, %%bx \n\t" 440 " jnz 2f \n\t" 441 442 "mov "BYTE "(%2), %%"REG_c" \n\t" 443 "movzwl (%%"REG_c"), %%esi \n\t" 444 "bswap %%esi \n\t" 445 "shrl $15, %%esi \n\t" 446 "subl $0xFFFF, %%esi \n\t" 447 "add $2, %%"REG_c" \n\t" 448 "mov %%"REG_c", "BYTE "(%2) \n\t" 449 450 "leal -1(%%ebx), %%ecx \n\t" 451 "xorl %%ebx, %%ecx \n\t" 452 "shrl $15, %%ecx \n\t" 453 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t" 454 "neg %%ecx \n\t" 455 "add $7, %%ecx \n\t" 456 457 "shll %%cl , %%esi \n\t" 458 "addl %%esi, %%ebx \n\t" 459 "2: \n\t" 460 "movl %%edx, "RANGE "(%2) \n\t" 461 "movl %%ebx, "LOW "(%2) \n\t" 462 :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or miscompiles it (for example if "+a"(bit) or "+m"(*state) is used 463 :"r"(state), "r"(c) 464 : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory" 465 ); 466 bit&=1; 467#else /* BRANCHLESS_CABAC_DECODER */ 468 469 470#if HAVE_FAST_CMOV 471#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 472 "mov "tmp" , %%ecx \n\t"\ 473 "shl $17 , "tmp" \n\t"\ 474 "cmp "low" , "tmp" \n\t"\ 475 "cmova %%ecx , "range" \n\t"\ 476 "sbb %%ecx , %%ecx \n\t"\ 477 "and %%ecx , "tmp" \n\t"\ 478 "sub "tmp" , "low" \n\t"\ 479 "xor %%ecx , "ret" \n\t" 480#else /* HAVE_FAST_CMOV */ 481#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 482 "mov "tmp" , %%ecx \n\t"\ 483 "shl $17 , "tmp" \n\t"\ 484 "sub "low" , "tmp" \n\t"\ 485 "sar $31 , "tmp" \n\t" /*lps_mask*/\ 486 "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ 487 "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ 488 "add %%ecx , "range" \n\t" /*new range*/\ 489 "shl $17 , %%ecx \n\t"\ 490 "and "tmp" , %%ecx \n\t"\ 491 "sub %%ecx , "low" \n\t"\ 492 "xor "tmp" , "ret" \n\t" 493#endif /* HAVE_FAST_CMOV */ 494 495 496#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 497 "movzbl "statep" , "ret" \n\t"\ 498 "mov "range" , "tmp" \n\t"\ 499 "and $0xC0 , "range" \n\t"\ 500 "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\ 501 "sub "range" , "tmp" \n\t"\ 502 BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 503 "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ 504 "shl %%cl , "range" \n\t"\ 505 "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ 506 "mov "tmpbyte" , "statep" \n\t"\ 507 "shl %%cl , "low" \n\t"\ 508 "test "lowword" , "lowword" \n\t"\ 509 " jnz 1f \n\t"\ 510 "mov "BYTE"("cabac"), %%"REG_c" \n\t"\ 511 "movzwl (%%"REG_c") , "tmp" \n\t"\ 512 "bswap "tmp" \n\t"\ 513 "shr $15 , "tmp" \n\t"\ 514 "sub $0xFFFF , "tmp" \n\t"\ 515 "add $2 , %%"REG_c" \n\t"\ 516 "mov %%"REG_c" , "BYTE "("cabac") \n\t"\ 517 "lea -1("low") , %%ecx \n\t"\ 518 "xor "low" , %%ecx \n\t"\ 519 "shr $15 , %%ecx \n\t"\ 520 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\ 521 "neg %%ecx \n\t"\ 522 "add $7 , %%ecx \n\t"\ 523 "shl %%cl , "tmp" \n\t"\ 524 "add "tmp" , "low" \n\t"\ 525 "1: \n\t" 526 527 __asm__ volatile( 528 "movl "RANGE "(%2), %%esi \n\t" 529 "movl "LOW "(%2), %%ebx \n\t" 530 BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl") 531 "movl %%esi, "RANGE "(%2) \n\t" 532 "movl %%ebx, "LOW "(%2) \n\t" 533 534 :"=&a"(bit) 535 :"r"(state), "r"(c) 536 : "%"REG_c, "%ebx", "%edx", "%esi", "memory" 537 ); 538 bit&=1; 539#endif /* BRANCHLESS_CABAC_DECODER */ 540#else /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ 541 int s = *state; 542 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; 543 int bit, lps_mask av_unused; 544 545 c->range -= RangeLPS; 546#ifndef BRANCHLESS_CABAC_DECODER 547 if(c->low < (c->range<<(CABAC_BITS+1))){ 548 bit= s&1; 549 *state= ff_h264_mps_state[s]; 550 renorm_cabac_decoder_once(c); 551 }else{ 552 bit= ff_h264_norm_shift[RangeLPS]; 553 c->low -= (c->range<<(CABAC_BITS+1)); 554 *state= ff_h264_lps_state[s]; 555 c->range = RangeLPS<<bit; 556 c->low <<= bit; 557 bit= (s&1)^1; 558 559 if(!(c->low & CABAC_MASK)){ 560 refill2(c); 561 } 562 } 563#else /* BRANCHLESS_CABAC_DECODER */ 564 lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; 565 566 c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; 567 c->range += (RangeLPS - c->range) & lps_mask; 568 569 s^=lps_mask; 570 *state= (ff_h264_mlps_state+128)[s]; 571 bit= s&1; 572 573 lps_mask= ff_h264_norm_shift[c->range]; 574 c->range<<= lps_mask; 575 c->low <<= lps_mask; 576 if(!(c->low & CABAC_MASK)) 577 refill2(c); 578#endif /* BRANCHLESS_CABAC_DECODER */ 579#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ 580 return bit; 581} 582 583static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ 584 return get_cabac_inline(c,state); 585} 586 587static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ 588 return get_cabac_inline(c,state); 589} 590 591static int av_unused get_cabac_bypass(CABACContext *c){ 592#if 0 //not faster 593 int bit; 594 __asm__ volatile( 595 "movl "RANGE "(%1), %%ebx \n\t" 596 "movl "LOW "(%1), %%eax \n\t" 597 "shl $17, %%ebx \n\t" 598 "add %%eax, %%eax \n\t" 599 "sub %%ebx, %%eax \n\t" 600 "cltd \n\t" 601 "and %%edx, %%ebx \n\t" 602 "add %%ebx, %%eax \n\t" 603 "test %%ax, %%ax \n\t" 604 " jnz 1f \n\t" 605 "movl "BYTE "(%1), %%"REG_b" \n\t" 606 "subl $0xFFFF, %%eax \n\t" 607 "movzwl (%%"REG_b"), %%ecx \n\t" 608 "bswap %%ecx \n\t" 609 "shrl $15, %%ecx \n\t" 610 "addl $2, %%"REG_b" \n\t" 611 "addl %%ecx, %%eax \n\t" 612 "movl %%"REG_b", "BYTE "(%1) \n\t" 613 "1: \n\t" 614 "movl %%eax, "LOW "(%1) \n\t" 615 616 :"=&d"(bit) 617 :"r"(c) 618 : "%eax", "%"REG_b, "%ecx", "memory" 619 ); 620 return bit+1; 621#else 622 int range; 623 c->low += c->low; 624 625 if(!(c->low & CABAC_MASK)) 626 refill(c); 627 628 range= c->range<<(CABAC_BITS+1); 629 if(c->low < range){ 630 return 0; 631 }else{ 632 c->low -= range; 633 return 1; 634 } 635#endif 636} 637 638 639static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ 640#if ARCH_X86 && HAVE_EBX_AVAILABLE 641 __asm__ volatile( 642 "movl "RANGE "(%1), %%ebx \n\t" 643 "movl "LOW "(%1), %%eax \n\t" 644 "shl $17, %%ebx \n\t" 645 "add %%eax, %%eax \n\t" 646 "sub %%ebx, %%eax \n\t" 647 "cltd \n\t" 648 "and %%edx, %%ebx \n\t" 649 "add %%ebx, %%eax \n\t" 650 "xor %%edx, %%ecx \n\t" 651 "sub %%edx, %%ecx \n\t" 652 "test %%ax, %%ax \n\t" 653 " jnz 1f \n\t" 654 "mov "BYTE "(%1), %%"REG_b" \n\t" 655 "subl $0xFFFF, %%eax \n\t" 656 "movzwl (%%"REG_b"), %%edx \n\t" 657 "bswap %%edx \n\t" 658 "shrl $15, %%edx \n\t" 659 "add $2, %%"REG_b" \n\t" 660 "addl %%edx, %%eax \n\t" 661 "mov %%"REG_b", "BYTE "(%1) \n\t" 662 "1: \n\t" 663 "movl %%eax, "LOW "(%1) \n\t" 664 665 :"+c"(val) 666 :"r"(c) 667 : "%eax", "%"REG_b, "%edx", "memory" 668 ); 669 return val; 670#else 671 int range, mask; 672 c->low += c->low; 673 674 if(!(c->low & CABAC_MASK)) 675 refill(c); 676 677 range= c->range<<(CABAC_BITS+1); 678 c->low -= range; 679 mask= c->low >> 31; 680 range &= mask; 681 c->low += range; 682 return (val^mask)-mask; 683#endif 684} 685 686/** 687 * 688 * @return the number of bytes read or 0 if no end 689 */ 690static int av_unused get_cabac_terminate(CABACContext *c){ 691 c->range -= 2; 692 if(c->low < c->range<<(CABAC_BITS+1)){ 693 renorm_cabac_decoder_once(c); 694 return 0; 695 }else{ 696 return c->bytestream - c->bytestream_start; 697 } 698} 699 700#if 0 701/** 702 * Get (truncated) unary binarization. 703 */ 704static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ 705 int i; 706 707 for(i=0; i<max; i++){ 708 if(get_cabac(c, state)==0) 709 return i; 710 711 if(i< max_index) state++; 712 } 713 714 return truncated ? max : -1; 715} 716 717/** 718 * get unary exp golomb k-th order binarization. 719 */ 720static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){ 721 int i, v; 722 int m= 1<<k; 723 724 if(get_cabac(c, state)==0) 725 return 0; 726 727 if(0 < max_index) state++; 728 729 for(i=1; i<max; i++){ 730 if(get_cabac(c, state)==0){ 731 if(is_signed && get_cabac_bypass(c)){ 732 return -i; 733 }else 734 return i; 735 } 736 737 if(i < max_index) state++; 738 } 739 740 while(get_cabac_bypass(c)){ 741 i+= m; 742 m+= m; 743 } 744 745 v=0; 746 while(m>>=1){ 747 v+= v + get_cabac_bypass(c); 748 } 749 i += v; 750 751 if(is_signed && get_cabac_bypass(c)){ 752 return -i; 753 }else 754 return i; 755} 756#endif /* 0 */ 757 758#endif /* AVCODEC_CABAC_H */ 759