FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
psymodel.c
Go to the documentation of this file.
1
/*
2
* audio encoder psychoacoustic model
3
* Copyright (C) 2008 Konstantin Shishkov
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
#include <string.h>
23
24
#include "
avcodec.h
"
25
#include "
psymodel.h
"
26
#include "
iirfilter.h
"
27
#include "
libavutil/mem.h
"
28
29
extern
const
FFPsyModel
ff_aac_psy_model
;
30
31
av_cold
int
ff_psy_init
(
FFPsyContext
*ctx,
AVCodecContext
*avctx,
int
num_lens,
32
const
uint8_t
**bands,
const
int
* num_bands,
33
int
num_groups,
const
uint8_t
*group_map)
34
{
35
int
i, j, k = 0;
36
37
ctx->
avctx
= avctx;
38
ctx->
ch
=
av_mallocz
(
sizeof
(ctx->
ch
[0]) * avctx->
channels
* 2);
39
ctx->
group
=
av_mallocz
(
sizeof
(ctx->
group
[0]) * num_groups);
40
ctx->
bands
=
av_malloc
(
sizeof
(ctx->
bands
[0]) * num_lens);
41
ctx->
num_bands
=
av_malloc
(
sizeof
(ctx->
num_bands
[0]) * num_lens);
42
memcpy(ctx->
bands
, bands,
sizeof
(ctx->
bands
[0]) * num_lens);
43
memcpy(ctx->
num_bands
, num_bands,
sizeof
(ctx->
num_bands
[0]) * num_lens);
44
45
/* assign channels to groups (with virtual channels for coupling) */
46
for
(i = 0; i < num_groups; i++) {
47
/* NOTE: Add 1 to handle the AAC chan_config without modification.
48
* This has the side effect of allowing an array of 0s to map
49
* to one channel per group.
50
*/
51
ctx->
group
[i].
num_ch
= group_map[i] + 1;
52
for
(j = 0; j < ctx->
group
[i].
num_ch
* 2; j++)
53
ctx->
group
[i].
ch
[j] = &ctx->
ch
[k++];
54
}
55
56
switch
(ctx->
avctx
->
codec_id
) {
57
case
AV_CODEC_ID_AAC
:
58
ctx->
model
= &
ff_aac_psy_model
;
59
break
;
60
}
61
if
(ctx->
model
->
init
)
62
return
ctx->
model
->
init
(ctx);
63
return
0;
64
}
65
66
FFPsyChannelGroup
*
ff_psy_find_group
(
FFPsyContext
*ctx,
int
channel)
67
{
68
int
i = 0, ch = 0;
69
70
while
(ch <= channel)
71
ch += ctx->
group
[i++].
num_ch
;
72
73
return
&ctx->
group
[i-1];
74
}
75
76
av_cold
void
ff_psy_end
(
FFPsyContext
*ctx)
77
{
78
if
(ctx->
model
&& ctx->
model
->
end
)
79
ctx->
model
->
end
(ctx);
80
av_freep
(&ctx->
bands
);
81
av_freep
(&ctx->
num_bands
);
82
av_freep
(&ctx->
group
);
83
av_freep
(&ctx->
ch
);
84
}
85
86
typedef
struct
FFPsyPreprocessContext
{
87
AVCodecContext
*
avctx
;
88
float
stereo_att
;
89
struct
FFIIRFilterCoeffs
*
fcoeffs
;
90
struct
FFIIRFilterState
**
fstate
;
91
struct
FFIIRFilterContext
fiir
;
92
}
FFPsyPreprocessContext
;
93
94
#define FILT_ORDER 4
95
96
av_cold
struct
FFPsyPreprocessContext
*
ff_psy_preprocess_init
(
AVCodecContext
*
avctx
)
97
{
98
FFPsyPreprocessContext
*ctx;
99
int
i;
100
float
cutoff_coeff = 0;
101
ctx =
av_mallocz
(
sizeof
(
FFPsyPreprocessContext
));
102
ctx->
avctx
=
avctx
;
103
104
if
(avctx->
cutoff
> 0)
105
cutoff_coeff = 2.0 * avctx->
cutoff
/ avctx->
sample_rate
;
106
107
if
(!cutoff_coeff && avctx->
codec_id
==
AV_CODEC_ID_AAC
)
108
cutoff_coeff = 2.0 *
AAC_CUTOFF
(avctx) / avctx->
sample_rate
;
109
110
if
(cutoff_coeff && cutoff_coeff < 0.98)
111
ctx->
fcoeffs
=
ff_iir_filter_init_coeffs
(avctx,
FF_FILTER_TYPE_BUTTERWORTH
,
112
FF_FILTER_MODE_LOWPASS
,
FILT_ORDER
,
113
cutoff_coeff, 0.0, 0.0);
114
if
(ctx->
fcoeffs
) {
115
ctx->
fstate
=
av_mallocz
(
sizeof
(ctx->
fstate
[0]) * avctx->
channels
);
116
for
(i = 0; i < avctx->
channels
; i++)
117
ctx->
fstate
[i] =
ff_iir_filter_init_state
(
FILT_ORDER
);
118
}
119
120
ff_iir_filter_init
(&ctx->
fiir
);
121
122
return
ctx;
123
}
124
125
void
ff_psy_preprocess
(
struct
FFPsyPreprocessContext
*ctx,
float
**audio,
int
channels)
126
{
127
int
ch;
128
int
frame_size
= ctx->
avctx
->
frame_size
;
129
FFIIRFilterContext
*iir = &ctx->
fiir
;
130
131
if
(ctx->
fstate
) {
132
for
(ch = 0; ch < channels; ch++)
133
iir->
filter_flt
(ctx->
fcoeffs
, ctx->
fstate
[ch], frame_size,
134
&audio[ch][frame_size], 1, &audio[ch][frame_size], 1);
135
}
136
}
137
138
av_cold
void
ff_psy_preprocess_end
(
struct
FFPsyPreprocessContext
*ctx)
139
{
140
int
i;
141
ff_iir_filter_free_coeffs
(ctx->
fcoeffs
);
142
if
(ctx->
fstate
)
143
for
(i = 0; i < ctx->
avctx
->
channels
; i++)
144
ff_iir_filter_free_state
(ctx->
fstate
[i]);
145
av_freep
(&ctx->
fstate
);
146
av_free
(ctx);
147
}
Generated on Sun Mar 23 2014 23:50:01 for FFmpeg by
1.8.2