Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavfilter
af_channelsplit.c
Go to the documentation of this file.
1
/*
2
* This file is part of Libav.
3
*
4
* Libav is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
8
*
9
* Libav is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with Libav; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
*/
18
26
#include "
libavutil/attributes.h
"
27
#include "
libavutil/channel_layout.h
"
28
#include "
libavutil/internal.h
"
29
#include "
libavutil/opt.h
"
30
31
#include "
audio.h
"
32
#include "
avfilter.h
"
33
#include "
formats.h
"
34
#include "
internal.h
"
35
36
typedef
struct
ChannelSplitContext
{
37
const
AVClass
*
class
;
38
39
uint64_t
channel_layout
;
40
char
*
channel_layout_str
;
41
}
ChannelSplitContext
;
42
43
#define OFFSET(x) offsetof(ChannelSplitContext, x)
44
#define A AV_OPT_FLAG_AUDIO_PARAM
45
static
const
AVOption
options
[] = {
46
{
"channel_layout"
,
"Input channel layout."
,
OFFSET
(channel_layout_str),
AV_OPT_TYPE_STRING
, { .str =
"stereo"
}, .flags =
A
},
47
{
NULL
},
48
};
49
50
static
const
AVClass
channelsplit_class
= {
51
.
class_name
=
"channelsplit filter"
,
52
.item_name =
av_default_item_name
,
53
.option =
options
,
54
.version =
LIBAVUTIL_VERSION_INT
,
55
};
56
57
static
av_cold
int
init
(
AVFilterContext
*ctx)
58
{
59
ChannelSplitContext
*s = ctx->
priv
;
60
int
nb_channels
;
61
int
ret = 0, i;
62
63
if
(!(s->
channel_layout
=
av_get_channel_layout
(s->
channel_layout_str
))) {
64
av_log
(ctx,
AV_LOG_ERROR
,
"Error parsing channel layout '%s'.\n"
,
65
s->
channel_layout_str
);
66
ret =
AVERROR
(EINVAL);
67
goto
fail;
68
}
69
70
nb_channels =
av_get_channel_layout_nb_channels
(s->
channel_layout
);
71
for
(i = 0; i <
nb_channels
; i++) {
72
uint64_t channel =
av_channel_layout_extract_channel
(s->
channel_layout
, i);
73
AVFilterPad
pad = { 0 };
74
75
pad.
type
=
AVMEDIA_TYPE_AUDIO
;
76
pad.
name
=
av_get_channel_name
(channel);
77
78
ff_insert_outpad
(ctx, i, &pad);
79
}
80
81
fail:
82
return
ret;
83
}
84
85
static
int
query_formats
(
AVFilterContext
*ctx)
86
{
87
ChannelSplitContext
*s = ctx->
priv
;
88
AVFilterChannelLayouts
*in_layouts =
NULL
;
89
int
i;
90
91
ff_set_common_formats
(ctx,
ff_planar_sample_fmts
());
92
ff_set_common_samplerates
(ctx,
ff_all_samplerates
());
93
94
ff_add_channel_layout
(&in_layouts, s->
channel_layout
);
95
ff_channel_layouts_ref
(in_layouts, &ctx->
inputs
[0]->
out_channel_layouts
);
96
97
for
(i = 0; i < ctx->
nb_outputs
; i++) {
98
AVFilterChannelLayouts
*out_layouts =
NULL
;
99
uint64_t channel =
av_channel_layout_extract_channel
(s->
channel_layout
, i);
100
101
ff_add_channel_layout
(&out_layouts, channel);
102
ff_channel_layouts_ref
(out_layouts, &ctx->
outputs
[i]->
in_channel_layouts
);
103
}
104
105
return
0;
106
}
107
108
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFrame
*buf)
109
{
110
AVFilterContext
*ctx = inlink->
dst
;
111
int
i, ret = 0;
112
113
for
(i = 0; i < ctx->
nb_outputs
; i++) {
114
AVFrame
*buf_out =
av_frame_clone
(buf);
115
116
if
(!buf_out) {
117
ret =
AVERROR
(ENOMEM);
118
break
;
119
}
120
121
buf_out->
data
[0] = buf_out->
extended_data
[0] = buf_out->
extended_data
[i];
122
buf_out->
channel_layout
=
123
av_channel_layout_extract_channel
(buf->
channel_layout
, i);
124
125
ret =
ff_filter_frame
(ctx->
outputs
[i], buf_out);
126
if
(ret < 0)
127
break
;
128
}
129
av_frame_free
(&buf);
130
return
ret;
131
}
132
133
static
const
AVFilterPad
avfilter_af_channelsplit_inputs
[] = {
134
{
135
.
name
=
"default"
,
136
.type =
AVMEDIA_TYPE_AUDIO
,
137
.filter_frame =
filter_frame
,
138
},
139
{
NULL
}
140
};
141
142
AVFilter
ff_af_channelsplit
= {
143
.
name
=
"channelsplit"
,
144
.description =
NULL_IF_CONFIG_SMALL
(
"Split audio into per-channel streams"
),
145
.priv_size =
sizeof
(
ChannelSplitContext
),
146
.priv_class = &channelsplit_class,
147
148
.
init
=
init
,
149
.
query_formats
=
query_formats
,
150
151
.
inputs
= avfilter_af_channelsplit_inputs,
152
.
outputs
=
NULL
,
153
154
.
flags
=
AVFILTER_FLAG_DYNAMIC_OUTPUTS
,
155
};
Generated on Tue Mar 1 2016 21:14:48 for Libav by
1.8.4