comparison aacpsy.c @ 11998:2e7db647fef8 libavcodec

aacenc: Fix window decision logic. This keeps the encoder from switching away from an wight short sequence prematurely when attacks are detected two frames in a row. It also allows for the legal and useful LONG_STOP_SEQUENCE to LONG_START_SEQUENCE transition.
author alexc
date Mon, 28 Jun 2010 21:49:26 +0000
parents 907ac02ef561
children 25ac974ce96d
comparison
equal deleted inserted replaced
11997:081702713f47 11998:2e7db647fef8
183 int br = ctx->avctx->bit_rate / ctx->avctx->channels; 183 int br = ctx->avctx->bit_rate / ctx->avctx->channels;
184 int attack_ratio = br <= 16000 ? 18 : 10; 184 int attack_ratio = br <= 16000 ? 18 : 10;
185 Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data; 185 Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data;
186 Psy3gppChannel *pch = &pctx->ch[channel]; 186 Psy3gppChannel *pch = &pctx->ch[channel];
187 uint8_t grouping = 0; 187 uint8_t grouping = 0;
188 int next_type = pch->next_window_seq;
188 FFPsyWindowInfo wi; 189 FFPsyWindowInfo wi;
189 190
190 memset(&wi, 0, sizeof(wi)); 191 memset(&wi, 0, sizeof(wi));
191 if (la) { 192 if (la) {
192 float s[8], v; 193 float s[8], v;
193 int switch_to_eight = 0; 194 int switch_to_eight = 0;
194 float sum = 0.0, sum2 = 0.0; 195 float sum = 0.0, sum2 = 0.0;
195 int attack_n = 0; 196 int attack_n = 0;
197 int stay_short = 0;
196 for (i = 0; i < 8; i++) { 198 for (i = 0; i < 8; i++) {
197 for (j = 0; j < 128; j++) { 199 for (j = 0; j < 128; j++) {
198 v = iir_filter(la[(i*128+j)*ctx->avctx->channels], pch->iir_state); 200 v = iir_filter(la[(i*128+j)*ctx->avctx->channels], pch->iir_state);
199 sum += v*v; 201 sum += v*v;
200 } 202 }
212 214
213 wi.window_type[1] = prev_type; 215 wi.window_type[1] = prev_type;
214 switch (prev_type) { 216 switch (prev_type) {
215 case ONLY_LONG_SEQUENCE: 217 case ONLY_LONG_SEQUENCE:
216 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; 218 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
219 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
217 break; 220 break;
218 case LONG_START_SEQUENCE: 221 case LONG_START_SEQUENCE:
219 wi.window_type[0] = EIGHT_SHORT_SEQUENCE; 222 wi.window_type[0] = EIGHT_SHORT_SEQUENCE;
220 grouping = pch->next_grouping; 223 grouping = pch->next_grouping;
224 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
221 break; 225 break;
222 case LONG_STOP_SEQUENCE: 226 case LONG_STOP_SEQUENCE:
223 wi.window_type[0] = ONLY_LONG_SEQUENCE; 227 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
228 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
224 break; 229 break;
225 case EIGHT_SHORT_SEQUENCE: 230 case EIGHT_SHORT_SEQUENCE:
226 wi.window_type[0] = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; 231 stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight;
227 grouping = switch_to_eight ? pch->next_grouping : 0; 232 wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
233 grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0;
234 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
228 break; 235 break;
229 } 236 }
237
230 pch->next_grouping = window_grouping[attack_n]; 238 pch->next_grouping = window_grouping[attack_n];
239 pch->next_window_seq = next_type;
231 } else { 240 } else {
232 for (i = 0; i < 3; i++) 241 for (i = 0; i < 3; i++)
233 wi.window_type[i] = prev_type; 242 wi.window_type[i] = prev_type;
234 grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0; 243 grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0;
235 } 244 }