Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * LucasArts VIMA decoder
  3.  * Copyright (c) 2012 Paul B Mahol
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. /**
  23.  * @file
  24.  * LucasArts VIMA audio decoder
  25.  * @author Paul B Mahol
  26.  */
  27.  
  28. #include "libavutil/channel_layout.h"
  29. #include "avcodec.h"
  30. #include "get_bits.h"
  31. #include "internal.h"
  32. #include "adpcm_data.h"
  33.  
  34. static int predict_table_init = 0;
  35. static uint16_t predict_table[5786 * 2];
  36.  
  37. static const uint8_t size_table[] =
  38. {
  39.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  40.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  41.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  42.     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  43.     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  44.     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  45. };
  46.  
  47. static const int8_t index_table1[] =
  48. {
  49.     -1, 4, -1, 4
  50. };
  51.  
  52. static const int8_t index_table2[] =
  53. {
  54.     -1, -1, 2, 6, -1, -1, 2, 6
  55. };
  56.  
  57. static const int8_t index_table3[] =
  58. {
  59.     -1, -1, -1, -1, 1, 2, 4, 6,
  60.     -1, -1, -1, -1, 1, 2, 4, 6
  61. };
  62.  
  63. static const int8_t index_table4[] =
  64. {
  65.     -1, -1, -1, -1, -1, -1, -1, -1,
  66.      1,  1,  1,  2,  2,  4,  5,  6,
  67.     -1, -1, -1, -1, -1, -1, -1, -1,
  68.      1,  1,  1,  2,  2,  4,  5,  6
  69. };
  70.  
  71. static const int8_t index_table5[] =
  72. {
  73.     -1, -1, -1, -1, -1, -1, -1, -1,
  74.     -1, -1, -1, -1, -1, -1, -1, -1,
  75.      1,  1,  1,  1,  1,  2,  2,  2,
  76.      2,  4,  4,  4,  5,  5,  6,  6,
  77.     -1, -1, -1, -1, -1, -1, -1, -1,
  78.     -1, -1, -1, -1, -1, -1, -1, -1,
  79.      1,  1,  1,  1,  1,  2,  2,  2,
  80.      2,  4,  4,  4,  5,  5,  6,  6
  81. };
  82.  
  83. static const int8_t index_table6[] =
  84. {
  85.     -1, -1, -1, -1, -1, -1, -1, -1,
  86.     -1, -1, -1, -1, -1, -1, -1, -1,
  87.     -1, -1, -1, -1, -1, -1, -1, -1,
  88.     -1, -1, -1, -1, -1, -1, -1, -1,
  89.      1,  1,  1,  1,  1,  1,  1,  1,
  90.      1,  1,  2,  2,  2,  2,  2,  2,
  91.      2,  2,  4,  4,  4,  4,  4,  4,
  92.      5,  5,  5,  5,  6,  6,  6,  6,
  93.     -1, -1, -1, -1, -1, -1, -1, -1,
  94.     -1, -1, -1, -1, -1, -1, -1, -1,
  95.     -1, -1, -1, -1, -1, -1, -1, -1,
  96.     -1, -1, -1, -1, -1, -1, -1, -1,
  97.      1,  1,  1,  1,  1,  1,  1,  1,
  98.      1,  1,  2,  2,  2,  2,  2,  2,
  99.      2,  2,  4,  4,  4,  4,  4,  4,
  100.      5,  5,  5,  5,  6,  6,  6,  6
  101. };
  102.  
  103. static const int8_t* const step_index_tables[] =
  104. {
  105.     index_table1, index_table2, index_table3,
  106.     index_table4, index_table5, index_table6
  107. };
  108.  
  109. static av_cold int decode_init(AVCodecContext *avctx)
  110. {
  111.     int start_pos;
  112.  
  113.     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
  114.  
  115.     if (predict_table_init)
  116.         return 0;
  117.  
  118.     for (start_pos = 0; start_pos < 64; start_pos++) {
  119.         unsigned int dest_pos, table_pos;
  120.  
  121.         for (table_pos = 0, dest_pos = start_pos;
  122.              table_pos < FF_ARRAY_ELEMS(ff_adpcm_step_table);
  123.              table_pos++, dest_pos += 64) {
  124.             int put = 0, count, table_value;
  125.  
  126.             table_value = ff_adpcm_step_table[table_pos];
  127.             for (count = 32; count != 0; count >>= 1) {
  128.                 if (start_pos & count)
  129.                     put += table_value;
  130.                 table_value >>= 1;
  131.             }
  132.             predict_table[dest_pos] = put;
  133.         }
  134.     }
  135.     predict_table_init = 1;
  136.  
  137.     return 0;
  138. }
  139.  
  140. static int decode_frame(AVCodecContext *avctx, void *data,
  141.                         int *got_frame_ptr, AVPacket *pkt)
  142. {
  143.     GetBitContext  gb;
  144.     AVFrame        *frame = data;
  145.     int16_t        pcm_data[2];
  146.     uint32_t       samples;
  147.     int8_t         channel_hint[2];
  148.     int            ret, chan, channels = 1;
  149.  
  150.     if (pkt->size < 13)
  151.         return AVERROR_INVALIDDATA;
  152.  
  153.     if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0)
  154.         return ret;
  155.  
  156.     samples = get_bits_long(&gb, 32);
  157.     if (samples == 0xffffffff) {
  158.         skip_bits_long(&gb, 32);
  159.         samples = get_bits_long(&gb, 32);
  160.     }
  161.  
  162.     if (samples > pkt->size * 2)
  163.         return AVERROR_INVALIDDATA;
  164.  
  165.     channel_hint[0] = get_sbits(&gb, 8);
  166.     if (channel_hint[0] & 0x80) {
  167.         channel_hint[0] = ~channel_hint[0];
  168.         channels = 2;
  169.     }
  170.     avctx->channels = channels;
  171.     avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO :
  172.                                               AV_CH_LAYOUT_MONO;
  173.     pcm_data[0] = get_sbits(&gb, 16);
  174.     if (channels > 1) {
  175.         channel_hint[1] = get_sbits(&gb, 8);
  176.         pcm_data[1] = get_sbits(&gb, 16);
  177.     }
  178.  
  179.     frame->nb_samples = samples;
  180.     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
  181.         return ret;
  182.  
  183.     for (chan = 0; chan < channels; chan++) {
  184.         uint16_t *dest = (uint16_t*)frame->data[0] + chan;
  185.         int step_index = channel_hint[chan];
  186.         int output = pcm_data[chan];
  187.         int sample;
  188.  
  189.         for (sample = 0; sample < samples; sample++) {
  190.             int lookup_size, lookup, highbit, lowbits;
  191.  
  192.             step_index  = av_clip(step_index, 0, 88);
  193.             lookup_size = size_table[step_index];
  194.             lookup      = get_bits(&gb, lookup_size);
  195.             highbit     = 1 << (lookup_size - 1);
  196.             lowbits     = highbit - 1;
  197.  
  198.             if (lookup & highbit)
  199.                 lookup ^= highbit;
  200.             else
  201.                 highbit = 0;
  202.  
  203.             if (lookup == lowbits) {
  204.                 output = get_sbits(&gb, 16);
  205.             } else {
  206.                 int predict_index, diff;
  207.  
  208.                 predict_index = (lookup << (7 - lookup_size)) | (step_index << 6);
  209.                 predict_index = av_clip(predict_index, 0, 5785);
  210.                 diff          = predict_table[predict_index];
  211.                 if (lookup)
  212.                     diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1);
  213.                 if (highbit)
  214.                     diff  = -diff;
  215.  
  216.                 output  = av_clip_int16(output + diff);
  217.             }
  218.  
  219.             *dest = output;
  220.             dest += channels;
  221.  
  222.             step_index += step_index_tables[lookup_size - 2][lookup];
  223.         }
  224.     }
  225.  
  226.     *got_frame_ptr   = 1;
  227.  
  228.     return pkt->size;
  229. }
  230.  
  231. AVCodec ff_vima_decoder = {
  232.     .name           = "vima",
  233.     .long_name      = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"),
  234.     .type           = AVMEDIA_TYPE_AUDIO,
  235.     .id             = AV_CODEC_ID_VIMA,
  236.     .init           = decode_init,
  237.     .decode         = decode_frame,
  238.     .capabilities   = CODEC_CAP_DR1,
  239. };
  240.