annotate psymodel.c @ 11060:daff45175333 libavcodec

Make the jump-table section-relative for x86_64 with PIC enabled. This allows to get rid of the macho64 specific hack that moves them to rodata (with worse cache behaviour) and avoids textrels which e.g. Gentoo does not allow for x86_64 libraries.
author reimar
date Sat, 30 Jan 2010 19:26:47 +0000
parents a79d7debe431
children 9db3fbaba639
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,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
56 const float *coeffs, FFPsyWindowInfo *wi)
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;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
83 float cutoff_coeff;
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;
a79d7debe431 Use cutoff frequency to adjust bandwidth in the generic psymodel preprocess.
alexc
parents: 9938
diff changeset
89 else if (avctx->flags & CODEC_FLAG_QSCALE)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
90 cutoff_coeff = 1.0f / av_clip(1 + avctx->global_quality / FF_QUALITY_SCALE, 1, 8);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
91 else
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
92 cutoff_coeff = avctx->bit_rate / (4.0f * avctx->sample_rate * avctx->channels);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
93
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
94 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
95 FILT_ORDER, cutoff_coeff, 0.0, 0.0);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
96 if (ctx->fcoeffs) {
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
97 ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
98 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
99 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
100 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
101 return ctx;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
102 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
103
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
104 void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
105 const int16_t *audio, int16_t *dest,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
106 int tag, int channels)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
107 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
108 int ch, i;
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
109 if (ctx->fstate) {
9938
6c1ac45b3097 cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents: 9937
diff changeset
110 for (ch = 0; ch < channels; ch++)
9935
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
111 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
112 audio + ch, ctx->avctx->channels,
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
113 dest + ch, ctx->avctx->channels);
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
114 } else {
9938
6c1ac45b3097 cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents: 9937
diff changeset
115 for (ch = 0; ch < channels; ch++)
9936
7f42ae22c351 Cosmetics: Pretty print the AAC encoder.
alexc
parents: 9935
diff changeset
116 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
117 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
118 }
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
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
121 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
122 {
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
123 int i;
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
124 ff_iir_filter_free_coeffs(ctx->fcoeffs);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
125 if (ctx->fstate)
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
126 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
127 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
128 av_freep(&ctx->fstate);
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
129 }
d09283aeeef8 Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
diff changeset
130