Libav
|
00001 /* 00002 * ADX ADPCM codecs 00003 * Copyright (c) 2001,2003 BERO 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 00022 #include "libavutil/intreadwrite.h" 00023 #include "avcodec.h" 00024 #include "adx.h" 00025 00035 static av_cold int adx_decode_init(AVCodecContext *avctx) 00036 { 00037 avctx->sample_fmt = SAMPLE_FMT_S16; 00038 return 0; 00039 } 00040 00041 /* 18 bytes <-> 32 samples */ 00042 00043 static void adx_decode(short *out,const unsigned char *in,PREV *prev) 00044 { 00045 int scale = AV_RB16(in); 00046 int i; 00047 int s0,s1,s2,d; 00048 00049 // printf("%x ",scale); 00050 00051 in+=2; 00052 s1 = prev->s1; 00053 s2 = prev->s2; 00054 for(i=0;i<16;i++) { 00055 d = in[i]; 00056 // d>>=4; if (d&8) d-=16; 00057 d = ((signed char)d >> 4); 00058 s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; 00059 s2 = s1; 00060 s1 = av_clip_int16(s0); 00061 *out++=s1; 00062 00063 d = in[i]; 00064 //d&=15; if (d&8) d-=16; 00065 d = ((signed char)(d<<4) >> 4); 00066 s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; 00067 s2 = s1; 00068 s1 = av_clip_int16(s0); 00069 *out++=s1; 00070 } 00071 prev->s1 = s1; 00072 prev->s2 = s2; 00073 00074 } 00075 00076 static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) 00077 { 00078 short tmp[32*2]; 00079 int i; 00080 00081 adx_decode(tmp ,in ,prev); 00082 adx_decode(tmp+32,in+18,prev+1); 00083 for(i=0;i<32;i++) { 00084 out[i*2] = tmp[i]; 00085 out[i*2+1] = tmp[i+32]; 00086 } 00087 } 00088 00089 /* return data offset or 0 */ 00090 static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) 00091 { 00092 int offset; 00093 00094 if (buf[0]!=0x80) return 0; 00095 offset = (AV_RB32(buf)^0x80000000)+4; 00096 if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0; 00097 00098 avctx->channels = buf[7]; 00099 avctx->sample_rate = AV_RB32(buf+8); 00100 avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; 00101 00102 return offset; 00103 } 00104 00105 static int adx_decode_frame(AVCodecContext *avctx, 00106 void *data, int *data_size, 00107 AVPacket *avpkt) 00108 { 00109 const uint8_t *buf0 = avpkt->data; 00110 int buf_size = avpkt->size; 00111 ADXContext *c = avctx->priv_data; 00112 short *samples = data; 00113 const uint8_t *buf = buf0; 00114 int rest = buf_size; 00115 00116 if (!c->header_parsed) { 00117 int hdrsize = adx_decode_header(avctx,buf,rest); 00118 if (hdrsize==0) return -1; 00119 c->header_parsed = 1; 00120 buf += hdrsize; 00121 rest -= hdrsize; 00122 } 00123 00124 /* 18 bytes of data are expanded into 32*2 bytes of audio, 00125 so guard against buffer overflows */ 00126 if(rest/18 > *data_size/64) 00127 rest = (*data_size/64) * 18; 00128 00129 if (c->in_temp) { 00130 int copysize = 18*avctx->channels - c->in_temp; 00131 memcpy(c->dec_temp+c->in_temp,buf,copysize); 00132 rest -= copysize; 00133 buf += copysize; 00134 if (avctx->channels==1) { 00135 adx_decode(samples,c->dec_temp,c->prev); 00136 samples += 32; 00137 } else { 00138 adx_decode_stereo(samples,c->dec_temp,c->prev); 00139 samples += 32*2; 00140 } 00141 } 00142 // 00143 if (avctx->channels==1) { 00144 while(rest>=18) { 00145 adx_decode(samples,buf,c->prev); 00146 rest-=18; 00147 buf+=18; 00148 samples+=32; 00149 } 00150 } else { 00151 while(rest>=18*2) { 00152 adx_decode_stereo(samples,buf,c->prev); 00153 rest-=18*2; 00154 buf+=18*2; 00155 samples+=32*2; 00156 } 00157 } 00158 // 00159 c->in_temp = rest; 00160 if (rest) { 00161 memcpy(c->dec_temp,buf,rest); 00162 buf+=rest; 00163 } 00164 *data_size = (uint8_t*)samples - (uint8_t*)data; 00165 // printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); 00166 return buf-buf0; 00167 } 00168 00169 AVCodec adpcm_adx_decoder = { 00170 "adpcm_adx", 00171 AVMEDIA_TYPE_AUDIO, 00172 CODEC_ID_ADPCM_ADX, 00173 sizeof(ADXContext), 00174 adx_decode_init, 00175 NULL, 00176 NULL, 00177 adx_decode_frame, 00178 .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), 00179 }; 00180