Mercurial > libavcodec.hg
comparison wma.c @ 9871:4433ce8ef249 libavcodec
Simplify run level decoding:
- remove unneeded vlc code < 0 check
- reorder vlc code handling so that the unlikely escape decoding
part comes last
- move overflow check out of the decode loop
- branchless sign conversion
author | faust3 |
---|---|
date | Sat, 20 Jun 2009 11:06:48 +0000 |
parents | 40638c6c2d69 |
children | 01ccb357a33c |
comparison
equal
deleted
inserted
replaced
9870:40638c6c2d69 | 9871:4433ce8ef249 |
---|---|
468 const uint16_t *level_table, const uint16_t *run_table, | 468 const uint16_t *level_table, const uint16_t *run_table, |
469 int version, WMACoef *ptr, int offset, | 469 int version, WMACoef *ptr, int offset, |
470 int num_coefs, int block_len, int frame_len_bits, | 470 int num_coefs, int block_len, int frame_len_bits, |
471 int coef_nb_bits) | 471 int coef_nb_bits) |
472 { | 472 { |
473 int code, run, level, sign; | 473 int code, level, sign; |
474 WMACoef* eptr = ptr + num_coefs; | 474 const unsigned int coef_mask = block_len - 1; |
475 ptr += offset; | 475 for (; offset < num_coefs; offset++) { |
476 for(;;) { | |
477 code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); | 476 code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); |
478 if (code < 0) | 477 if (code > 1) { |
479 return -1; | 478 /** normal code */ |
480 if (code == 1) { | 479 offset += run_table[code]; |
480 level = level_table[code]; | |
481 } else if (code == 1) { | |
481 /* EOB */ | 482 /* EOB */ |
482 break; | 483 break; |
483 } else if (code == 0) { | 484 } else { |
484 /* escape */ | 485 /* escape */ |
485 if (!version) { | 486 if (!version) { |
486 level = get_bits(gb, coef_nb_bits); | 487 level = get_bits(gb, coef_nb_bits); |
487 /* NOTE: this is rather suboptimal. reading | 488 /* NOTE: this is rather suboptimal. reading |
488 block_len_bits would be better */ | 489 block_len_bits would be better */ |
489 run = get_bits(gb, frame_len_bits); | 490 offset += get_bits(gb, frame_len_bits); |
490 } else { | 491 } else { |
491 level = ff_wma_get_large_val(gb); | 492 level = ff_wma_get_large_val(gb); |
492 /** escape decode */ | 493 /** escape decode */ |
493 if (get_bits1(gb)) { | 494 if (get_bits1(gb)) { |
494 if (get_bits1(gb)) { | 495 if (get_bits1(gb)) { |
495 if (get_bits1(gb)) { | 496 if (get_bits1(gb)) { |
496 av_log(avctx,AV_LOG_ERROR, | 497 av_log(avctx,AV_LOG_ERROR, |
497 "broken escape sequence\n"); | 498 "broken escape sequence\n"); |
498 return -1; | 499 return -1; |
499 } else | 500 } else |
500 run = get_bits(gb, frame_len_bits) + 4; | 501 offset += get_bits(gb, frame_len_bits) + 4; |
501 } else | 502 } else |
502 run = get_bits(gb, 2) + 1; | 503 offset += get_bits(gb, 2) + 1; |
503 } else | 504 } |
504 run = 0; | |
505 } | 505 } |
506 } else { | 506 } |
507 /* normal code */ | 507 sign = get_bits1(gb) - 1; |
508 run = run_table[code]; | 508 ptr[offset & coef_mask] = (level^sign) - sign; |
509 level = level_table[code]; | 509 } |
510 } | 510 /** NOTE: EOB can be omitted */ |
511 sign = get_bits1(gb); | 511 if (offset > num_coefs) { |
512 if (!sign) | 512 av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); |
513 level = -level; | 513 return -1; |
514 ptr += run; | 514 } |
515 if (ptr >= eptr) | 515 |
516 { | |
517 av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); | |
518 break; | |
519 } | |
520 *ptr++ = level; | |
521 /* NOTE: EOB can be omitted */ | |
522 if (ptr >= eptr) | |
523 break; | |
524 } | |
525 return 0; | 516 return 0; |
526 } | 517 } |
527 | 518 |