diff options
Diffstat (limited to 'apps/codecs/libwmapro/wma.c')
-rw-r--r-- | apps/codecs/libwmapro/wma.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/apps/codecs/libwmapro/wma.c b/apps/codecs/libwmapro/wma.c index 4b36c84aad..b1b1268eea 100644 --- a/apps/codecs/libwmapro/wma.c +++ b/apps/codecs/libwmapro/wma.c | |||
@@ -523,3 +523,58 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, | |||
523 | return 0; | 523 | return 0; |
524 | } | 524 | } |
525 | 525 | ||
526 | int ff_wma_fix_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, | ||
527 | VLC *vlc, | ||
528 | const int32_t *level_table, const uint16_t *run_table, | ||
529 | int version, int32_t *ptr, int offset, | ||
530 | int num_coefs, int block_len, int frame_len_bits, | ||
531 | int coef_nb_bits) | ||
532 | { | ||
533 | int32_t code, level, sign; | ||
534 | const unsigned int coef_mask = block_len - 1; | ||
535 | for (; offset < num_coefs; offset++) { | ||
536 | code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); | ||
537 | if (code > 1) { | ||
538 | /** normal code */ | ||
539 | offset += run_table[code]; | ||
540 | sign = !get_bits1(gb); | ||
541 | ptr[offset & coef_mask] = sign ? -level_table[code] : level_table[code]; | ||
542 | ptr[offset & coef_mask] <<= 16; | ||
543 | } else if (code == 1) { | ||
544 | /** EOB */ | ||
545 | break; | ||
546 | } else { | ||
547 | /** escape */ | ||
548 | if (!version) { | ||
549 | level = get_bits(gb, coef_nb_bits); | ||
550 | /** NOTE: this is rather suboptimal. reading | ||
551 | block_len_bits would be better */ | ||
552 | offset += get_bits(gb, frame_len_bits); | ||
553 | } else { | ||
554 | level = ff_wma_get_large_val(gb); | ||
555 | /** escape decode */ | ||
556 | if (get_bits1(gb)) { | ||
557 | if (get_bits1(gb)) { | ||
558 | if (get_bits1(gb)) { | ||
559 | av_log(avctx,AV_LOG_ERROR, | ||
560 | "broken escape sequence\n"); | ||
561 | return -1; | ||
562 | } else | ||
563 | offset += get_bits(gb, frame_len_bits) + 4; | ||
564 | } else | ||
565 | offset += get_bits(gb, 2) + 1; | ||
566 | } | ||
567 | } | ||
568 | sign = !get_bits1(gb); | ||
569 | ptr[offset & coef_mask] = sign ? -level : level; | ||
570 | ptr[offset & coef_mask] <<=16; | ||
571 | } | ||
572 | } | ||
573 | /** NOTE: EOB can be omitted */ | ||
574 | if (offset > num_coefs) { | ||
575 | av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); | ||
576 | return -1; | ||
577 | } | ||
578 | |||
579 | return 0; | ||
580 | } | ||