From patchwork Sun May 20 18:53:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Holljes X-Patchwork-Id: 9029 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:155:0:0:0:0:0 with SMTP id c82-v6csp7570436jad; Sun, 20 May 2018 12:01:48 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrIIov2GshflkmypRSW9/r8BrLCJaJqHhuM4X0FqiDly8pwBK/P1i1qwdZBfjm3SvrNP79+ X-Received: by 2002:a1c:b54c:: with SMTP id e73-v6mr8245987wmf.121.1526842908100; Sun, 20 May 2018 12:01:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526842908; cv=none; d=google.com; s=arc-20160816; b=1LDZsnq9LV+noHk2Aj9652/E4bn2y9FDsJXNefipVEceMe3/pdC2Zp58x1yW8s3C9+ S7jerN3lqxLspW0KJIZSmbu+YzAE7sdxwJr6bW8jSEaqk0Q9cPEQzB3OVUCHNw3YHC74 OeZRQ2mooGcZPEH6I3AECY7WLRoHqDoy9379qizjf4aVfrx5KwutjS35MnY49BaxEQCj YMy2XIBAKoajvMWzx9STvly3V/up6eqXRfrcj8EGKPUSmITZ/QD3zgwPGmxq8xp0kymF k2ZrTffaMQqguxdUturpDr12iQe362YH3BJqMtH2vKjHNxB7a+wXIKbQ59Vx43W3lN3U OyNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=i6ZNBWhbboxQAikDS3eqQlPgvYX7dfWd1YqnGR/Ib04=; b=xHeFz2rPB9R0JyQMRdu8YcYsUtuDAozabnSru0Uvo16i0X29vUzzcrl3jhGo5uSFcc qk3bSqGWjFIr+Uv/ULBGpFgREESP/1y0nK2oqdtahbTJ7c+JJ2TMKKax4esIsYb9Mp1R jH3qYNLS5QAQwmnNIhYqcoajWinGDOWED4VmS0g3uXkdncqrvhulwAVXuMpMSpgaX554 mrFJdlquizZjq+8kaNDGq41PUgR/i66ml0t/t+DecAeY+9kK0ERcYFpaD8nGq1BmxQ8r 60GfybJSSIp7Pv3nMFhWFv9164gDMK160SCJyoh8TFZ1I2B5SrmV41iRz33BIaW3EvVy lC7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@googlemail.com header.s=20161025 header.b=LwJ59Vsk; 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=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id z23-v6si4297165wma.81.2018.05.20.12.01.47; Sun, 20 May 2018 12:01:48 -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=@googlemail.com header.s=20161025 header.b=LwJ59Vsk; 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=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3F06068A571; Sun, 20 May 2018 22:01:06 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 876B068A510 for ; Sun, 20 May 2018 22:00:59 +0300 (EEST) Received: by mail-wr0-f194.google.com with SMTP id w18-v6so10139096wrn.6 for ; Sun, 20 May 2018 12:01:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UcEXVYIFkrqq2Iy7uK5r7GJZ82gcsZG1djfeT4OfoJk=; b=LwJ59Vsk2ldjtnZ31QpG4NfpM5t8tINauRK0q+++d3UiFoj2SaM2snjdqRoKdoQ1V2 lw/dH5JDnZaD7+WfmqMx4/tLKNK6iv+Fq/UQQHsurdTDdnI2/VWrSCtSITPm2TzFLjrZ P/lx+fIpOTrS5gBjsnXkFhD/xbYPidurr1hR6A5eaXr56vqyKAXgX3le32cR2tN/9/DD tsvW5mY8aAP2hDxDsnR0jJ0oHoJVFdmRx0MLp0VcYpP60SIIXB3q96Vojsk4eaF+LMNT zWd0wArDxN64YtU78I5tCxstBEEmp+U7BOjk898sh3J/6aLmpCE4YSIwgo3e44zdAYax RvXA== 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=UcEXVYIFkrqq2Iy7uK5r7GJZ82gcsZG1djfeT4OfoJk=; b=Tp+BC8FZDKvrFflKeve8TuNsYuevmhViYj+UtwirMqZ4miGiQcLFkMMYe4PvF7X0L+ 4MK86tOip1sK/oUV2l9e878cL800uf2W+9sJG4HP3mrH6PLRj/dKKqMuc+CBFg2ESyyV xmPLwFvkR7CZz5S1gano+/wirOXT3mRqw3SSrFdsx7QfOXUh8xLlsWTXBBQ8dohZl5PH Rtil+/0BgIwOvQvciz3Xj3oJU1gDPyAUqFXpAKmxTYrsxjhvCq+ufCvvPUQnQPPu5Fv9 92CDjStkygWQuwfjCJVtqHg9Jzn4LiG3lAnDnYPMZ5+ph3YBdtkpIpR4dfIMrRrFpJsE ODmw== X-Gm-Message-State: ALKqPwdHYjlnLFwPfZy4x3uFqwBktd4HRFAR3J3ozhCoVduaDs2xfgZc QjA6ikVSlg6WlhZRWEwStIX40Q== X-Received: by 2002:adf:adf0:: with SMTP id w103-v6mr14376268wrc.101.1526842453954; Sun, 20 May 2018 11:54:13 -0700 (PDT) Received: from localhost.localdomain ([46.5.2.0]) by smtp.gmail.com with ESMTPSA id u8-v6sm3755918wmc.40.2018.05.20.11.54.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 May 2018 11:54:13 -0700 (PDT) From: Stephan Holljes To: ffmpeg-devel@ffmpeg.org Date: Sun, 20 May 2018 20:53:58 +0200 Message-Id: <20180520185404.29836-3-klaxa1337@googlemail.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180520185404.29836-1-klaxa1337@googlemail.com> References: <20180520185404.29836-1-klaxa1337@googlemail.com> Subject: [FFmpeg-devel] [PATCH 2/8] ffserver: Implement lua config file reader 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: Stephan Holljes MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Stephan Holljes --- configreader.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configreader.h | 46 +++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 configreader.c create mode 100644 configreader.h diff --git a/configreader.c b/configreader.c new file mode 100644 index 0000000..84b27fa --- /dev/null +++ b/configreader.c @@ -0,0 +1,211 @@ +/* + * 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 "configreader.h" +#include "httpd.h" +#include +#include +#include +#include +#include + +#include + +const char *stream_format_names[] = { "mkv" }; + +void stream_free(struct StreamConfig *stream) +{ + if (stream->stream_name) + av_free(stream->stream_name); + if (stream->input_uri) + av_free(stream->input_uri); + if (stream->formats) + av_free(stream->formats); +} + +void config_free(struct HTTPDConfig *config) +{ + int i; + if (config->server_name) + av_free(config->server_name); + if (config->bind_address) + av_free(config->bind_address); + if (config->streams) { + for (i = 0; i < config->nb_streams; i++) + stream_free(&config->streams[i]); + av_free(config->streams); + } +} + +void config_dump(struct HTTPDConfig *config) { + int i, j; + printf("======\nserver name: %s\nbind_address: %s\nport: %d\nnb_streams: %d\n", + config->server_name, config->bind_address, config->port, config->nb_streams); + for (i = 0; i < config->nb_streams; i++) { + printf("------\nstream_name: %s\ninput: %s\nformats: ", + config->streams[i].stream_name, config->streams[i].input_uri); + for (j = 0; j < config->streams[i].nb_formats; j++) { + printf("%s ", stream_format_names[config->streams[i].formats[j]]); + } + printf("\n"); + } +} + +int configs_read(struct HTTPDConfig **configs, const char *filename) +{ + int ret = 0; + int nb_configs = 0; + int nb_streams = 0; + int nb_formats = 0; + int i; + int index = 0; + const char *key, *error; + struct HTTPDConfig *parsed_configs = NULL; + struct HTTPDConfig *config; + struct StreamConfig *stream; + lua_State *L = luaL_newstate(); + ret = luaL_loadfile(L, filename); + if (ret != 0) { + fprintf(stderr, "Unable to open config file: %s\n", lua_tostring(L, -1)); + lua_close(L); + return -1; + } + + ret = lua_pcall(L, 0, 0, 0); + + if (ret != 0) { + fprintf(stderr, "Unable to read config file: %s\n", lua_tostring(L, -1)); + lua_close(L); + return -1; + } + lua_getglobal(L, "settings"); + if (lua_type(L, -1) != LUA_TTABLE) { + lua_pushstring(L, "Error \"settings\" is not a table"); + goto fail; + } + lua_pushnil(L); + + // iterate servers + while (lua_next(L, -2) != 0) { + nb_configs++; + parsed_configs = av_realloc(parsed_configs, nb_configs * sizeof(struct HTTPDConfig)); + config = &parsed_configs[nb_configs - 1]; + config->server_name = NULL; + config->bind_address = NULL; + config->port = 0; + config->accept_timeout = 1000; + config->streams = NULL; + config->nb_streams = 0; + if (lua_type(L, -2) != LUA_TSTRING) { + lua_pushstring(L, "Error server name is not a string."); + goto fail; + } + if (lua_type(L, -1) != LUA_TTABLE) { + lua_pushstring(L, "Error server settings is not a table."); + goto fail; + } + config->server_name = av_strdup(lua_tostring(L, -2)); + lua_pushnil(L); + // iterate server properties + nb_streams = 0; + while(lua_next(L, -2) != 0) { + if (lua_type(L, -2) != LUA_TSTRING) { + lua_pushstring(L, "Error server property is not a string."); + goto fail; + } + key = lua_tostring(L, -2); + if (!strncmp("bind_address", key, 12)) { + config->bind_address = av_strdup(lua_tostring(L, -1)); + } else if (!strncmp("port", key, 4)) { + config->port = (int) lua_tonumber(L, -1); + } else { + // keys that are not "bind_address" or "port" are streams + if (lua_type(L, -1) != LUA_TTABLE) { + lua_pushstring(L, "Error Stream configuration is not a table."); + goto fail; + } + + nb_streams++; + config->streams = av_realloc(config->streams, nb_streams * sizeof(struct StreamConfig)); + stream = &config->streams[nb_streams - 1]; + stream->input_uri = NULL; + stream->formats = NULL; + stream->stream_name = av_strdup(lua_tostring(L, -2)); + lua_pushnil(L); + while(lua_next(L, -2) != 0) { + if (lua_type(L, -2) != LUA_TSTRING) { + lua_pushstring(L, "Error stream property is not a string."); + goto fail; + } + key = lua_tostring(L, -2); + if (!strncmp("input", key, 5)) { + stream->input_uri = av_strdup(lua_tostring(L, -1)); + } else if (!strncmp("formats", key, 7)) { + index = 1; + nb_formats = 0; + lua_pushnumber(L, index); + while(1) { + lua_gettable(L, -2); + if (lua_isnil(L, -1)) + break; + if (lua_type(L, -1) != LUA_TSTRING) { + lua_pushstring(L, "Error format name is not a string."); + goto fail; + } + stream->formats = av_realloc(stream->formats, + (nb_formats + 1) * sizeof(enum StreamFormat)); + key = lua_tostring(L, -1); + if (!strncmp("mkv", key, 3)) { + stream->formats[nb_formats++] = FMT_MATROSKA; + } else { + fprintf(stderr, "Warning unknown format (%s) in stream format configuration.\n", + key); + av_realloc(stream->formats, nb_formats * sizeof(enum StreamFormat)); + } + stream->nb_formats = nb_formats; + lua_pop(L, 1); + lua_pushnumber(L, ++index); + } + lua_pop(L, 1); + + } else { + fprintf(stderr, "Warning unknown key (%s) in stream configuration.\n", key); + } + lua_pop(L, 1); + } + } + lua_pop(L, 1); + } + config->nb_streams = nb_streams; + lua_pop(L, 1); + } + + lua_close(L); + *configs = parsed_configs; + return nb_configs; + +fail: + error = lua_tostring(L, -1); + fprintf(stderr, "%s\n", error); + lua_close(L); + for (i = 0; i < nb_configs; i++) + config_free(&parsed_configs[i]); + av_free(parsed_configs); + return -1; +} + diff --git a/configreader.h b/configreader.h new file mode 100644 index 0000000..788ff60 --- /dev/null +++ b/configreader.h @@ -0,0 +1,46 @@ +/* + * 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 + */ + +#ifndef CONFIGREADER_H +#define CONFIGREADER_H + +#include "httpd.h" + +/** + * Read configurations from a file using the json format. The configurations + * are allocated as an array at *configs. This has to be freed by the user. + * + * @param configs pointer to a pointer where configurations will be allocated. + * @param filename filename of the configuration to use. + * @return number of configurations read, -1 on error. + */ +int configs_read(struct HTTPDConfig **configs, const char *filename); + +/** + * Dump a configuration to stdout. + * @param config pointer to a configuration + */ +void config_dump(struct HTTPDConfig *config); + +/** + * Free a configuration. + * @param config pointer to a configuration + */ +void config_free(struct HTTPDConfig *config); + +#endif