blob: 1bec85b9e393621ff39b10cbb78e83295454dd51
1 | /* |
2 | * AAC encoder long term prediction extension |
3 | * Copyright (C) 2015 Rostislav Pehlivanov |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
7 | * FFmpeg is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * FFmpeg is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with FFmpeg; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | /** |
23 | * @file |
24 | * AAC encoder long term prediction extension |
25 | * @author Rostislav Pehlivanov ( atomnuker gmail com ) |
26 | */ |
27 | |
28 | #include "aacenc_ltp.h" |
29 | #include "aacenc_quantization.h" |
30 | #include "aacenc_utils.h" |
31 | |
32 | /** |
33 | * Encode LTP data. |
34 | */ |
35 | void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce, |
36 | int common_window) |
37 | { |
38 | int i; |
39 | IndividualChannelStream *ics = &sce->ics; |
40 | if (s->profile != FF_PROFILE_AAC_LTP || !ics->predictor_present) |
41 | return; |
42 | if (common_window) |
43 | put_bits(&s->pb, 1, 0); |
44 | put_bits(&s->pb, 1, ics->ltp.present); |
45 | if (!ics->ltp.present) |
46 | return; |
47 | put_bits(&s->pb, 11, ics->ltp.lag); |
48 | put_bits(&s->pb, 3, ics->ltp.coef_idx); |
49 | for (i = 0; i < FFMIN(ics->max_sfb, MAX_LTP_LONG_SFB); i++) |
50 | put_bits(&s->pb, 1, ics->ltp.used[i]); |
51 | } |
52 | |
53 | void ff_aac_ltp_insert_new_frame(AACEncContext *s) |
54 | { |
55 | int i, ch, tag, chans, cur_channel, start_ch = 0; |
56 | ChannelElement *cpe; |
57 | SingleChannelElement *sce; |
58 | for (i = 0; i < s->chan_map[0]; i++) { |
59 | cpe = &s->cpe[i]; |
60 | tag = s->chan_map[i+1]; |
61 | chans = tag == TYPE_CPE ? 2 : 1; |
62 | for (ch = 0; ch < chans; ch++) { |
63 | sce = &cpe->ch[ch]; |
64 | cur_channel = start_ch + ch; |
65 | /* New sample + overlap */ |
66 | memcpy(&sce->ltp_state[0], &sce->ltp_state[1024], 1024*sizeof(sce->ltp_state[0])); |
67 | memcpy(&sce->ltp_state[1024], &s->planar_samples[cur_channel][2048], 1024*sizeof(sce->ltp_state[0])); |
68 | memcpy(&sce->ltp_state[2048], &sce->ret_buf[0], 1024*sizeof(sce->ltp_state[0])); |
69 | sce->ics.ltp.lag = 0; |
70 | } |
71 | start_ch += chans; |
72 | } |
73 | } |
74 | |
75 | static void get_lag(float *buf, const float *new, LongTermPrediction *ltp) |
76 | { |
77 | int i, j, lag, max_corr = 0; |
78 | float max_ratio; |
79 | for (i = 0; i < 2048; i++) { |
80 | float corr, s0 = 0.0f, s1 = 0.0f; |
81 | const int start = FFMAX(0, i - 1024); |
82 | for (j = start; j < 2048; j++) { |
83 | const int idx = j - i + 1024; |
84 | s0 += new[j]*buf[idx]; |
85 | s1 += buf[idx]*buf[idx]; |
86 | } |
87 | corr = s1 > 0.0f ? s0/sqrt(s1) : 0.0f; |
88 | if (corr > max_corr) { |
89 | max_corr = corr; |
90 | lag = i; |
91 | max_ratio = corr/(2048-start); |
92 | } |
93 | } |
94 | ltp->lag = FFMAX(av_clip_uintp2(lag, 11), 0); |
95 | ltp->coef_idx = quant_array_idx(max_ratio, ltp_coef, 8); |
96 | ltp->coef = ltp_coef[ltp->coef_idx]; |
97 | } |
98 | |
99 | static void generate_samples(float *buf, LongTermPrediction *ltp) |
100 | { |
101 | int i, samples_num = 2048; |
102 | if (!ltp->lag) { |
103 | ltp->present = 0; |
104 | return; |
105 | } else if (ltp->lag < 1024) { |
106 | samples_num = ltp->lag + 1024; |
107 | } |
108 | for (i = 0; i < samples_num; i++) |
109 | buf[i] = ltp->coef*buf[i + 2048 - ltp->lag]; |
110 | memset(&buf[i], 0, (2048 - i)*sizeof(float)); |
111 | } |
112 | |
113 | /** |
114 | * Process LTP parameters |
115 | * @see Patent WO2006070265A1 |
116 | */ |
117 | void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce) |
118 | { |
119 | float *pred_signal = &sce->ltp_state[0]; |
120 | const float *samples = &s->planar_samples[s->cur_channel][1024]; |
121 | |
122 | if (s->profile != FF_PROFILE_AAC_LTP) |
123 | return; |
124 | |
125 | /* Calculate lag */ |
126 | get_lag(pred_signal, samples, &sce->ics.ltp); |
127 | generate_samples(pred_signal, &sce->ics.ltp); |
128 | } |
129 | |
130 | void ff_aac_adjust_common_ltp(AACEncContext *s, ChannelElement *cpe) |
131 | { |
132 | int sfb, count = 0; |
133 | SingleChannelElement *sce0 = &cpe->ch[0]; |
134 | SingleChannelElement *sce1 = &cpe->ch[1]; |
135 | |
136 | if (!cpe->common_window || |
137 | sce0->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE || |
138 | sce1->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { |
139 | sce0->ics.ltp.present = 0; |
140 | return; |
141 | } |
142 | |
143 | for (sfb = 0; sfb < FFMIN(sce0->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++) { |
144 | int sum = sce0->ics.ltp.used[sfb] + sce1->ics.ltp.used[sfb]; |
145 | if (sum != 2) { |
146 | sce0->ics.ltp.used[sfb] = 0; |
147 | } else if (sum == 2) { |
148 | count++; |
149 | } |
150 | } |
151 | |
152 | sce0->ics.ltp.present = !!count; |
153 | sce0->ics.predictor_present = !!count; |
154 | } |
155 | |
156 | /** |
157 | * Mark LTP sfb's |
158 | */ |
159 | void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce, |
160 | int common_window) |
161 | { |
162 | int w, g, w2, i, start = 0, count = 0; |
163 | int saved_bits = -(15 + FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB)); |
164 | float *C34 = &s->scoefs[128*0], *PCD = &s->scoefs[128*1]; |
165 | float *PCD34 = &s->scoefs[128*2]; |
166 | const int max_ltp = FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); |
167 | |
168 | if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { |
169 | if (sce->ics.ltp.lag) { |
170 | memset(&sce->ltp_state[0], 0, 3072*sizeof(sce->ltp_state[0])); |
171 | memset(&sce->ics.ltp, 0, sizeof(LongTermPrediction)); |
172 | } |
173 | return; |
174 | } |
175 | |
176 | if (!sce->ics.ltp.lag || s->lambda > 120.0f) |
177 | return; |
178 | |
179 | for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { |
180 | start = 0; |
181 | for (g = 0; g < sce->ics.num_swb; g++) { |
182 | int bits1 = 0, bits2 = 0; |
183 | float dist1 = 0.0f, dist2 = 0.0f; |
184 | if (w*16+g > max_ltp) { |
185 | start += sce->ics.swb_sizes[g]; |
186 | continue; |
187 | } |
188 | for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { |
189 | int bits_tmp1, bits_tmp2; |
190 | FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; |
191 | for (i = 0; i < sce->ics.swb_sizes[g]; i++) |
192 | PCD[i] = sce->coeffs[start+(w+w2)*128+i] - sce->lcoeffs[start+(w+w2)*128+i]; |
193 | s->abs_pow34(C34, &sce->coeffs[start+(w+w2)*128], sce->ics.swb_sizes[g]); |
194 | s->abs_pow34(PCD34, PCD, sce->ics.swb_sizes[g]); |
195 | dist1 += quantize_band_cost(s, &sce->coeffs[start+(w+w2)*128], C34, sce->ics.swb_sizes[g], |
196 | sce->sf_idx[(w+w2)*16+g], sce->band_type[(w+w2)*16+g], |
197 | s->lambda/band->threshold, INFINITY, &bits_tmp1, NULL, 0); |
198 | dist2 += quantize_band_cost(s, PCD, PCD34, sce->ics.swb_sizes[g], |
199 | sce->sf_idx[(w+w2)*16+g], |
200 | sce->band_type[(w+w2)*16+g], |
201 | s->lambda/band->threshold, INFINITY, &bits_tmp2, NULL, 0); |
202 | bits1 += bits_tmp1; |
203 | bits2 += bits_tmp2; |
204 | } |
205 | if (dist2 < dist1 && bits2 < bits1) { |
206 | for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) |
207 | for (i = 0; i < sce->ics.swb_sizes[g]; i++) |
208 | sce->coeffs[start+(w+w2)*128+i] -= sce->lcoeffs[start+(w+w2)*128+i]; |
209 | sce->ics.ltp.used[w*16+g] = 1; |
210 | saved_bits += bits1 - bits2; |
211 | count++; |
212 | } |
213 | start += sce->ics.swb_sizes[g]; |
214 | } |
215 | } |
216 | |
217 | sce->ics.ltp.present = !!count && (saved_bits >= 0); |
218 | sce->ics.predictor_present = !!sce->ics.ltp.present; |
219 | |
220 | /* Reset any marked sfbs */ |
221 | if (!sce->ics.ltp.present && !!count) { |
222 | for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { |
223 | start = 0; |
224 | for (g = 0; g < sce->ics.num_swb; g++) { |
225 | if (sce->ics.ltp.used[w*16+g]) { |
226 | for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { |
227 | for (i = 0; i < sce->ics.swb_sizes[g]; i++) { |
228 | sce->coeffs[start+(w+w2)*128+i] += sce->lcoeffs[start+(w+w2)*128+i]; |
229 | } |
230 | } |
231 | } |
232 | start += sce->ics.swb_sizes[g]; |
233 | } |
234 | } |
235 | } |
236 | } |
237 |