Deprecated in c29038f3041a4080342b2e333c1967d136749c0f. The resample filter based upon this library has been removed as well.
Showing the changes to libavfilter (3 of 59 files). Show all
Unified · Split
| @@ -135,7 +135,6 @@ OBJS-$(CONFIG_LV2_FILTER) += af_lv2.o · 134 unmodified lines | ||
| 135 | 135 | OBJS-$(CONFIG_MCOMPAND_FILTER) += af_mcompand.o |
| 136 | 136 | OBJS-$(CONFIG_PAN_FILTER) += af_pan.o |
| 137 | 137 | OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o |
| 138 | −OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o | |
| 139 | 138 | OBJS-$(CONFIG_RUBBERBAND_FILTER) += af_rubberband.o |
| 140 | 139 | OBJS-$(CONFIG_SIDECHAINCOMPRESS_FILTER) += af_sidechaincompress.o |
| 141 | 140 | OBJS-$(CONFIG_SIDECHAINGATE_FILTER) += af_agate.o |
| @@ -1,369 +0,0 @@ | ||
| 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 | − * sample format and channel layout conversion audio filter | |
| 22 | − */ | |
| 23 | − | |
| 24 | −#include "libavutil/avassert.h" | |
| 25 | −#include "libavutil/avstring.h" | |
| 26 | −#include "libavutil/common.h" | |
| 27 | −#include "libavutil/dict.h" | |
| 28 | −#include "libavutil/mathematics.h" | |
| 29 | −#include "libavutil/opt.h" | |
| 30 | − | |
| 31 | −#include "libavresample/avresample.h" | |
| 32 | − | |
| 33 | −#include "audio.h" | |
| 34 | −#include "avfilter.h" | |
| 35 | −#include "formats.h" | |
| 36 | −#include "internal.h" | |
| 37 | − | |
| 38 | −typedef struct ResampleContext { | |
| 39 | − const AVClass *class; | |
| 40 | − AVAudioResampleContext *avr; | |
| 41 | − AVDictionary *options; | |
| 42 | − | |
| 43 | − int resampling; | |
| 44 | − int64_t next_pts; | |
| 45 | − int64_t next_in_pts; | |
| 46 | − | |
| 47 | − /* set by filter_frame() to signal an output frame to request_frame() */ | |
| 48 | − int got_output; | |
| 49 | −} ResampleContext; | |
| 50 | − | |
| 51 | −static av_cold int init(AVFilterContext *ctx, AVDictionary **opts) | |
| 52 | −{ | |
| 53 | − ResampleContext *s = ctx->priv; | |
| 54 | − const AVClass *avr_class = avresample_get_class(); | |
| 55 | − AVDictionaryEntry *e = NULL; | |
| 56 | − | |
| 57 | − while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) { | |
| 58 | − if (av_opt_find(&avr_class, e->key, NULL, 0, | |
| 59 | − AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN)) | |
| 60 | − av_dict_set(&s->options, e->key, e->value, 0); | |
| 61 | − } | |
| 62 | − | |
| 63 | − e = NULL; | |
| 64 | − while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX))) | |
| 65 | − av_dict_set(opts, e->key, NULL, 0); | |
| 66 | − | |
| 67 | − /* do not allow the user to override basic format options */ | |
| 68 | − av_dict_set(&s->options, "in_channel_layout", NULL, 0); | |
| 69 | − av_dict_set(&s->options, "out_channel_layout", NULL, 0); | |
| 70 | − av_dict_set(&s->options, "in_sample_fmt", NULL, 0); | |
| 71 | − av_dict_set(&s->options, "out_sample_fmt", NULL, 0); | |
| 72 | − av_dict_set(&s->options, "in_sample_rate", NULL, 0); | |
| 73 | − av_dict_set(&s->options, "out_sample_rate", NULL, 0); | |
| 74 | − | |
| 75 | − return 0; | |
| 76 | −} | |
| 77 | − | |
| 78 | −static av_cold void uninit(AVFilterContext *ctx) | |
| 79 | −{ | |
| 80 | − ResampleContext *s = ctx->priv; | |
| 81 | − | |
| 82 | − if (s->avr) { | |
| 83 | − avresample_close(s->avr); | |
| 84 | − avresample_free(&s->avr); | |
| 85 | − } | |
| 86 | − av_dict_free(&s->options); | |
| 87 | −} | |
| 88 | − | |
| 89 | −static int query_formats(AVFilterContext *ctx) | |
| 90 | −{ | |
| 91 | − AVFilterLink *inlink = ctx->inputs[0]; | |
| 92 | − AVFilterLink *outlink = ctx->outputs[0]; | |
| 93 | − AVFilterFormats *in_formats, *out_formats, *in_samplerates, *out_samplerates; | |
| 94 | − AVFilterChannelLayouts *in_layouts, *out_layouts; | |
| 95 | − int ret; | |
| 96 | − | |
| 97 | − if (!(in_formats = ff_all_formats (AVMEDIA_TYPE_AUDIO)) || | |
| 98 | − !(out_formats = ff_all_formats (AVMEDIA_TYPE_AUDIO)) || | |
| 99 | − !(in_samplerates = ff_all_samplerates ( )) || | |
| 100 | − !(out_samplerates = ff_all_samplerates ( )) || | |
| 101 | − !(in_layouts = ff_all_channel_layouts ( )) || | |
| 102 | − !(out_layouts = ff_all_channel_layouts ( ))) | |
| 103 | − return AVERROR(ENOMEM); | |
| 104 | − | |
| 105 | − if ((ret = ff_formats_ref (in_formats, &inlink->outcfg.formats )) < 0 || | |
| 106 | − (ret = ff_formats_ref (out_formats, &outlink->incfg.formats )) < 0 || | |
| 107 | − (ret = ff_formats_ref (in_samplerates, &inlink->outcfg.samplerates )) < 0 || | |
| 108 | − (ret = ff_formats_ref (out_samplerates, &outlink->incfg.samplerates )) < 0 || | |
| 109 | − (ret = ff_channel_layouts_ref (in_layouts, &inlink->outcfg.channel_layouts)) < 0 || | |
| 110 | − (ret = ff_channel_layouts_ref (out_layouts, &outlink->incfg.channel_layouts)) < 0) | |
| 111 | − return ret; | |
| 112 | − | |
| 113 | − return 0; | |
| 114 | −} | |
| 115 | − | |
| 116 | −static int config_output(AVFilterLink *outlink) | |
| 117 | −{ | |
| 118 | − AVFilterContext *ctx = outlink->src; | |
| 119 | − AVFilterLink *inlink = ctx->inputs[0]; | |
| 120 | − ResampleContext *s = ctx->priv; | |
| 121 | − char buf1[64], buf2[64]; | |
| 122 | − int ret; | |
| 123 | − | |
| 124 | − int64_t resampling_forced; | |
| 125 | − | |
| 126 | − if (s->avr) { | |
| 127 | − avresample_close(s->avr); | |
| 128 | − avresample_free(&s->avr); | |
| 129 | − } | |
| 130 | − | |
| 131 | − if (inlink->channel_layout == outlink->channel_layout && | |
| 132 | − inlink->sample_rate == outlink->sample_rate && | |
| 133 | − (inlink->format == outlink->format || | |
| 134 | − (av_get_channel_layout_nb_channels(inlink->channel_layout) == 1 && | |
| 135 | − av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 && | |
| 136 | − av_get_planar_sample_fmt(inlink->format) == | |
| 137 | − av_get_planar_sample_fmt(outlink->format)))) | |
| 138 | − return 0; | |
| 139 | − | |
| 140 | − if (!(s->avr = avresample_alloc_context())) | |
| 141 | − return AVERROR(ENOMEM); | |
| 142 | − | |
| 143 | − if (s->options) { | |
| 144 | − int ret; | |
| 145 | − AVDictionaryEntry *e = NULL; | |
| 146 | − while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX))) | |
| 147 | − av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value); | |
| 148 | − | |
| 149 | − ret = av_opt_set_dict(s->avr, &s->options); | |
| 150 | − if (ret < 0) | |
| 151 | − return ret; | |
| 152 | − } | |
| 153 | − | |
| 154 | − av_opt_set_int(s->avr, "in_channel_layout", inlink ->channel_layout, 0); | |
| 155 | − av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0); | |
| 156 | − av_opt_set_int(s->avr, "in_sample_fmt", inlink ->format, 0); | |
| 157 | − av_opt_set_int(s->avr, "out_sample_fmt", outlink->format, 0); | |
| 158 | − av_opt_set_int(s->avr, "in_sample_rate", inlink ->sample_rate, 0); | |
| 159 | − av_opt_set_int(s->avr, "out_sample_rate", outlink->sample_rate, 0); | |
| 160 | − | |
| 161 | − if ((ret = avresample_open(s->avr)) < 0) | |
| 162 | − return ret; | |
| 163 | − | |
| 164 | − av_opt_get_int(s->avr, "force_resampling", 0, &resampling_forced); | |
| 165 | − s->resampling = resampling_forced || (inlink->sample_rate != outlink->sample_rate); | |
| 166 | − | |
| 167 | − if (s->resampling) { | |
| 168 | − outlink->time_base = (AVRational){ 1, outlink->sample_rate }; | |
| 169 | − s->next_pts = AV_NOPTS_VALUE; | |
| 170 | − s->next_in_pts = AV_NOPTS_VALUE; | |
| 171 | − } else | |
| 172 | − outlink->time_base = inlink->time_base; | |
| 173 | − | |
| 174 | − av_get_channel_layout_string(buf1, sizeof(buf1), | |
| 175 | − -1, inlink ->channel_layout); | |
| 176 | − av_get_channel_layout_string(buf2, sizeof(buf2), | |
| 177 | − -1, outlink->channel_layout); | |
| 178 | − av_log(ctx, AV_LOG_VERBOSE, | |
| 179 | − "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n", | |
| 180 | − av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1, | |
| 181 | − av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2); | |
| 182 | − | |
| 183 | − return 0; | |
| 184 | −} | |
| 185 | − | |
| 186 | −static int request_frame(AVFilterLink *outlink) | |
| 187 | −{ | |
| 188 | − AVFilterContext *ctx = outlink->src; | |
| 189 | − ResampleContext *s = ctx->priv; | |
| 190 | − int ret = 0; | |
| 191 | − | |
| 192 | − s->got_output = 0; | |
| 193 | − while (ret >= 0 && !s->got_output) | |
| 194 | − ret = ff_request_frame(ctx->inputs[0]); | |
| 195 | − | |
| 196 | − /* flush the lavr delay buffer */ | |
| 197 | − if (ret == AVERROR_EOF && s->avr) { | |
| 198 | − AVFrame *frame; | |
| 199 | − int nb_samples = avresample_get_out_samples(s->avr, 0); | |
| 200 | − | |
| 201 | − if (!nb_samples) | |
| 202 | − return ret; | |
| 203 | − | |
| 204 | − frame = ff_get_audio_buffer(outlink, nb_samples); | |
| 205 | − if (!frame) | |
| 206 | − return AVERROR(ENOMEM); | |
| 207 | − | |
| 208 | − ret = avresample_convert(s->avr, frame->extended_data, | |
| 209 | − frame->linesize[0], nb_samples, | |
| 210 | − NULL, 0, 0); | |
| 211 | − if (ret <= 0) { | |
| 212 | − av_frame_free(&frame); | |
| 213 | − return (ret == 0) ? AVERROR_EOF : ret; | |
| 214 | − } | |
| 215 | − | |
| 216 | − frame->nb_samples = ret; | |
| 217 | − frame->pts = s->next_pts; | |
| 218 | − return ff_filter_frame(outlink, frame); | |
| 219 | − } | |
| 220 | − return ret; | |
| 221 | −} | |
| 222 | − | |
| 223 | −static int filter_frame(AVFilterLink *inlink, AVFrame *in) | |
| 224 | −{ | |
| 225 | − AVFilterContext *ctx = inlink->dst; | |
| 226 | − ResampleContext *s = ctx->priv; | |
| 227 | − AVFilterLink *outlink = ctx->outputs[0]; | |
| 228 | − int ret; | |
| 229 | − | |
| 230 | − if (s->avr) { | |
| 231 | − AVFrame *out; | |
| 232 | − int delay, nb_samples; | |
| 233 | − | |
| 234 | − /* maximum possible samples lavr can output */ | |
| 235 | − delay = avresample_get_delay(s->avr); | |
| 236 | − nb_samples = avresample_get_out_samples(s->avr, in->nb_samples); | |
| 237 | − | |
| 238 | − out = ff_get_audio_buffer(outlink, nb_samples); | |
| 239 | − if (!out) { | |
| 240 | − ret = AVERROR(ENOMEM); | |
| 241 | − goto fail; | |
| 242 | − } | |
| 243 | − | |
| 244 | − ret = avresample_convert(s->avr, out->extended_data, out->linesize[0], | |
| 245 | − nb_samples, in->extended_data, in->linesize[0], | |
| 246 | − in->nb_samples); | |
| 247 | − if (ret <= 0) { | |
| 248 | − av_frame_free(&out); | |
| 249 | − if (ret < 0) | |
| 250 | − goto fail; | |
| 251 | − } | |
| 252 | − | |
| 253 | − av_assert0(!avresample_available(s->avr)); | |
| 254 | − | |
| 255 | − if (s->resampling && s->next_pts == AV_NOPTS_VALUE) { | |
| 256 | − if (in->pts == AV_NOPTS_VALUE) { | |
| 257 | − av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, " | |
| 258 | − "assuming 0.\n"); | |
| 259 | − s->next_pts = 0; | |
| 260 | − } else | |
| 261 | − s->next_pts = av_rescale_q(in->pts, inlink->time_base, | |
| 262 | − outlink->time_base); | |
| 263 | − } | |
| 264 | − | |
| 265 | − if (ret > 0) { | |
| 266 | − out->nb_samples = ret; | |
| 267 | − | |
| 268 | − ret = av_frame_copy_props(out, in); | |
| 269 | − if (ret < 0) { | |
| 270 | − av_frame_free(&out); | |
| 271 | − goto fail; | |
| 272 | − } | |
| 273 | − | |
| 274 | − if (s->resampling) { | |
| 275 | − out->sample_rate = outlink->sample_rate; | |
| 276 | − /* Only convert in->pts if there is a discontinuous jump. | |
| 277 | − This ensures that out->pts tracks the number of samples actually | |
| 278 | − output by the resampler in the absence of such a jump. | |
| 279 | − Otherwise, the rounding in av_rescale_q() and av_rescale() | |
| 280 | − causes off-by-1 errors. */ | |
| 281 | − if (in->pts != AV_NOPTS_VALUE && in->pts != s->next_in_pts) { | |
| 282 | − out->pts = av_rescale_q(in->pts, inlink->time_base, | |
| 283 | − outlink->time_base) - | |
| 284 | − av_rescale(delay, outlink->sample_rate, | |
| 285 | − inlink->sample_rate); | |
| 286 | − } else | |
| 287 | − out->pts = s->next_pts; | |
| 288 | − | |
| 289 | − s->next_pts = out->pts + out->nb_samples; | |
| 290 | − s->next_in_pts = in->pts + in->nb_samples; | |
| 291 | − } else | |
| 292 | − out->pts = in->pts; | |
| 293 | − | |
| 294 | − ret = ff_filter_frame(outlink, out); | |
| 295 | − s->got_output = 1; | |
| 296 | − } | |
| 297 | − | |
| 298 | −fail: | |
| 299 | − av_frame_free(&in); | |
| 300 | − } else { | |
| 301 | − in->format = outlink->format; | |
| 302 | − ret = ff_filter_frame(outlink, in); | |
| 303 | − s->got_output = 1; | |
| 304 | − } | |
| 305 | − | |
| 306 | − return ret; | |
| 307 | −} | |
| 308 | − | |
| 309 | −#if FF_API_CHILD_CLASS_NEXT | |
| 310 | −static const AVClass *resample_child_class_next(const AVClass *prev) | |
| 311 | −{ | |
| 312 | − return prev ? NULL : avresample_get_class(); | |
| 313 | −} | |
| 314 | −#endif | |
| 315 | − | |
| 316 | −static const AVClass *resample_child_class_iterate(void **iter) | |
| 317 | −{ | |
| 318 | − const AVClass *c = *iter ? NULL : avresample_get_class(); | |
| 319 | − *iter = (void*)(uintptr_t)c; | |
| 320 | − return c; | |
| 321 | −} | |
| 322 | − | |
| 323 | −static void *resample_child_next(void *obj, void *prev) | |
| 324 | −{ | |
| 325 | − ResampleContext *s = obj; | |
| 326 | − return prev ? NULL : s->avr; | |
| 327 | −} | |
| 328 | − | |
| 329 | −static const AVClass resample_class = { | |
| 330 | − .class_name = "resample", | |
| 331 | − .item_name = av_default_item_name, | |
| 332 | − .version = LIBAVUTIL_VERSION_INT, | |
| 333 | −#if FF_API_CHILD_CLASS_NEXT | |
| 334 | − .child_class_next = resample_child_class_next, | |
| 335 | −#endif | |
| 336 | − .child_class_iterate = resample_child_class_iterate, | |
| 337 | − .child_next = resample_child_next, | |
| 338 | −}; | |
| 339 | − | |
| 340 | −static const AVFilterPad avfilter_af_resample_inputs[] = { | |
| 341 | − { | |
| 342 | − .name = "default", | |
| 343 | − .type = AVMEDIA_TYPE_AUDIO, | |
| 344 | − .filter_frame = filter_frame, | |
| 345 | − }, | |
| 346 | − { NULL } | |
| 347 | −}; | |
| 348 | − | |
| 349 | −static const AVFilterPad avfilter_af_resample_outputs[] = { | |
| 350 | − { | |
| 351 | − .name = "default", | |
| 352 | − .type = AVMEDIA_TYPE_AUDIO, | |
| 353 | − .config_props = config_output, | |
| 354 | − .request_frame = request_frame | |
| 355 | − }, | |
| 356 | − { NULL } | |
| 357 | −}; | |
| 358 | − | |
| 359 | −AVFilter ff_af_resample = { | |
| 360 | − .name = "resample", | |
| 361 | − .description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."), | |
| 362 | − .priv_size = sizeof(ResampleContext), | |
| 363 | − .priv_class = &resample_class, | |
| 364 | − .init_dict = init, | |
| 365 | − .uninit = uninit, | |
| 366 | − .query_formats = query_formats, | |
| 367 | − .inputs = avfilter_af_resample_inputs, | |
| 368 | − .outputs = avfilter_af_resample_outputs, | |
| 369 | −}; | |
| @@ -129,7 +129,6 @@ extern AVFilter ff_af_lv2; · 128 unmodified lines | ||
| 129 | 129 | extern AVFilter ff_af_mcompand; |
| 130 | 130 | extern AVFilter ff_af_pan; |
| 131 | 131 | extern AVFilter ff_af_replaygain; |
| 132 | −extern AVFilter ff_af_resample; | |
| 133 | 132 | extern AVFilter ff_af_rubberband; |
| 134 | 133 | extern AVFilter ff_af_sidechaincompress; |
| 135 | 134 | extern AVFilter ff_af_sidechaingate; |