00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdint.h>
00023 #include "libavutil/common.h"
00024 #include "libavutil/intreadwrite.h"
00025 #include "avcodec.h"
00026
00036 static const int8_t ws_adpcm_4bit[] = {
00037 -9, -8, -6, -5, -4, -3, -2, -1,
00038 0, 1, 2, 3, 4, 5, 6, 8
00039 };
00040
00041 typedef struct WSSndContext {
00042 AVFrame frame;
00043 } WSSndContext;
00044
00045 static av_cold int ws_snd_decode_init(AVCodecContext *avctx)
00046 {
00047 WSSndContext *s = avctx->priv_data;
00048
00049 if (avctx->channels != 1) {
00050 av_log_ask_for_sample(avctx, "unsupported number of channels\n");
00051 return AVERROR(EINVAL);
00052 }
00053
00054 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
00055
00056 avcodec_get_frame_defaults(&s->frame);
00057 avctx->coded_frame = &s->frame;
00058
00059 return 0;
00060 }
00061
00062 static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
00063 int *got_frame_ptr, AVPacket *avpkt)
00064 {
00065 WSSndContext *s = avctx->priv_data;
00066 const uint8_t *buf = avpkt->data;
00067 int buf_size = avpkt->size;
00068
00069 int in_size, out_size, ret;
00070 int sample = 128;
00071 uint8_t *samples;
00072 uint8_t *samples_end;
00073
00074 if (!buf_size)
00075 return 0;
00076
00077 if (buf_size < 4) {
00078 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
00079 return AVERROR(EINVAL);
00080 }
00081
00082 out_size = AV_RL16(&buf[0]);
00083 in_size = AV_RL16(&buf[2]);
00084 buf += 4;
00085
00086 if (in_size > buf_size) {
00087 av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n");
00088 return -1;
00089 }
00090
00091
00092 s->frame.nb_samples = out_size;
00093 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
00094 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00095 return ret;
00096 }
00097 samples = s->frame.data[0];
00098 samples_end = samples + out_size;
00099
00100 if (in_size == out_size) {
00101 memcpy(samples, buf, out_size);
00102 *got_frame_ptr = 1;
00103 *(AVFrame *)data = s->frame;
00104 return buf_size;
00105 }
00106
00107 while (samples < samples_end && buf - avpkt->data < buf_size) {
00108 int code, smp, size;
00109 uint8_t count;
00110 code = *buf >> 6;
00111 count = *buf & 0x3F;
00112 buf++;
00113
00114
00115 switch (code) {
00116 case 0: smp = 4 * (count + 1); break;
00117 case 1: smp = 2 * (count + 1); break;
00118 case 2: smp = (count & 0x20) ? 1 : count + 1; break;
00119 default: smp = count + 1; break;
00120 }
00121 if (samples_end - samples < smp)
00122 break;
00123
00124
00125 size = ((code == 2 && (count & 0x20)) || code == 3) ? 0 : count + 1;
00126 if ((buf - avpkt->data) + size > buf_size)
00127 break;
00128
00129 switch (code) {
00130 case 0:
00131 for (count++; count > 0; count--) {
00132 code = *buf++;
00133 sample += ( code & 0x3) - 2;
00134 sample = av_clip_uint8(sample);
00135 *samples++ = sample;
00136 sample += ((code >> 2) & 0x3) - 2;
00137 sample = av_clip_uint8(sample);
00138 *samples++ = sample;
00139 sample += ((code >> 4) & 0x3) - 2;
00140 sample = av_clip_uint8(sample);
00141 *samples++ = sample;
00142 sample += (code >> 6) - 2;
00143 sample = av_clip_uint8(sample);
00144 *samples++ = sample;
00145 }
00146 break;
00147 case 1:
00148 for (count++; count > 0; count--) {
00149 code = *buf++;
00150 sample += ws_adpcm_4bit[code & 0xF];
00151 sample = av_clip_uint8(sample);
00152 *samples++ = sample;
00153 sample += ws_adpcm_4bit[code >> 4];
00154 sample = av_clip_uint8(sample);
00155 *samples++ = sample;
00156 }
00157 break;
00158 case 2:
00159 if (count & 0x20) {
00160 int8_t t;
00161 t = count;
00162 t <<= 3;
00163 sample += t >> 3;
00164 sample = av_clip_uint8(sample);
00165 *samples++ = sample;
00166 } else {
00167 memcpy(samples, buf, smp);
00168 samples += smp;
00169 buf += smp;
00170 sample = buf[-1];
00171 }
00172 break;
00173 default:
00174 memset(samples, sample, smp);
00175 samples += smp;
00176 }
00177 }
00178
00179 s->frame.nb_samples = samples - s->frame.data[0];
00180 *got_frame_ptr = 1;
00181 *(AVFrame *)data = s->frame;
00182
00183 return buf_size;
00184 }
00185
00186 AVCodec ff_ws_snd1_decoder = {
00187 .name = "ws_snd1",
00188 .type = AVMEDIA_TYPE_AUDIO,
00189 .id = AV_CODEC_ID_WESTWOOD_SND1,
00190 .priv_data_size = sizeof(WSSndContext),
00191 .init = ws_snd_decode_init,
00192 .decode = ws_snd_decode_frame,
00193 .capabilities = CODEC_CAP_DR1,
00194 .long_name = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"),
00195 };