Libav 0.7.1
|
00001 /* 00002 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder 00003 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #ifndef AVCODEC_CABAC_H 00028 #define AVCODEC_CABAC_H 00029 00030 #include "put_bits.h" 00031 00032 //#undef NDEBUG 00033 #include <assert.h> 00034 #include "libavutil/x86_cpu.h" 00035 00036 #define CABAC_BITS 16 00037 #define CABAC_MASK ((1<<CABAC_BITS)-1) 00038 #define BRANCHLESS_CABAC_DECODER 1 00039 //#define ARCH_X86_DISABLED 1 00040 00041 typedef struct CABACContext{ 00042 int low; 00043 int range; 00044 int outstanding_count; 00045 #ifdef STRICT_LIMITS 00046 int symCount; 00047 #endif 00048 const uint8_t *bytestream_start; 00049 const uint8_t *bytestream; 00050 const uint8_t *bytestream_end; 00051 PutBitContext pb; 00052 }CABACContext; 00053 00054 extern uint8_t ff_h264_mlps_state[4*64]; 00055 extern uint8_t ff_h264_lps_range[4*2*64]; 00056 extern uint8_t ff_h264_mps_state[2*64]; 00057 extern uint8_t ff_h264_lps_state[2*64]; 00058 extern const uint8_t ff_h264_norm_shift[512]; 00059 00060 00061 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); 00062 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); 00063 void ff_init_cabac_states(CABACContext *c); 00064 00065 00066 static inline void put_cabac_bit(CABACContext *c, int b){ 00067 put_bits(&c->pb, 1, b); 00068 for(;c->outstanding_count; c->outstanding_count--){ 00069 put_bits(&c->pb, 1, 1-b); 00070 } 00071 } 00072 00073 static inline void renorm_cabac_encoder(CABACContext *c){ 00074 while(c->range < 0x100){ 00075 //FIXME optimize 00076 if(c->low<0x100){ 00077 put_cabac_bit(c, 0); 00078 }else if(c->low<0x200){ 00079 c->outstanding_count++; 00080 c->low -= 0x100; 00081 }else{ 00082 put_cabac_bit(c, 1); 00083 c->low -= 0x200; 00084 } 00085 00086 c->range+= c->range; 00087 c->low += c->low; 00088 } 00089 } 00090 00091 #ifdef TEST 00092 static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ 00093 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state]; 00094 00095 if(bit == ((*state)&1)){ 00096 c->range -= RangeLPS; 00097 *state= ff_h264_mps_state[*state]; 00098 }else{ 00099 c->low += c->range - RangeLPS; 00100 c->range = RangeLPS; 00101 *state= ff_h264_lps_state[*state]; 00102 } 00103 00104 renorm_cabac_encoder(c); 00105 00106 #ifdef STRICT_LIMITS 00107 c->symCount++; 00108 #endif 00109 } 00110 00111 static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){ 00112 assert(c->range > RangeLPS); 00113 00114 if(!bit){ 00115 c->range -= RangeLPS; 00116 }else{ 00117 c->low += c->range - RangeLPS; 00118 c->range = RangeLPS; 00119 } 00120 00121 renorm_cabac_encoder(c); 00122 00123 #ifdef STRICT_LIMITS 00124 c->symCount++; 00125 #endif 00126 } 00127 00131 static void put_cabac_bypass(CABACContext *c, int bit){ 00132 c->low += c->low; 00133 00134 if(bit){ 00135 c->low += c->range; 00136 } 00137 //FIXME optimize 00138 if(c->low<0x200){ 00139 put_cabac_bit(c, 0); 00140 }else if(c->low<0x400){ 00141 c->outstanding_count++; 00142 c->low -= 0x200; 00143 }else{ 00144 put_cabac_bit(c, 1); 00145 c->low -= 0x400; 00146 } 00147 00148 #ifdef STRICT_LIMITS 00149 c->symCount++; 00150 #endif 00151 } 00152 00157 static int put_cabac_terminate(CABACContext *c, int bit){ 00158 c->range -= 2; 00159 00160 if(!bit){ 00161 renorm_cabac_encoder(c); 00162 }else{ 00163 c->low += c->range; 00164 c->range= 2; 00165 00166 renorm_cabac_encoder(c); 00167 00168 assert(c->low <= 0x1FF); 00169 put_cabac_bit(c, c->low>>9); 00170 put_bits(&c->pb, 2, ((c->low>>7)&3)|1); 00171 00172 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong 00173 } 00174 00175 #ifdef STRICT_LIMITS 00176 c->symCount++; 00177 #endif 00178 00179 return (put_bits_count(&c->pb)+7)>>3; 00180 } 00181 00185 static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){ 00186 int i; 00187 00188 assert(v <= max); 00189 00190 #if 1 00191 for(i=0; i<v; i++){ 00192 put_cabac(c, state, 1); 00193 if(i < max_index) state++; 00194 } 00195 if(truncated==0 || v<max) 00196 put_cabac(c, state, 0); 00197 #else 00198 if(v <= max_index){ 00199 for(i=0; i<v; i++){ 00200 put_cabac(c, state+i, 1); 00201 } 00202 if(truncated==0 || v<max) 00203 put_cabac(c, state+i, 0); 00204 }else{ 00205 for(i=0; i<=max_index; i++){ 00206 put_cabac(c, state+i, 1); 00207 } 00208 for(; i<v; i++){ 00209 put_cabac(c, state+max_index, 1); 00210 } 00211 if(truncated==0 || v<max) 00212 put_cabac(c, state+max_index, 0); 00213 } 00214 #endif 00215 } 00216 00220 static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){ 00221 int i; 00222 00223 if(v==0) 00224 put_cabac(c, state, 0); 00225 else{ 00226 const int sign= v < 0; 00227 00228 if(is_signed) v= FFABS(v); 00229 00230 if(v<max){ 00231 for(i=0; i<v; i++){ 00232 put_cabac(c, state, 1); 00233 if(i < max_index) state++; 00234 } 00235 00236 put_cabac(c, state, 0); 00237 }else{ 00238 int m= 1<<k; 00239 00240 for(i=0; i<max; i++){ 00241 put_cabac(c, state, 1); 00242 if(i < max_index) state++; 00243 } 00244 00245 v -= max; 00246 while(v >= m){ //FIXME optimize 00247 put_cabac_bypass(c, 1); 00248 v-= m; 00249 m+= m; 00250 } 00251 put_cabac_bypass(c, 0); 00252 while(m>>=1){ 00253 put_cabac_bypass(c, v&m); 00254 } 00255 } 00256 00257 if(is_signed) 00258 put_cabac_bypass(c, sign); 00259 } 00260 } 00261 #endif /* TEST */ 00262 00263 static void refill(CABACContext *c){ 00264 #if CABAC_BITS == 16 00265 c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 00266 #else 00267 c->low+= c->bytestream[0]<<1; 00268 #endif 00269 c->low -= CABAC_MASK; 00270 c->bytestream+= CABAC_BITS/8; 00271 } 00272 00273 #if ! ( ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) ) 00274 static void refill2(CABACContext *c){ 00275 int i, x; 00276 00277 x= c->low ^ (c->low-1); 00278 i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; 00279 00280 x= -CABAC_MASK; 00281 00282 #if CABAC_BITS == 16 00283 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 00284 #else 00285 x+= c->bytestream[0]<<1; 00286 #endif 00287 00288 c->low += x<<i; 00289 c->bytestream+= CABAC_BITS/8; 00290 } 00291 #endif 00292 00293 static inline void renorm_cabac_decoder(CABACContext *c){ 00294 while(c->range < 0x100){ 00295 c->range+= c->range; 00296 c->low+= c->low; 00297 if(!(c->low & CABAC_MASK)) 00298 refill(c); 00299 } 00300 } 00301 00302 static inline void renorm_cabac_decoder_once(CABACContext *c){ 00303 #ifdef ARCH_X86_DISABLED 00304 int temp; 00305 #if 0 00306 //P3:683 athlon:475 00307 __asm__( 00308 "lea -0x100(%0), %2 \n\t" 00309 "shr $31, %2 \n\t" //FIXME 31->63 for x86-64 00310 "shl %%cl, %0 \n\t" 00311 "shl %%cl, %1 \n\t" 00312 : "+r"(c->range), "+r"(c->low), "+c"(temp) 00313 ); 00314 #elif 0 00315 //P3:680 athlon:474 00316 __asm__( 00317 "cmp $0x100, %0 \n\t" 00318 "setb %%cl \n\t" //FIXME 31->63 for x86-64 00319 "shl %%cl, %0 \n\t" 00320 "shl %%cl, %1 \n\t" 00321 : "+r"(c->range), "+r"(c->low), "+c"(temp) 00322 ); 00323 #elif 1 00324 int temp2; 00325 //P3:665 athlon:517 00326 __asm__( 00327 "lea -0x100(%0), %%eax \n\t" 00328 "cltd \n\t" 00329 "mov %0, %%eax \n\t" 00330 "and %%edx, %0 \n\t" 00331 "and %1, %%edx \n\t" 00332 "add %%eax, %0 \n\t" 00333 "add %%edx, %1 \n\t" 00334 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) 00335 ); 00336 #elif 0 00337 int temp2; 00338 //P3:673 athlon:509 00339 __asm__( 00340 "cmp $0x100, %0 \n\t" 00341 "sbb %%edx, %%edx \n\t" 00342 "mov %0, %%eax \n\t" 00343 "and %%edx, %0 \n\t" 00344 "and %1, %%edx \n\t" 00345 "add %%eax, %0 \n\t" 00346 "add %%edx, %1 \n\t" 00347 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) 00348 ); 00349 #else 00350 int temp2; 00351 //P3:677 athlon:511 00352 __asm__( 00353 "cmp $0x100, %0 \n\t" 00354 "lea (%0, %0), %%eax \n\t" 00355 "lea (%1, %1), %%edx \n\t" 00356 "cmovb %%eax, %0 \n\t" 00357 "cmovb %%edx, %1 \n\t" 00358 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) 00359 ); 00360 #endif 00361 #else 00362 //P3:675 athlon:476 00363 int shift= (uint32_t)(c->range - 0x100)>>31; 00364 c->range<<= shift; 00365 c->low <<= shift; 00366 #endif 00367 if(!(c->low & CABAC_MASK)) 00368 refill(c); 00369 } 00370 00371 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ 00372 //FIXME gcc generates duplicate load/stores for c->low and c->range 00373 #define LOW "0" 00374 #define RANGE "4" 00375 #if ARCH_X86_64 00376 #define BYTESTART "16" 00377 #define BYTE "24" 00378 #define BYTEEND "32" 00379 #else 00380 #define BYTESTART "12" 00381 #define BYTE "16" 00382 #define BYTEEND "20" 00383 #endif 00384 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) 00385 int bit; 00386 00387 #ifndef BRANCHLESS_CABAC_DECODER 00388 __asm__ volatile( 00389 "movzbl (%1), %0 \n\t" 00390 "movl "RANGE "(%2), %%ebx \n\t" 00391 "movl "RANGE "(%2), %%edx \n\t" 00392 "andl $0xC0, %%ebx \n\t" 00393 "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t" 00394 "movl "LOW "(%2), %%ebx \n\t" 00395 //eax:state ebx:low, edx:range, esi:RangeLPS 00396 "subl %%esi, %%edx \n\t" 00397 "movl %%edx, %%ecx \n\t" 00398 "shll $17, %%ecx \n\t" 00399 "cmpl %%ecx, %%ebx \n\t" 00400 " ja 1f \n\t" 00401 00402 #if 1 00403 //athlon:4067 P3:4110 00404 "lea -0x100(%%edx), %%ecx \n\t" 00405 "shr $31, %%ecx \n\t" 00406 "shl %%cl, %%edx \n\t" 00407 "shl %%cl, %%ebx \n\t" 00408 #else 00409 //athlon:4057 P3:4130 00410 "cmp $0x100, %%edx \n\t" //FIXME avoidable 00411 "setb %%cl \n\t" 00412 "shl %%cl, %%edx \n\t" 00413 "shl %%cl, %%ebx \n\t" 00414 #endif 00415 "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t" 00416 "movb %%cl, (%1) \n\t" 00417 //eax:state ebx:low, edx:range, esi:RangeLPS 00418 "test %%bx, %%bx \n\t" 00419 " jnz 2f \n\t" 00420 "mov "BYTE "(%2), %%"REG_S" \n\t" 00421 "subl $0xFFFF, %%ebx \n\t" 00422 "movzwl (%%"REG_S"), %%ecx \n\t" 00423 "bswap %%ecx \n\t" 00424 "shrl $15, %%ecx \n\t" 00425 "add $2, %%"REG_S" \n\t" 00426 "addl %%ecx, %%ebx \n\t" 00427 "mov %%"REG_S", "BYTE "(%2) \n\t" 00428 "jmp 2f \n\t" 00429 "1: \n\t" 00430 //eax:state ebx:low, edx:range, esi:RangeLPS 00431 "subl %%ecx, %%ebx \n\t" 00432 "movl %%esi, %%edx \n\t" 00433 "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t" 00434 "shll %%cl, %%ebx \n\t" 00435 "shll %%cl, %%edx \n\t" 00436 "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t" 00437 "movb %%cl, (%1) \n\t" 00438 "add $1, %0 \n\t" 00439 "test %%bx, %%bx \n\t" 00440 " jnz 2f \n\t" 00441 00442 "mov "BYTE "(%2), %%"REG_c" \n\t" 00443 "movzwl (%%"REG_c"), %%esi \n\t" 00444 "bswap %%esi \n\t" 00445 "shrl $15, %%esi \n\t" 00446 "subl $0xFFFF, %%esi \n\t" 00447 "add $2, %%"REG_c" \n\t" 00448 "mov %%"REG_c", "BYTE "(%2) \n\t" 00449 00450 "leal -1(%%ebx), %%ecx \n\t" 00451 "xorl %%ebx, %%ecx \n\t" 00452 "shrl $15, %%ecx \n\t" 00453 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t" 00454 "neg %%ecx \n\t" 00455 "add $7, %%ecx \n\t" 00456 00457 "shll %%cl , %%esi \n\t" 00458 "addl %%esi, %%ebx \n\t" 00459 "2: \n\t" 00460 "movl %%edx, "RANGE "(%2) \n\t" 00461 "movl %%ebx, "LOW "(%2) \n\t" 00462 :"=&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 00463 :"r"(state), "r"(c) 00464 : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory" 00465 ); 00466 bit&=1; 00467 #else /* BRANCHLESS_CABAC_DECODER */ 00468 00469 00470 #if HAVE_FAST_CMOV 00471 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 00472 "mov "tmp" , %%ecx \n\t"\ 00473 "shl $17 , "tmp" \n\t"\ 00474 "cmp "low" , "tmp" \n\t"\ 00475 "cmova %%ecx , "range" \n\t"\ 00476 "sbb %%ecx , %%ecx \n\t"\ 00477 "and %%ecx , "tmp" \n\t"\ 00478 "sub "tmp" , "low" \n\t"\ 00479 "xor %%ecx , "ret" \n\t" 00480 #else /* HAVE_FAST_CMOV */ 00481 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 00482 "mov "tmp" , %%ecx \n\t"\ 00483 "shl $17 , "tmp" \n\t"\ 00484 "sub "low" , "tmp" \n\t"\ 00485 "sar $31 , "tmp" \n\t" /*lps_mask*/\ 00486 "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ 00487 "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ 00488 "add %%ecx , "range" \n\t" /*new range*/\ 00489 "shl $17 , %%ecx \n\t"\ 00490 "and "tmp" , %%ecx \n\t"\ 00491 "sub %%ecx , "low" \n\t"\ 00492 "xor "tmp" , "ret" \n\t" 00493 #endif /* HAVE_FAST_CMOV */ 00494 00495 00496 #define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 00497 "movzbl "statep" , "ret" \n\t"\ 00498 "mov "range" , "tmp" \n\t"\ 00499 "and $0xC0 , "range" \n\t"\ 00500 "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\ 00501 "sub "range" , "tmp" \n\t"\ 00502 BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ 00503 "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ 00504 "shl %%cl , "range" \n\t"\ 00505 "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ 00506 "mov "tmpbyte" , "statep" \n\t"\ 00507 "shl %%cl , "low" \n\t"\ 00508 "test "lowword" , "lowword" \n\t"\ 00509 " jnz 1f \n\t"\ 00510 "mov "BYTE"("cabac"), %%"REG_c" \n\t"\ 00511 "movzwl (%%"REG_c") , "tmp" \n\t"\ 00512 "bswap "tmp" \n\t"\ 00513 "shr $15 , "tmp" \n\t"\ 00514 "sub $0xFFFF , "tmp" \n\t"\ 00515 "add $2 , %%"REG_c" \n\t"\ 00516 "mov %%"REG_c" , "BYTE "("cabac") \n\t"\ 00517 "lea -1("low") , %%ecx \n\t"\ 00518 "xor "low" , %%ecx \n\t"\ 00519 "shr $15 , %%ecx \n\t"\ 00520 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\ 00521 "neg %%ecx \n\t"\ 00522 "add $7 , %%ecx \n\t"\ 00523 "shl %%cl , "tmp" \n\t"\ 00524 "add "tmp" , "low" \n\t"\ 00525 "1: \n\t" 00526 00527 __asm__ volatile( 00528 "movl "RANGE "(%2), %%esi \n\t" 00529 "movl "LOW "(%2), %%ebx \n\t" 00530 BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl") 00531 "movl %%esi, "RANGE "(%2) \n\t" 00532 "movl %%ebx, "LOW "(%2) \n\t" 00533 00534 :"=&a"(bit) 00535 :"r"(state), "r"(c) 00536 : "%"REG_c, "%ebx", "%edx", "%esi", "memory" 00537 ); 00538 bit&=1; 00539 #endif /* BRANCHLESS_CABAC_DECODER */ 00540 #else /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ 00541 int s = *state; 00542 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; 00543 int bit, lps_mask av_unused; 00544 00545 c->range -= RangeLPS; 00546 #ifndef BRANCHLESS_CABAC_DECODER 00547 if(c->low < (c->range<<(CABAC_BITS+1))){ 00548 bit= s&1; 00549 *state= ff_h264_mps_state[s]; 00550 renorm_cabac_decoder_once(c); 00551 }else{ 00552 bit= ff_h264_norm_shift[RangeLPS]; 00553 c->low -= (c->range<<(CABAC_BITS+1)); 00554 *state= ff_h264_lps_state[s]; 00555 c->range = RangeLPS<<bit; 00556 c->low <<= bit; 00557 bit= (s&1)^1; 00558 00559 if(!(c->low & CABAC_MASK)){ 00560 refill2(c); 00561 } 00562 } 00563 #else /* BRANCHLESS_CABAC_DECODER */ 00564 lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; 00565 00566 c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; 00567 c->range += (RangeLPS - c->range) & lps_mask; 00568 00569 s^=lps_mask; 00570 *state= (ff_h264_mlps_state+128)[s]; 00571 bit= s&1; 00572 00573 lps_mask= ff_h264_norm_shift[c->range]; 00574 c->range<<= lps_mask; 00575 c->low <<= lps_mask; 00576 if(!(c->low & CABAC_MASK)) 00577 refill2(c); 00578 #endif /* BRANCHLESS_CABAC_DECODER */ 00579 #endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ 00580 return bit; 00581 } 00582 00583 static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ 00584 return get_cabac_inline(c,state); 00585 } 00586 00587 static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ 00588 return get_cabac_inline(c,state); 00589 } 00590 00591 static int av_unused get_cabac_bypass(CABACContext *c){ 00592 #if 0 //not faster 00593 int bit; 00594 __asm__ volatile( 00595 "movl "RANGE "(%1), %%ebx \n\t" 00596 "movl "LOW "(%1), %%eax \n\t" 00597 "shl $17, %%ebx \n\t" 00598 "add %%eax, %%eax \n\t" 00599 "sub %%ebx, %%eax \n\t" 00600 "cltd \n\t" 00601 "and %%edx, %%ebx \n\t" 00602 "add %%ebx, %%eax \n\t" 00603 "test %%ax, %%ax \n\t" 00604 " jnz 1f \n\t" 00605 "movl "BYTE "(%1), %%"REG_b" \n\t" 00606 "subl $0xFFFF, %%eax \n\t" 00607 "movzwl (%%"REG_b"), %%ecx \n\t" 00608 "bswap %%ecx \n\t" 00609 "shrl $15, %%ecx \n\t" 00610 "addl $2, %%"REG_b" \n\t" 00611 "addl %%ecx, %%eax \n\t" 00612 "movl %%"REG_b", "BYTE "(%1) \n\t" 00613 "1: \n\t" 00614 "movl %%eax, "LOW "(%1) \n\t" 00615 00616 :"=&d"(bit) 00617 :"r"(c) 00618 : "%eax", "%"REG_b, "%ecx", "memory" 00619 ); 00620 return bit+1; 00621 #else 00622 int range; 00623 c->low += c->low; 00624 00625 if(!(c->low & CABAC_MASK)) 00626 refill(c); 00627 00628 range= c->range<<(CABAC_BITS+1); 00629 if(c->low < range){ 00630 return 0; 00631 }else{ 00632 c->low -= range; 00633 return 1; 00634 } 00635 #endif 00636 } 00637 00638 00639 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ 00640 #if ARCH_X86 && HAVE_EBX_AVAILABLE 00641 __asm__ volatile( 00642 "movl "RANGE "(%1), %%ebx \n\t" 00643 "movl "LOW "(%1), %%eax \n\t" 00644 "shl $17, %%ebx \n\t" 00645 "add %%eax, %%eax \n\t" 00646 "sub %%ebx, %%eax \n\t" 00647 "cltd \n\t" 00648 "and %%edx, %%ebx \n\t" 00649 "add %%ebx, %%eax \n\t" 00650 "xor %%edx, %%ecx \n\t" 00651 "sub %%edx, %%ecx \n\t" 00652 "test %%ax, %%ax \n\t" 00653 " jnz 1f \n\t" 00654 "mov "BYTE "(%1), %%"REG_b" \n\t" 00655 "subl $0xFFFF, %%eax \n\t" 00656 "movzwl (%%"REG_b"), %%edx \n\t" 00657 "bswap %%edx \n\t" 00658 "shrl $15, %%edx \n\t" 00659 "add $2, %%"REG_b" \n\t" 00660 "addl %%edx, %%eax \n\t" 00661 "mov %%"REG_b", "BYTE "(%1) \n\t" 00662 "1: \n\t" 00663 "movl %%eax, "LOW "(%1) \n\t" 00664 00665 :"+c"(val) 00666 :"r"(c) 00667 : "%eax", "%"REG_b, "%edx", "memory" 00668 ); 00669 return val; 00670 #else 00671 int range, mask; 00672 c->low += c->low; 00673 00674 if(!(c->low & CABAC_MASK)) 00675 refill(c); 00676 00677 range= c->range<<(CABAC_BITS+1); 00678 c->low -= range; 00679 mask= c->low >> 31; 00680 range &= mask; 00681 c->low += range; 00682 return (val^mask)-mask; 00683 #endif 00684 } 00685 00690 static int av_unused get_cabac_terminate(CABACContext *c){ 00691 c->range -= 2; 00692 if(c->low < c->range<<(CABAC_BITS+1)){ 00693 renorm_cabac_decoder_once(c); 00694 return 0; 00695 }else{ 00696 return c->bytestream - c->bytestream_start; 00697 } 00698 } 00699 00700 #if 0 00701 00704 static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ 00705 int i; 00706 00707 for(i=0; i<max; i++){ 00708 if(get_cabac(c, state)==0) 00709 return i; 00710 00711 if(i< max_index) state++; 00712 } 00713 00714 return truncated ? max : -1; 00715 } 00716 00720 static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){ 00721 int i, v; 00722 int m= 1<<k; 00723 00724 if(get_cabac(c, state)==0) 00725 return 0; 00726 00727 if(0 < max_index) state++; 00728 00729 for(i=1; i<max; i++){ 00730 if(get_cabac(c, state)==0){ 00731 if(is_signed && get_cabac_bypass(c)){ 00732 return -i; 00733 }else 00734 return i; 00735 } 00736 00737 if(i < max_index) state++; 00738 } 00739 00740 while(get_cabac_bypass(c)){ 00741 i+= m; 00742 m+= m; 00743 } 00744 00745 v=0; 00746 while(m>>=1){ 00747 v+= v + get_cabac_bypass(c); 00748 } 00749 i += v; 00750 00751 if(is_signed && get_cabac_bypass(c)){ 00752 return -i; 00753 }else 00754 return i; 00755 } 00756 #endif /* 0 */ 00757 00758 #endif /* AVCODEC_CABAC_H */