Libav 0.7.1
|
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 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 = AV_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 int stereo = s->channels - 1; 00173 short *output_samples = data; 00174 int shift[2]; 00175 unsigned char byte; 00176 short diff; 00177 00178 if (!buf_size) 00179 return 0; 00180 00181 if (stereo && (buf_size & 1)) 00182 buf_size--; 00183 00184 // almost every DPCM variant expands one byte of data into two 00185 if(*data_size/2 < buf_size) 00186 return -1; 00187 00188 switch(avctx->codec->id) { 00189 00190 case CODEC_ID_ROQ_DPCM: 00191 if (s->channels == 1) 00192 predictor[0] = AV_RL16(&buf[6]); 00193 else { 00194 predictor[0] = buf[7] << 8; 00195 predictor[1] = buf[6] << 8; 00196 } 00197 SE_16BIT(predictor[0]); 00198 SE_16BIT(predictor[1]); 00199 00200 /* decode the samples */ 00201 for (in = 8, out = 0; in < buf_size; in++, out++) { 00202 predictor[channel_number] += s->roq_square_array[buf[in]]; 00203 predictor[channel_number] = av_clip_int16(predictor[channel_number]); 00204 output_samples[out] = predictor[channel_number]; 00205 00206 /* toggle channel */ 00207 channel_number ^= s->channels - 1; 00208 } 00209 break; 00210 00211 case CODEC_ID_INTERPLAY_DPCM: 00212 in = 6; /* skip over the stream mask and stream length */ 00213 predictor[0] = AV_RL16(&buf[in]); 00214 in += 2; 00215 SE_16BIT(predictor[0]) 00216 output_samples[out++] = predictor[0]; 00217 if (s->channels == 2) { 00218 predictor[1] = AV_RL16(&buf[in]); 00219 in += 2; 00220 SE_16BIT(predictor[1]) 00221 output_samples[out++] = predictor[1]; 00222 } 00223 00224 while (in < buf_size) { 00225 predictor[channel_number] += interplay_delta_table[buf[in++]]; 00226 predictor[channel_number] = av_clip_int16(predictor[channel_number]); 00227 output_samples[out++] = predictor[channel_number]; 00228 00229 /* toggle channel */ 00230 channel_number ^= s->channels - 1; 00231 } 00232 00233 break; 00234 00235 case CODEC_ID_XAN_DPCM: 00236 in = 0; 00237 shift[0] = shift[1] = 4; 00238 predictor[0] = AV_RL16(&buf[in]); 00239 in += 2; 00240 SE_16BIT(predictor[0]); 00241 if (s->channels == 2) { 00242 predictor[1] = AV_RL16(&buf[in]); 00243 in += 2; 00244 SE_16BIT(predictor[1]); 00245 } 00246 00247 while (in < buf_size) { 00248 byte = buf[in++]; 00249 diff = (byte & 0xFC) << 8; 00250 if ((byte & 0x03) == 3) 00251 shift[channel_number]++; 00252 else 00253 shift[channel_number] -= (2 * (byte & 3)); 00254 /* saturate the shifter to a lower limit of 0 */ 00255 if (shift[channel_number] < 0) 00256 shift[channel_number] = 0; 00257 00258 diff >>= shift[channel_number]; 00259 predictor[channel_number] += diff; 00260 00261 predictor[channel_number] = av_clip_int16(predictor[channel_number]); 00262 output_samples[out++] = predictor[channel_number]; 00263 00264 /* toggle channel */ 00265 channel_number ^= s->channels - 1; 00266 } 00267 break; 00268 case CODEC_ID_SOL_DPCM: 00269 in = 0; 00270 if (avctx->codec_tag != 3) { 00271 if(*data_size/4 < buf_size) 00272 return -1; 00273 while (in < buf_size) { 00274 int n1, n2; 00275 n1 = (buf[in] >> 4) & 0xF; 00276 n2 = buf[in++] & 0xF; 00277 s->sample[0] += s->sol_table[n1]; 00278 if (s->sample[0] < 0) s->sample[0] = 0; 00279 if (s->sample[0] > 255) s->sample[0] = 255; 00280 output_samples[out++] = (s->sample[0] - 128) << 8; 00281 s->sample[s->channels - 1] += s->sol_table[n2]; 00282 if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0; 00283 if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255; 00284 output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8; 00285 } 00286 } else { 00287 while (in < buf_size) { 00288 int n; 00289 n = buf[in++]; 00290 if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F]; 00291 else s->sample[channel_number] += s->sol_table[n & 0x7F]; 00292 s->sample[channel_number] = av_clip_int16(s->sample[channel_number]); 00293 output_samples[out++] = s->sample[channel_number]; 00294 /* toggle channel */ 00295 channel_number ^= s->channels - 1; 00296 } 00297 } 00298 break; 00299 } 00300 00301 *data_size = out * sizeof(short); 00302 return avpkt->size; 00303 } 00304 00305 #define DPCM_DECODER(id, name, long_name_) \ 00306 AVCodec ff_ ## name ## _decoder = { \ 00307 #name, \ 00308 AVMEDIA_TYPE_AUDIO, \ 00309 id, \ 00310 sizeof(DPCMContext), \ 00311 dpcm_decode_init, \ 00312 NULL, \ 00313 NULL, \ 00314 dpcm_decode_frame, \ 00315 .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ 00316 } 00317 00318 DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay"); 00319 DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); 00320 DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); 00321 DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");