[FFmpeg-devel] [PATCH 2/5] wma lossless: reuse scalarproduct_and_madd_int16
Christophe Gisquet
christophe.gisquet at gmail.com
Fri May 10 11:32:55 CEST 2013
Approximate relative speedup depending on instruction set:
plain C: -6%
mmxext: 51%
sse2: 54%
---
libavcodec/wmalosslessdec.c | 48 +++++++++++++++++----------------------------
1 file changed, 18 insertions(+), 30 deletions(-)
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 90a0109..e566943 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -29,6 +29,7 @@
#include "internal.h"
#include "get_bits.h"
#include "put_bits.h"
+#include "dsputil.h"
#include "wma.h"
#include "wma_common.h"
@@ -66,6 +67,7 @@ typedef struct {
typedef struct WmallDecodeCtx {
/* generic decoder variables */
AVCodecContext *avctx;
+ DSPContext dsp; ///< accelerated DSP functions
AVFrame frame;
uint8_t frame_data[MAX_FRAMESIZE + FF_INPUT_BUFFER_PADDING_SIZE]; ///< compressed frame data
PutBitContext pb; ///< context for filling the frame_data buffer
@@ -141,9 +143,9 @@ typedef struct WmallDecodeCtx {
int scaling;
int coefsend;
int bitsend;
- int16_t coefs[MAX_ORDER];
- int16_t lms_prevvalues[MAX_ORDER * 2];
- int16_t lms_updates[MAX_ORDER * 2];
+ DECLARE_ALIGNED(16, int16_t, coefs)[MAX_ORDER];
+ DECLARE_ALIGNED(16, int16_t, lms_prevvalues)[MAX_ORDER * 2];
+ DECLARE_ALIGNED(16, int16_t, lms_updates)[MAX_ORDER * 2];
int recent;
} cdlms[WMALL_MAX_CHANNELS][9];
@@ -179,6 +181,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
int i, log2_max_num_subframes;
s->avctx = avctx;
+ ff_dsputil_init(&s->dsp, avctx);
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
if (avctx->extradata_size >= 18) {
@@ -684,35 +687,11 @@ static void revert_mclms(WmallDecodeCtx *s, int tile_size)
}
}
-static int lms_predict(WmallDecodeCtx *s, int ich, int ilms)
+static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int input)
{
- int pred = 0, icoef;
- int recent = s->cdlms[ich][ilms].recent;
-
- for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
- pred += s->cdlms[ich][ilms].coefs[icoef] *
- s->cdlms[ich][ilms].lms_prevvalues[icoef + recent];
-
- return pred;
-}
-
-static void lms_update(WmallDecodeCtx *s, int ich, int ilms,
- int input, int residue)
-{
- int icoef;
int recent = s->cdlms[ich][ilms].recent;
int range = 1 << s->bits_per_sample - 1;
- if (residue < 0) {
- for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
- s->cdlms[ich][ilms].coefs[icoef] -=
- s->cdlms[ich][ilms].lms_updates[icoef + recent];
- } else if (residue > 0) {
- for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
- s->cdlms[ich][ilms].coefs[icoef] +=
- s->cdlms[ich][ilms].lms_updates[icoef + recent];
- }
-
if (recent)
recent--;
else {
@@ -773,6 +752,9 @@ static void use_normal_update_speed(WmallDecodeCtx *s, int ich)
s->update_speed[ich] = 8;
}
+/** Get sign of integer (1 for positive, -1 for negative and 0 for zero) */
+#define WMASIGN(x) ((x > 0) - (x < 0))
+
static void revert_cdlms(WmallDecodeCtx *s, int ch,
int coef_begin, int coef_end)
{
@@ -783,9 +765,15 @@ static void revert_cdlms(WmallDecodeCtx *s, int ch,
for (icoef = coef_begin; icoef < coef_end; icoef++) {
pred = 1 << (s->cdlms[ch][ilms].scaling - 1);
residue = s->channel_residues[ch][icoef];
- pred += lms_predict(s, ch, ilms);
+ pred += s->dsp.scalarproduct_and_madd_int16(s->cdlms[ch][ilms].coefs,
+ s->cdlms[ch][ilms].lms_prevvalues
+ + s->cdlms[ch][ilms].recent,
+ s->cdlms[ch][ilms].lms_updates
+ + s->cdlms[ch][ilms].recent,
+ s->cdlms[ch][ilms].order,
+ WMASIGN(residue));
input = residue + (pred >> s->cdlms[ch][ilms].scaling);
- lms_update(s, ch, ilms, input, residue);
+ lms_update(s, ch, ilms, input);
s->channel_residues[ch][icoef] = input;
}
}
--
1.8.0.msysgit.0
More information about the ffmpeg-devel
mailing list