LCOV - code coverage report
Current view: top level - libavcodec - dpcm.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 105 175 60.0 %
Date: 2017-12-15 11:05:35 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Assorted DPCM codecs
       3             :  * Copyright (c) 2003 The FFmpeg project
       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             :  * Assorted DPCM (differential pulse code modulation) audio codecs
      25             :  * by Mike Melanson (melanson@pcisys.net)
      26             :  * Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt)
      27             :  * for more information on the specific data formats, visit:
      28             :  *   http://www.pcisys.net/~melanson/codecs/simpleaudio.html
      29             :  * SOL DPCMs implemented by Konstantin Shishkov
      30             :  *
      31             :  * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files
      32             :  * found in the Wing Commander IV computer game. These AVI files contain
      33             :  * WAVEFORMAT headers which report the audio format as 0x01: raw PCM.
      34             :  * Clearly incorrect. To detect Xan DPCM, you will probably have to
      35             :  * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan'
      36             :  * (Xan video) for its video codec. Alternately, such AVI files also contain
      37             :  * the fourcc 'Axan' in the 'auds' chunk of the AVI header.
      38             :  */
      39             : 
      40             : #include "libavutil/intreadwrite.h"
      41             : #include "avcodec.h"
      42             : #include "bytestream.h"
      43             : #include "internal.h"
      44             : #include "mathops.h"
      45             : 
      46             : typedef struct DPCMContext {
      47             :     int16_t array[256];
      48             :     int sample[2];                  ///< previous sample (for SOL_DPCM)
      49             :     const int8_t *sol_table;        ///< delta table for SOL_DPCM
      50             : } DPCMContext;
      51             : 
      52             : static const int16_t interplay_delta_table[] = {
      53             :          0,      1,      2,      3,      4,      5,      6,      7,
      54             :          8,      9,     10,     11,     12,     13,     14,     15,
      55             :         16,     17,     18,     19,     20,     21,     22,     23,
      56             :         24,     25,     26,     27,     28,     29,     30,     31,
      57             :         32,     33,     34,     35,     36,     37,     38,     39,
      58             :         40,     41,     42,     43,     47,     51,     56,     61,
      59             :         66,     72,     79,     86,     94,    102,    112,    122,
      60             :        133,    145,    158,    173,    189,    206,    225,    245,
      61             :        267,    292,    318,    348,    379,    414,    452,    493,
      62             :        538,    587,    640,    699,    763,    832,    908,    991,
      63             :       1081,   1180,   1288,   1405,   1534,   1673,   1826,   1993,
      64             :       2175,   2373,   2590,   2826,   3084,   3365,   3672,   4008,
      65             :       4373,   4772,   5208,   5683,   6202,   6767,   7385,   8059,
      66             :       8794,   9597,  10472,  11428,  12471,  13609,  14851,  16206,
      67             :      17685,  19298,  21060,  22981,  25078,  27367,  29864,  32589,
      68             :     -29973, -26728, -23186, -19322, -15105, -10503,  -5481,     -1,
      69             :          1,      1,   5481,  10503,  15105,  19322,  23186,  26728,
      70             :      29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
      71             :     -17685, -16206, -14851, -13609, -12471, -11428, -10472,  -9597,
      72             :      -8794,  -8059,  -7385,  -6767,  -6202,  -5683,  -5208,  -4772,
      73             :      -4373,  -4008,  -3672,  -3365,  -3084,  -2826,  -2590,  -2373,
      74             :      -2175,  -1993,  -1826,  -1673,  -1534,  -1405,  -1288,  -1180,
      75             :      -1081,   -991,   -908,   -832,   -763,   -699,   -640,   -587,
      76             :       -538,   -493,   -452,   -414,   -379,   -348,   -318,   -292,
      77             :       -267,   -245,   -225,   -206,   -189,   -173,   -158,   -145,
      78             :       -133,   -122,   -112,   -102,    -94,    -86,    -79,    -72,
      79             :        -66,    -61,    -56,    -51,    -47,    -43,    -42,    -41,
      80             :        -40,    -39,    -38,    -37,    -36,    -35,    -34,    -33,
      81             :        -32,    -31,    -30,    -29,    -28,    -27,    -26,    -25,
      82             :        -24,    -23,    -22,    -21,    -20,    -19,    -18,    -17,
      83             :        -16,    -15,    -14,    -13,    -12,    -11,    -10,     -9,
      84             :         -8,     -7,     -6,     -5,     -4,     -3,     -2,     -1
      85             : 
      86             : };
      87             : 
      88             : static const int8_t sol_table_old[16] = {
      89             :       0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF, 0x15,
      90             :     -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1,  0x0
      91             : };
      92             : 
      93             : static const int8_t sol_table_new[16] = {
      94             :     0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF,  0x15,
      95             :     0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15
      96             : };
      97             : 
      98             : static const int16_t sol_table_16[128] = {
      99             :     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
     100             :     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
     101             :     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
     102             :     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
     103             :     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
     104             :     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
     105             :     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
     106             :     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
     107             :     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
     108             :     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
     109             :     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
     110             :     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
     111             :     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
     112             : };
     113             : 
     114             : 
     115          14 : static av_cold int dpcm_decode_init(AVCodecContext *avctx)
     116             : {
     117          14 :     DPCMContext *s = avctx->priv_data;
     118             :     int i;
     119             : 
     120          14 :     if (avctx->channels < 1 || avctx->channels > 2) {
     121           0 :         av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
     122           0 :         return AVERROR(EINVAL);
     123             :     }
     124             : 
     125          14 :     s->sample[0] = s->sample[1] = 0;
     126             : 
     127          14 :     switch(avctx->codec->id) {
     128             : 
     129           5 :     case AV_CODEC_ID_ROQ_DPCM:
     130             :         /* initialize square table */
     131         645 :         for (i = 0; i < 128; i++) {
     132         640 :             int16_t square = i * i;
     133         640 :             s->array[i      ] =  square;
     134         640 :             s->array[i + 128] = -square;
     135             :         }
     136           5 :         break;
     137             : 
     138           2 :     case AV_CODEC_ID_SOL_DPCM:
     139           2 :         switch(avctx->codec_tag){
     140           0 :         case 1:
     141           0 :             s->sol_table = sol_table_old;
     142           0 :             s->sample[0] = s->sample[1] = 0x80;
     143           0 :             break;
     144           0 :         case 2:
     145           0 :             s->sol_table = sol_table_new;
     146           0 :             s->sample[0] = s->sample[1] = 0x80;
     147           0 :             break;
     148           2 :         case 3:
     149           2 :             break;
     150           0 :         default:
     151           0 :             av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
     152           0 :             return -1;
     153             :         }
     154           2 :         break;
     155             : 
     156           0 :     case AV_CODEC_ID_SDX2_DPCM:
     157           0 :         for (i = -128; i < 128; i++) {
     158           0 :             int16_t square = i * i * 2;
     159           0 :             s->array[i+128] = i < 0 ? -square: square;
     160             :         }
     161           0 :         break;
     162             : 
     163           0 :     case AV_CODEC_ID_GREMLIN_DPCM: {
     164           0 :         int delta = 0;
     165           0 :         int code = 64;
     166           0 :         int step = 45;
     167             : 
     168           0 :         s->array[0] = 0;
     169           0 :         for (i = 0; i < 127; i++) {
     170           0 :             delta += (code >> 5);
     171           0 :             code  += step;
     172           0 :             step  += 2;
     173             : 
     174           0 :             s->array[i*2 + 1] =  delta;
     175           0 :             s->array[i*2 + 2] = -delta;
     176             :         }
     177           0 :         s->array[255] = delta + (code >> 5);
     178             :         }
     179           0 :         break;
     180             : 
     181           7 :     default:
     182           7 :         break;
     183             :     }
     184             : 
     185          14 :     if (avctx->codec->id == AV_CODEC_ID_SOL_DPCM && avctx->codec_tag != 3)
     186           0 :         avctx->sample_fmt = AV_SAMPLE_FMT_U8;
     187             :     else
     188          14 :         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
     189             : 
     190          14 :     return 0;
     191             : }
     192             : 
     193             : 
     194         649 : static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
     195             :                              int *got_frame_ptr, AVPacket *avpkt)
     196             : {
     197         649 :     int buf_size = avpkt->size;
     198         649 :     DPCMContext *s = avctx->priv_data;
     199         649 :     AVFrame *frame = data;
     200         649 :     int out = 0, ret;
     201             :     int predictor[2];
     202         649 :     int ch = 0;
     203         649 :     int stereo = avctx->channels - 1;
     204             :     int16_t *output_samples, *samples_end;
     205             :     GetByteContext gb;
     206             : 
     207         649 :     if (stereo && (buf_size & 1))
     208           0 :         buf_size--;
     209         649 :     bytestream2_init(&gb, avpkt->data, buf_size);
     210             : 
     211             :     /* calculate output size */
     212         649 :     switch(avctx->codec->id) {
     213         340 :     case AV_CODEC_ID_ROQ_DPCM:
     214         340 :         out = buf_size - 8;
     215         340 :         break;
     216         124 :     case AV_CODEC_ID_INTERPLAY_DPCM:
     217         124 :         out = buf_size - 6 - avctx->channels;
     218         124 :         break;
     219         111 :     case AV_CODEC_ID_XAN_DPCM:
     220         111 :         out = buf_size - 2 * avctx->channels;
     221         111 :         break;
     222          74 :     case AV_CODEC_ID_SOL_DPCM:
     223          74 :         if (avctx->codec_tag != 3)
     224           0 :             out = buf_size * 2;
     225             :         else
     226          74 :             out = buf_size;
     227          74 :         break;
     228           0 :     case AV_CODEC_ID_GREMLIN_DPCM:
     229             :     case AV_CODEC_ID_SDX2_DPCM:
     230           0 :         out = buf_size;
     231           0 :         break;
     232             :     }
     233         649 :     if (out <= 0) {
     234           0 :         av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
     235           0 :         return AVERROR(EINVAL);
     236             :     }
     237         649 :     if (out % avctx->channels) {
     238           0 :         av_log(avctx, AV_LOG_WARNING, "channels have differing number of samples\n");
     239             :     }
     240             : 
     241             :     /* get output buffer */
     242         649 :     frame->nb_samples = (out + avctx->channels - 1) / avctx->channels;
     243         649 :     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
     244           0 :         return ret;
     245         649 :     output_samples = (int16_t *)frame->data[0];
     246         649 :     samples_end = output_samples + out;
     247             : 
     248         649 :     switch(avctx->codec->id) {
     249             : 
     250         340 :     case AV_CODEC_ID_ROQ_DPCM:
     251         340 :         bytestream2_skipu(&gb, 6);
     252             : 
     253         340 :         if (stereo) {
     254         340 :             predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
     255         340 :             predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
     256             :         } else {
     257           0 :             predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16);
     258             :         }
     259             : 
     260             :         /* decode the samples */
     261      523580 :         while (output_samples < samples_end) {
     262      522900 :             predictor[ch] += s->array[bytestream2_get_byteu(&gb)];
     263      522900 :             predictor[ch]  = av_clip_int16(predictor[ch]);
     264      522900 :             *output_samples++ = predictor[ch];
     265             : 
     266             :             /* toggle channel */
     267      522900 :             ch ^= stereo;
     268             :         }
     269         340 :         break;
     270             : 
     271         124 :     case AV_CODEC_ID_INTERPLAY_DPCM:
     272         124 :         bytestream2_skipu(&gb, 6);  /* skip over the stream mask and stream length */
     273             : 
     274         372 :         for (ch = 0; ch < avctx->channels; ch++) {
     275         248 :             predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
     276         248 :             *output_samples++ = predictor[ch];
     277             :         }
     278             : 
     279         124 :         ch = 0;
     280      364876 :         while (output_samples < samples_end) {
     281      364628 :             predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)];
     282      364628 :             predictor[ch]  = av_clip_int16(predictor[ch]);
     283      364628 :             *output_samples++ = predictor[ch];
     284             : 
     285             :             /* toggle channel */
     286      364628 :             ch ^= stereo;
     287             :         }
     288         124 :         break;
     289             : 
     290         111 :     case AV_CODEC_ID_XAN_DPCM:
     291             :     {
     292         111 :         int shift[2] = { 4, 4 };
     293             : 
     294         333 :         for (ch = 0; ch < avctx->channels; ch++)
     295         222 :             predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
     296             : 
     297         111 :         ch = 0;
     298      326340 :         while (output_samples < samples_end) {
     299      326118 :             int diff = bytestream2_get_byteu(&gb);
     300      326118 :             int n    = diff & 3;
     301             : 
     302      326118 :             if (n == 3)
     303      134940 :                 shift[ch]++;
     304             :             else
     305      191178 :                 shift[ch] -= (2 * n);
     306      326118 :             diff = sign_extend((diff &~ 3) << 8, 16);
     307             : 
     308             :             /* saturate the shifter to a lower limit of 0 */
     309      326118 :             if (shift[ch] < 0)
     310           0 :                 shift[ch] = 0;
     311             : 
     312      326118 :             diff >>= shift[ch];
     313      326118 :             predictor[ch] += diff;
     314             : 
     315      326118 :             predictor[ch] = av_clip_int16(predictor[ch]);
     316      326118 :             *output_samples++ = predictor[ch];
     317             : 
     318             :             /* toggle channel */
     319      326118 :             ch ^= stereo;
     320             :         }
     321         111 :         break;
     322             :     }
     323          74 :     case AV_CODEC_ID_SOL_DPCM:
     324          74 :         if (avctx->codec_tag != 3) {
     325           0 :             uint8_t *output_samples_u8 = frame->data[0],
     326           0 :                     *samples_end_u8 = output_samples_u8 + out;
     327           0 :             while (output_samples_u8 < samples_end_u8) {
     328           0 :                 int n = bytestream2_get_byteu(&gb);
     329             : 
     330           0 :                 s->sample[0] += s->sol_table[n >> 4];
     331           0 :                 s->sample[0]  = av_clip_uint8(s->sample[0]);
     332           0 :                 *output_samples_u8++ = s->sample[0];
     333             : 
     334           0 :                 s->sample[stereo] += s->sol_table[n & 0x0F];
     335           0 :                 s->sample[stereo]  = av_clip_uint8(s->sample[stereo]);
     336           0 :                 *output_samples_u8++ = s->sample[stereo];
     337             :             }
     338             :         } else {
     339      299586 :             while (output_samples < samples_end) {
     340      299438 :                 int n = bytestream2_get_byteu(&gb);
     341      299438 :                 if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
     342      150564 :                 else          s->sample[ch] += sol_table_16[n & 0x7F];
     343      299438 :                 s->sample[ch] = av_clip_int16(s->sample[ch]);
     344      299438 :                 *output_samples++ = s->sample[ch];
     345             :                 /* toggle channel */
     346      299438 :                 ch ^= stereo;
     347             :             }
     348             :         }
     349          74 :         break;
     350             : 
     351           0 :     case AV_CODEC_ID_SDX2_DPCM:
     352           0 :         while (output_samples < samples_end) {
     353           0 :             int8_t n = bytestream2_get_byteu(&gb);
     354             : 
     355           0 :             if (!(n & 1))
     356           0 :                 s->sample[ch] = 0;
     357           0 :             s->sample[ch] += s->array[n + 128];
     358           0 :             s->sample[ch]  = av_clip_int16(s->sample[ch]);
     359           0 :             *output_samples++ = s->sample[ch];
     360           0 :             ch ^= stereo;
     361             :         }
     362           0 :         break;
     363             : 
     364           0 :     case AV_CODEC_ID_GREMLIN_DPCM: {
     365           0 :         int idx = 0;
     366             : 
     367           0 :         while (output_samples < samples_end) {
     368           0 :             uint8_t n = bytestream2_get_byteu(&gb);
     369             : 
     370           0 :             *output_samples++ = s->sample[idx] += s->array[n];
     371           0 :             idx ^= 1;
     372             :         }
     373             :         }
     374           0 :         break;
     375             :     }
     376             : 
     377         649 :     *got_frame_ptr = 1;
     378             : 
     379         649 :     return avpkt->size;
     380             : }
     381             : 
     382             : #define DPCM_DECODER(id_, name_, long_name_)                \
     383             : AVCodec ff_ ## name_ ## _decoder = {                        \
     384             :     .name           = #name_,                               \
     385             :     .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
     386             :     .type           = AVMEDIA_TYPE_AUDIO,                   \
     387             :     .id             = id_,                                  \
     388             :     .priv_data_size = sizeof(DPCMContext),                  \
     389             :     .init           = dpcm_decode_init,                     \
     390             :     .decode         = dpcm_decode_frame,                    \
     391             :     .capabilities   = AV_CODEC_CAP_DR1,                     \
     392             : }
     393             : 
     394             : DPCM_DECODER(AV_CODEC_ID_GREMLIN_DPCM,   gremlin_dpcm,   "DPCM Gremlin");
     395             : DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
     396             : DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM,       roq_dpcm,       "DPCM id RoQ");
     397             : DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM,      sdx2_dpcm,      "DPCM Squareroot-Delta-Exact");
     398             : DPCM_DECODER(AV_CODEC_ID_SOL_DPCM,       sol_dpcm,       "DPCM Sol");
     399             : DPCM_DECODER(AV_CODEC_ID_XAN_DPCM,       xan_dpcm,       "DPCM Xan");

Generated by: LCOV version 1.13