annotate psymodel.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 94b578d0af10
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
1 /*
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
2 * audio encoder psychoacoustic model
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
3 * Copyright (C) 2008 Konstantin Shishkov
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
4 *
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
5 * This file is part of FFmpeg.
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
6 *
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
11 *
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
15 * Lesser General Public License for more details.
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
16 *
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
20 */
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
21
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
22 #include "avcodec.h"
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
23 #include "psymodel.h"
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
24 #include "iirfilter.h"
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
25
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
26 extern const FFPsyModel ff_aac_psy_model;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
27
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
28 av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
29 int num_lens,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
30 const uint8_t **bands, const int* num_bands)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
31 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
32 ctx->avctx = avctx;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
33 ctx->psy_bands = av_mallocz(sizeof(FFPsyBand) * PSY_MAX_BANDS * avctx->channels);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
34 ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
35 ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
36 memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
37 memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
38 switch (ctx->avctx->codec_id) {
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
39 case CODEC_ID_AAC:
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
40 ctx->model = &ff_aac_psy_model;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
41 break;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
42 }
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
43 if (ctx->model->init)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
44 return ctx->model->init(ctx);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
45 return 0;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
46 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
47
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
48 FFPsyWindowInfo ff_psy_suggest_window(FFPsyContext *ctx,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
49 const int16_t *audio, const int16_t *la,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
50 int channel, int prev_type)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
51 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
52 return ctx->model->window(ctx, audio, la, channel, prev_type);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
53 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
54
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
55 void ff_psy_set_band_info(FFPsyContext *ctx, int channel,
12442
94b578d0af10 psymodel: Const correct FFPsyWindowInfo.
alexc
parents: 12125
diff changeset
56 const float *coeffs, const FFPsyWindowInfo *wi)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
57 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
58 ctx->model->analyze(ctx, channel, coeffs, wi);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
59 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
60
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
61 av_cold void ff_psy_end(FFPsyContext *ctx)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
62 {
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
63 if (ctx->model->end)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
64 ctx->model->end(ctx);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
65 av_freep(&ctx->bands);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
66 av_freep(&ctx->num_bands);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
67 av_freep(&ctx->psy_bands);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
68 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
69
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
70 typedef struct FFPsyPreprocessContext{
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
71 AVCodecContext *avctx;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
72 float stereo_att;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
73 struct FFIIRFilterCoeffs *fcoeffs;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
74 struct FFIIRFilterState **fstate;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
75 }FFPsyPreprocessContext;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
76
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
77 #define FILT_ORDER 4
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
78
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
79 av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
80 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
81 FFPsyPreprocessContext *ctx;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
82 int i;
11579
9db3fbaba639 aacenc: Don't lowpass the input unless specifically requested.
alexc
parents: 9953
diff changeset
83 float cutoff_coeff = 0;
9937
3e39dbd2d9eb cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents: 9936
diff changeset
84 ctx = av_mallocz(sizeof(FFPsyPreprocessContext));
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
85 ctx->avctx = avctx;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
86
9953
a79d7debe431 Use cutoff frequency to adjust bandwidth in the generic psymodel preprocess.
alexc
parents: 9938
diff changeset
87 if (avctx->cutoff > 0)
a79d7debe431 Use cutoff frequency to adjust bandwidth in the generic psymodel preprocess.
alexc
parents: 9938
diff changeset
88 cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
89
11579
9db3fbaba639 aacenc: Don't lowpass the input unless specifically requested.
alexc
parents: 9953
diff changeset
90 if (cutoff_coeff)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
91 ctx->fcoeffs = ff_iir_filter_init_coeffs(FF_FILTER_TYPE_BUTTERWORTH, FF_FILTER_MODE_LOWPASS,
9937
3e39dbd2d9eb cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents: 9936
diff changeset
92 FILT_ORDER, cutoff_coeff, 0.0, 0.0);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
93 if (ctx->fcoeffs) {
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
94 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
95 for (i = 0; i < avctx->channels; i++)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
96 ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
97 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
98 return ctx;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
99 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
100
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
101 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
102 const int16_t *audio, int16_t *dest,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
103 int tag, int channels)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
104 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
105 int ch, i;
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
106 if (ctx->fstate) {
9938
6c1ac45b3097 cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents: 9937
diff changeset
107 for (ch = 0; ch < channels; ch++)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
108 ff_iir_filter(ctx->fcoeffs, ctx->fstate[tag+ch], ctx->avctx->frame_size,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
109 audio + ch, ctx->avctx->channels,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
110 dest + ch, ctx->avctx->channels);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
111 } else {
9938
6c1ac45b3097 cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents: 9937
diff changeset
112 for (ch = 0; ch < channels; ch++)
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
113 for (i = 0; i < ctx->avctx->frame_size; i++)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
114 dest[i*ctx->avctx->channels + ch] = audio[i*ctx->avctx->channels + ch];
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
115 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
116 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
117
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
118 av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
119 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
120 int i;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
121 ff_iir_filter_free_coeffs(ctx->fcoeffs);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
122 if (ctx->fstate)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
123 for (i = 0; i < ctx->avctx->channels; i++)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
124 ff_iir_filter_free_state(ctx->fstate[i]);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
125 av_freep(&ctx->fstate);
12125
a93946f63075 Fix a leak in the AAC encoder
mstorsjo
parents: 11996
diff changeset
126 av_free(ctx);
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
127 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
128