comparison h264.c @ 6749:b1778cf7f3b1 libavcodec

Use a state machine to reduce branching logic in decode_cabac_residual. Patch by Jason Garrett-Glaser (darkshikari gmail com)
author astrange
date Sun, 04 May 2008 22:39:12 +0000
parents 5df0c730234d
children 73de16350531
comparison
equal deleted inserted replaced
6748:7fea187c80b0 6749:b1778cf7f3b1
5392 { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5, 5392 { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5,
5393 6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11, 5393 6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11,
5394 9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9, 5394 9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
5395 9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 } 5395 9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 }
5396 }; 5396 };
5397 /* node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
5398 * 4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter).
5399 * map node ctx => cabac ctx for level=1 */
5400 static const uint8_t coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
5401 /* map node ctx => cabac ctx for level>1 */
5402 static const uint8_t coeff_abs_levelgt1_ctx[8] = { 5, 5, 5, 5, 6, 7, 8, 9 };
5403 static const uint8_t coeff_abs_level_transition[2][8] = {
5404 /* update node ctx after decoding a level=1 */
5405 { 1, 2, 3, 3, 4, 5, 6, 7 },
5406 /* update node ctx after decoding a level>1 */
5407 { 4, 4, 4, 4, 5, 6, 7, 7 }
5408 };
5397 5409
5398 int index[64]; 5410 int index[64];
5399 5411
5400 int av_unused last; 5412 int av_unused last;
5401 int coeff_count = 0; 5413 int coeff_count = 0;
5402 5414 int node_ctx = 0;
5403 int abslevel1 = 1;
5404 int abslevelgt1 = 0;
5405 5415
5406 uint8_t *significant_coeff_ctx_base; 5416 uint8_t *significant_coeff_ctx_base;
5407 uint8_t *last_coeff_ctx_base; 5417 uint8_t *last_coeff_ctx_base;
5408 uint8_t *abs_level_m1_ctx_base; 5418 uint8_t *abs_level_m1_ctx_base;
5409 5419
5493 assert( cat == 5 ); 5503 assert( cat == 5 );
5494 fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1); 5504 fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1);
5495 } 5505 }
5496 5506
5497 for( coeff_count--; coeff_count >= 0; coeff_count-- ) { 5507 for( coeff_count--; coeff_count >= 0; coeff_count-- ) {
5498 uint8_t *ctx = (abslevelgt1 != 0 ? 0 : FFMIN( 4, abslevel1 )) + abs_level_m1_ctx_base; 5508 uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base;
5509
5499 int j= scantable[index[coeff_count]]; 5510 int j= scantable[index[coeff_count]];
5500 5511
5501 if( get_cabac( CC, ctx ) == 0 ) { 5512 if( get_cabac( CC, ctx ) == 0 ) {
5513 node_ctx = coeff_abs_level_transition[0][node_ctx];
5502 if( !qmul ) { 5514 if( !qmul ) {
5503 block[j] = get_cabac_bypass_sign( CC, -1); 5515 block[j] = get_cabac_bypass_sign( CC, -1);
5504 }else{ 5516 }else{
5505 block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; 5517 block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6;
5506 } 5518 }
5507
5508 abslevel1++;
5509 } else { 5519 } else {
5510 int coeff_abs = 2; 5520 int coeff_abs = 2;
5511 ctx = 5 + FFMIN( 4, abslevelgt1 ) + abs_level_m1_ctx_base; 5521 ctx = coeff_abs_levelgt1_ctx[node_ctx] + abs_level_m1_ctx_base;
5522 node_ctx = coeff_abs_level_transition[1][node_ctx];
5523
5512 while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { 5524 while( coeff_abs < 15 && get_cabac( CC, ctx ) ) {
5513 coeff_abs++; 5525 coeff_abs++;
5514 } 5526 }
5515 5527
5516 if( coeff_abs >= 15 ) { 5528 if( coeff_abs >= 15 ) {
5531 else block[j] = coeff_abs; 5543 else block[j] = coeff_abs;
5532 }else{ 5544 }else{
5533 if( get_cabac_bypass( CC ) ) block[j] = (-coeff_abs * qmul[j] + 32) >> 6; 5545 if( get_cabac_bypass( CC ) ) block[j] = (-coeff_abs * qmul[j] + 32) >> 6;
5534 else block[j] = ( coeff_abs * qmul[j] + 32) >> 6; 5546 else block[j] = ( coeff_abs * qmul[j] + 32) >> 6;
5535 } 5547 }
5536
5537 abslevelgt1++;
5538 } 5548 }
5539 } 5549 }
5540 #ifdef CABAC_ON_STACK 5550 #ifdef CABAC_ON_STACK
5541 h->cabac.range = cc.range ; 5551 h->cabac.range = cc.range ;
5542 h->cabac.low = cc.low ; 5552 h->cabac.low = cc.low ;