Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net> Signed-off-by: Martin Storsjö <martin@martin.st>tags/n2.6
| @@ -511,8 +511,8 @@ OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o adpcm_data.o | |||||
| OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o adpcm_data.o | OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o adpcm_data.o | ||||
| OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o adpcm_data.o | OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o adpcm_data.o | ||||
| OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o adpcm_data.o | OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o adpcm_data.o | ||||
| OBJS-$(CONFIG_ADPCM_G722_DECODER) += g722.o g722dec.o | |||||
| OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722enc.o | |||||
| OBJS-$(CONFIG_ADPCM_G722_DECODER) += g722.o g722dsp.o g722dec.o | |||||
| OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722dsp.o g722enc.o | |||||
| OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o | OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o | ||||
| OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o | OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o | ||||
| OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o | OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o | ||||
| @@ -71,16 +71,6 @@ const int16_t ff_g722_low_inv_quant6[64] = { | |||||
| 211, 170, 130, 91, 54, 17, -54, -17 | 211, 170, 130, 91, 54, 17, -54, -17 | ||||
| }; | }; | ||||
| /** | |||||
| * quadrature mirror filter (QMF) coefficients | |||||
| * | |||||
| * ITU-T G.722 Table 11 | |||||
| */ | |||||
| static const int16_t qmf_coeffs[12] = { | |||||
| 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, | |||||
| }; | |||||
| /** | /** | ||||
| * adaptive predictor | * adaptive predictor | ||||
| * | * | ||||
| @@ -157,15 +147,3 @@ void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh, | |||||
| high_log_factor_step[ihigh&1], 0, 22528); | high_log_factor_step[ihigh&1], 0, 22528); | ||||
| band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11)); | band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11)); | ||||
| } | } | ||||
| void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2) | |||||
| { | |||||
| int i; | |||||
| *xout1 = 0; | |||||
| *xout2 = 0; | |||||
| for (i = 0; i < 12; i++) { | |||||
| MAC16(*xout2, prev_samples[2*i ], qmf_coeffs[i ]); | |||||
| MAC16(*xout1, prev_samples[2*i+1], qmf_coeffs[11-i]); | |||||
| } | |||||
| } | |||||
| @@ -27,6 +27,7 @@ | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "g722dsp.h" | |||||
| #define PREV_SAMPLES_BUF_SIZE 1024 | #define PREV_SAMPLES_BUF_SIZE 1024 | ||||
| @@ -61,6 +62,8 @@ typedef struct G722Context { | |||||
| int value; | int value; | ||||
| int prev; | int prev; | ||||
| } *paths[2]; | } *paths[2]; | ||||
| G722DSPContext dsp; | |||||
| } G722Context; | } G722Context; | ||||
| extern const int16_t ff_g722_high_inv_quant[4]; | extern const int16_t ff_g722_high_inv_quant[4]; | ||||
| @@ -72,6 +75,4 @@ void ff_g722_update_low_predictor(struct G722Band *band, const int ilow); | |||||
| void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh, | void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh, | ||||
| const int ihigh); | const int ihigh); | ||||
| void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2); | |||||
| #endif /* AVCODEC_G722_H */ | #endif /* AVCODEC_G722_H */ | ||||
| @@ -67,6 +67,8 @@ static av_cold int g722_decode_init(AVCodecContext * avctx) | |||||
| c->band[1].scale_factor = 2; | c->band[1].scale_factor = 2; | ||||
| c->prev_samples_pos = 22; | c->prev_samples_pos = 22; | ||||
| ff_g722dsp_init(&c->dsp); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -122,8 +124,8 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, | |||||
| c->prev_samples[c->prev_samples_pos++] = rlow + rhigh; | c->prev_samples[c->prev_samples_pos++] = rlow + rhigh; | ||||
| c->prev_samples[c->prev_samples_pos++] = rlow - rhigh; | c->prev_samples[c->prev_samples_pos++] = rlow - rhigh; | ||||
| ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, | |||||
| &xout1, &xout2); | |||||
| c->dsp.apply_qmf(c->prev_samples + c->prev_samples_pos - 24, | |||||
| &xout1, &xout2); | |||||
| *out_buf++ = av_clip_int16(xout1 >> 11); | *out_buf++ = av_clip_int16(xout1 >> 11); | ||||
| *out_buf++ = av_clip_int16(xout2 >> 11); | *out_buf++ = av_clip_int16(xout2 >> 11); | ||||
| if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { | if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { | ||||
| @@ -0,0 +1,47 @@ | |||||
| /* | |||||
| * Copyright (c) 2015 Peter Meerwald <pmeerw@pmeerw.net> | |||||
| * | |||||
| * This file is part of Libav. | |||||
| * | |||||
| * Libav is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * | |||||
| * Libav is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with Libav; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #include "g722dsp.h" | |||||
| #include "mathops.h" | |||||
| /* | |||||
| * quadrature mirror filter (QMF) coefficients (ITU-T G.722 Table 11) inlined | |||||
| * in code below: 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11 | |||||
| */ | |||||
| static const int16_t qmf_coeffs[12] = { | |||||
| 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, | |||||
| }; | |||||
| static void g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2) | |||||
| { | |||||
| int i; | |||||
| *xout1 = 0; | |||||
| *xout2 = 0; | |||||
| for (i = 0; i < 12; i++) { | |||||
| MAC16(*xout2, prev_samples[2*i ], qmf_coeffs[i ]); | |||||
| MAC16(*xout1, prev_samples[2*i+1], qmf_coeffs[11-i]); | |||||
| } | |||||
| } | |||||
| av_cold void ff_g722dsp_init(G722DSPContext *c) | |||||
| { | |||||
| c->apply_qmf = g722_apply_qmf; | |||||
| } | |||||
| @@ -0,0 +1,32 @@ | |||||
| /* | |||||
| * Copyright (c) 2015 Peter Meerwald <pmeerw@pmeerw.net> | |||||
| * | |||||
| * This file is part of Libav. | |||||
| * | |||||
| * Libav is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * | |||||
| * Libav is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with Libav; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #ifndef AVCODEC_G722DSP_H | |||||
| #define AVCODEC_G722DSP_H | |||||
| #include <stdint.h> | |||||
| typedef struct G722DSPContext { | |||||
| void (*apply_qmf)(const int16_t *prev_samples, int *xout1, int *xout2); | |||||
| } G722DSPContext; | |||||
| void ff_g722dsp_init(G722DSPContext *c); | |||||
| #endif /* AVCODEC_G722DSP_H */ | |||||
| @@ -119,6 +119,8 @@ static av_cold int g722_encode_init(AVCodecContext * avctx) | |||||
| } | } | ||||
| } | } | ||||
| ff_g722dsp_init(&c->dsp); | |||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| g722_encode_close(avctx); | g722_encode_close(avctx); | ||||
| @@ -138,7 +140,7 @@ static inline void filter_samples(G722Context *c, const int16_t *samples, | |||||
| int xout1, xout2; | int xout1, xout2; | ||||
| c->prev_samples[c->prev_samples_pos++] = samples[0]; | c->prev_samples[c->prev_samples_pos++] = samples[0]; | ||||
| c->prev_samples[c->prev_samples_pos++] = samples[1]; | c->prev_samples[c->prev_samples_pos++] = samples[1]; | ||||
| ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); | |||||
| c->dsp.apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); | |||||
| *xlow = xout1 + xout2 >> 14; | *xlow = xout1 + xout2 >> 14; | ||||
| *xhigh = xout1 - xout2 >> 14; | *xhigh = xout1 - xout2 >> 14; | ||||
| if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { | if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { | ||||