History

aacenc: remove support for AAC LTP profile

The LTP profile of AAC is... terrible. It was an early 90's attempt at bridging the gap between speech codecs and general purpose codecs. It did so by trying to exploit the fact that most speech patterns are regular. Unfortunately, it went about it the same way as AAC Main, by taking the previous frame's samples, modifying them through an LPC filter, transforming them back using a forward MDCT, putting the output coefficients back into the current frame, and using delta coding. But once again, they ignored basic mathematics and MDCT leakage. Thankfully, because AAC LTP is meant to operate at very low bitrates, the extreme quantization results in most leakage being irrelevant. Unfortunately, the result is that the output sounds pretty much terrible regardless of whether LTP is enabled or not. This was the first attempt at trying to couple speech coding into AAC. No, the second attempt did not succeed either. Nnnneither did the third. Or fourth. For the fifth one, they literally just jammed a speech codec into AAC with USAC once they saw Opus do it. Just drop support for encoding AAC LTP. It was always experimental to begin with.

Lynne committed 1 year ago

Commit 93835331 parent 9b11fef7 files · +1 −355Browse files

Unified · Split

7 files
  1. libavcodec/Makefile +0 −1
  2. libavcodec/aaccoder.c +0 −16
  3. libavcodec/aacenc.c +1 −40
  4. libavcodec/aacenc.h +0 −20
  5. libavcodec/aacenc_ltp.c +0 −236
  6. libavcodec/aacenc_ltp.h +0 −41
  7. libavcodec/aacenctab.h +0 −1
libavcodec/Makefile+0−1
@@ -198,7 +198,6 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ · 197 unmodified lines
198 aacpsy.o aactab.o \198 aacpsy.o aactab.o \
199 aacenc_is.o \199 aacenc_is.o \
200 aacenc_tns.o \200 aacenc_tns.o \
201 aacenc_ltp.o \
202 psymodel.o kbdwin.o \201 psymodel.o kbdwin.o \
203 mpeg4audio_sample_rates.o202 mpeg4audio_sample_rates.o
204OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o203OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o
libavcodec/aaccoder.c+0−16
@@ -47,7 +47,6 @@ · 46 unmodified lines
47 47
48#include "aacenc_is.h"48#include "aacenc_is.h"
49#include "aacenc_tns.h"49#include "aacenc_tns.h"
50#include "aacenc_ltp.h"
51 50
52#include "libavcodec/aaccoder_twoloop.h"51#include "libavcodec/aaccoder_twoloop.h"
53 52
@@ -1121,16 +1120,11 @@ const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { · 1067 unmodified lines
1121 encode_window_bands_info,1120 encode_window_bands_info,
1122 quantize_and_encode_band,1121 quantize_and_encode_band,
1123 ff_aac_encode_tns_info,1122 ff_aac_encode_tns_info,
1124 ff_aac_encode_ltp_info,
1125 ff_aac_adjust_common_ltp,
1126 ff_aac_apply_tns,1123 ff_aac_apply_tns,
1127 ff_aac_update_ltp,
1128 ff_aac_ltp_insert_new_frame,
1129 set_special_band_scalefactors,1124 set_special_band_scalefactors,
1130 search_for_pns,1125 search_for_pns,
1131 mark_pns,1126 mark_pns,
1132 ff_aac_search_for_tns,1127 ff_aac_search_for_tns,
1133 ff_aac_search_for_ltp,
1134 search_for_ms,1128 search_for_ms,
1135 ff_aac_search_for_is,1129 ff_aac_search_for_is,
1136 },1130 },
@@ -1139,16 +1133,11 @@ const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { · 2 unmodified lines
1139 codebook_trellis_rate,1133 codebook_trellis_rate,
1140 quantize_and_encode_band,1134 quantize_and_encode_band,
1141 ff_aac_encode_tns_info,1135 ff_aac_encode_tns_info,
1142 ff_aac_encode_ltp_info,
1143 ff_aac_adjust_common_ltp,
1144 ff_aac_apply_tns,1136 ff_aac_apply_tns,
1145 ff_aac_update_ltp,
1146 ff_aac_ltp_insert_new_frame,
1147 set_special_band_scalefactors,1137 set_special_band_scalefactors,
1148 search_for_pns,1138 search_for_pns,
1149 mark_pns,1139 mark_pns,
1150 ff_aac_search_for_tns,1140 ff_aac_search_for_tns,
1151 ff_aac_search_for_ltp,
1152 search_for_ms,1141 search_for_ms,
1153 ff_aac_search_for_is,1142 ff_aac_search_for_is,
1154 },1143 },
@@ -1157,16 +1146,11 @@ const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { · 2 unmodified lines
1157 codebook_trellis_rate,1146 codebook_trellis_rate,
1158 quantize_and_encode_band,1147 quantize_and_encode_band,
1159 ff_aac_encode_tns_info,1148 ff_aac_encode_tns_info,
1160 ff_aac_encode_ltp_info,
1161 ff_aac_adjust_common_ltp,
1162 ff_aac_apply_tns,1149 ff_aac_apply_tns,
1163 ff_aac_update_ltp,
1164 ff_aac_ltp_insert_new_frame,
1165 set_special_band_scalefactors,1150 set_special_band_scalefactors,
1166 search_for_pns,1151 search_for_pns,
1167 mark_pns,1152 mark_pns,
1168 ff_aac_search_for_tns,1153 ff_aac_search_for_tns,
1169 ff_aac_search_for_ltp,
1170 search_for_ms,1154 search_for_ms,
1171 ff_aac_search_for_is,1155 ff_aac_search_for_is,
1172 },1156 },
libavcodec/aacenc.c+1−40
@@ -762,11 +762,8 @@ static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, · 761 unmodified lines
762 int common_window)762 int common_window)
763{763{
764 put_bits(&s->pb, 8, sce->sf_idx[0]);764 put_bits(&s->pb, 8, sce->sf_idx[0]);
765 if (!common_window) {765 if (!common_window)
766 put_ics_info(s, &sce->ics);766 put_ics_info(s, &sce->ics);
767 if (s->coder->encode_ltp_info)
768 s->coder->encode_ltp_info(s, sce, 0);
769 }
770 encode_band_info(s, sce);767 encode_band_info(s, sce);
771 encode_scale_factors(avctx, s, sce);768 encode_scale_factors(avctx, s, sce);
772 encode_pulses(s, &sce->pulse);769 encode_pulses(s, &sce->pulse);
@@ -933,12 +930,6 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 160 unmodified lines
933 930
934 apply_window_and_mdct(s, sce, overlap);931 apply_window_and_mdct(s, sce, overlap);
935 932
936 if (s->options.ltp && s->coder->update_ltp) {
937 s->coder->update_ltp(s, sce);
938 apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, &sce->ltp_state[0]);
939 s->mdct1024_fn(s->mdct1024, sce->lcoeffs, sce->ret_buf, sizeof(float));
940 }
941
942 for (k = 0; k < 1024; k++) {933 for (k = 0; k < 1024; k++) {
943 if (!(fabs(cpe->ch[ch].coeffs[k]) < 1E16)) { // Ensure headroom for energy calculation934 if (!(fabs(cpe->ch[ch].coeffs[k]) < 1E16)) { // Ensure headroom for energy calculation
944 av_log(avctx, AV_LOG_ERROR, "Input contains (near) NaN/+-Inf\n");935 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, · 29 unmodified lines
974 for (ch = 0; ch < chans; ch++) {965 for (ch = 0; ch < chans; ch++) {
975 sce = &cpe->ch[ch];966 sce = &cpe->ch[ch];
976 coeffs[ch] = sce->coeffs;967 coeffs[ch] = sce->coeffs;
977 sce->ics.ltp.present = 0;
978 memset(sce->ics.ltp.used, 0, sizeof(sce->ics.ltp.used));
979 memset(&sce->tns, 0, sizeof(TemporalNoiseShaping));968 memset(&sce->tns, 0, sizeof(TemporalNoiseShaping));
980 for (w = 0; w < 128; w++)969 for (w = 0; w < 128; w++)
981 if (sce->band_type[w] > RESERVED_BT)970 if (sce->band_type[w] > RESERVED_BT)
@@ -1036,24 +1025,10 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 54 unmodified lines
1036 apply_mid_side_stereo(cpe);1025 apply_mid_side_stereo(cpe);
1037 }1026 }
1038 adjust_frame_information(cpe, chans);1027 adjust_frame_information(cpe, chans);
1039 if (s->options.ltp) { /* LTP */
1040 for (ch = 0; ch < chans; ch++) {
1041 sce = &cpe->ch[ch];
1042 s->cur_channel = start_ch + ch;
1043 if (s->coder->search_for_ltp)
1044 s->coder->search_for_ltp(s, sce, cpe->common_window);
1045 if (sce->ics.ltp.present) pred_mode = 1;
1046 }
1047 s->cur_channel = start_ch;
1048 if (s->coder->adjust_common_ltp)
1049 s->coder->adjust_common_ltp(s, cpe);
1050 }
1051 if (chans == 2) {1028 if (chans == 2) {
1052 put_bits(&s->pb, 1, cpe->common_window);1029 put_bits(&s->pb, 1, cpe->common_window);
1053 if (cpe->common_window) {1030 if (cpe->common_window) {
1054 put_ics_info(s, &cpe->ch[0].ics);1031 put_ics_info(s, &cpe->ch[0].ics);
1055 if (s->coder->encode_ltp_info)
1056 s->coder->encode_ltp_info(s, &cpe->ch[0], 1);
1057 encode_ms_info(&s->pb, cpe);1032 encode_ms_info(&s->pb, cpe);
1058 if (cpe->ms_mode) ms_mode = 1;1033 if (cpe->ms_mode) ms_mode = 1;
1059 }1034 }
@@ -1138,9 +1113,6 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 78 unmodified lines
1138 }1113 }
1139 } while (1);1114 } while (1);
1140 1115
1141 if (s->options.ltp && s->coder->ltp_insert_new_frame)
1142 s->coder->ltp_insert_new_frame(s);
1143
1144 put_bits(&s->pb, 3, TYPE_END);1116 put_bits(&s->pb, 3, TYPE_END);
1145 flush_put_bits(&s->pb);1117 flush_put_bits(&s->pb);
1146 1118
@@ -1289,17 +1261,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) · 142 unmodified lines
1289 ERROR_IF(i == FF_ARRAY_ELEMS(aacenc_profiles), "Profile not supported!\n");1261 ERROR_IF(i == FF_ARRAY_ELEMS(aacenc_profiles), "Profile not supported!\n");
1290 if (avctx->profile == AV_PROFILE_MPEG2_AAC_LOW) {1262 if (avctx->profile == AV_PROFILE_MPEG2_AAC_LOW) {
1291 avctx->profile = AV_PROFILE_AAC_LOW;1263 avctx->profile = AV_PROFILE_AAC_LOW;
1292 ERROR_IF(s->options.ltp,
1293 "LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n");
1294 WARN_IF(s->options.pns,1264 WARN_IF(s->options.pns,
1295 "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n");1265 "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n");
1296 s->options.pns = 0;1266 s->options.pns = 0;
1297 } else if (avctx->profile == AV_PROFILE_AAC_LTP) {
1298 s->options.ltp = 1;
1299 } else if (s->options.ltp) {
1300 avctx->profile = AV_PROFILE_AAC_LTP;
1301 WARN_IF(1,
1302 "Chainging profile to \"aac_ltp\"\n");
1303 }1267 }
1304 s->profile = avctx->profile;1268 s->profile = avctx->profile;
1305 1269
@@ -1311,8 +1275,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) · 5 unmodified lines
1311 s->options.intensity_stereo = 0;1275 s->options.intensity_stereo = 0;
1312 s->options.pns = 0;1276 s->options.pns = 0;
1313 }1277 }
1314 ERROR_IF(s->options.ltp && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL,
1315 "The LPT profile requires experimental compliance, add -strict -2 to enable!\n");
1316 1278
1317 /* M/S introduces horrible artifacts with multichannel files, this is temporary */1279 /* M/S introduces horrible artifacts with multichannel files, this is temporary */
1318 if (s->channels > 3)1280 if (s->channels > 3)
@@ -1360,7 +1322,6 @@ static const AVOption aacenc_options[] = { · 41 unmodified lines
1360 {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},1322 {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
1361 {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},1323 {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
1362 {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},1324 {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
1363 {"aac_ltp", "Long term prediction", offsetof(AACEncContext, options.ltp), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
1364 {"aac_pce", "Forces the use of PCEs", offsetof(AACEncContext, options.pce), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},1325 {"aac_pce", "Forces the use of PCEs", offsetof(AACEncContext, options.pce), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
1365 FF_AAC_PROFILE_OPTS1326 FF_AAC_PROFILE_OPTS
1366 {NULL}1327 {NULL}
libavcodec/aacenc.h+0−20
@@ -67,23 +67,11 @@ typedef struct AACEncOptions { · 66 unmodified lines
67 int coder;67 int coder;
68 int pns;68 int pns;
69 int tns;69 int tns;
70 int ltp;
71 int pce;70 int pce;
72 int mid_side;71 int mid_side;
73 int intensity_stereo;72 int intensity_stereo;
74} AACEncOptions;73} AACEncOptions;
75 74
76/**
77 * Long Term Prediction
78 */
79typedef struct LongTermPrediction {
80 int8_t present;
81 int16_t lag;
82 int coef_idx;
83 float coef;
84 int8_t used[MAX_LTP_LONG_SFB];
85} LongTermPrediction;
86
87/**75/**
88 * Individual Channel Stream76 * Individual Channel Stream
89 */77 */
@@ -92,7 +80,6 @@ typedef struct IndividualChannelStream { · 2 unmodified lines
92 enum WindowSequence window_sequence[2];80 enum WindowSequence window_sequence[2];
93 uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.81 uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
94 uint8_t group_len[8];82 uint8_t group_len[8];
95 LongTermPrediction ltp;
96 const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window83 const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
97 const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window84 const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window
98 int num_swb; ///< number of scalefactor window bands85 int num_swb; ///< number of scalefactor window bands
@@ -132,8 +119,6 @@ typedef struct SingleChannelElement { · 33 unmodified lines
132 DECLARE_ALIGNED(32, float, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine119 DECLARE_ALIGNED(32, float, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine
133 DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed120 DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed
134 DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer121 DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer
135 DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP
136 DECLARE_ALIGNED(32, float, lcoeffs)[1024]; ///< MDCT of LTP coefficients
137 PredictorState predictor_state[MAX_PREDICTORS];122 PredictorState predictor_state[MAX_PREDICTORS];
138} SingleChannelElement;123} SingleChannelElement;
139 124
@@ -161,16 +146,11 @@ typedef struct AACCoefficientsEncoder { · 21 unmodified lines
161 void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, float *out, int size,146 void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, float *out, int size,
162 int scale_idx, int cb, const float lambda, int rtz);147 int scale_idx, int cb, const float lambda, int rtz);
163 void (*encode_tns_info)(struct AACEncContext *s, SingleChannelElement *sce);148 void (*encode_tns_info)(struct AACEncContext *s, SingleChannelElement *sce);
164 void (*encode_ltp_info)(struct AACEncContext *s, SingleChannelElement *sce, int common_window);
165 void (*adjust_common_ltp)(struct AACEncContext *s, ChannelElement *cpe);
166 void (*apply_tns_filt)(struct AACEncContext *s, SingleChannelElement *sce);149 void (*apply_tns_filt)(struct AACEncContext *s, SingleChannelElement *sce);
167 void (*update_ltp)(struct AACEncContext *s, SingleChannelElement *sce);
168 void (*ltp_insert_new_frame)(struct AACEncContext *s);
169 void (*set_special_band_scalefactors)(struct AACEncContext *s, SingleChannelElement *sce);150 void (*set_special_band_scalefactors)(struct AACEncContext *s, SingleChannelElement *sce);
170 void (*search_for_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce);151 void (*search_for_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce);
171 void (*mark_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce);152 void (*mark_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce);
172 void (*search_for_tns)(struct AACEncContext *s, SingleChannelElement *sce);153 void (*search_for_tns)(struct AACEncContext *s, SingleChannelElement *sce);
173 void (*search_for_ltp)(struct AACEncContext *s, SingleChannelElement *sce, int common_window);
174 void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe);154 void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe);
175 void (*search_for_is)(struct AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe);155 void (*search_for_is)(struct AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe);
176} AACCoefficientsEncoder;156} AACCoefficientsEncoder;
libavcodec/aacenc_ltp.c+0−236
@@ -1,236 +0,0 @@
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 */
35void 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 != AV_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
53void 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
75static void get_lag(float *buf, const float *new, LongTermPrediction *ltp)
76{
77 int i, j, lag = 0, max_corr = 0;
78 float max_ratio = 0.0f;
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, ff_ltp_coef, 8);
96 ltp->coef = ff_ltp_coef[ltp->coef_idx];
97}
98
99static 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 */
117void 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 != AV_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
130void 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 {
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 */
159void 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->aacdsp.abs_pow34(C34, &sce->coeffs[start+(w+w2)*128], sce->ics.swb_sizes[g]);
194 s->aacdsp.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);
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);
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}
libavcodec/aacenc_ltp.h+0−41
@@ -1,41 +0,0 @@
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#ifndef AVCODEC_AACENC_LTP_H
29#define AVCODEC_AACENC_LTP_H
30
31#include "aacenc.h"
32
33void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce,
34 int common_window);
35void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce);
36void ff_aac_adjust_common_ltp(AACEncContext *s, ChannelElement *cpe);
37void ff_aac_ltp_insert_new_frame(AACEncContext *s);
38void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce,
39 int common_window);
40
41#endif /* AVCODEC_AACENC_LTP_H */
libavcodec/aacenctab.h+0−1
@@ -126,7 +126,6 @@ static const unsigned char aac_maxval_cb[] = { · 125 unmodified lines
126 126
127static const int aacenc_profiles[] = {127static const int aacenc_profiles[] = {
128 AV_PROFILE_AAC_LOW,128 AV_PROFILE_AAC_LOW,
129 AV_PROFILE_AAC_LTP,
130 AV_PROFILE_MPEG2_AAC_LOW,129 AV_PROFILE_MPEG2_AAC_LOW,
131};130};
132 131

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t