Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> --- 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 <stdio.h> +#include <string.h> +#include <lua5.3/lua.h> +#include <lua5.3/lauxlib.h> +#include <lua5.3/lualib.h> + +#include <libavutil/mem.h> + +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 -- 2.16.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel