Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * AAC encoder intensity stereo | ||
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 Intensity Stereo | ||
25 | * @author Rostislav Pehlivanov ( atomnuker gmail com ) | ||
26 | */ | ||
27 | |||
28 | #include "aacenc.h" | ||
29 | #include "aacenc_utils.h" | ||
30 | #include "aacenc_is.h" | ||
31 | #include "aacenc_quantization.h" | ||
32 | |||
33 | /** Frequency in Hz for lower limit of intensity stereo **/ | ||
34 | #define INT_STEREO_LOW_LIMIT 6100 | ||
35 | |||
36 | struct AACISError { | ||
37 | int pass; /* 1 if dist2 <= dist1 */ | ||
38 | int phase; /* -1 or +1 */ | ||
39 | float error; /* fabs(dist1 - dist2) */ | ||
40 | float dist1; /* From original coeffs */ | ||
41 | float dist2; /* From IS'd coeffs */ | ||
42 | float ener01; | ||
43 | }; | ||
44 | |||
45 | 17290 | static struct AACISError aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe, | |
46 | int start, int w, int g, float ener0, | ||
47 | float ener1, float ener01, int phase) | ||
48 | { | ||
49 | int i, w2; | ||
50 | 17290 | SingleChannelElement *sce0 = &cpe->ch[0]; | |
51 | 17290 | SingleChannelElement *sce1 = &cpe->ch[1]; | |
52 | 17290 | float *L = sce0->coeffs; | |
53 | 17290 | float *R = sce1->coeffs; | |
54 | 17290 | float *L34 = &s->scoefs[256*0], *R34 = &s->scoefs[256*1]; | |
55 | 17290 | float *IS = &s->scoefs[256*2], *I34 = &s->scoefs[256*3]; | |
56 | 17290 | float dist1 = 0.0f, dist2 = 0.0f; | |
57 | 17290 | struct AACISError is_error = {0}; | |
58 | |||
59 |
3/4✓ Branch 0 taken 16832 times.
✓ Branch 1 taken 458 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16832 times.
|
17290 | if (ener01 <= 0 || ener0 <= 0) { |
60 | 458 | is_error.pass = 0; | |
61 | 458 | return is_error; | |
62 | } | ||
63 | |||
64 |
2/2✓ Branch 0 taken 17028 times.
✓ Branch 1 taken 16832 times.
|
33860 | for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { |
65 | 17028 | FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g]; | |
66 | 17028 | FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g]; | |
67 | 17028 | int is_band_type, is_sf_idx = FFMAX(1, sce0->sf_idx[w*16+g]-4); | |
68 | 17028 | float e01_34 = phase*pos_pow34(ener1/ener0); | |
69 | 17028 | float maxval, dist_spec_err = 0.0f; | |
70 |
2/2✓ Branch 0 taken 6056 times.
✓ Branch 1 taken 10972 times.
|
17028 | float minthr = FFMIN(band0->threshold, band1->threshold); |
71 |
2/2✓ Branch 0 taken 582476 times.
✓ Branch 1 taken 17028 times.
|
599504 | for (i = 0; i < sce0->ics.swb_sizes[g]; i++) |
72 | 582476 | IS[i] = (L[start+(w+w2)*128+i] + phase*R[start+(w+w2)*128+i])*sqrt(ener0/ener01); | |
73 | 17028 | s->aacdsp.abs_pow34(L34, &L[start+(w+w2)*128], sce0->ics.swb_sizes[g]); | |
74 | 17028 | s->aacdsp.abs_pow34(R34, &R[start+(w+w2)*128], sce0->ics.swb_sizes[g]); | |
75 | 17028 | s->aacdsp.abs_pow34(I34, IS, sce0->ics.swb_sizes[g]); | |
76 | 17028 | maxval = find_max_val(1, sce0->ics.swb_sizes[g], I34); | |
77 | 17028 | is_band_type = find_min_book(maxval, is_sf_idx); | |
78 | 34056 | dist1 += quantize_band_cost(s, &L[start + (w+w2)*128], L34, | |
79 | 17028 | sce0->ics.swb_sizes[g], | |
80 | 17028 | sce0->sf_idx[w*16+g], | |
81 | 17028 | sce0->band_type[w*16+g], | |
82 | 17028 | s->lambda / band0->threshold, INFINITY, NULL, NULL); | |
83 | 34056 | dist1 += quantize_band_cost(s, &R[start + (w+w2)*128], R34, | |
84 | 17028 | sce1->ics.swb_sizes[g], | |
85 | 17028 | sce1->sf_idx[w*16+g], | |
86 | 17028 | sce1->band_type[w*16+g], | |
87 | 17028 | s->lambda / band1->threshold, INFINITY, NULL, NULL); | |
88 | 34056 | dist2 += quantize_band_cost(s, IS, I34, sce0->ics.swb_sizes[g], | |
89 | is_sf_idx, is_band_type, | ||
90 | 17028 | s->lambda / minthr, INFINITY, NULL, NULL); | |
91 |
2/2✓ Branch 0 taken 582476 times.
✓ Branch 1 taken 17028 times.
|
599504 | for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { |
92 | 582476 | dist_spec_err += (L34[i] - I34[i])*(L34[i] - I34[i]); | |
93 | 582476 | dist_spec_err += (R34[i] - I34[i]*e01_34)*(R34[i] - I34[i]*e01_34); | |
94 | } | ||
95 | 17028 | dist_spec_err *= s->lambda / minthr; | |
96 | 17028 | dist2 += dist_spec_err; | |
97 | } | ||
98 | |||
99 | 16832 | is_error.pass = dist2 <= dist1; | |
100 | 16832 | is_error.phase = phase; | |
101 | 16832 | is_error.error = dist2 - dist1; | |
102 | 16832 | is_error.dist1 = dist1; | |
103 | 16832 | is_error.dist2 = dist2; | |
104 | 16832 | is_error.ener01 = ener01; | |
105 | |||
106 | 16832 | return is_error; | |
107 | } | ||
108 | |||
109 | 1334 | void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe) | |
110 | { | ||
111 | 1334 | SingleChannelElement *sce0 = &cpe->ch[0]; | |
112 | 1334 | SingleChannelElement *sce1 = &cpe->ch[1]; | |
113 | 1334 | int start = 0, count = 0, w, w2, g, i, prev_sf1 = -1, prev_bt = -1, prev_is = 0; | |
114 | 1334 | const float freq_mult = avctx->sample_rate/(1024.0f/sce0->ics.num_windows)/2.0f; | |
115 | uint8_t nextband1[128]; | ||
116 | |||
117 |
2/2✓ Branch 0 taken 707 times.
✓ Branch 1 taken 627 times.
|
1334 | if (!cpe->common_window) |
118 | 707 | return; | |
119 | |||
120 | /** Scout out next nonzero bands */ | ||
121 | 627 | ff_init_nextband_map(sce1, nextband1); | |
122 | |||
123 |
2/2✓ Branch 0 taken 661 times.
✓ Branch 1 taken 627 times.
|
1288 | for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { |
124 | 661 | start = 0; | |
125 |
2/2✓ Branch 0 taken 30709 times.
✓ Branch 1 taken 661 times.
|
31370 | for (g = 0; g < sce0->ics.num_swb; g++) { |
126 |
2/2✓ Branch 0 taken 9451 times.
✓ Branch 1 taken 21258 times.
|
30709 | if (start*freq_mult > INT_STEREO_LOW_LIMIT*(s->lambda/170.0f) && |
127 |
4/4✓ Branch 0 taken 9274 times.
✓ Branch 1 taken 177 times.
✓ Branch 2 taken 8665 times.
✓ Branch 3 taken 609 times.
|
9451 | cpe->ch[0].band_type[w*16+g] != NOISE_BT && !cpe->ch[0].zeroes[w*16+g] && |
128 |
4/6✓ Branch 0 taken 8645 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8645 times.
✗ Branch 5 not taken.
|
17310 | cpe->ch[1].band_type[w*16+g] != NOISE_BT && !cpe->ch[1].zeroes[w*16+g] && |
129 | 8645 | ff_sfdelta_can_remove_band(sce1, nextband1, prev_sf1, w*16+g)) { | |
130 | 8645 | float ener0 = 0.0f, ener1 = 0.0f, ener01 = 0.0f, ener01p = 0.0f; | |
131 | struct AACISError ph_err1, ph_err2, *best; | ||
132 |
2/2✓ Branch 0 taken 8757 times.
✓ Branch 1 taken 8645 times.
|
17402 | for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { |
133 |
2/2✓ Branch 0 taken 298564 times.
✓ Branch 1 taken 8757 times.
|
307321 | for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { |
134 | 298564 | float coef0 = sce0->coeffs[start+(w+w2)*128+i]; | |
135 | 298564 | float coef1 = sce1->coeffs[start+(w+w2)*128+i]; | |
136 | 298564 | ener0 += coef0*coef0; | |
137 | 298564 | ener1 += coef1*coef1; | |
138 | 298564 | ener01 += (coef0 + coef1)*(coef0 + coef1); | |
139 | 298564 | ener01p += (coef0 - coef1)*(coef0 - coef1); | |
140 | } | ||
141 | } | ||
142 | 8645 | ph_err1 = aac_is_encoding_err(s, cpe, start, w, g, | |
143 | ener0, ener1, ener01p, -1); | ||
144 | 8645 | ph_err2 = aac_is_encoding_err(s, cpe, start, w, g, | |
145 | ener0, ener1, ener01, +1); | ||
146 |
4/4✓ Branch 0 taken 7886 times.
✓ Branch 1 taken 759 times.
✓ Branch 2 taken 1019 times.
✓ Branch 3 taken 6867 times.
|
8645 | best = (ph_err1.pass && ph_err1.error < ph_err2.error) ? &ph_err1 : &ph_err2; |
147 |
2/2✓ Branch 0 taken 8564 times.
✓ Branch 1 taken 81 times.
|
8645 | if (best->pass) { |
148 | 8564 | cpe->is_mask[w*16+g] = 1; | |
149 | 8564 | cpe->ms_mask[w*16+g] = 0; | |
150 | 8564 | cpe->ch[0].is_ener[w*16+g] = sqrt(ener0 / best->ener01); | |
151 | 8564 | cpe->ch[1].is_ener[w*16+g] = ener0/ener1; | |
152 |
2/2✓ Branch 0 taken 7545 times.
✓ Branch 1 taken 1019 times.
|
8564 | cpe->ch[1].band_type[w*16+g] = (best->phase > 0) ? INTENSITY_BT : INTENSITY_BT2; |
153 |
4/4✓ Branch 0 taken 8055 times.
✓ Branch 1 taken 509 times.
✓ Branch 2 taken 2367 times.
✓ Branch 3 taken 5688 times.
|
8564 | if (prev_is && prev_bt != cpe->ch[1].band_type[w*16+g]) { |
154 | /** Flip M/S mask and pick the other CB, since it encodes more efficiently */ | ||
155 | 2367 | cpe->ms_mask[w*16+g] = 1; | |
156 |
2/2✓ Branch 0 taken 1793 times.
✓ Branch 1 taken 574 times.
|
2367 | cpe->ch[1].band_type[w*16+g] = (best->phase > 0) ? INTENSITY_BT2 : INTENSITY_BT; |
157 | } | ||
158 | 8564 | prev_bt = cpe->ch[1].band_type[w*16+g]; | |
159 | 8564 | count++; | |
160 | } | ||
161 | } | ||
162 |
4/4✓ Branch 0 taken 27510 times.
✓ Branch 1 taken 3199 times.
✓ Branch 2 taken 17848 times.
✓ Branch 3 taken 9662 times.
|
30709 | if (!sce1->zeroes[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT) |
163 | 17848 | prev_sf1 = sce1->sf_idx[w*16+g]; | |
164 | 30709 | prev_is = cpe->is_mask[w*16+g]; | |
165 | 30709 | start += sce0->ics.swb_sizes[g]; | |
166 | } | ||
167 | } | ||
168 | 627 | cpe->is_mode = !!count; | |
169 | } | ||
170 |