From patchwork Mon Mar 6 02:46:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rostislav Pehlivanov X-Patchwork-Id: 2761 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.31.14 with SMTP id f14csp1220070vsf; Sun, 5 Mar 2017 18:55:07 -0800 (PST) X-Received: by 10.223.135.153 with SMTP id b25mr12224833wrb.169.1488768907867; Sun, 05 Mar 2017 18:55:07 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j2si24643460wra.66.2017.03.05.18.55.07; Sun, 05 Mar 2017 18:55:07 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EF6D4688275; Mon, 6 Mar 2017 04:54:52 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6406D6804C0 for ; Mon, 6 Mar 2017 04:54:46 +0200 (EET) Received: by mail-wm0-f68.google.com with SMTP id z63so9372191wmg.2 for ; Sun, 05 Mar 2017 18:54:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iL2IdCpB5IakjPCzchW6XzjGZxHiwVo9bopx639jCZ4=; b=tzPWV3T/Aht+q7ybyxXEkkt6fYfVieExOP1u3TkWlBAnBVHI4Khr61lRcFOUeui0lH TeFMtDbyFeG7X3bKvN6Mfax3TKukkk1XekaPTel/UktixgPgt56/jkjSA0XmYaDMugNa xdiI0TqmE+hlxzYVJOmpJuMZ/BVdlAyP6riVT9eFIYq+RY/vfQuee3buiIYRmjNo4Js2 Nn2rreCAWjlO5HfdXl/6BXFZNTNGFb/ztD57Ux5gzxEaUQPv0Zq+DyAq2dk+xoJcdq4w kQF0O9mA4UHHoV14qTzvbL/5taxmRoHKHm4HGO69rHInec7+Od2VcIdxzheFAcDFxwdy rvew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iL2IdCpB5IakjPCzchW6XzjGZxHiwVo9bopx639jCZ4=; b=bLLmTko1QzD3SJu/8HbCRO1Id8faxpBz24y4ChA7+E9UDMSJU5FhlGIEPQHYiR79nx fgcadswHLdd3LDj2sNsR+VHIdsCmRQOP7Cn7gNK1OAmGq6ABTwthxsEbo8B33w4t3dzH pOwNaxwdk4osZBqP/2tJqOc69V9eqS/axYnxmlVWB9GpRcntbfd4mKmgDrrT2CDIgd+d rX0hNJQXU64DfI5bYFfIBVivr2WNiZuIs9+oN4HTNgaAMYunp+ziP2669MBrMEBsgTJL Fv7qbgsIIiQKSd1cEXgkeW/DG9pGsYVGVGcyZrZcgpwVVJfYKhXNyLxbPYhKezVNPFLH NgyA== X-Gm-Message-State: AMke39loEGzTeb+pIl4pOb44Nm4YecnwVTaWQfjdngIETz5jlNb4Nb5YBODPjsTwzseyLg== X-Received: by 10.28.139.134 with SMTP id n128mr667589wmd.132.1488768417933; Sun, 05 Mar 2017 18:46:57 -0800 (PST) Received: from moonbase.lan (host86-146-196-130.range86-146.btcentralplus.com. [86.146.196.130]) by smtp.gmail.com with ESMTPSA id c58sm25150104wrc.9.2017.03.05.18.46.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 Mar 2017 18:46:57 -0800 (PST) From: Rostislav Pehlivanov To: ffmpeg-devel@ffmpeg.org Date: Mon, 6 Mar 2017 02:46:51 +0000 Message-Id: <20170306024651.66336-4-atomnuker@gmail.com> X-Mailer: git-send-email 2.12.0.rc1.440.g5b76565f74 In-Reply-To: <20170306024651.66336-1-atomnuker@gmail.com> References: <20170306024651.66336-1-atomnuker@gmail.com> Subject: [FFmpeg-devel] [PATCH 4/4] lavfi: remove af_asynts filter X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Rostislav Pehlivanov MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Long overdue for removal, af_aresample should be used instead. Signed-off-by: Rostislav Pehlivanov --- Changelog | 1 + configure | 2 - doc/filters.texi | 33 ----- libavfilter/Makefile | 1 - libavfilter/af_asyncts.c | 323 -------------------------------------------- libavfilter/allfilters.c | 1 - libavfilter/version.h | 2 +- tests/fate/filter-audio.mak | 6 - 8 files changed, 2 insertions(+), 367 deletions(-) delete mode 100644 libavfilter/af_asyncts.c diff --git a/Changelog b/Changelog index 13628ca28b..88e188bacb 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : +- Removed asyncts filter (use af_aresample instead) - CrystalHD decoder moved to new decode API - add internal ebur128 library, remove external libebur128 dependency - Pro-MPEG CoP #3-R2 FEC protocol diff --git a/configure b/configure index 0199fec5c0..a307ed81b6 100755 --- a/configure +++ b/configure @@ -3074,7 +3074,6 @@ afftfilt_filter_select="fft" amovie_filter_deps="avcodec avformat" aresample_filter_deps="swresample" ass_filter_deps="libass" -asyncts_filter_deps="avresample" atempo_filter_deps="avcodec" atempo_filter_select="rdft" azmq_filter_deps="libzmq" @@ -6460,7 +6459,6 @@ enabled zlib && add_cppflags -DZLIB_CONST enabled afftfilt_filter && prepend avfilter_deps "avcodec" enabled amovie_filter && prepend avfilter_deps "avformat avcodec" enabled aresample_filter && prepend avfilter_deps "swresample" -enabled asyncts_filter && prepend avfilter_deps "avresample" enabled atempo_filter && prepend avfilter_deps "avcodec" enabled cover_rect_filter && prepend avfilter_deps "avformat avcodec" enabled ebur128_filter && enabled swresample && prepend avfilter_deps "swresample" diff --git a/doc/filters.texi b/doc/filters.texi index b5265d9297..da20a7e7e3 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1642,39 +1642,6 @@ Number of occasions (not the number of samples) that the signal attained either Overall bit depth of audio. Number of bits used for each sample. @end table -@section asyncts - -Synchronize audio data with timestamps by squeezing/stretching it and/or -dropping samples/adding silence when needed. - -This filter is not built by default, please use @ref{aresample} to do squeezing/stretching. - -It accepts the following parameters: -@table @option - -@item compensate -Enable stretching/squeezing the data to make it match the timestamps. Disabled -by default. When disabled, time gaps are covered with silence. - -@item min_delta -The minimum difference between timestamps and audio data (in seconds) to trigger -adding/dropping samples. The default value is 0.1. If you get an imperfect -sync with this filter, try setting this parameter to 0. - -@item max_comp -The maximum compensation in samples per second. Only relevant with compensate=1. -The default value is 500. - -@item first_pts -Assume that the first PTS should be this value. The time base is 1 / sample -rate. This allows for padding/trimming at the start of the stream. By default, -no assumption is made about the first frame's expected PTS, so no padding or -trimming is done. For example, this could be set to 0 to pad the beginning with -silence if an audio stream starts after the video stream or to trim any samples -with a negative PTS due to encoder delay. - -@end table - @section atempo Adjust audio tempo. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 6b9fba2d4c..d3641370de 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -67,7 +67,6 @@ OBJS-$(CONFIG_ASIDEDATA_FILTER) += f_sidedata.o OBJS-$(CONFIG_ASPLIT_FILTER) += split.o OBJS-$(CONFIG_ASTATS_FILTER) += af_astats.o OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o -OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o OBJS-$(CONFIG_ATRIM_FILTER) += trim.o OBJS-$(CONFIG_AZMQ_FILTER) += f_zmq.o diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c deleted file mode 100644 index a33e0dd67e..0000000000 --- a/libavfilter/af_asyncts.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavresample/avresample.h" -#include "libavutil/attributes.h" -#include "libavutil/audio_fifo.h" -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct ASyncContext { - const AVClass *class; - - AVAudioResampleContext *avr; - int64_t pts; ///< timestamp in samples of the first sample in fifo - int min_delta; ///< pad/trim min threshold in samples - int first_frame; ///< 1 until filter_frame() has processed at least 1 frame with a pts != AV_NOPTS_VALUE - int64_t first_pts; ///< user-specified first expected pts, in samples - int comp; ///< current resample compensation - - /* options */ - int resample; - float min_delta_sec; - int max_comp; - - /* set by filter_frame() to signal an output frame to request_frame() */ - int got_output; -} ASyncContext; - -#define OFFSET(x) offsetof(ASyncContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption asyncts_options[] = { - { "compensate", "Stretch/squeeze the data to make it match the timestamps", OFFSET(resample), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, A|F }, - { "min_delta", "Minimum difference between timestamps and audio data " - "(in seconds) to trigger padding/trimmin the data.", OFFSET(min_delta_sec), AV_OPT_TYPE_FLOAT, { .dbl = 0.1 }, 0, INT_MAX, A|F }, - { "max_comp", "Maximum compensation in samples per second.", OFFSET(max_comp), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, A|F }, - { "first_pts", "Assume the first pts should be this value.", OFFSET(first_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(asyncts); - -static av_cold int init(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - s->pts = AV_NOPTS_VALUE; - s->first_frame = 1; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - if (s->avr) { - avresample_close(s->avr); - avresample_free(&s->avr); - } -} - -static int config_props(AVFilterLink *link) -{ - ASyncContext *s = link->src->priv; - int ret; - - s->min_delta = s->min_delta_sec * link->sample_rate; - link->time_base = (AVRational){1, link->sample_rate}; - - s->avr = avresample_alloc_context(); - if (!s->avr) - return AVERROR(ENOMEM); - - av_opt_set_int(s->avr, "in_channel_layout", link->channel_layout, 0); - av_opt_set_int(s->avr, "out_channel_layout", link->channel_layout, 0); - av_opt_set_int(s->avr, "in_sample_fmt", link->format, 0); - av_opt_set_int(s->avr, "out_sample_fmt", link->format, 0); - av_opt_set_int(s->avr, "in_sample_rate", link->sample_rate, 0); - av_opt_set_int(s->avr, "out_sample_rate", link->sample_rate, 0); - - if (s->resample) - av_opt_set_int(s->avr, "force_resampling", 1, 0); - - if ((ret = avresample_open(s->avr)) < 0) - return ret; - - return 0; -} - -/* get amount of data currently buffered, in samples */ -static int64_t get_delay(ASyncContext *s) -{ - return avresample_available(s->avr) + avresample_get_delay(s->avr); -} - -static void handle_trimming(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - if (s->pts < s->first_pts) { - int delta = FFMIN(s->first_pts - s->pts, avresample_available(s->avr)); - av_log(ctx, AV_LOG_VERBOSE, "Trimming %d samples from start\n", - delta); - avresample_read(s->avr, NULL, delta); - s->pts += delta; - } else if (s->first_frame) - s->pts = s->first_pts; -} - -static int request_frame(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - ASyncContext *s = ctx->priv; - int ret = 0; - int nb_samples; - - s->got_output = 0; - ret = ff_request_frame(ctx->inputs[0]); - - /* flush the fifo */ - if (ret == AVERROR_EOF) { - if (s->first_pts != AV_NOPTS_VALUE) - handle_trimming(ctx); - - if (nb_samples = get_delay(s)) { - AVFrame *buf = ff_get_audio_buffer(link, nb_samples); - if (!buf) - return AVERROR(ENOMEM); - ret = avresample_convert(s->avr, buf->extended_data, - buf->linesize[0], nb_samples, NULL, 0, 0); - if (ret <= 0) { - av_frame_free(&buf); - return (ret < 0) ? ret : AVERROR_EOF; - } - - buf->pts = s->pts; - return ff_filter_frame(link, buf); - } - } - - return ret; -} - -static int write_to_fifo(ASyncContext *s, AVFrame *buf) -{ - int ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); - av_frame_free(&buf); - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - ASyncContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int nb_channels = av_get_channel_layout_nb_channels(buf->channel_layout); - int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts : - av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); - int out_size, ret; - int64_t delta; - int64_t new_pts; - - /* buffer data until we get the next timestamp */ - if (s->pts == AV_NOPTS_VALUE || pts == AV_NOPTS_VALUE) { - if (pts != AV_NOPTS_VALUE) { - s->pts = pts - get_delay(s); - } - return write_to_fifo(s, buf); - } - - if (s->first_pts != AV_NOPTS_VALUE) { - handle_trimming(ctx); - if (!avresample_available(s->avr)) - return write_to_fifo(s, buf); - } - - /* when we have two timestamps, compute how many samples would we have - * to add/remove to get proper sync between data and timestamps */ - delta = pts - s->pts - get_delay(s); - out_size = avresample_available(s->avr); - - if (llabs(delta) > s->min_delta || - (s->first_frame && delta && s->first_pts != AV_NOPTS_VALUE)) { - av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta); - out_size = av_clipl_int32((int64_t)out_size + delta); - } else { - if (s->resample) { - // adjust the compensation if delta is non-zero - int delay = get_delay(s); - int comp = s->comp + av_clip(delta * inlink->sample_rate / delay, - -s->max_comp, s->max_comp); - if (comp != s->comp) { - av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp); - if (avresample_set_compensation(s->avr, comp, inlink->sample_rate) == 0) { - s->comp = comp; - } - } - } - // adjust PTS to avoid monotonicity errors with input PTS jitter - pts -= delta; - delta = 0; - } - - if (out_size > 0) { - AVFrame *buf_out = ff_get_audio_buffer(outlink, out_size); - if (!buf_out) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if (s->first_frame && delta > 0) { - int planar = av_sample_fmt_is_planar(buf_out->format); - int planes = planar ? nb_channels : 1; - int block_size = av_get_bytes_per_sample(buf_out->format) * - (planar ? 1 : nb_channels); - - int ch; - - av_samples_set_silence(buf_out->extended_data, 0, delta, - nb_channels, buf->format); - - for (ch = 0; ch < planes; ch++) - buf_out->extended_data[ch] += delta * block_size; - - avresample_read(s->avr, buf_out->extended_data, out_size); - - for (ch = 0; ch < planes; ch++) - buf_out->extended_data[ch] -= delta * block_size; - } else { - avresample_read(s->avr, buf_out->extended_data, out_size); - - if (delta > 0) { - av_samples_set_silence(buf_out->extended_data, out_size - delta, - delta, nb_channels, buf->format); - } - } - buf_out->pts = s->pts; - ret = ff_filter_frame(outlink, buf_out); - if (ret < 0) - goto fail; - s->got_output = 1; - } else if (avresample_available(s->avr)) { - av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " - "whole buffer.\n"); - } - - /* drain any remaining buffered data */ - avresample_read(s->avr, NULL, avresample_available(s->avr)); - - new_pts = pts - avresample_get_delay(s->avr); - /* check for s->pts monotonicity */ - if (new_pts > s->pts) { - s->pts = new_pts; - ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); - } else { - av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " - "whole buffer.\n"); - ret = 0; - } - - s->first_frame = 0; -fail: - av_frame_free(&buf); - - return ret; -} - -static const AVFilterPad avfilter_af_asyncts_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_asyncts_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_props, - .request_frame = request_frame - }, - { NULL } -}; - -AVFilter ff_af_asyncts = { - .name = "asyncts", - .description = NULL_IF_CONFIG_SMALL("Sync audio data to timestamps."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(ASyncContext), - .priv_class = &asyncts_class, - .query_formats = ff_query_formats_all_layouts, - .inputs = avfilter_af_asyncts_inputs, - .outputs = avfilter_af_asyncts_outputs, -}; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 15a74c4eed..21830fb420 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -84,7 +84,6 @@ void avfilter_register_all(void) REGISTER_FILTER(ASPLIT, asplit, af); REGISTER_FILTER(ASTATS, astats, af); REGISTER_FILTER(ASTREAMSELECT, astreamselect, af); - REGISTER_FILTER(ASYNCTS, asyncts, af); REGISTER_FILTER(ATEMPO, atempo, af); REGISTER_FILTER(ATRIM, atrim, af); REGISTER_FILTER(AZMQ, azmq, af); diff --git a/libavfilter/version.h b/libavfilter/version.h index 3cd6e24b27..4be7abb653 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #define LIBAVFILTER_VERSION_MAJOR 6 #define LIBAVFILTER_VERSION_MINOR 75 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak index 6de3c46b0e..2b8ac98562 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -187,12 +187,6 @@ $(FATE_AMIX): SRC1 = $(TARGET_PATH)/tests/data/asynth-44100-2-2.wav $(FATE_AMIX): CMP = oneoff $(FATE_AMIX): CMP_UNIT = f32 -FATE_AFILTER_SAMPLES-$(call FILTERDEMDECMUX, ASYNCTS, FLV, NELLYMOSER, PCM_S16LE) += fate-filter-asyncts -fate-filter-asyncts: SRC = $(TARGET_SAMPLES)/nellymoser/nellymoser-discont.flv -fate-filter-asyncts: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af asyncts -fate-filter-asyncts: CMP = oneoff -fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont-async-v3.pcm - FATE_AFILTER_SAMPLES-$(CONFIG_ARESAMPLE_FILTER) += fate-filter-aresample fate-filter-aresample: SRC = $(TARGET_SAMPLES)/nellymoser/nellymoser-discont.flv fate-filter-aresample: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af aresample=min_comp=0.001:min_hard_comp=0.1:first_pts=0