From patchwork Sun Oct 16 23:02:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Faiz X-Patchwork-Id: 1029 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.133 with SMTP id o127csp121409vsd; Sun, 16 Oct 2016 16:17:50 -0700 (PDT) X-Received: by 10.28.149.209 with SMTP id x200mr6907824wmd.123.1476659870764; Sun, 16 Oct 2016 16:17:50 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id wt3si37316846wjb.9.2016.10.16.16.17.50; Sun, 16 Oct 2016 16:17:50 -0700 (PDT) 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 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 31B8D68981C; Mon, 17 Oct 2016 02:17:46 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf0-f193.google.com (mail-pf0-f193.google.com [209.85.192.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E1A656891F5 for ; Mon, 17 Oct 2016 02:17:38 +0300 (EEST) Received: by mail-pf0-f193.google.com with SMTP id s8so11493010pfj.2 for ; Sun, 16 Oct 2016 16:17:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=OsPMxkhQNVIx6joVKLm3v5PLQ8TngeJhUEeizJHkPfU=; b=lYrCEbu0OGScOuVGSE32z+S5wYpE5Hx9YVHxBhoaWLL83Ybt6QVKUlZjlkStOKwbRX NtzUgxscSiOXLNRSjRFfJdJ3uKt19Rq34fzRRsdZqY3gJ9Y2S0vQunUM48O6hFZ4/k9G bTGM2n+GUIqIQLTplz/F1zHZrHKDWS7zCDj8StdHQswQBfzL3qllVqDXS3VI/on3wHCq Agbasdl5NxWoyA0/140ud9lj0tBW3v+1ULWGt1RDrFR1SPeK9PJF7iHRAT3rZBDQxc/y Ffo+50eZ7lVMT4QTy/KcQeQQRA0TpFowazRGMXATYFRg+xzcgMzSJmQIoiCRz2ilLZqf 3zBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=OsPMxkhQNVIx6joVKLm3v5PLQ8TngeJhUEeizJHkPfU=; b=K7At7WngwkDX2yoCmALtxzsnZTFTi0VOHaeFTrENbPg6l/nz1BOJVB5dHZg0B5wsUo 6MHvjPCPfFQiyBOEOJ1DEruQDG+oSgRKjw7YeKsKcy6VS8HmJS/RYZKOXzajlvCVYUQs JlTJE5L72naJ+UXiIk5Xp8E7ZJNpKrPI3lOu6QBVTNqv1PvfV37Fn+mjScE6EqxiVyRC UXuhsummhvv2JUfJtnJmvuS+ltNikx8lpmY6brwLvITWG00xcNl0YZ/BR/liqqHedDRH zT11eKGVpU2o4/s//DMtG2oGkLUF7MAE3kTv0hOLsITkVTJ7QwEu13aFVrF5PpxkQShi IHdA== X-Gm-Message-State: AA6/9RmX+L5RxZPurylq/cOnNllLge6y9sb6lBbhj5NZz9LBGH5g283IWB1shu+8qUIouA== X-Received: by 10.98.22.23 with SMTP id 23mr11093935pfw.65.1476659080885; Sun, 16 Oct 2016 16:04:40 -0700 (PDT) Received: from localhost.localdomain.localdomain ([202.67.46.2]) by smtp.gmail.com with ESMTPSA id e74sm41875914pfk.13.2016.10.16.16.04.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 16 Oct 2016 16:04:40 -0700 (PDT) From: Muhammad Faiz To: ffmpeg-devel@ffmpeg.org Date: Mon, 17 Oct 2016 06:02:41 +0700 Message-Id: <1476658961-26912-1-git-send-email-mfcc64@gmail.com> X-Mailer: git-send-email 2.5.0 Subject: [FFmpeg-devel] [PATCH] avfilter/showcqt: add font option 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: Muhammad Faiz MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" this is fontconfig pattern Signed-off-by: Muhammad Faiz --- doc/filters.texi | 10 ++++++ libavfilter/avf_showcqt.c | 85 +++++++++++++++++++++++++++++++++++++++++++---- libavfilter/avf_showcqt.h | 1 + 3 files changed, 89 insertions(+), 7 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index ad5969b..8fda8a1 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -16870,6 +16870,10 @@ use embedded font. Note that drawing with font file or embedded font is not implemented with custom @var{basefreq} and @var{endfreq}, use @var{axisfile} option instead. +@item font +Specify fontconfig pattern. This has lower priority than @var{fontfile}. +The : in the pattern may be replaced by | to avoid unnecessary escaping. + @item fontcolor Specify font color expression. This is arithmetic expression that should return integer value 0xRRGGBB. It can contain variables: @@ -16993,6 +16997,12 @@ fontcolor='if(mod(floor(midi(f)+0.5),12), 0x0000FF, g(1))':fontfile=myfont.ttf @end example @item +Custom font using fontconfig: +@example +font='Courier New,Monospace,mono|bold' +@end example + +@item Custom frequency range with custom axis using image file: @example axisfile=myaxis.png:basefreq=40:endfreq=10000 diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c index 7c76b1f..37e20b4 100644 --- a/libavfilter/avf_showcqt.c +++ b/libavfilter/avf_showcqt.c @@ -36,6 +36,10 @@ #include FT_FREETYPE_H #endif +#if CONFIG_LIBFONTCONFIG +#include +#endif + #include "avf_showcqt.h" #define BASEFREQ 20.01523126408007475 @@ -78,7 +82,8 @@ static const AVOption showcqt_options[] = { { "tlength", "set tlength", OFFSET(tlength), AV_OPT_TYPE_STRING, { .str = TLENGTH }, CHAR_MIN, CHAR_MAX, FLAGS }, { "count", "set transform count", OFFSET(count), AV_OPT_TYPE_INT, { .i64 = 6 }, 1, 30, FLAGS }, { "fcount", "set frequency count", OFFSET(fcount), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 10, FLAGS }, - { "fontfile", "set axis font", OFFSET(fontfile), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, FLAGS }, + { "fontfile", "set axis font file", OFFSET(fontfile), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, FLAGS }, + { "font", "set axis font", OFFSET(font), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, FLAGS }, { "fontcolor", "set font color", OFFSET(fontcolor), AV_OPT_TYPE_STRING, { .str = FONTCOLOR }, CHAR_MIN, CHAR_MAX, FLAGS }, { "axisfile", "set axis image", OFFSET(axisfile), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, FLAGS }, { "axis", "draw axis", OFFSET(axis), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, @@ -492,7 +497,7 @@ static int init_axis_color(ShowCQTContext *s, AVFrame *tmp, int half) return 0; } -static int render_freetype(ShowCQTContext *s, AVFrame *tmp) +static int render_freetype(ShowCQTContext *s, AVFrame *tmp, char *fontfile) { #if CONFIG_LIBFREETYPE const char *str = "EF G A BC D "; @@ -506,13 +511,13 @@ static int render_freetype(ShowCQTContext *s, AVFrame *tmp) int non_monospace_warning = 0; int x; - if (!s->fontfile) + if (!fontfile) return AVERROR(EINVAL); if (FT_Init_FreeType(&lib)) goto fail; - if (FT_New_Face(lib, s->fontfile, 0, &face)) + if (FT_New_Face(lib, fontfile, 0, &face)) goto fail; if (FT_Set_Char_Size(face, 16*64, 0, 0, 0)) @@ -565,17 +570,81 @@ static int render_freetype(ShowCQTContext *s, AVFrame *tmp) return 0; fail: - av_log(s->ctx, AV_LOG_WARNING, "error while loading freetype font, using default font instead.\n"); + av_log(s->ctx, AV_LOG_WARNING, "error while loading freetype font.\n"); FT_Done_Face(face); FT_Done_FreeType(lib); return AVERROR(EINVAL); #else - if (s->fontfile) + if (fontfile) av_log(s->ctx, AV_LOG_WARNING, "freetype is not available, ignoring fontfile option.\n"); return AVERROR(EINVAL); #endif } +static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char* font) +{ +#if CONFIG_LIBFONTCONFIG + FcConfig *fontconfig; + FcPattern *pat, *best; + FcResult result = FcResultMatch; + char *filename; + int i, ret; + + if (!font) + return AVERROR(EINVAL); + + for (i = 0; font[i]; i++) { + if (font[i] == '|') + font[i] = ':'; + } + + if (!(fontconfig = FcInitLoadConfigAndFonts())) { + av_log(s->ctx, AV_LOG_ERROR, "impossible to init fontconfig.\n"); + return AVERROR_UNKNOWN; + } + + if (!(pat = FcNameParse((uint8_t *)font))) { + av_log(s->ctx, AV_LOG_ERROR, "could not parse fontconfig pat.\n"); + FcConfigDestroy(fontconfig); + return AVERROR(EINVAL); + } + + FcDefaultSubstitute(pat); + + if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) { + av_log(s->ctx, AV_LOG_ERROR, "could not substitue fontconfig options.\n"); + FcPatternDestroy(pat); + FcConfigDestroy(fontconfig); + return AVERROR(ENOMEM); + } + + best = FcFontMatch(fontconfig, pat, &result); + FcPatternDestroy(pat); + + ret = AVERROR(EINVAL); + if (!best || result != FcResultMatch) { + av_log(s->ctx, AV_LOG_ERROR, "cannot find a valid font for %s.\n", font); + goto fail; + } + + if (FcPatternGetString(best, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch) { + av_log(s->ctx, AV_LOG_ERROR, "no file path for %s\n", font); + goto fail; + } + + ret = render_freetype(s, tmp, filename); + +fail: + FcPatternDestroy(best); + FcConfigDestroy(fontconfig); + return ret; +#else + if (font) + av_log(s->ctx, AV_LOG_WARNING, "fontconfig is not available, ignoring font option.\n"); + return AVERROR(EINVAL); +#endif +} + static int render_default_font(AVFrame *tmp) { const char *str = "EF G A BC D "; @@ -615,7 +684,9 @@ static int init_axis_from_font(ShowCQTContext *s) if (!(s->axis_frame = av_frame_alloc())) goto fail; - if (render_freetype(s, tmp) < 0 && (default_font = 1, ret = render_default_font(tmp)) < 0) + if (render_freetype(s, tmp, s->fontfile) < 0 && + render_fontconfig(s, tmp, s->font) < 0 && + (default_font = 1, ret = render_default_font(tmp)) < 0) goto fail; if (default_font) diff --git a/libavfilter/avf_showcqt.h b/libavfilter/avf_showcqt.h index 71e9d13..d0bacaf 100644 --- a/libavfilter/avf_showcqt.h +++ b/libavfilter/avf_showcqt.h @@ -109,6 +109,7 @@ typedef struct { int count; int fcount; char *fontfile; + char *font; char *fontcolor; char *axisfile; int axis;