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
libavfilter
af_channelsplit.c
Go to the documentation of this file.
1
/*
2
* This file is part of FFmpeg.
3
*
4
* FFmpeg 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
* FFmpeg 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 FFmpeg; 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/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
#define F AV_OPT_FLAG_FILTERING_PARAM
46
static
const
AVOption
channelsplit_options
[] = {
47
{
"channel_layout"
,
"Input channel layout."
,
OFFSET
(channel_layout_str),
AV_OPT_TYPE_STRING
, { .str =
"stereo"
}, .flags =
A
|
F
},
48
{ NULL }
49
};
50
51
AVFILTER_DEFINE_CLASS
(channelsplit);
52
53
static
av_cold
int
init
(
AVFilterContext
*ctx)
54
{
55
ChannelSplitContext
*
s
= ctx->
priv
;
56
int
nb_channels
;
57
int
ret
= 0, i;
58
59
if
(!(s->
channel_layout
=
av_get_channel_layout
(s->
channel_layout_str
))) {
60
av_log
(ctx,
AV_LOG_ERROR
,
"Error parsing channel layout '%s'.\n"
,
61
s->
channel_layout_str
);
62
ret =
AVERROR
(EINVAL);
63
goto
fail;
64
}
65
66
nb_channels =
av_get_channel_layout_nb_channels
(s->
channel_layout
);
67
for
(i = 0; i <
nb_channels
; i++) {
68
uint64_t channel =
av_channel_layout_extract_channel
(s->
channel_layout
, i);
69
AVFilterPad
pad = { 0 };
70
71
pad.
type
=
AVMEDIA_TYPE_AUDIO
;
72
pad.
name
=
av_get_channel_name
(channel);
73
74
ff_insert_outpad
(ctx, i, &pad);
75
}
76
77
fail:
78
return
ret
;
79
}
80
81
static
int
query_formats
(
AVFilterContext
*ctx)
82
{
83
ChannelSplitContext
*
s
= ctx->
priv
;
84
AVFilterChannelLayouts
*in_layouts = NULL;
85
int
i;
86
87
ff_set_common_formats
(ctx,
ff_planar_sample_fmts
());
88
ff_set_common_samplerates
(ctx,
ff_all_samplerates
());
89
90
ff_add_channel_layout
(&in_layouts, s->
channel_layout
);
91
ff_channel_layouts_ref
(in_layouts, &ctx->
inputs
[0]->
out_channel_layouts
);
92
93
for
(i = 0; i < ctx->
nb_outputs
; i++) {
94
AVFilterChannelLayouts
*out_layouts = NULL;
95
uint64_t channel =
av_channel_layout_extract_channel
(s->
channel_layout
, i);
96
97
ff_add_channel_layout
(&out_layouts, channel);
98
ff_channel_layouts_ref
(out_layouts, &ctx->
outputs
[i]->
in_channel_layouts
);
99
}
100
101
return
0;
102
}
103
104
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFrame
*
buf
)
105
{
106
AVFilterContext
*ctx = inlink->
dst
;
107
int
i,
ret
= 0;
108
109
for
(i = 0; i < ctx->
nb_outputs
; i++) {
110
AVFrame
*buf_out =
av_frame_clone
(buf);
111
112
if
(!buf_out) {
113
ret =
AVERROR
(ENOMEM);
114
break
;
115
}
116
117
buf_out->
data
[0] = buf_out->
extended_data
[0] = buf_out->
extended_data
[i];
118
buf_out->
channel_layout
=
119
av_channel_layout_extract_channel
(buf->
channel_layout
, i);
120
av_frame_set_channels
(buf_out, 1);
121
122
ret =
ff_filter_frame
(ctx->
outputs
[i], buf_out);
123
if
(ret < 0)
124
break
;
125
}
126
av_frame_free
(&buf);
127
return
ret
;
128
}
129
130
static
const
AVFilterPad
avfilter_af_channelsplit_inputs
[] = {
131
{
132
.
name
=
"default"
,
133
.type =
AVMEDIA_TYPE_AUDIO
,
134
.filter_frame =
filter_frame
,
135
},
136
{ NULL }
137
};
138
139
AVFilter
ff_af_channelsplit
= {
140
.
name
=
"channelsplit"
,
141
.description =
NULL_IF_CONFIG_SMALL
(
"Split audio into per-channel streams."
),
142
.priv_size =
sizeof
(
ChannelSplitContext
),
143
.priv_class = &channelsplit_class,
144
.
init
=
init
,
145
.
query_formats
=
query_formats
,
146
.
inputs
= avfilter_af_channelsplit_inputs,
147
.
outputs
= NULL,
148
.
flags
=
AVFILTER_FLAG_DYNAMIC_OUTPUTS
,
149
};
Generated on Fri Dec 5 2014 04:42:07 for FFmpeg by
1.8.2