• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • 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 FFmpeg.
00006  *
00007  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 
00043 typedef struct DPCMContext {
00044     int channels;
00045     short roq_square_array[256];
00046     long sample[2];//for SOL_DPCM
00047     const int *sol_table;//for SOL_DPCM
00048 } DPCMContext;
00049 
00050 #define SE_16BIT(x)  if (x & 0x8000) x -= 0x10000;
00051 
00052 static const int 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 int sol_table_old[16] =
00089     { 0x0,  0x1,  0x2 , 0x3,  0x6,  0xA,  0xF, 0x15,
00090     -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0};
00091 
00092 static const int sol_table_new[16] =
00093     { 0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF,  0x15,
00094       0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15};
00095 
00096 static const int sol_table_16[128] = {
00097     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
00098     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
00099     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
00100     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
00101     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
00102     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
00103     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
00104     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
00105     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
00106     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
00107     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
00108     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
00109     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
00110 };
00111 
00112 
00113 
00114 static av_cold int dpcm_decode_init(AVCodecContext *avctx)
00115 {
00116     DPCMContext *s = avctx->priv_data;
00117     int i;
00118     short square;
00119 
00120     s->channels = avctx->channels;
00121     s->sample[0] = s->sample[1] = 0;
00122 
00123     switch(avctx->codec->id) {
00124 
00125     case CODEC_ID_ROQ_DPCM:
00126         /* initialize square table */
00127         for (i = 0; i < 128; i++) {
00128             square = i * i;
00129             s->roq_square_array[i] = square;
00130             s->roq_square_array[i + 128] = -square;
00131         }
00132         break;
00133 
00134 
00135     case CODEC_ID_SOL_DPCM:
00136         switch(avctx->codec_tag){
00137         case 1:
00138             s->sol_table=sol_table_old;
00139             s->sample[0] = s->sample[1] = 0x80;
00140             break;
00141         case 2:
00142             s->sol_table=sol_table_new;
00143             s->sample[0] = s->sample[1] = 0x80;
00144             break;
00145         case 3:
00146             s->sol_table=sol_table_16;
00147             break;
00148         default:
00149             av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
00150             return -1;
00151         }
00152         break;
00153 
00154     default:
00155         break;
00156     }
00157 
00158     avctx->sample_fmt = SAMPLE_FMT_S16;
00159     return 0;
00160 }
00161 
00162 static int dpcm_decode_frame(AVCodecContext *avctx,
00163                              void *data, int *data_size,
00164                              AVPacket *avpkt)
00165 {
00166     const uint8_t *buf = avpkt->data;
00167     int buf_size = avpkt->size;
00168     DPCMContext *s = avctx->priv_data;
00169     int in, out = 0;
00170     int predictor[2];
00171     int channel_number = 0;
00172     short *output_samples = data;
00173     int shift[2];
00174     unsigned char byte;
00175     short diff;
00176 
00177     if (!buf_size)
00178         return 0;
00179 
00180     // almost every DPCM variant expands one byte of data into two
00181     if(*data_size/2 < buf_size)
00182         return -1;
00183 
00184     switch(avctx->codec->id) {
00185 
00186     case CODEC_ID_ROQ_DPCM:
00187         if (s->channels == 1)
00188             predictor[0] = AV_RL16(&buf[6]);
00189         else {
00190             predictor[0] = buf[7] << 8;
00191             predictor[1] = buf[6] << 8;
00192         }
00193         SE_16BIT(predictor[0]);
00194         SE_16BIT(predictor[1]);
00195 
00196         /* decode the samples */
00197         for (in = 8, out = 0; in < buf_size; in++, out++) {
00198             predictor[channel_number] += s->roq_square_array[buf[in]];
00199             predictor[channel_number] = av_clip_int16(predictor[channel_number]);
00200             output_samples[out] = predictor[channel_number];
00201 
00202             /* toggle channel */
00203             channel_number ^= s->channels - 1;
00204         }
00205         break;
00206 
00207     case CODEC_ID_INTERPLAY_DPCM:
00208         in = 6;  /* skip over the stream mask and stream length */
00209         predictor[0] = AV_RL16(&buf[in]);
00210         in += 2;
00211         SE_16BIT(predictor[0])
00212         output_samples[out++] = predictor[0];
00213         if (s->channels == 2) {
00214             predictor[1] = AV_RL16(&buf[in]);
00215             in += 2;
00216             SE_16BIT(predictor[1])
00217             output_samples[out++] = predictor[1];
00218         }
00219 
00220         while (in < buf_size) {
00221             predictor[channel_number] += interplay_delta_table[buf[in++]];
00222             predictor[channel_number] = av_clip_int16(predictor[channel_number]);
00223             output_samples[out++] = predictor[channel_number];
00224 
00225             /* toggle channel */
00226             channel_number ^= s->channels - 1;
00227         }
00228 
00229         break;
00230 
00231     case CODEC_ID_XAN_DPCM:
00232         in = 0;
00233         shift[0] = shift[1] = 4;
00234         predictor[0] = AV_RL16(&buf[in]);
00235         in += 2;
00236         SE_16BIT(predictor[0]);
00237         if (s->channels == 2) {
00238             predictor[1] = AV_RL16(&buf[in]);
00239             in += 2;
00240             SE_16BIT(predictor[1]);
00241         }
00242 
00243         while (in < buf_size) {
00244             byte = buf[in++];
00245             diff = (byte & 0xFC) << 8;
00246             if ((byte & 0x03) == 3)
00247                 shift[channel_number]++;
00248             else
00249                 shift[channel_number] -= (2 * (byte & 3));
00250             /* saturate the shifter to a lower limit of 0 */
00251             if (shift[channel_number] < 0)
00252                 shift[channel_number] = 0;
00253 
00254             diff >>= shift[channel_number];
00255             predictor[channel_number] += diff;
00256 
00257             predictor[channel_number] = av_clip_int16(predictor[channel_number]);
00258             output_samples[out++] = predictor[channel_number];
00259 
00260             /* toggle channel */
00261             channel_number ^= s->channels - 1;
00262         }
00263         break;
00264     case CODEC_ID_SOL_DPCM:
00265         in = 0;
00266         if (avctx->codec_tag != 3) {
00267             if(*data_size/4 < buf_size)
00268                 return -1;
00269             while (in < buf_size) {
00270                 int n1, n2;
00271                 n1 = (buf[in] >> 4) & 0xF;
00272                 n2 = buf[in++] & 0xF;
00273                 s->sample[0] += s->sol_table[n1];
00274                 if (s->sample[0] < 0) s->sample[0] = 0;
00275                 if (s->sample[0] > 255) s->sample[0] = 255;
00276                 output_samples[out++] = (s->sample[0] - 128) << 8;
00277                 s->sample[s->channels - 1] += s->sol_table[n2];
00278                 if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0;
00279                 if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255;
00280                 output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8;
00281             }
00282         } else {
00283             while (in < buf_size) {
00284                 int n;
00285                 n = buf[in++];
00286                 if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F];
00287                 else s->sample[channel_number] += s->sol_table[n & 0x7F];
00288                 s->sample[channel_number] = av_clip_int16(s->sample[channel_number]);
00289                 output_samples[out++] = s->sample[channel_number];
00290                 /* toggle channel */
00291                 channel_number ^= s->channels - 1;
00292             }
00293         }
00294         break;
00295     }
00296 
00297     *data_size = out * sizeof(short);
00298     return buf_size;
00299 }
00300 
00301 #define DPCM_DECODER(id, name, long_name_)      \
00302 AVCodec name ## _decoder = {                    \
00303     #name,                                      \
00304     AVMEDIA_TYPE_AUDIO,                         \
00305     id,                                         \
00306     sizeof(DPCMContext),                        \
00307     dpcm_decode_init,                           \
00308     NULL,                                       \
00309     NULL,                                       \
00310     dpcm_decode_frame,                          \
00311     .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
00312 };
00313 
00314 DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
00315 DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
00316 DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
00317 DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");

Generated on Fri Sep 16 2011 17:17:35 for FFmpeg by  doxygen 1.7.1