00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #ifndef FFMPEG_CABAC_H
00028 #define FFMPEG_CABAC_H
00029
00030 #include "bitstream.h"
00031
00032
00033 #include <assert.h>
00034 #ifdef ARCH_X86
00035 #include "x86_cpu.h"
00036 #endif
00037
00038 #define CABAC_BITS 16
00039 #define CABAC_MASK ((1<<CABAC_BITS)-1)
00040 #define BRANCHLESS_CABAC_DECODER 1
00041
00042
00043 typedef struct CABACContext{
00044 int low;
00045 int range;
00046 int outstanding_count;
00047 #ifdef STRICT_LIMITS
00048 int symCount;
00049 #endif
00050 const uint8_t *bytestream_start;
00051 const uint8_t *bytestream;
00052 const uint8_t *bytestream_end;
00053 PutBitContext pb;
00054 }CABACContext;
00055
00056 extern uint8_t ff_h264_mlps_state[4*64];
00057 extern uint8_t ff_h264_lps_range[4*2*64];
00058 extern uint8_t ff_h264_mps_state[2*64];
00059 extern uint8_t ff_h264_lps_state[2*64];
00060 extern const uint8_t ff_h264_norm_shift[512];
00061
00062
00063 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
00064 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
00065 void ff_init_cabac_states(CABACContext *c);
00066
00067
00068 static inline void put_cabac_bit(CABACContext *c, int b){
00069 put_bits(&c->pb, 1, b);
00070 for(;c->outstanding_count; c->outstanding_count--){
00071 put_bits(&c->pb, 1, 1-b);
00072 }
00073 }
00074
00075 static inline void renorm_cabac_encoder(CABACContext *c){
00076 while(c->range < 0x100){
00077
00078 if(c->low<0x100){
00079 put_cabac_bit(c, 0);
00080 }else if(c->low<0x200){
00081 c->outstanding_count++;
00082 c->low -= 0x100;
00083 }else{
00084 put_cabac_bit(c, 1);
00085 c->low -= 0x200;
00086 }
00087
00088 c->range+= c->range;
00089 c->low += c->low;
00090 }
00091 }
00092
00093 #ifdef TEST
00094 static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
00095 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
00096
00097 if(bit == ((*state)&1)){
00098 c->range -= RangeLPS;
00099 *state= ff_h264_mps_state[*state];
00100 }else{
00101 c->low += c->range - RangeLPS;
00102 c->range = RangeLPS;
00103 *state= ff_h264_lps_state[*state];
00104 }
00105
00106 renorm_cabac_encoder(c);
00107
00108 #ifdef STRICT_LIMITS
00109 c->symCount++;
00110 #endif
00111 }
00112
00113 static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){
00114 assert(c->range > RangeLPS);
00115
00116 if(!bit){
00117 c->range -= RangeLPS;
00118 }else{
00119 c->low += c->range - RangeLPS;
00120 c->range = RangeLPS;
00121 }
00122
00123 renorm_cabac_encoder(c);
00124
00125 #ifdef STRICT_LIMITS
00126 c->symCount++;
00127 #endif
00128 }
00129
00133 static void put_cabac_bypass(CABACContext *c, int bit){
00134 c->low += c->low;
00135
00136 if(bit){
00137 c->low += c->range;
00138 }
00139
00140 if(c->low<0x200){
00141 put_cabac_bit(c, 0);
00142 }else if(c->low<0x400){
00143 c->outstanding_count++;
00144 c->low -= 0x200;
00145 }else{
00146 put_cabac_bit(c, 1);
00147 c->low -= 0x400;
00148 }
00149
00150 #ifdef STRICT_LIMITS
00151 c->symCount++;
00152 #endif
00153 }
00154
00159 static int put_cabac_terminate(CABACContext *c, int bit){
00160 c->range -= 2;
00161
00162 if(!bit){
00163 renorm_cabac_encoder(c);
00164 }else{
00165 c->low += c->range;
00166 c->range= 2;
00167
00168 renorm_cabac_encoder(c);
00169
00170 assert(c->low <= 0x1FF);
00171 put_cabac_bit(c, c->low>>9);
00172 put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
00173
00174 flush_put_bits(&c->pb);
00175 }
00176
00177 #ifdef STRICT_LIMITS
00178 c->symCount++;
00179 #endif
00180
00181 return (put_bits_count(&c->pb)+7)>>3;
00182 }
00183
00187 static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
00188 int i;
00189
00190 assert(v <= max);
00191
00192 #if 1
00193 for(i=0; i<v; i++){
00194 put_cabac(c, state, 1);
00195 if(i < max_index) state++;
00196 }
00197 if(truncated==0 || v<max)
00198 put_cabac(c, state, 0);
00199 #else
00200 if(v <= max_index){
00201 for(i=0; i<v; i++){
00202 put_cabac(c, state+i, 1);
00203 }
00204 if(truncated==0 || v<max)
00205 put_cabac(c, state+i, 0);
00206 }else{
00207 for(i=0; i<=max_index; i++){
00208 put_cabac(c, state+i, 1);
00209 }
00210 for(; i<v; i++){
00211 put_cabac(c, state+max_index, 1);
00212 }
00213 if(truncated==0 || v<max)
00214 put_cabac(c, state+max_index, 0);
00215 }
00216 #endif
00217 }
00218
00222 static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
00223 int i;
00224
00225 if(v==0)
00226 put_cabac(c, state, 0);
00227 else{
00228 const int sign= v < 0;
00229
00230 if(is_signed) v= FFABS(v);
00231
00232 if(v<max){
00233 for(i=0; i<v; i++){
00234 put_cabac(c, state, 1);
00235 if(i < max_index) state++;
00236 }
00237
00238 put_cabac(c, state, 0);
00239 }else{
00240 int m= 1<<k;
00241
00242 for(i=0; i<max; i++){
00243 put_cabac(c, state, 1);
00244 if(i < max_index) state++;
00245 }
00246
00247 v -= max;
00248 while(v >= m){
00249 put_cabac_bypass(c, 1);
00250 v-= m;
00251 m+= m;
00252 }
00253 put_cabac_bypass(c, 0);
00254 while(m>>=1){
00255 put_cabac_bypass(c, v&m);
00256 }
00257 }
00258
00259 if(is_signed)
00260 put_cabac_bypass(c, sign);
00261 }
00262 }
00263 #endif
00264
00265 static void refill(CABACContext *c){
00266 #if CABAC_BITS == 16
00267 c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
00268 #else
00269 c->low+= c->bytestream[0]<<1;
00270 #endif
00271 c->low -= CABAC_MASK;
00272 c->bytestream+= CABAC_BITS/8;
00273 }
00274
00275 #if ! ( defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) )
00276 static void refill2(CABACContext *c){
00277 int i, x;
00278
00279 x= c->low ^ (c->low-1);
00280 i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
00281
00282 x= -CABAC_MASK;
00283
00284 #if CABAC_BITS == 16
00285 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
00286 #else
00287 x+= c->bytestream[0]<<1;
00288 #endif
00289
00290 c->low += x<<i;
00291 c->bytestream+= CABAC_BITS/8;
00292 }
00293 #endif
00294
00295 static inline void renorm_cabac_decoder(CABACContext *c){
00296 while(c->range < 0x100){
00297 c->range+= c->range;
00298 c->low+= c->low;
00299 if(!(c->low & CABAC_MASK))
00300 refill(c);
00301 }
00302 }
00303
00304 static inline void renorm_cabac_decoder_once(CABACContext *c){
00305 #ifdef ARCH_X86_DISABLED
00306 int temp;
00307 #if 0
00308
00309 asm(
00310 "lea -0x100(%0), %2 \n\t"
00311 "shr $31, %2 \n\t"
00312 "shl %%cl, %0 \n\t"
00313 "shl %%cl, %1 \n\t"
00314 : "+r"(c->range), "+r"(c->low), "+c"(temp)
00315 );
00316 #elif 0
00317
00318 asm(
00319 "cmp $0x100, %0 \n\t"
00320 "setb %%cl \n\t"
00321 "shl %%cl, %0 \n\t"
00322 "shl %%cl, %1 \n\t"
00323 : "+r"(c->range), "+r"(c->low), "+c"(temp)
00324 );
00325 #elif 1
00326 int temp2;
00327
00328 asm(
00329 "lea -0x100(%0), %%eax \n\t"
00330 "cdq \n\t"
00331 "mov %0, %%eax \n\t"
00332 "and %%edx, %0 \n\t"
00333 "and %1, %%edx \n\t"
00334 "add %%eax, %0 \n\t"
00335 "add %%edx, %1 \n\t"
00336 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
00337 );
00338 #elif 0
00339 int temp2;
00340
00341 asm(
00342 "cmp $0x100, %0 \n\t"
00343 "sbb %%edx, %%edx \n\t"
00344 "mov %0, %%eax \n\t"
00345 "and %%edx, %0 \n\t"
00346 "and %1, %%edx \n\t"
00347 "add %%eax, %0 \n\t"
00348 "add %%edx, %1 \n\t"
00349 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
00350 );
00351 #else
00352 int temp2;
00353
00354 asm(
00355 "cmp $0x100, %0 \n\t"
00356 "lea (%0, %0), %%eax \n\t"
00357 "lea (%1, %1), %%edx \n\t"
00358 "cmovb %%eax, %0 \n\t"
00359 "cmovb %%edx, %1 \n\t"
00360 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
00361 );
00362 #endif
00363 #else
00364
00365 int shift= (uint32_t)(c->range - 0x100)>>31;
00366 c->range<<= shift;
00367 c->low <<= shift;
00368 #endif
00369 if(!(c->low & CABAC_MASK))
00370 refill(c);
00371 }
00372
00373 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
00374
00375 #define LOW "0"
00376 #define RANGE "4"
00377 #ifdef ARCH_X86_64
00378 #define BYTESTART "16"
00379 #define BYTE "24"
00380 #define BYTEEND "32"
00381 #else
00382 #define BYTESTART "12"
00383 #define BYTE "16"
00384 #define BYTEEND "20"
00385 #endif
00386 #if defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS)
00387 int bit;
00388
00389 #ifndef BRANCHLESS_CABAC_DECODER
00390 asm volatile(
00391 "movzbl (%1), %0 \n\t"
00392 "movl "RANGE "(%2), %%ebx \n\t"
00393 "movl "RANGE "(%2), %%edx \n\t"
00394 "andl $0xC0, %%ebx \n\t"
00395 "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t"
00396 "movl "LOW "(%2), %%ebx \n\t"
00397
00398 "subl %%esi, %%edx \n\t"
00399 "movl %%edx, %%ecx \n\t"
00400 "shll $17, %%ecx \n\t"
00401 "cmpl %%ecx, %%ebx \n\t"
00402 " ja 1f \n\t"
00403
00404 #if 1
00405
00406 "lea -0x100(%%edx), %%ecx \n\t"
00407 "shr $31, %%ecx \n\t"
00408 "shl %%cl, %%edx \n\t"
00409 "shl %%cl, %%ebx \n\t"
00410 #else
00411
00412 "cmp $0x100, %%edx \n\t"
00413 "setb %%cl \n\t"
00414 "shl %%cl, %%edx \n\t"
00415 "shl %%cl, %%ebx \n\t"
00416 #endif
00417 "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t"
00418 "movb %%cl, (%1) \n\t"
00419
00420 "test %%bx, %%bx \n\t"
00421 " jnz 2f \n\t"
00422 "mov "BYTE "(%2), %%"REG_S" \n\t"
00423 "subl $0xFFFF, %%ebx \n\t"
00424 "movzwl (%%"REG_S"), %%ecx \n\t"
00425 "bswap %%ecx \n\t"
00426 "shrl $15, %%ecx \n\t"
00427 "add $2, %%"REG_S" \n\t"
00428 "addl %%ecx, %%ebx \n\t"
00429 "mov %%"REG_S", "BYTE "(%2) \n\t"
00430 "jmp 2f \n\t"
00431 "1: \n\t"
00432
00433 "subl %%ecx, %%ebx \n\t"
00434 "movl %%esi, %%edx \n\t"
00435 "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t"
00436 "shll %%cl, %%ebx \n\t"
00437 "shll %%cl, %%edx \n\t"
00438 "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t"
00439 "movb %%cl, (%1) \n\t"
00440 "add $1, %0 \n\t"
00441 "test %%bx, %%bx \n\t"
00442 " jnz 2f \n\t"
00443
00444 "mov "BYTE "(%2), %%"REG_c" \n\t"
00445 "movzwl (%%"REG_c"), %%esi \n\t"
00446 "bswap %%esi \n\t"
00447 "shrl $15, %%esi \n\t"
00448 "subl $0xFFFF, %%esi \n\t"
00449 "add $2, %%"REG_c" \n\t"
00450 "mov %%"REG_c", "BYTE "(%2) \n\t"
00451
00452 "leal -1(%%ebx), %%ecx \n\t"
00453 "xorl %%ebx, %%ecx \n\t"
00454 "shrl $15, %%ecx \n\t"
00455 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"
00456 "neg %%ecx \n\t"
00457 "add $7, %%ecx \n\t"
00458
00459 "shll %%cl , %%esi \n\t"
00460 "addl %%esi, %%ebx \n\t"
00461 "2: \n\t"
00462 "movl %%edx, "RANGE "(%2) \n\t"
00463 "movl %%ebx, "LOW "(%2) \n\t"
00464 :"=&a"(bit)
00465 :"r"(state), "r"(c)
00466 : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory"
00467 );
00468 bit&=1;
00469 #else
00470
00471
00472 #if defined HAVE_FAST_CMOV
00473 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
00474 "mov "tmp" , %%ecx \n\t"\
00475 "shl $17 , "tmp" \n\t"\
00476 "cmp "low" , "tmp" \n\t"\
00477 "cmova %%ecx , "range" \n\t"\
00478 "sbb %%ecx , %%ecx \n\t"\
00479 "and %%ecx , "tmp" \n\t"\
00480 "sub "tmp" , "low" \n\t"\
00481 "xor %%ecx , "ret" \n\t"
00482 #else
00483 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
00484 "mov "tmp" , %%ecx \n\t"\
00485 "shl $17 , "tmp" \n\t"\
00486 "sub "low" , "tmp" \n\t"\
00487 "sar $31 , "tmp" \n\t" \
00488 "sub %%ecx , "range" \n\t" \
00489 "and "tmp" , "range" \n\t" \
00490 "add %%ecx , "range" \n\t" \
00491 "shl $17 , %%ecx \n\t"\
00492 "and "tmp" , %%ecx \n\t"\
00493 "sub %%ecx , "low" \n\t"\
00494 "xor "tmp" , "ret" \n\t"
00495 #endif
00496
00497
00498 #define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
00499 "movzbl "statep" , "ret" \n\t"\
00500 "mov "range" , "tmp" \n\t"\
00501 "and $0xC0 , "range" \n\t"\
00502 "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\
00503 "sub "range" , "tmp" \n\t"\
00504 BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
00505 "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\
00506 "shl %%cl , "range" \n\t"\
00507 "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\
00508 "mov "tmpbyte" , "statep" \n\t"\
00509 "shl %%cl , "low" \n\t"\
00510 "test "lowword" , "lowword" \n\t"\
00511 " jnz 1f \n\t"\
00512 "mov "BYTE"("cabac"), %%"REG_c" \n\t"\
00513 "movzwl (%%"REG_c") , "tmp" \n\t"\
00514 "bswap "tmp" \n\t"\
00515 "shr $15 , "tmp" \n\t"\
00516 "sub $0xFFFF , "tmp" \n\t"\
00517 "add $2 , %%"REG_c" \n\t"\
00518 "mov %%"REG_c" , "BYTE "("cabac") \n\t"\
00519 "lea -1("low") , %%ecx \n\t"\
00520 "xor "low" , %%ecx \n\t"\
00521 "shr $15 , %%ecx \n\t"\
00522 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\
00523 "neg %%ecx \n\t"\
00524 "add $7 , %%ecx \n\t"\
00525 "shl %%cl , "tmp" \n\t"\
00526 "add "tmp" , "low" \n\t"\
00527 "1: \n\t"
00528
00529 asm volatile(
00530 "movl "RANGE "(%2), %%esi \n\t"
00531 "movl "LOW "(%2), %%ebx \n\t"
00532 BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl")
00533 "movl %%esi, "RANGE "(%2) \n\t"
00534 "movl %%ebx, "LOW "(%2) \n\t"
00535
00536 :"=&a"(bit)
00537 :"r"(state), "r"(c)
00538 : "%"REG_c, "%ebx", "%edx", "%esi", "memory"
00539 );
00540 bit&=1;
00541 #endif
00542 #else
00543 int s = *state;
00544 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s];
00545 int bit, lps_mask av_unused;
00546
00547 c->range -= RangeLPS;
00548 #ifndef BRANCHLESS_CABAC_DECODER
00549 if(c->low < (c->range<<(CABAC_BITS+1))){
00550 bit= s&1;
00551 *state= ff_h264_mps_state[s];
00552 renorm_cabac_decoder_once(c);
00553 }else{
00554 bit= ff_h264_norm_shift[RangeLPS];
00555 c->low -= (c->range<<(CABAC_BITS+1));
00556 *state= ff_h264_lps_state[s];
00557 c->range = RangeLPS<<bit;
00558 c->low <<= bit;
00559 bit= (s&1)^1;
00560
00561 if(!(c->low & CABAC_MASK)){
00562 refill2(c);
00563 }
00564 }
00565 #else
00566 lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31;
00567
00568 c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask;
00569 c->range += (RangeLPS - c->range) & lps_mask;
00570
00571 s^=lps_mask;
00572 *state= (ff_h264_mlps_state+128)[s];
00573 bit= s&1;
00574
00575 lps_mask= ff_h264_norm_shift[c->range];
00576 c->range<<= lps_mask;
00577 c->low <<= lps_mask;
00578 if(!(c->low & CABAC_MASK))
00579 refill2(c);
00580 #endif
00581 #endif
00582 return bit;
00583 }
00584
00585 static int av_noinline get_cabac_noinline(CABACContext *c, uint8_t * const state){
00586 return get_cabac_inline(c,state);
00587 }
00588
00589 static int get_cabac(CABACContext *c, uint8_t * const state){
00590 return get_cabac_inline(c,state);
00591 }
00592
00593 static int get_cabac_bypass(CABACContext *c){
00594 #if 0 //not faster
00595 int bit;
00596 asm volatile(
00597 "movl "RANGE "(%1), %%ebx \n\t"
00598 "movl "LOW "(%1), %%eax \n\t"
00599 "shl $17, %%ebx \n\t"
00600 "add %%eax, %%eax \n\t"
00601 "sub %%ebx, %%eax \n\t"
00602 "cdq \n\t"
00603 "and %%edx, %%ebx \n\t"
00604 "add %%ebx, %%eax \n\t"
00605 "test %%ax, %%ax \n\t"
00606 " jnz 1f \n\t"
00607 "movl "BYTE "(%1), %%"REG_b" \n\t"
00608 "subl $0xFFFF, %%eax \n\t"
00609 "movzwl (%%"REG_b"), %%ecx \n\t"
00610 "bswap %%ecx \n\t"
00611 "shrl $15, %%ecx \n\t"
00612 "addl $2, %%"REG_b" \n\t"
00613 "addl %%ecx, %%eax \n\t"
00614 "movl %%"REG_b", "BYTE "(%1) \n\t"
00615 "1: \n\t"
00616 "movl %%eax, "LOW "(%1) \n\t"
00617
00618 :"=&d"(bit)
00619 :"r"(c)
00620 : "%eax", "%"REG_b, "%ecx", "memory"
00621 );
00622 return bit+1;
00623 #else
00624 int range;
00625 c->low += c->low;
00626
00627 if(!(c->low & CABAC_MASK))
00628 refill(c);
00629
00630 range= c->range<<(CABAC_BITS+1);
00631 if(c->low < range){
00632 return 0;
00633 }else{
00634 c->low -= range;
00635 return 1;
00636 }
00637 #endif
00638 }
00639
00640
00641 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
00642 #if defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__))
00643 asm volatile(
00644 "movl "RANGE "(%1), %%ebx \n\t"
00645 "movl "LOW "(%1), %%eax \n\t"
00646 "shl $17, %%ebx \n\t"
00647 "add %%eax, %%eax \n\t"
00648 "sub %%ebx, %%eax \n\t"
00649 "cdq \n\t"
00650 "and %%edx, %%ebx \n\t"
00651 "add %%ebx, %%eax \n\t"
00652 "xor %%edx, %%ecx \n\t"
00653 "sub %%edx, %%ecx \n\t"
00654 "test %%ax, %%ax \n\t"
00655 " jnz 1f \n\t"
00656 "mov "BYTE "(%1), %%"REG_b" \n\t"
00657 "subl $0xFFFF, %%eax \n\t"
00658 "movzwl (%%"REG_b"), %%edx \n\t"
00659 "bswap %%edx \n\t"
00660 "shrl $15, %%edx \n\t"
00661 "add $2, %%"REG_b" \n\t"
00662 "addl %%edx, %%eax \n\t"
00663 "mov %%"REG_b", "BYTE "(%1) \n\t"
00664 "1: \n\t"
00665 "movl %%eax, "LOW "(%1) \n\t"
00666
00667 :"+c"(val)
00668 :"r"(c)
00669 : "%eax", "%"REG_b, "%edx", "memory"
00670 );
00671 return val;
00672 #else
00673 int range, mask;
00674 c->low += c->low;
00675
00676 if(!(c->low & CABAC_MASK))
00677 refill(c);
00678
00679 range= c->range<<(CABAC_BITS+1);
00680 c->low -= range;
00681 mask= c->low >> 31;
00682 range &= mask;
00683 c->low += range;
00684 return (val^mask)-mask;
00685 #endif
00686 }
00687
00688
00689
00690 #if defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS)
00691 static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *significant_coeff_ctx_base, int *index){
00692 void *end= significant_coeff_ctx_base + max_coeff - 1;
00693 int minusstart= -(int)significant_coeff_ctx_base;
00694 int minusindex= 4-(int)index;
00695 int coeff_count;
00696 asm volatile(
00697 "movl "RANGE "(%3), %%esi \n\t"
00698 "movl "LOW "(%3), %%ebx \n\t"
00699
00700 "2: \n\t"
00701
00702 BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
00703
00704 "test $1, %%edx \n\t"
00705 " jz 3f \n\t"
00706
00707 BRANCHLESS_GET_CABAC("%%edx", "%3", "61(%1)", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
00708
00709 "mov %2, %%"REG_a" \n\t"
00710 "movl %4, %%ecx \n\t"
00711 "add %1, %%"REG_c" \n\t"
00712 "movl %%ecx, (%%"REG_a") \n\t"
00713
00714 "test $1, %%edx \n\t"
00715 " jnz 4f \n\t"
00716
00717 "add $4, %%"REG_a" \n\t"
00718 "mov %%"REG_a", %2 \n\t"
00719
00720 "3: \n\t"
00721 "add $1, %1 \n\t"
00722 "cmp %5, %1 \n\t"
00723 " jb 2b \n\t"
00724 "mov %2, %%"REG_a" \n\t"
00725 "movl %4, %%ecx \n\t"
00726 "add %1, %%"REG_c" \n\t"
00727 "movl %%ecx, (%%"REG_a") \n\t"
00728 "4: \n\t"
00729 "add %6, %%eax \n\t"
00730 "shr $2, %%eax \n\t"
00731
00732 "movl %%esi, "RANGE "(%3) \n\t"
00733 "movl %%ebx, "LOW "(%3) \n\t"
00734 :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index)\
00735 :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex)\
00736 : "%"REG_c, "%ebx", "%edx", "%esi", "memory"\
00737 );
00738 return coeff_count;
00739 }
00740
00741 static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, const uint8_t *sig_off){
00742 int minusindex= 4-(int)index;
00743 int coeff_count;
00744 long last=0;
00745 asm volatile(
00746 "movl "RANGE "(%3), %%esi \n\t"
00747 "movl "LOW "(%3), %%ebx \n\t"
00748
00749 "mov %1, %%"REG_D" \n\t"
00750 "2: \n\t"
00751
00752 "mov %6, %%"REG_a" \n\t"
00753 "movzbl (%%"REG_a", %%"REG_D"), %%edi \n\t"
00754 "add %5, %%"REG_D" \n\t"
00755
00756 BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
00757
00758 "mov %1, %%edi \n\t"
00759 "test $1, %%edx \n\t"
00760 " jz 3f \n\t"
00761
00762 "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t"
00763 "add %5, %%"REG_D" \n\t"
00764
00765 BRANCHLESS_GET_CABAC("%%edx", "%3", "15(%%"REG_D")", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
00766
00767 "mov %2, %%"REG_a" \n\t"
00768 "mov %1, %%edi \n\t"
00769 "movl %%edi, (%%"REG_a") \n\t"
00770
00771 "test $1, %%edx \n\t"
00772 " jnz 4f \n\t"
00773
00774 "add $4, %%"REG_a" \n\t"
00775 "mov %%"REG_a", %2 \n\t"
00776
00777 "3: \n\t"
00778 "addl $1, %%edi \n\t"
00779 "mov %%edi, %1 \n\t"
00780 "cmpl $63, %%edi \n\t"
00781 " jb 2b \n\t"
00782 "mov %2, %%"REG_a" \n\t"
00783 "movl %%edi, (%%"REG_a") \n\t"
00784 "4: \n\t"
00785 "addl %4, %%eax \n\t"
00786 "shr $2, %%eax \n\t"
00787
00788 "movl %%esi, "RANGE "(%3) \n\t"
00789 "movl %%ebx, "LOW "(%3) \n\t"
00790 :"=&a"(coeff_count),"+m"(last), "+m"(index)\
00791 :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off)\
00792 : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory"\
00793 );
00794 return coeff_count;
00795 }
00796 #endif
00797
00802 static int get_cabac_terminate(CABACContext *c){
00803 c->range -= 2;
00804 if(c->low < c->range<<(CABAC_BITS+1)){
00805 renorm_cabac_decoder_once(c);
00806 return 0;
00807 }else{
00808 return c->bytestream - c->bytestream_start;
00809 }
00810 }
00811
00812 #if 0
00813
00816 static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
00817 int i;
00818
00819 for(i=0; i<max; i++){
00820 if(get_cabac(c, state)==0)
00821 return i;
00822
00823 if(i< max_index) state++;
00824 }
00825
00826 return truncated ? max : -1;
00827 }
00828
00832 static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
00833 int i, v;
00834 int m= 1<<k;
00835
00836 if(get_cabac(c, state)==0)
00837 return 0;
00838
00839 if(0 < max_index) state++;
00840
00841 for(i=1; i<max; i++){
00842 if(get_cabac(c, state)==0){
00843 if(is_signed && get_cabac_bypass(c)){
00844 return -i;
00845 }else
00846 return i;
00847 }
00848
00849 if(i < max_index) state++;
00850 }
00851
00852 while(get_cabac_bypass(c)){
00853 i+= m;
00854 m+= m;
00855 }
00856
00857 v=0;
00858 while(m>>=1){
00859 v+= v + get_cabac_bypass(c);
00860 }
00861 i += v;
00862
00863 if(is_signed && get_cabac_bypass(c)){
00864 return -i;
00865 }else
00866 return i;
00867 }
00868 #endif
00869
00870 #endif