• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/dpcm.c

Go to the documentation of this file.
00001 /*
00002  * Assorted DPCM codecs
00003  * Copyright (c) 2003 The ffmpeg Project
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00040 #include "libavutil/intreadwrite.h"
00041 #include "avcodec.h"
00042 #include "bytestream.h"
00043 
00044 typedef struct DPCMContext {
00045     AVFrame frame;
00046     int channels;
00047     int16_t roq_square_array[256];
00048     int sample[2];                  
00049     const int8_t *sol_table;        
00050 } DPCMContext;
00051 
00052 static const int16_t interplay_delta_table[] = {
00053          0,      1,      2,      3,      4,      5,      6,      7,
00054          8,      9,     10,     11,     12,     13,     14,     15,
00055         16,     17,     18,     19,     20,     21,     22,     23,
00056         24,     25,     26,     27,     28,     29,     30,     31,
00057         32,     33,     34,     35,     36,     37,     38,     39,
00058         40,     41,     42,     43,     47,     51,     56,     61,
00059         66,     72,     79,     86,     94,    102,    112,    122,
00060        133,    145,    158,    173,    189,    206,    225,    245,
00061        267,    292,    318,    348,    379,    414,    452,    493,
00062        538,    587,    640,    699,    763,    832,    908,    991,
00063       1081,   1180,   1288,   1405,   1534,   1673,   1826,   1993,
00064       2175,   2373,   2590,   2826,   3084,   3365,   3672,   4008,
00065       4373,   4772,   5208,   5683,   6202,   6767,   7385,   8059,
00066       8794,   9597,  10472,  11428,  12471,  13609,  14851,  16206,
00067      17685,  19298,  21060,  22981,  25078,  27367,  29864,  32589,
00068     -29973, -26728, -23186, -19322, -15105, -10503,  -5481,     -1,
00069          1,      1,   5481,  10503,  15105,  19322,  23186,  26728,
00070      29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
00071     -17685, -16206, -14851, -13609, -12471, -11428, -10472,  -9597,
00072      -8794,  -8059,  -7385,  -6767,  -6202,  -5683,  -5208,  -4772,
00073      -4373,  -4008,  -3672,  -3365,  -3084,  -2826,  -2590,  -2373,
00074      -2175,  -1993,  -1826,  -1673,  -1534,  -1405,  -1288,  -1180,
00075      -1081,   -991,   -908,   -832,   -763,   -699,   -640,   -587,
00076       -538,   -493,   -452,   -414,   -379,   -348,   -318,   -292,
00077       -267,   -245,   -225,   -206,   -189,   -173,   -158,   -145,
00078       -133,   -122,   -112,   -102,    -94,    -86,    -79,    -72,
00079        -66,    -61,    -56,    -51,    -47,    -43,    -42,    -41,
00080        -40,    -39,    -38,    -37,    -36,    -35,    -34,    -33,
00081        -32,    -31,    -30,    -29,    -28,    -27,    -26,    -25,
00082        -24,    -23,    -22,    -21,    -20,    -19,    -18,    -17,
00083        -16,    -15,    -14,    -13,    -12,    -11,    -10,     -9,
00084         -8,     -7,     -6,     -5,     -4,     -3,     -2,     -1
00085 
00086 };
00087 
00088 static const int8_t sol_table_old[16] = {
00089       0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF, 0x15,
00090     -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1,  0x0
00091 };
00092 
00093 static const int8_t sol_table_new[16] = {
00094     0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF,  0x15,
00095     0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15
00096 };
00097 
00098 static const int16_t sol_table_16[128] = {
00099     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
00100     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
00101     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
00102     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
00103     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
00104     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
00105     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
00106     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
00107     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
00108     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
00109     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
00110     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
00111     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
00112 };
00113 
00114 
00115 static av_cold int dpcm_decode_init(AVCodecContext *avctx)
00116 {
00117     DPCMContext *s = avctx->priv_data;
00118     int i;
00119 
00120     if (avctx->channels < 1 || avctx->channels > 2) {
00121         av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");
00122         return AVERROR(EINVAL);
00123     }
00124 
00125     s->channels = avctx->channels;
00126     s->sample[0] = s->sample[1] = 0;
00127 
00128     switch(avctx->codec->id) {
00129 
00130     case CODEC_ID_ROQ_DPCM:
00131         /* initialize square table */
00132         for (i = 0; i < 128; i++) {
00133             int16_t square = i * i;
00134             s->roq_square_array[i      ] =  square;
00135             s->roq_square_array[i + 128] = -square;
00136         }
00137         break;
00138 
00139     case CODEC_ID_SOL_DPCM:
00140         switch(avctx->codec_tag){
00141         case 1:
00142             s->sol_table = sol_table_old;
00143             s->sample[0] = s->sample[1] = 0x80;
00144             break;
00145         case 2:
00146             s->sol_table = sol_table_new;
00147             s->sample[0] = s->sample[1] = 0x80;
00148             break;
00149         case 3:
00150             break;
00151         default:
00152             av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
00153             return -1;
00154         }
00155         break;
00156 
00157     default:
00158         break;
00159     }
00160 
00161     if (avctx->codec->id == CODEC_ID_SOL_DPCM && avctx->codec_tag != 3)
00162         avctx->sample_fmt = AV_SAMPLE_FMT_U8;
00163     else
00164         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00165 
00166     avcodec_get_frame_defaults(&s->frame);
00167     avctx->coded_frame = &s->frame;
00168 
00169     return 0;
00170 }
00171 
00172 
00173 static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
00174                              int *got_frame_ptr, AVPacket *avpkt)
00175 {
00176     const uint8_t *buf = avpkt->data;
00177     int buf_size = avpkt->size;
00178     const uint8_t *buf_end = buf + buf_size;
00179     DPCMContext *s = avctx->priv_data;
00180     int out = 0, ret;
00181     int predictor[2];
00182     int ch = 0;
00183     int stereo = s->channels - 1;
00184     int16_t *output_samples;
00185 
00186     /* calculate output size */
00187     switch(avctx->codec->id) {
00188     case CODEC_ID_ROQ_DPCM:
00189         out = buf_size - 8;
00190         break;
00191     case CODEC_ID_INTERPLAY_DPCM:
00192         out = buf_size - 6 - s->channels;
00193         break;
00194     case CODEC_ID_XAN_DPCM:
00195         out = buf_size - 2 * s->channels;
00196         break;
00197     case CODEC_ID_SOL_DPCM:
00198         if (avctx->codec_tag != 3)
00199             out = buf_size * 2;
00200         else
00201             out = buf_size;
00202         break;
00203     }
00204     if (out <= 0) {
00205         av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
00206         return AVERROR(EINVAL);
00207     }
00208 
00209     /* get output buffer */
00210     s->frame.nb_samples = out / s->channels;
00211     if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
00212         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00213         return ret;
00214     }
00215     output_samples = (int16_t *)s->frame.data[0];
00216 
00217     switch(avctx->codec->id) {
00218 
00219     case CODEC_ID_ROQ_DPCM:
00220         buf += 6;
00221 
00222         if (stereo) {
00223             predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8);
00224             predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8);
00225         } else {
00226             predictor[0] = (int16_t)bytestream_get_le16(&buf);
00227         }
00228 
00229         /* decode the samples */
00230         while (buf < buf_end) {
00231             predictor[ch] += s->roq_square_array[*buf++];
00232             predictor[ch]  = av_clip_int16(predictor[ch]);
00233             *output_samples++ = predictor[ch];
00234 
00235             /* toggle channel */
00236             ch ^= stereo;
00237         }
00238         break;
00239 
00240     case CODEC_ID_INTERPLAY_DPCM:
00241         buf += 6;  /* skip over the stream mask and stream length */
00242 
00243         for (ch = 0; ch < s->channels; ch++) {
00244             predictor[ch] = (int16_t)bytestream_get_le16(&buf);
00245             *output_samples++ = predictor[ch];
00246         }
00247 
00248         ch = 0;
00249         while (buf < buf_end) {
00250             predictor[ch] += interplay_delta_table[*buf++];
00251             predictor[ch]  = av_clip_int16(predictor[ch]);
00252             *output_samples++ = predictor[ch];
00253 
00254             /* toggle channel */
00255             ch ^= stereo;
00256         }
00257         break;
00258 
00259     case CODEC_ID_XAN_DPCM:
00260     {
00261         int shift[2] = { 4, 4 };
00262 
00263         for (ch = 0; ch < s->channels; ch++)
00264             predictor[ch] = (int16_t)bytestream_get_le16(&buf);
00265 
00266         ch = 0;
00267         while (buf < buf_end) {
00268             uint8_t n = *buf++;
00269             int16_t diff = (n & 0xFC) << 8;
00270             if ((n & 0x03) == 3)
00271                 shift[ch]++;
00272             else
00273                 shift[ch] -= (2 * (n & 3));
00274             /* saturate the shifter to a lower limit of 0 */
00275             if (shift[ch] < 0)
00276                 shift[ch] = 0;
00277 
00278             diff >>= shift[ch];
00279             predictor[ch] += diff;
00280 
00281             predictor[ch] = av_clip_int16(predictor[ch]);
00282             *output_samples++ = predictor[ch];
00283 
00284             /* toggle channel */
00285             ch ^= stereo;
00286         }
00287         break;
00288     }
00289     case CODEC_ID_SOL_DPCM:
00290         if (avctx->codec_tag != 3) {
00291             uint8_t *output_samples_u8 = s->frame.data[0];
00292             while (buf < buf_end) {
00293                 uint8_t n = *buf++;
00294 
00295                 s->sample[0] += s->sol_table[n >> 4];
00296                 s->sample[0]  = av_clip_uint8(s->sample[0]);
00297                 *output_samples_u8++ = s->sample[0];
00298 
00299                 s->sample[stereo] += s->sol_table[n & 0x0F];
00300                 s->sample[stereo]  = av_clip_uint8(s->sample[stereo]);
00301                 *output_samples_u8++ = s->sample[stereo];
00302             }
00303         } else {
00304             while (buf < buf_end) {
00305                 uint8_t n = *buf++;
00306                 if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
00307                 else          s->sample[ch] += sol_table_16[n & 0x7F];
00308                 s->sample[ch] = av_clip_int16(s->sample[ch]);
00309                 *output_samples++ = s->sample[ch];
00310                 /* toggle channel */
00311                 ch ^= stereo;
00312             }
00313         }
00314         break;
00315     }
00316 
00317     *got_frame_ptr   = 1;
00318     *(AVFrame *)data = s->frame;
00319 
00320     return buf_size;
00321 }
00322 
00323 #define DPCM_DECODER(id_, name_, long_name_)                \
00324 AVCodec ff_ ## name_ ## _decoder = {                        \
00325     .name           = #name_,                               \
00326     .type           = AVMEDIA_TYPE_AUDIO,                   \
00327     .id             = id_,                                  \
00328     .priv_data_size = sizeof(DPCMContext),                  \
00329     .init           = dpcm_decode_init,                     \
00330     .decode         = dpcm_decode_frame,                    \
00331     .capabilities   = CODEC_CAP_DR1,                        \
00332     .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
00333 }
00334 
00335 DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
00336 DPCM_DECODER(CODEC_ID_ROQ_DPCM,       roq_dpcm,       "DPCM id RoQ");
00337 DPCM_DECODER(CODEC_ID_SOL_DPCM,       sol_dpcm,       "DPCM Sol");
00338 DPCM_DECODER(CODEC_ID_XAN_DPCM,       xan_dpcm,       "DPCM Xan");
Generated on Sat Mar 17 2012 12:57:44 for Libav by doxygen 1.7.1