summaryrefslogtreecommitdiff
path: root/apps/codecs/libwmapro/wma.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libwmapro/wma.c')
-rw-r--r--apps/codecs/libwmapro/wma.c55
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
526int 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}