FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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
19
/**
20
* @file
21
* Channel split filter
22
*
23
* Split an audio stream into per-channel streams.
24
*/
25
26
#include "
libavutil/channel_layout.h
"
27
#include "
libavutil/internal.h
"
28
#include "
libavutil/opt.h
"
29
30
#include "
audio.h
"
31
#include "
avfilter.h
"
32
#include "
formats.h
"
33
#include "
internal.h
"
34
35
typedef
struct
ChannelSplitContext
{
36
const
AVClass
*
class
;
37
38
uint64_t
channel_layout
;
39
char
*
channel_layout_str
;
40
}
ChannelSplitContext
;
41
42
#define OFFSET(x) offsetof(ChannelSplitContext, x)
43
#define A AV_OPT_FLAG_AUDIO_PARAM
44
#define F AV_OPT_FLAG_FILTERING_PARAM
45
static
const
AVOption
channelsplit_options
[] = {
46
{
"channel_layout"
,
"Input channel layout."
,
OFFSET
(channel_layout_str),
AV_OPT_TYPE_STRING
, { .str =
"stereo"
}, .flags =
A
|
F
},
47
{
NULL
},
48
};
49
50
AVFILTER_DEFINE_CLASS
(channelsplit);
51
52
static
int
init
(
AVFilterContext
*ctx,
const
char
*
arg
)
53
{
54
ChannelSplitContext
*s = ctx->
priv
;
55
int
nb_channels
;
56
int
ret = 0, i;
57
58
s->
class
= &channelsplit_class;
59
av_opt_set_defaults
(s);
60
if
((ret =
av_set_options_string
(s, arg,
"="
,
":"
)) < 0)
61
return
ret;
62
if
(!(s->
channel_layout
=
av_get_channel_layout
(s->
channel_layout_str
))) {
63
av_log
(ctx,
AV_LOG_ERROR
,
"Error parsing channel layout '%s'.\n"
,
64
s->
channel_layout_str
);
65
ret =
AVERROR
(EINVAL);
66
goto
fail;
67
}
68
69
nb_channels =
av_get_channel_layout_nb_channels
(s->
channel_layout
);
70
for
(i = 0; i <
nb_channels
; i++) {
71
uint64_t channel =
av_channel_layout_extract_channel
(s->
channel_layout
, i);
72
AVFilterPad
pad = { 0 };
73
74
pad.
type
=
AVMEDIA_TYPE_AUDIO
;
75
pad.
name
=
av_get_channel_name
(channel);
76
77
ff_insert_outpad
(ctx, i, &pad);
78
}
79
80
fail:
81
av_opt_free
(s);
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,
AVFilterBufferRef
*buf)
109
{
110
AVFilterContext
*ctx = inlink->
dst
;
111
int
i, ret = 0;
112
113
for
(i = 0; i < ctx->
nb_outputs
; i++) {
114
AVFilterBufferRef
*buf_out =
avfilter_ref_buffer
(buf, ~
AV_PERM_WRITE
);
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->
audio
->
channel_layout
=
123
av_channel_layout_extract_channel
(buf->
audio
->
channel_layout
, i);
124
125
ret =
ff_filter_frame
(ctx->
outputs
[i], buf_out);
126
if
(ret < 0)
127
break
;
128
}
129
avfilter_unref_buffer
(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
avfilter_af_channelsplit
= {
143
.
name
=
"channelsplit"
,
144
.description =
NULL_IF_CONFIG_SMALL
(
"Split audio into per-channel streams"
),
145
.priv_size =
sizeof
(
ChannelSplitContext
),
146
147
.
init
=
init
,
148
.
query_formats
=
query_formats
,
149
150
.
inputs
= avfilter_af_channelsplit_inputs,
151
.
outputs
=
NULL
,
152
.priv_class = &channelsplit_class,
153
};
Generated on Sat May 25 2013 03:58:44 for FFmpeg by
1.8.2