diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 82fc9c9dc6..499f826635 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -198,7 +198,6 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ aacpsy.o aactab.o \ aacenc_is.o \ aacenc_tns.o \ - aacenc_ltp.o \ psymodel.o kbdwin.o \ mpeg4audio_sample_rates.o OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 1999f588e4..478eda86f3 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -47,7 +47,6 @@ #include "aacenc_is.h" #include "aacenc_tns.h" -#include "aacenc_ltp.h" #include "libavcodec/aaccoder_twoloop.h" @@ -1121,16 +1120,11 @@ const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { encode_window_bands_info, quantize_and_encode_band, ff_aac_encode_tns_info, - ff_aac_encode_ltp_info, - ff_aac_adjust_common_ltp, ff_aac_apply_tns, - ff_aac_update_ltp, - ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, - ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, }, @@ -1139,16 +1133,11 @@ const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { codebook_trellis_rate, quantize_and_encode_band, ff_aac_encode_tns_info, - ff_aac_encode_ltp_info, - ff_aac_adjust_common_ltp, ff_aac_apply_tns, - ff_aac_update_ltp, - ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, - ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, }, @@ -1157,16 +1146,11 @@ const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { codebook_trellis_rate, quantize_and_encode_band, ff_aac_encode_tns_info, - ff_aac_encode_ltp_info, - ff_aac_adjust_common_ltp, ff_aac_apply_tns, - ff_aac_update_ltp, - ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, - ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, }, diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index f1bc078cb0..5ed54dbcb3 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -762,11 +762,8 @@ static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, int common_window) { put_bits(&s->pb, 8, sce->sf_idx[0]); - if (!common_window) { + if (!common_window) put_ics_info(s, &sce->ics); - if (s->coder->encode_ltp_info) - s->coder->encode_ltp_info(s, sce, 0); - } encode_band_info(s, sce); encode_scale_factors(avctx, s, sce); encode_pulses(s, &sce->pulse); @@ -933,12 +930,6 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, apply_window_and_mdct(s, sce, overlap); - if (s->options.ltp && s->coder->update_ltp) { - s->coder->update_ltp(s, sce); - apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, &sce->ltp_state[0]); - s->mdct1024_fn(s->mdct1024, sce->lcoeffs, sce->ret_buf, sizeof(float)); - } - for (k = 0; k < 1024; k++) { if (!(fabs(cpe->ch[ch].coeffs[k]) < 1E16)) { // Ensure headroom for energy calculation av_log(avctx, AV_LOG_ERROR, "Input contains (near) NaN/+-Inf\n"); @@ -974,8 +965,6 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, for (ch = 0; ch < chans; ch++) { sce = &cpe->ch[ch]; coeffs[ch] = sce->coeffs; - sce->ics.ltp.present = 0; - memset(sce->ics.ltp.used, 0, sizeof(sce->ics.ltp.used)); memset(&sce->tns, 0, sizeof(TemporalNoiseShaping)); for (w = 0; w < 128; w++) if (sce->band_type[w] > RESERVED_BT) @@ -1036,24 +1025,10 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, apply_mid_side_stereo(cpe); } adjust_frame_information(cpe, chans); - if (s->options.ltp) { /* LTP */ - for (ch = 0; ch < chans; ch++) { - sce = &cpe->ch[ch]; - s->cur_channel = start_ch + ch; - if (s->coder->search_for_ltp) - s->coder->search_for_ltp(s, sce, cpe->common_window); - if (sce->ics.ltp.present) pred_mode = 1; - } - s->cur_channel = start_ch; - if (s->coder->adjust_common_ltp) - s->coder->adjust_common_ltp(s, cpe); - } if (chans == 2) { put_bits(&s->pb, 1, cpe->common_window); if (cpe->common_window) { put_ics_info(s, &cpe->ch[0].ics); - if (s->coder->encode_ltp_info) - s->coder->encode_ltp_info(s, &cpe->ch[0], 1); encode_ms_info(&s->pb, cpe); if (cpe->ms_mode) ms_mode = 1; } @@ -1138,9 +1113,6 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } } while (1); - if (s->options.ltp && s->coder->ltp_insert_new_frame) - s->coder->ltp_insert_new_frame(s); - put_bits(&s->pb, 3, TYPE_END); flush_put_bits(&s->pb); @@ -1289,17 +1261,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) ERROR_IF(i == FF_ARRAY_ELEMS(aacenc_profiles), "Profile not supported!\n"); if (avctx->profile == AV_PROFILE_MPEG2_AAC_LOW) { avctx->profile = AV_PROFILE_AAC_LOW; - ERROR_IF(s->options.ltp, - "LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n"); WARN_IF(s->options.pns, "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n"); s->options.pns = 0; - } else if (avctx->profile == AV_PROFILE_AAC_LTP) { - s->options.ltp = 1; - } else if (s->options.ltp) { - avctx->profile = AV_PROFILE_AAC_LTP; - WARN_IF(1, - "Chainging profile to \"aac_ltp\"\n"); } s->profile = avctx->profile; @@ -1311,8 +1275,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) s->options.intensity_stereo = 0; s->options.pns = 0; } - ERROR_IF(s->options.ltp && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL, - "The LPT profile requires experimental compliance, add -strict -2 to enable!\n"); /* M/S introduces horrible artifacts with multichannel files, this is temporary */ if (s->channels > 3) @@ -1360,7 +1322,6 @@ static const AVOption aacenc_options[] = { {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, - {"aac_ltp", "Long term prediction", offsetof(AACEncContext, options.ltp), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS}, {"aac_pce", "Forces the use of PCEs", offsetof(AACEncContext, options.pce), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS}, FF_AAC_PROFILE_OPTS {NULL} diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h index 8389699141..360402a06e 100644 --- a/libavcodec/aacenc.h +++ b/libavcodec/aacenc.h @@ -67,23 +67,11 @@ typedef struct AACEncOptions { int coder; int pns; int tns; - int ltp; int pce; int mid_side; int intensity_stereo; } AACEncOptions; -/** - * Long Term Prediction - */ -typedef struct LongTermPrediction { - int8_t present; - int16_t lag; - int coef_idx; - float coef; - int8_t used[MAX_LTP_LONG_SFB]; -} LongTermPrediction; - /** * Individual Channel Stream */ @@ -92,7 +80,6 @@ typedef struct IndividualChannelStream { enum WindowSequence window_sequence[2]; uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window. uint8_t group_len[8]; - LongTermPrediction ltp; const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window int num_swb; ///< number of scalefactor window bands @@ -132,8 +119,6 @@ typedef struct SingleChannelElement { DECLARE_ALIGNED(32, float, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer - DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP - DECLARE_ALIGNED(32, float, lcoeffs)[1024]; ///< MDCT of LTP coefficients PredictorState predictor_state[MAX_PREDICTORS]; } SingleChannelElement; @@ -161,16 +146,11 @@ typedef struct AACCoefficientsEncoder { void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, float *out, int size, int scale_idx, int cb, const float lambda, int rtz); void (*encode_tns_info)(struct AACEncContext *s, SingleChannelElement *sce); - void (*encode_ltp_info)(struct AACEncContext *s, SingleChannelElement *sce, int common_window); - void (*adjust_common_ltp)(struct AACEncContext *s, ChannelElement *cpe); void (*apply_tns_filt)(struct AACEncContext *s, SingleChannelElement *sce); - void (*update_ltp)(struct AACEncContext *s, SingleChannelElement *sce); - void (*ltp_insert_new_frame)(struct AACEncContext *s); void (*set_special_band_scalefactors)(struct AACEncContext *s, SingleChannelElement *sce); void (*search_for_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce); void (*mark_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce); void (*search_for_tns)(struct AACEncContext *s, SingleChannelElement *sce); - void (*search_for_ltp)(struct AACEncContext *s, SingleChannelElement *sce, int common_window); void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe); void (*search_for_is)(struct AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe); } AACCoefficientsEncoder; diff --git a/libavcodec/aacenc_ltp.c b/libavcodec/aacenc_ltp.c deleted file mode 100644 index 58f7921074..0000000000 --- a/libavcodec/aacenc_ltp.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * AAC encoder long term prediction extension - * Copyright (C) 2015 Rostislav Pehlivanov - * - * This file is part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC encoder long term prediction extension - * @author Rostislav Pehlivanov ( atomnuker gmail com ) - */ - -#include "aacenc_ltp.h" -#include "aacenc_quantization.h" -#include "aacenc_utils.h" - -/** - * Encode LTP data. - */ -void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce, - int common_window) -{ - int i; - IndividualChannelStream *ics = &sce->ics; - if (s->profile != AV_PROFILE_AAC_LTP || !ics->predictor_present) - return; - if (common_window) - put_bits(&s->pb, 1, 0); - put_bits(&s->pb, 1, ics->ltp.present); - if (!ics->ltp.present) - return; - put_bits(&s->pb, 11, ics->ltp.lag); - put_bits(&s->pb, 3, ics->ltp.coef_idx); - for (i = 0; i < FFMIN(ics->max_sfb, MAX_LTP_LONG_SFB); i++) - put_bits(&s->pb, 1, ics->ltp.used[i]); -} - -void ff_aac_ltp_insert_new_frame(AACEncContext *s) -{ - int i, ch, tag, chans, cur_channel, start_ch = 0; - ChannelElement *cpe; - SingleChannelElement *sce; - for (i = 0; i < s->chan_map[0]; i++) { - cpe = &s->cpe[i]; - tag = s->chan_map[i+1]; - chans = tag == TYPE_CPE ? 2 : 1; - for (ch = 0; ch < chans; ch++) { - sce = &cpe->ch[ch]; - cur_channel = start_ch + ch; - /* New sample + overlap */ - memcpy(&sce->ltp_state[0], &sce->ltp_state[1024], 1024*sizeof(sce->ltp_state[0])); - memcpy(&sce->ltp_state[1024], &s->planar_samples[cur_channel][2048], 1024*sizeof(sce->ltp_state[0])); - memcpy(&sce->ltp_state[2048], &sce->ret_buf[0], 1024*sizeof(sce->ltp_state[0])); - sce->ics.ltp.lag = 0; - } - start_ch += chans; - } -} - -static void get_lag(float *buf, const float *new, LongTermPrediction *ltp) -{ - int i, j, lag = 0, max_corr = 0; - float max_ratio = 0.0f; - for (i = 0; i < 2048; i++) { - float corr, s0 = 0.0f, s1 = 0.0f; - const int start = FFMAX(0, i - 1024); - for (j = start; j < 2048; j++) { - const int idx = j - i + 1024; - s0 += new[j]*buf[idx]; - s1 += buf[idx]*buf[idx]; - } - corr = s1 > 0.0f ? s0/sqrt(s1) : 0.0f; - if (corr > max_corr) { - max_corr = corr; - lag = i; - max_ratio = corr/(2048-start); - } - } - ltp->lag = FFMAX(av_clip_uintp2(lag, 11), 0); - ltp->coef_idx = quant_array_idx(max_ratio, ff_ltp_coef, 8); - ltp->coef = ff_ltp_coef[ltp->coef_idx]; -} - -static void generate_samples(float *buf, LongTermPrediction *ltp) -{ - int i, samples_num = 2048; - if (!ltp->lag) { - ltp->present = 0; - return; - } else if (ltp->lag < 1024) { - samples_num = ltp->lag + 1024; - } - for (i = 0; i < samples_num; i++) - buf[i] = ltp->coef*buf[i + 2048 - ltp->lag]; - memset(&buf[i], 0, (2048 - i)*sizeof(float)); -} - -/** - * Process LTP parameters - * @see Patent WO2006070265A1 - */ -void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce) -{ - float *pred_signal = &sce->ltp_state[0]; - const float *samples = &s->planar_samples[s->cur_channel][1024]; - - if (s->profile != AV_PROFILE_AAC_LTP) - return; - - /* Calculate lag */ - get_lag(pred_signal, samples, &sce->ics.ltp); - generate_samples(pred_signal, &sce->ics.ltp); -} - -void ff_aac_adjust_common_ltp(AACEncContext *s, ChannelElement *cpe) -{ - int sfb, count = 0; - SingleChannelElement *sce0 = &cpe->ch[0]; - SingleChannelElement *sce1 = &cpe->ch[1]; - - if (!cpe->common_window || - sce0->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE || - sce1->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - sce0->ics.ltp.present = 0; - return; - } - - for (sfb = 0; sfb < FFMIN(sce0->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++) { - int sum = sce0->ics.ltp.used[sfb] + sce1->ics.ltp.used[sfb]; - if (sum != 2) { - sce0->ics.ltp.used[sfb] = 0; - } else { - count++; - } - } - - sce0->ics.ltp.present = !!count; - sce0->ics.predictor_present = !!count; -} - -/** - * Mark LTP sfb's - */ -void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce, - int common_window) -{ - int w, g, w2, i, start = 0, count = 0; - int saved_bits = -(15 + FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB)); - float *C34 = &s->scoefs[128*0], *PCD = &s->scoefs[128*1]; - float *PCD34 = &s->scoefs[128*2]; - const int max_ltp = FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); - - if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - if (sce->ics.ltp.lag) { - memset(&sce->ltp_state[0], 0, 3072*sizeof(sce->ltp_state[0])); - memset(&sce->ics.ltp, 0, sizeof(LongTermPrediction)); - } - return; - } - - if (!sce->ics.ltp.lag || s->lambda > 120.0f) - return; - - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = 0; - for (g = 0; g < sce->ics.num_swb; g++) { - int bits1 = 0, bits2 = 0; - float dist1 = 0.0f, dist2 = 0.0f; - if (w*16+g > max_ltp) { - start += sce->ics.swb_sizes[g]; - continue; - } - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - int bits_tmp1, bits_tmp2; - FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; - for (i = 0; i < sce->ics.swb_sizes[g]; i++) - PCD[i] = sce->coeffs[start+(w+w2)*128+i] - sce->lcoeffs[start+(w+w2)*128+i]; - s->aacdsp.abs_pow34(C34, &sce->coeffs[start+(w+w2)*128], sce->ics.swb_sizes[g]); - s->aacdsp.abs_pow34(PCD34, PCD, sce->ics.swb_sizes[g]); - dist1 += quantize_band_cost(s, &sce->coeffs[start+(w+w2)*128], C34, sce->ics.swb_sizes[g], - sce->sf_idx[(w+w2)*16+g], sce->band_type[(w+w2)*16+g], - s->lambda/band->threshold, INFINITY, &bits_tmp1, NULL); - dist2 += quantize_band_cost(s, PCD, PCD34, sce->ics.swb_sizes[g], - sce->sf_idx[(w+w2)*16+g], - sce->band_type[(w+w2)*16+g], - s->lambda/band->threshold, INFINITY, &bits_tmp2, NULL); - bits1 += bits_tmp1; - bits2 += bits_tmp2; - } - if (dist2 < dist1 && bits2 < bits1) { - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) - for (i = 0; i < sce->ics.swb_sizes[g]; i++) - sce->coeffs[start+(w+w2)*128+i] -= sce->lcoeffs[start+(w+w2)*128+i]; - sce->ics.ltp.used[w*16+g] = 1; - saved_bits += bits1 - bits2; - count++; - } - start += sce->ics.swb_sizes[g]; - } - } - - sce->ics.ltp.present = !!count && (saved_bits >= 0); - sce->ics.predictor_present = !!sce->ics.ltp.present; - - /* Reset any marked sfbs */ - if (!sce->ics.ltp.present && !!count) { - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = 0; - for (g = 0; g < sce->ics.num_swb; g++) { - if (sce->ics.ltp.used[w*16+g]) { - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - for (i = 0; i < sce->ics.swb_sizes[g]; i++) { - sce->coeffs[start+(w+w2)*128+i] += sce->lcoeffs[start+(w+w2)*128+i]; - } - } - } - start += sce->ics.swb_sizes[g]; - } - } - } -} diff --git a/libavcodec/aacenc_ltp.h b/libavcodec/aacenc_ltp.h deleted file mode 100644 index 7276878427..0000000000 --- a/libavcodec/aacenc_ltp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * AAC encoder long term prediction extension - * Copyright (C) 2015 Rostislav Pehlivanov - * - * This file is part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC encoder long term prediction extension - * @author Rostislav Pehlivanov ( atomnuker gmail com ) - */ - -#ifndef AVCODEC_AACENC_LTP_H -#define AVCODEC_AACENC_LTP_H - -#include "aacenc.h" - -void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce, - int common_window); -void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce); -void ff_aac_adjust_common_ltp(AACEncContext *s, ChannelElement *cpe); -void ff_aac_ltp_insert_new_frame(AACEncContext *s); -void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce, - int common_window); - -#endif /* AVCODEC_AACENC_LTP_H */ diff --git a/libavcodec/aacenctab.h b/libavcodec/aacenctab.h index 78e424a675..60e1f22387 100644 --- a/libavcodec/aacenctab.h +++ b/libavcodec/aacenctab.h @@ -126,7 +126,6 @@ static const unsigned char aac_maxval_cb[] = { static const int aacenc_profiles[] = { AV_PROFILE_AAC_LOW, - AV_PROFILE_AAC_LTP, AV_PROFILE_MPEG2_AAC_LOW, };