annotate g722.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 750ff18b7394
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12478
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
1 /*
12508
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
2 * G.722 ADPCM audio encoder/decoder
12478
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
3 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
4 * Copyright (c) CMU 1993 Computer Science, Speech Group
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
5 * Chengxiang Lu and Alex Hauptmann
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
6 * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
7 * Copyright (c) 2009 Kenan Gillet
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
8 * Copyright (c) 2010 Martin Storsjo
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
9 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
10 * This file is part of FFmpeg.
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
11 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
12 * FFmpeg is free software; you can redistribute it and/or
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
13 * modify it under the terms of the GNU Lesser General Public
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
14 * License as published by the Free Software Foundation; either
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
15 * version 2.1 of the License, or (at your option) any later version.
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
16 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
17 * FFmpeg is distributed in the hope that it will be useful,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
20 * Lesser General Public License for more details.
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
21 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
22 * You should have received a copy of the GNU Lesser General Public
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
23 * License along with FFmpeg; if not, write to the Free Software
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
25 */
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
26
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
27 /**
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
28 * @file
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
29 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
30 * G.722 ADPCM audio codec
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
31 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
32 * This G.722 decoder is a bit-exact implementation of the ITU G.722
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
33 * specification for all three specified bitrates - 64000bps, 56000bps
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
34 * and 48000bps. It passes the ITU tests.
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
35 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
36 * @note For the 56000bps and 48000bps bitrates, the lowest 1 or 2 bits
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
37 * respectively of each byte are ignored.
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
38 */
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
39
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
40 #include "avcodec.h"
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
41 #include "mathops.h"
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
42 #include "get_bits.h"
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
43
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
44 #define PREV_SAMPLES_BUF_SIZE 1024
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
45
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
46 typedef struct {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
47 int16_t prev_samples[PREV_SAMPLES_BUF_SIZE]; ///< memory of past decoded samples
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
48 int prev_samples_pos; ///< the number of values in prev_samples
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
49
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
50 /**
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
51 * The band[0] and band[1] correspond respectively to the lower band and higher band.
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
52 */
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
53 struct G722Band {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
54 int16_t s_predictor; ///< predictor output value
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
55 int32_t s_zero; ///< previous output signal from zero predictor
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
56 int8_t part_reconst_mem[2]; ///< signs of previous partially reconstructed signals
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
57 int16_t prev_qtzd_reconst; ///< previous quantized reconstructed signal (internal value, using low_inv_quant4)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
58 int16_t pole_mem[2]; ///< second-order pole section coefficient buffer
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
59 int32_t diff_mem[6]; ///< quantizer difference signal memory
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
60 int16_t zero_mem[6]; ///< Seventh-order zero section coefficient buffer
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
61 int16_t log_factor; ///< delayed 2-logarithmic quantizer factor
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
62 int16_t scale_factor; ///< delayed quantizer scale factor
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
63 } band[2];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
64 } G722Context;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
65
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
66
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
67 static const int8_t sign_lookup[2] = { -1, 1 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
68
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
69 static const int16_t inv_log2_table[32] = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
70 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
71 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
72 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
73 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
74 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
75 static const int16_t high_log_factor_step[2] = { 798, -214 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
76 static const int16_t high_inv_quant[4] = { -926, -202, 926, 202 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
77 /**
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
78 * low_log_factor_step[index] == wl[rl42[index]]
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
79 */
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
80 static const int16_t low_log_factor_step[16] = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
81 -60, 3042, 1198, 538, 334, 172, 58, -30,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
82 3042, 1198, 538, 334, 172, 58, -30, -60
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
83 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
84 static const int16_t low_inv_quant4[16] = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
85 0, -2557, -1612, -1121, -786, -530, -323, -150,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
86 2557, 1612, 1121, 786, 530, 323, 150, 0
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
87 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
88
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
89 /**
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
90 * quadrature mirror filter (QMF) coefficients
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
91 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
92 * ITU-T G.722 Table 11
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
93 */
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
94 static const int16_t qmf_coeffs[12] = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
95 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
96 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
97
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
98
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
99 /**
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
100 * adaptive predictor
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
101 *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
102 * @param cur_diff the dequantized and scaled delta calculated from the
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
103 * current codeword
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
104 */
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
105 static void do_adaptive_prediction(struct G722Band *band, const int cur_diff)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
106 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
107 int sg[2], limit, i, cur_qtzd_reconst;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
108
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
109 const int cur_part_reconst = band->s_zero + cur_diff < 0;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
110
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
111 sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
112 sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
113 band->part_reconst_mem[1] = band->part_reconst_mem[0];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
114 band->part_reconst_mem[0] = cur_part_reconst;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
115
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
116 band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) +
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
117 (sg[1] << 7) + (band->pole_mem[1] * 127 >> 7), -12288, 12288);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
118
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
119 limit = 15360 - band->pole_mem[1];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
120 band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
121
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
122
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
123 if (cur_diff) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
124 for (i = 0; i < 6; i++)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
125 band->zero_mem[i] = ((band->zero_mem[i]*255) >> 8) +
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
126 ((band->diff_mem[i]^cur_diff) < 0 ? -128 : 128);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
127 } else
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
128 for (i = 0; i < 6; i++)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
129 band->zero_mem[i] = (band->zero_mem[i]*255) >> 8;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
130
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
131 for (i = 5; i > 0; i--)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
132 band->diff_mem[i] = band->diff_mem[i-1];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
133 band->diff_mem[0] = av_clip_int16(cur_diff << 1);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
134
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
135 band->s_zero = 0;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
136 for (i = 5; i >= 0; i--)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
137 band->s_zero += (band->zero_mem[i]*band->diff_mem[i]) >> 15;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
138
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
139
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
140 cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) << 1);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
141 band->s_predictor = av_clip_int16(band->s_zero +
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
142 (band->pole_mem[0] * cur_qtzd_reconst >> 15) +
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
143 (band->pole_mem[1] * band->prev_qtzd_reconst >> 15));
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
144 band->prev_qtzd_reconst = cur_qtzd_reconst;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
145 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
146
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
147 static int inline linear_scale_factor(const int log_factor)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
148 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
149 const int wd1 = inv_log2_table[(log_factor >> 6) & 31];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
150 const int shift = log_factor >> 11;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
151 return shift < 0 ? wd1 >> -shift : wd1 << shift;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
152 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
153
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
154 static void update_low_predictor(struct G722Band *band, const int ilow)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
155 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
156 do_adaptive_prediction(band,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
157 band->scale_factor * low_inv_quant4[ilow] >> 10);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
158
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
159 // quantizer adaptation
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
160 band->log_factor = av_clip((band->log_factor * 127 >> 7) +
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
161 low_log_factor_step[ilow], 0, 18432);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
162 band->scale_factor = linear_scale_factor(band->log_factor - (8 << 11));
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
163 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
164
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
165 static void update_high_predictor(struct G722Band *band, const int dhigh,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
166 const int ihigh)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
167 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
168 do_adaptive_prediction(band, dhigh);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
169
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
170 // quantizer adaptation
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
171 band->log_factor = av_clip((band->log_factor * 127 >> 7) +
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
172 high_log_factor_step[ihigh&1], 0, 22528);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
173 band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11));
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
174 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
175
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
176 static void apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
177 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
178 int i;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
179
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
180 *xout1 = 0;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
181 *xout2 = 0;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
182 for (i = 0; i < 12; i++) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
183 MAC16(*xout2, prev_samples[2*i ], qmf_coeffs[i ]);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
184 MAC16(*xout1, prev_samples[2*i+1], qmf_coeffs[11-i]);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
185 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
186 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
187
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
188 static av_cold int g722_init(AVCodecContext * avctx)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
189 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
190 G722Context *c = avctx->priv_data;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
191
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
192 if (avctx->channels != 1) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
193 av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n");
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
194 return AVERROR_INVALIDDATA;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
195 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
196 avctx->sample_fmt = SAMPLE_FMT_S16;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
197
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
198 switch (avctx->bits_per_coded_sample) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
199 case 8:
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
200 case 7:
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
201 case 6:
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
202 break;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
203 default:
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
204 av_log(avctx, AV_LOG_WARNING, "Unsupported bits_per_coded_sample [%d], "
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
205 "assuming 8\n",
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
206 avctx->bits_per_coded_sample);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
207 case 0:
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
208 avctx->bits_per_coded_sample = 8;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
209 break;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
210 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
211
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
212 c->band[0].scale_factor = 8;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
213 c->band[1].scale_factor = 2;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
214 c->prev_samples_pos = 22;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
215
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
216 if (avctx->lowres)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
217 avctx->sample_rate /= 2;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
218
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
219 return 0;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
220 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
221
12508
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
222 #if CONFIG_ADPCM_G722_DECODER
12478
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
223 static const int16_t low_inv_quant5[32] = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
224 -35, -35, -2919, -2195, -1765, -1458, -1219, -1023,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
225 -858, -714, -587, -473, -370, -276, -190, -110,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
226 2919, 2195, 1765, 1458, 1219, 1023, 858, 714,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
227 587, 473, 370, 276, 190, 110, 35, -35
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
228 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
229 static const int16_t low_inv_quant6[64] = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
230 -17, -17, -17, -17, -3101, -2738, -2376, -2088,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
231 -1873, -1689, -1535, -1399, -1279, -1170, -1072, -982,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
232 -899, -822, -750, -682, -618, -558, -501, -447,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
233 -396, -347, -300, -254, -211, -170, -130, -91,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
234 3101, 2738, 2376, 2088, 1873, 1689, 1535, 1399,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
235 1279, 1170, 1072, 982, 899, 822, 750, 682,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
236 618, 558, 501, 447, 396, 347, 300, 254,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
237 211, 170, 130, 91, 54, 17, -54, -17
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
238 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
239
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
240 static const int16_t *low_inv_quants[3] = { low_inv_quant6, low_inv_quant5,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
241 low_inv_quant4 };
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
242
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
243 static int g722_decode_frame(AVCodecContext *avctx, void *data,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
244 int *data_size, AVPacket *avpkt)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
245 {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
246 G722Context *c = avctx->priv_data;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
247 int16_t *out_buf = data;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
248 int j, out_len = 0;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
249 const int skip = 8 - avctx->bits_per_coded_sample;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
250 const int16_t *quantizer_table = low_inv_quants[skip];
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
251 GetBitContext gb;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
252
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
253 init_get_bits(&gb, avpkt->data, avpkt->size * 8);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
254
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
255 for (j = 0; j < avpkt->size; j++) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
256 int ilow, ihigh, rlow;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
257
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
258 ihigh = get_bits(&gb, 2);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
259 ilow = get_bits(&gb, 6 - skip);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
260 skip_bits(&gb, skip);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
261
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
262 rlow = av_clip((c->band[0].scale_factor * quantizer_table[ilow] >> 10)
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
263 + c->band[0].s_predictor, -16384, 16383);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
264
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
265 update_low_predictor(&c->band[0], ilow >> (2 - skip));
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
266
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
267 if (!avctx->lowres) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
268 const int dhigh = c->band[1].scale_factor *
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
269 high_inv_quant[ihigh] >> 10;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
270 const int rhigh = av_clip(dhigh + c->band[1].s_predictor,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
271 -16384, 16383);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
272 int xout1, xout2;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
273
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
274 update_high_predictor(&c->band[1], dhigh, ihigh);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
275
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
276 c->prev_samples[c->prev_samples_pos++] = rlow + rhigh;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
277 c->prev_samples[c->prev_samples_pos++] = rlow - rhigh;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
278 apply_qmf(c->prev_samples + c->prev_samples_pos - 24,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
279 &xout1, &xout2);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
280 out_buf[out_len++] = av_clip_int16(xout1 >> 12);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
281 out_buf[out_len++] = av_clip_int16(xout2 >> 12);
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
282 if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
283 memmove(c->prev_samples,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
284 c->prev_samples + c->prev_samples_pos - 22,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
285 22 * sizeof(c->prev_samples[0]));
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
286 c->prev_samples_pos = 22;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
287 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
288 } else
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
289 out_buf[out_len++] = rlow;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
290 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
291 *data_size = out_len << 1;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
292 return avpkt->size;
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
293 }
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
294
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
295 AVCodec adpcm_g722_decoder = {
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
296 .name = "g722",
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
297 .type = AVMEDIA_TYPE_AUDIO,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
298 .id = CODEC_ID_ADPCM_G722,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
299 .priv_data_size = sizeof(G722Context),
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
300 .init = g722_init,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
301 .decode = g722_decode_frame,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
302 .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
303 .max_lowres = 1,
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
304 };
12508
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
305 #endif
12478
5942c42c44e5 Add G.722 ADPCM audio decoder
mstorsjo
parents:
diff changeset
306
12508
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
307 #if CONFIG_ADPCM_G722_ENCODER
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
308 static const int16_t low_quant[33] = {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
309 35, 72, 110, 150, 190, 233, 276, 323,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
310 370, 422, 473, 530, 587, 650, 714, 786,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
311 858, 940, 1023, 1121, 1219, 1339, 1458, 1612,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
312 1765, 1980, 2195, 2557, 2919
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
313 };
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
314
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
315 static inline void filter_samples(G722Context *c, const int16_t *samples,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
316 int *xlow, int *xhigh)
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
317 {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
318 int xout1, xout2;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
319 c->prev_samples[c->prev_samples_pos++] = samples[0];
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
320 c->prev_samples[c->prev_samples_pos++] = samples[1];
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
321 apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
322 *xlow = xout1 + xout2 >> 13;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
323 *xhigh = xout1 - xout2 >> 13;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
324 if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
325 memmove(c->prev_samples,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
326 c->prev_samples + c->prev_samples_pos - 22,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
327 22 * sizeof(c->prev_samples[0]));
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
328 c->prev_samples_pos = 22;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
329 }
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
330 }
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
331
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
332 static inline int encode_high(const struct G722Band *state, int xhigh)
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
333 {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
334 int diff = av_clip_int16(xhigh - state->s_predictor);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
335 int pred = 141 * state->scale_factor >> 8;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
336 /* = diff >= 0 ? (diff < pred) + 2 : diff >= -pred */
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
337 return ((diff ^ (diff >> (sizeof(diff)*8-1))) < pred) + 2*(diff >= 0);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
338 }
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
339
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
340 static inline int encode_low(const struct G722Band* state, int xlow)
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
341 {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
342 int diff = av_clip_int16(xlow - state->s_predictor);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
343 /* = diff >= 0 ? diff : -(diff + 1) */
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
344 int limit = diff ^ (diff >> (sizeof(diff)*8-1));
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
345 int i = 0;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
346 limit = limit + 1 << 10;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
347 if (limit > low_quant[8] * state->scale_factor)
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
348 i = 9;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
349 while (i < 29 && limit > low_quant[i] * state->scale_factor)
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
350 i++;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
351 return (diff < 0 ? (i < 2 ? 63 : 33) : 61) - i;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
352 }
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
353
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
354 static int g722_encode_frame(AVCodecContext *avctx,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
355 uint8_t *dst, int buf_size, void *data)
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
356 {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
357 G722Context *c = avctx->priv_data;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
358 const int16_t *samples = data;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
359 int i;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
360
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
361 for (i = 0; i < buf_size >> 1; i++) {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
362 int xlow, xhigh, ihigh, ilow;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
363 filter_samples(c, &samples[2*i], &xlow, &xhigh);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
364 ihigh = encode_high(&c->band[1], xhigh);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
365 ilow = encode_low(&c->band[0], xlow);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
366 update_high_predictor(&c->band[1], c->band[1].scale_factor *
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
367 high_inv_quant[ihigh] >> 10, ihigh);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
368 update_low_predictor(&c->band[0], ilow >> 2);
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
369 *dst++ = ihigh << 6 | ilow;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
370 }
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
371 return i;
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
372 }
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
373
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
374 AVCodec adpcm_g722_encoder = {
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
375 .name = "g722",
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
376 .type = AVMEDIA_TYPE_AUDIO,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
377 .id = CODEC_ID_ADPCM_G722,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
378 .priv_data_size = sizeof(G722Context),
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
379 .init = g722_init,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
380 .encode = g722_encode_frame,
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
381 .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
382 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
383 };
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
384 #endif
750ff18b7394 Add a G.722 encoder
mstorsjo
parents: 12478
diff changeset
385