GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* Copyright (c) 2011 Mina Nagy Zaki |
||
3 |
* |
||
4 |
* This file is part of FFmpeg. |
||
5 |
* |
||
6 |
* FFmpeg is free software; you can redistribute it and/or |
||
7 |
* modify it under the terms of the GNU Lesser General Public |
||
8 |
* License as published by the Free Software Foundation; either |
||
9 |
* version 2.1 of the License, or (at your option) any later version. |
||
10 |
* |
||
11 |
* FFmpeg is distributed in the hope that it will be useful, |
||
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
14 |
* Lesser General Public License for more details. |
||
15 |
* |
||
16 |
* You should have received a copy of the GNU Lesser General Public |
||
17 |
* License along with FFmpeg; if not, write to the Free Software |
||
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
19 |
*/ |
||
20 |
|||
21 |
/** |
||
22 |
* @file |
||
23 |
* format audio filter |
||
24 |
*/ |
||
25 |
|||
26 |
#include "libavutil/avstring.h" |
||
27 |
#include "libavutil/channel_layout.h" |
||
28 |
#include "libavutil/common.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 AFormatContext { |
||
37 |
const AVClass *class; |
||
38 |
|||
39 |
AVFilterFormats *formats; |
||
40 |
AVFilterFormats *sample_rates; |
||
41 |
AVFilterChannelLayouts *channel_layouts; |
||
42 |
|||
43 |
char *formats_str; |
||
44 |
char *sample_rates_str; |
||
45 |
char *channel_layouts_str; |
||
46 |
} AFormatContext; |
||
47 |
|||
48 |
#define OFFSET(x) offsetof(AFormatContext, x) |
||
49 |
#define A AV_OPT_FLAG_AUDIO_PARAM |
||
50 |
#define F AV_OPT_FLAG_FILTERING_PARAM |
||
51 |
static const AVOption aformat_options[] = { |
||
52 |
{ "sample_fmts", "A '|'-separated list of sample formats.", OFFSET(formats_str), AV_OPT_TYPE_STRING, .flags = A|F }, |
||
53 |
{ "f", "A '|'-separated list of sample formats.", OFFSET(formats_str), AV_OPT_TYPE_STRING, .flags = A|F }, |
||
54 |
{ "sample_rates", "A '|'-separated list of sample rates.", OFFSET(sample_rates_str), AV_OPT_TYPE_STRING, .flags = A|F }, |
||
55 |
{ "r", "A '|'-separated list of sample rates.", OFFSET(sample_rates_str), AV_OPT_TYPE_STRING, .flags = A|F }, |
||
56 |
{ "channel_layouts", "A '|'-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A|F }, |
||
57 |
{ "cl", "A '|'-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A|F }, |
||
58 |
{ NULL } |
||
59 |
}; |
||
60 |
|||
61 |
AVFILTER_DEFINE_CLASS(aformat); |
||
62 |
|||
63 |
#define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc) \ |
||
64 |
do { \ |
||
65 |
char *next, *cur = str, sep; \ |
||
66 |
int ret; \ |
||
67 |
\ |
||
68 |
if (str && strchr(str, ',')) { \ |
||
69 |
av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use '|' to "\ |
||
70 |
"separate %s.\n", desc); \ |
||
71 |
sep = ','; \ |
||
72 |
} else \ |
||
73 |
sep = '|'; \ |
||
74 |
\ |
||
75 |
while (cur) { \ |
||
76 |
type fmt; \ |
||
77 |
next = strchr(cur, sep); \ |
||
78 |
if (next) \ |
||
79 |
*next++ = 0; \ |
||
80 |
\ |
||
81 |
if ((fmt = get_fmt(cur)) == none) { \ |
||
82 |
av_log(ctx, AV_LOG_ERROR, "Error parsing " desc ": %s.\n", cur);\ |
||
83 |
return AVERROR(EINVAL); \ |
||
84 |
} \ |
||
85 |
if ((ret = add_to_list(&list, fmt)) < 0) { \ |
||
86 |
return ret; \ |
||
87 |
} \ |
||
88 |
\ |
||
89 |
cur = next; \ |
||
90 |
} \ |
||
91 |
} while (0) |
||
92 |
|||
93 |
296 |
static int get_sample_rate(const char *samplerate) |
|
94 |
{ |
||
95 |
296 |
int ret = strtol(samplerate, NULL, 0); |
|
96 |
296 |
return FFMAX(ret, 0); |
|
97 |
} |
||
98 |
|||
99 |
1440 |
static av_cold int init(AVFilterContext *ctx) |
|
100 |
{ |
||
101 |
1440 |
AFormatContext *s = ctx->priv; |
|
102 |
|||
103 |
✓✗✗✓ ✓✓✗✓ ✗✓✓✓ |
2917 |
PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats, |
104 |
ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); |
||
105 |
✓✓✗✓ ✓✓✗✓ ✗✓✓✓ |
1736 |
PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format, |
106 |
get_sample_rate, 0, "sample rate"); |
||
107 |
✓✓✗✓ ✓✓✗✓ ✗✓✓✓ |
1691 |
PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts, |
108 |
ff_add_channel_layout, av_get_channel_layout, 0, |
||
109 |
"channel layout"); |
||
110 |
|||
111 |
1440 |
return 0; |
|
112 |
} |
||
113 |
|||
114 |
1440 |
static av_cold void uninit(AVFilterContext *ctx) |
|
115 |
{ |
||
116 |
1440 |
AFormatContext *s = ctx->priv; |
|
117 |
|||
118 |
1440 |
ff_formats_unref(&s->formats); |
|
119 |
1440 |
ff_formats_unref(&s->sample_rates); |
|
120 |
1440 |
ff_channel_layouts_unref(&s->channel_layouts); |
|
121 |
1440 |
} |
|
122 |
|||
123 |
1440 |
static int query_formats(AVFilterContext *ctx) |
|
124 |
{ |
||
125 |
1440 |
AFormatContext *s = ctx->priv; |
|
126 |
int ret; |
||
127 |
|||
128 |
✓✗ | 1440 |
ret = ff_set_common_formats(ctx, s->formats ? s->formats : |
129 |
ff_all_formats(AVMEDIA_TYPE_AUDIO)); |
||
130 |
1440 |
s->formats = NULL; |
|
131 |
✗✓ | 1440 |
if (ret < 0) |
132 |
return ret; |
||
133 |
✓✓ | 2819 |
ret = ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates : |
134 |
1379 |
ff_all_samplerates()); |
|
135 |
1440 |
s->sample_rates = NULL; |
|
136 |
✗✓ | 1440 |
if (ret < 0) |
137 |
return ret; |
||
138 |
✓✓ | 2825 |
ret = ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts : |
139 |
1385 |
ff_all_channel_counts()); |
|
140 |
1440 |
s->channel_layouts = NULL; |
|
141 |
1440 |
return ret; |
|
142 |
} |
||
143 |
|||
144 |
static const AVFilterPad avfilter_af_aformat_inputs[] = { |
||
145 |
{ |
||
146 |
.name = "default", |
||
147 |
.type = AVMEDIA_TYPE_AUDIO, |
||
148 |
}, |
||
149 |
{ NULL } |
||
150 |
}; |
||
151 |
|||
152 |
static const AVFilterPad avfilter_af_aformat_outputs[] = { |
||
153 |
{ |
||
154 |
.name = "default", |
||
155 |
.type = AVMEDIA_TYPE_AUDIO |
||
156 |
}, |
||
157 |
{ NULL } |
||
158 |
}; |
||
159 |
|||
160 |
AVFilter ff_af_aformat = { |
||
161 |
.name = "aformat", |
||
162 |
.description = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."), |
||
163 |
.init = init, |
||
164 |
.uninit = uninit, |
||
165 |
.query_formats = query_formats, |
||
166 |
.priv_size = sizeof(AFormatContext), |
||
167 |
.priv_class = &aformat_class, |
||
168 |
.inputs = avfilter_af_aformat_inputs, |
||
169 |
.outputs = avfilter_af_aformat_outputs, |
||
170 |
}; |
Generated by: GCOVR (Version 4.2) |