Commit 8e7e74df authored by Rostislav Pehlivanov's avatar Rostislav Pehlivanov

opus_pvq: port to allow for SIMD functions

Signed-off-by: 's avatarRostislav Pehlivanov <atomnuker@gmail.com>
parent e6ec482b
......@@ -753,15 +753,15 @@ static void celt_decode_bands(CeltFrame *f, OpusRangeCoder *rc)
}
if (f->dual_stereo) {
cm[0] = ff_celt_decode_band(f, rc, i, X, NULL, band_size, b / 2, f->blocks,
cm[0] = f->pvq->decode_band(f->pvq, f, rc, i, X, NULL, band_size, b / 2, f->blocks,
effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]);
cm[1] = ff_celt_decode_band(f, rc, i, Y, NULL, band_size, b/2, f->blocks,
cm[1] = f->pvq->decode_band(f->pvq, f, rc, i, Y, NULL, band_size, b/2, f->blocks,
effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL, f->size,
norm2 + band_offset, 0, 1.0f, lowband_scratch, cm[1]);
} else {
cm[0] = ff_celt_decode_band(f, rc, i, X, Y, band_size, b, f->blocks,
cm[0] = f->pvq->decode_band(f->pvq, f, rc, i, X, Y, band_size, b, f->blocks,
effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]|cm[1]);
cm[1] = cm[0];
......@@ -984,6 +984,8 @@ void ff_celt_free(CeltFrame **f)
for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++)
ff_mdct15_uninit(&frm->imdct[i]);
ff_celt_pvq_uninit(&frm->pvq);
av_freep(&frm->dsp);
av_freep(f);
}
......@@ -1006,11 +1008,12 @@ int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels)
frm->avctx = avctx;
frm->output_channels = output_channels;
for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++) {
ret = ff_mdct15_init(&frm->imdct[i], 1, i + 3, -1.0f);
if (ret < 0)
for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++)
if ((ret = ff_mdct15_init(&frm->imdct[i], 1, i + 3, -1.0f)) < 0)
goto fail;
if ((ret = ff_celt_pvq_init(&frm->pvq)) < 0)
goto fail;
}
frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
if (!frm->dsp) {
......
......@@ -27,6 +27,7 @@
#include <float.h>
#include "opus.h"
#include "opus_pvq.h"
#include "mdct15.h"
#include "libavutil/float_dsp.h"
......@@ -43,6 +44,8 @@
#define CELT_POSTFILTER_MINPERIOD 15
#define CELT_ENERGY_SILENCE (-28.0f)
typedef struct CeltPVQ CeltPVQ;
enum CeltSpread {
CELT_SPREAD_NONE,
CELT_SPREAD_LIGHT,
......@@ -92,6 +95,7 @@ struct CeltFrame {
MDCT15Context *imdct[4];
AVFloatDSPContext *dsp;
CeltBlock block[2];
CeltPVQ *pvq;
int channels;
int output_channels;
......@@ -125,8 +129,6 @@ struct CeltFrame {
int fine_priority[CELT_MAX_BANDS];
int pulses [CELT_MAX_BANDS];
int tf_change [CELT_MAX_BANDS];
DECLARE_ALIGNED(32, float, scratch)[22 * 8]; // MAX(ff_celt_freq_range) * 1<<CELT_MAX_LOG_BLOCKS
};
/* LCG for noise generation */
......
This diff is collapsed.
......@@ -23,22 +23,28 @@
#ifndef AVCODEC_OPUS_PVQ_H
#define AVCODEC_OPUS_PVQ_H
#include "opus.h"
#include "opus_celt.h"
/* Decodes a band using PVQ */
uint32_t ff_celt_decode_band(CeltFrame *f, OpusRangeCoder *rc, const int band,
float *X, float *Y, int N, int b, uint32_t blocks,
float *lowband, int duration, float *lowband_out, int level,
float gain, float *lowband_scratch, int fill);
#define QUANT_FN(name) uint32_t (name)(struct CeltPVQ *pvq, CeltFrame *f, \
OpusRangeCoder *rc, const int band, float *X, \
float *Y, int N, int b, uint32_t blocks, \
float *lowband, int duration, \
float *lowband_out, int level, float gain, \
float *lowband_scratch, int fill)
/* Encodes a band using PVQ */
uint32_t ff_celt_encode_band(CeltFrame *f, OpusRangeCoder *rc, const int band,
float *X, float *Y, int N, int b, uint32_t blocks,
float *lowband, int duration, float *lowband_out, int level,
float gain, float *lowband_scratch, int fill);
struct CeltPVQ {
DECLARE_ALIGNED(32, int, qcoeff )[176];
DECLARE_ALIGNED(32, float, hadamard_tmp)[176];
float ff_celt_quant_band_cost(CeltFrame *f, OpusRangeCoder *rc, int band,
float *bits, float lambda);
float (*pvq_search)(float *X, int *y, int K, int N);
QUANT_FN(*decode_band);
QUANT_FN(*encode_band);
float (*band_cost)(struct CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc,
int band, float *bits, float lambda);
};
int ff_celt_pvq_init (struct CeltPVQ **pvq);
void ff_celt_pvq_uninit(struct CeltPVQ **pvq);
#endif /* AVCODEC_OPUS_PVQ_H */
......@@ -55,6 +55,7 @@ typedef struct OpusEncContext {
AudioFrameQueue afq;
AVFloatDSPContext *dsp;
MDCT15Context *mdct[CELT_BLOCK_NB];
CeltPVQ *pvq;
struct FFBufQueue bufqueue;
enum OpusMode mode;
......@@ -797,15 +798,15 @@ static void celt_quant_bands(OpusRangeCoder *rc, CeltFrame *f)
}
if (f->dual_stereo) {
cm[0] = ff_celt_encode_band(f, rc, i, X, NULL, band_size, b / 2, f->blocks,
cm[0] = f->pvq->encode_band(f->pvq, f, rc, i, X, NULL, band_size, b / 2, f->blocks,
effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]);
cm[1] = ff_celt_encode_band(f, rc, i, Y, NULL, band_size, b / 2, f->blocks,
cm[1] = f->pvq->encode_band(f->pvq, f, rc, i, Y, NULL, band_size, b / 2, f->blocks,
effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL, f->size,
norm2 + band_offset, 0, 1.0f, lowband_scratch, cm[1]);
} else {
cm[0] = ff_celt_encode_band(f, rc, i, X, Y, band_size, b, f->blocks,
cm[0] = f->pvq->encode_band(f->pvq, f, rc, i, X, Y, band_size, b, f->blocks,
effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
norm + band_offset, 0, 1.0f, lowband_scratch, cm[0] | cm[1]);
cm[1] = cm[0];
......@@ -883,6 +884,7 @@ static void ff_opus_psy_celt_frame_setup(OpusEncContext *s, CeltFrame *f, int in
f->avctx = s->avctx;
f->dsp = s->dsp;
f->pvq = s->pvq;
f->start_band = (s->mode == OPUS_MODE_HYBRID) ? 17 : 0;
f->end_band = ff_celt_band_end[s->bandwidth];
f->channels = s->channels;
......@@ -1019,6 +1021,7 @@ static av_cold int opus_encode_end(AVCodecContext *avctx)
for (i = 0; i < CELT_BLOCK_NB; i++)
ff_mdct15_uninit(&s->mdct[i]);
ff_celt_pvq_uninit(&s->pvq);
av_freep(&s->dsp);
av_freep(&s->frame);
av_freep(&s->rc);
......@@ -1075,6 +1078,9 @@ static av_cold int opus_encode_init(AVCodecContext *avctx)
ff_af_queue_init(avctx, &s->afq);
if ((ret = ff_celt_pvq_init(&s->pvq)) < 0)
return ret;
if (!(s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT)))
return AVERROR(ENOMEM);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment