* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/channel_layout.h"
#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "get_bits.h"
}
static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype,
- float *out)
+ float **out)
{
const ModeTab *mtab = tctx->mtab;
int size1, size2;
size2 = tctx->last_block_pos[0];
size1 = mtab->size - size2;
- if (tctx->avctx->channels == 2) {
- tctx->dsp.butterflies_float_interleave(out, prev_buf,
- &prev_buf[2*mtab->size],
- size1);
-
- out += 2 * size1;
-
- tctx->dsp.butterflies_float_interleave(out, tctx->curr_frame,
- &tctx->curr_frame[2*mtab->size],
- size2);
- } else {
- memcpy(out, prev_buf, size1 * sizeof(*out));
- out += size1;
+ memcpy(&out[0][0 ], prev_buf, size1 * sizeof(out[0][0]));
+ memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0]));
- memcpy(out, tctx->curr_frame, size2 * sizeof(*out));
+ if (tctx->avctx->channels == 2) {
+ memcpy(&out[1][0], &prev_buf[2*mtab->size], size1 * sizeof(out[1][0]));
+ memcpy(&out[1][size1], &tctx->curr_frame[2*mtab->size], size2 * sizeof(out[1][0]));
+ tctx->dsp.butterflies_float(out[0], out[1], mtab->size);
}
-
}
static void dec_bark_env(TwinContext *tctx, const uint8_t *in, int use_hist,
TwinContext *tctx = avctx->priv_data;
GetBitContext gb;
const ModeTab *mtab = tctx->mtab;
- float *out = NULL;
+ float **out = NULL;
enum FrameType ftype;
int window_type, ret;
static const enum FrameType wtype_to_ftype_table[] = {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
}
- out = (float *)tctx->frame.data[0];
+ out = (float **)tctx->frame.extended_data;
}
init_get_bits(&gb, buf, buf_size * 8);
int isampf, ibps;
tctx->avctx = avctx;
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
if (!avctx->extradata || avctx->extradata_size < 12) {
av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
avctx->channels = AV_RB32(avctx->extradata ) + 1;
avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
isampf = AV_RB32(avctx->extradata + 8);
+
+ if (isampf < 8 || isampf > 44) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n");
+ return AVERROR_INVALIDDATA;
+ }
switch (isampf) {
case 44: avctx->sample_rate = 44100; break;
case 22: avctx->sample_rate = 22050; break;
default: avctx->sample_rate = isampf * 1000; break;
}
- if (avctx->channels > CHANNELS_MAX) {
+ if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) {
av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
avctx->channels);
return -1;
}
+ avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
+ AV_CH_LAYOUT_STEREO;
+
ibps = avctx->bit_rate / (1000 * avctx->channels);
+ if (ibps > 255U) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported per channel bitrate %dkbps\n", ibps);
+ return AVERROR_INVALIDDATA;
+ }
+
switch ((isampf << 8) + ibps) {
case (8 <<8) + 8: tctx->mtab = &mode_08_08; break;
case (11<<8) + 8: tctx->mtab = &mode_11_08; break;
.decode = twin_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_NONE },
};