From patchwork Thu Mar 9 09:34:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takayuki 'January June' Suwa X-Patchwork-Id: 2852 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.50.79 with SMTP id y76csp247273vsy; Thu, 9 Mar 2017 01:34:40 -0800 (PST) X-Received: by 10.223.149.66 with SMTP id 60mr9371935wrs.29.1489052080753; Thu, 09 Mar 2017 01:34:40 -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 l2si7976935wrb.253.2017.03.09.01.34.39; Thu, 09 Mar 2017 01:34:40 -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 9CC30688332; Thu, 9 Mar 2017 11:34:23 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg0-f41.google.com (mail-pg0-f41.google.com [74.125.83.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B2C2668830D for ; Thu, 9 Mar 2017 11:34:16 +0200 (EET) Received: by mail-pg0-f41.google.com with SMTP id b129so24519930pgc.2 for ; Thu, 09 Mar 2017 01:34:30 -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; bh=TAMzudiB8ChBzeVv5E9YPXLWNea6vPaJ0Ff5+JHzoCg=; b=qeYNrC+eW8JCc+CXK12J7uX97pZlVD6nfZaIJOelgCJ17WpHOekdaBoYhOzHFu65TL mgaXx1rgWYlvjInA1gmVv3nqrrXMJBV0xOEWMXAK9SNdqHH1NMLw72LElsN784a/5ty/ 2EEHY8MQDdgAlA6OcwoFMkP8KFNG+tX/51YC64Foe433Zg9oXbsshcqPPdr8/G2zqPaT mzbl/jZ5NprmqWHrSPMEfcmdoKyDFO00XJyjle/mXXQLexpykntHsEXyxUX484tpGmRd +ChqGT2eokhdys9P6hsVAry0HWcqH0RxC5Hox/OkQWsDcpP2tnwX9UR+sYR0lmwKBDzv pxoA== 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; bh=TAMzudiB8ChBzeVv5E9YPXLWNea6vPaJ0Ff5+JHzoCg=; b=Ke18Xh0XRb8141U4LrdRL/iclIoTVS5KQWtsrnNhonGuyJvt2AsIwki3k95kDSkCOj CqdrAyrZ40PL1n6BnVFZyId2JLbXca+4yhtW5sNiAuDmFvoyMebBISRUNArWFzUgiI/S XBSwLObeT1RxvACQrwBXEHS0F2/UIsxUMCIYrrVCKxfl90/7hYjcwm83lDzEVejy4KzY 3R2wXOYbOkvHgELZfFtLaugaSe2rZh6DZ+wQBgpCcMOAuTim5F1HtjYE2X6A2c3iwl1R JHFjlStNYiVk/+3WUtd8aKReh2wkJRPa+vXfOA10lmG6qRBcrN32r7QXj/NO5jE00wrF i5og== X-Gm-Message-State: AMke39n0dh8RHcEIXc7YGXzk5ujTd2bOa7+RFpbfy/Wp4O5dbw/5nx7roBYSeMtjcpkWMQ== X-Received: by 10.84.198.164 with SMTP id p33mr15915002pld.127.1489052069098; Thu, 09 Mar 2017 01:34:29 -0800 (PST) Received: from localhost.localdomain (h175-177-005-137.catv02.itscom.jp. [175.177.5.137]) by smtp.gmail.com with ESMTPSA id d68sm11133955pfj.92.2017.03.09.01.34.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Mar 2017 01:34:28 -0800 (PST) From: Takayuki 'January June' Suwa To: ffmpeg-devel@ffmpeg.org Date: Thu, 9 Mar 2017 18:34:23 +0900 Message-Id: <1489052063-24497-1-git-send-email-jjsuwa.sys3175@gmail.com> X-Mailer: git-send-email 2.1.4 Subject: [FFmpeg-devel] [PATCH] avfilter: support for output samplerate fallbacking 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: Takayuki 'January June' Suwa MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Thank you for reviewing @ #2781. > I do not think this option should be global. I agree that public global options should not be added (or removed :) w/o discussion. > Possibly, the good solution may be to extend the "sws_flags=" feature > to allow to set more graph options from the graph description. There are some reasons why I chose to add new ones to the AVFilter context but not to extend the "swr_flags=", 1. The function swap_samplerates_on_filter() in avfiltergraph.c receives a pointer to AVFilterContext 2. Less elegant to pack a single value of the existing option with additional bit-chunks But prepending of explicit aresample will be required because of auto-inserted one cannot be received the info. -af "aresample=osr_fallback_method=highest,aformat=sample_rates=..." > I would rather not have the numeric values of the option exposed to the > user, only symbolic constants. > Re-aligning other lines is normally done in a separate patch, if ever. > I think this shoulw be "case 0" (except see below) and default should > trigger an assert failure. > Magic constants like that are not good design, they need to be expressed > by an enum. > Jumping from one case clause to another does not look like an acceptable > use of goto in readable code. Worth obeying :) Finally, it's obvious "osr_fallback_method" is lengthy and ugly :( Please suggest more concise and plain alternatives. --- libavfilter/avfilter.c | 6 ++++++ libavfilter/avfilter.h | 11 +++++++++++ libavfilter/avfiltergraph.c | 27 ++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index b431990..0d467ec 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -665,6 +665,12 @@ static const AVOption avfilter_options[] = { { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, { "threads", "Allowed number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, + { "osr_fallback_method", "Output sample rate fallback method when no exact match found", OFFSET(osr_fallback_method), AV_OPT_TYPE_INT, + { .i64 = AVOSRFB_CLOSEST }, AVOSRFB_CLOSEST, AVOSRFB_HIGHEST, FLAGS, "osr_fallback_method" }, + { "closest", "to the closest one, regardless of higher or lower", 0, AV_OPT_TYPE_CONST, { .i64 = AVOSRFB_CLOSEST }, 0, 0, FLAGS, "osr_fallback_method" }, + { "higher", "to the closest higher one", 0, AV_OPT_TYPE_CONST, { .i64 = AVOSRFB_HIGHER }, 0, 0, FLAGS, "osr_fallback_method" }, + { "twice_higher", "to the closest twice higher one", 0, AV_OPT_TYPE_CONST, { .i64 = AVOSRFB_TWICE_HIGHER }, 0, 0, FLAGS, "osr_fallback_method" }, + { "highest", "to the highest one", 0, AV_OPT_TYPE_CONST, { .i64 = AVOSRFB_HIGHEST }, 0, 0, FLAGS, "osr_fallback_method" }, { NULL }, }; diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index b56615c..3eb455f 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -384,6 +384,17 @@ struct AVFilterContext { int nb_threads; /** + * Output sample rate fallback method when no exact match found in the next + * filter's available input sample rates. + */ + enum { + AVOSRFB_CLOSEST = 0, ///< to the closest one, regardless of higher or lower + AVOSRFB_HIGHER, ///< to the closest higher one + AVOSRFB_TWICE_HIGHER, ///< to the closest twice higher one + AVOSRFB_HIGHEST, ///< to the highest one + } osr_fallback_method; + + /** * Ready status of the filter. * A non-0 value means that the filter needs activating; * a higher value suggests a more urgent activation. diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 534c670..0f193ec 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -874,7 +874,32 @@ static void swap_samplerates_on_filter(AVFilterContext *filter) continue; for (j = 0; j < outlink->in_samplerates->nb_formats; j++) { - int diff = abs(sample_rate - outlink->in_samplerates->formats[j]); + int diff; + switch(filter->osr_fallback_method) { + case AVOSRFB_CLOSEST: + diff = abs(sample_rate - outlink->in_samplerates->formats[j]); + break; + case AVOSRFB_HIGHER: + if ((diff = outlink->in_samplerates->formats[j] - sample_rate) >= 0) + break; + diff = INT_MAX - outlink->in_samplerates->formats[j]; + break; + case AVOSRFB_TWICE_HIGHER: + if ((diff = outlink->in_samplerates->formats[j] - sample_rate) == 0) + break; + if ((diff = outlink->in_samplerates->formats[j] - sample_rate * 2) >= 0) + break; + diff = INT_MAX - outlink->in_samplerates->formats[j]; + break; + case AVOSRFB_HIGHEST: + if ((diff = outlink->in_samplerates->formats[j] - sample_rate) == 0) + break; + diff = INT_MAX - outlink->in_samplerates->formats[j]; + break; + default: + av_assert0(0); // enum out of range + break; + } av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates