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