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