diff options
Diffstat (limited to 'wsutil/codecs.c')
-rw-r--r-- | wsutil/codecs.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/wsutil/codecs.c b/wsutil/codecs.c new file mode 100644 index 0000000..857cd33 --- /dev/null +++ b/wsutil/codecs.c @@ -0,0 +1,194 @@ +/* codecs.c + * codecs interface 2007 Tomas Kukosa + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include "codecs.h" + +#include <wsutil/wslog.h> +#ifdef HAVE_PLUGINS +#include <wsutil/plugins.h> +#endif + +#ifdef HAVE_PLUGINS +static plugins_t *libwscodecs_plugins = NULL; +#endif + +static GSList *codecs_plugins = NULL; + +#ifdef HAVE_PLUGINS +void +codecs_register_plugin(const codecs_plugin *plug) +{ + codecs_plugins = g_slist_prepend(codecs_plugins, (codecs_plugin *)plug); +} +#else /* HAVE_PLUGINS */ +void +codecs_register_plugin(const codecs_plugin *plug _U_) +{ + ws_warning("codecs_register_plugin: built without support for binary plugins"); +} +#endif /* HAVE_PLUGINS */ + +static void +call_plugin_register_codec_module(void * data, void * user_data _U_) +{ + codecs_plugin *plug = (codecs_plugin *)data; + + if (plug->register_codec_module) { + plug->register_codec_module(); + } +} + + +/* + * For all codec plugins, call their register routines. + */ +void +codecs_init(void) +{ +#ifdef HAVE_PLUGINS + libwscodecs_plugins = plugins_init(WS_PLUGIN_CODEC); +#endif + g_slist_foreach(codecs_plugins, call_plugin_register_codec_module, NULL); +} + +void +codecs_cleanup(void) +{ + g_slist_free(codecs_plugins); + codecs_plugins = NULL; +#ifdef HAVE_PLUGINS + plugins_cleanup(libwscodecs_plugins); + libwscodecs_plugins = NULL; +#endif +} + + +struct codec_handle { + const char *name; + codec_init_fn init_fn; + codec_release_fn release_fn; + codec_get_channels_fn channels_fn; + codec_get_frequency_fn frequency_fn; + codec_decode_fn decode_fn; +}; + +/* + * List of registered codecs. + */ +static GHashTable *registered_codecs = NULL; + + +/* Find a registered codec by name. */ +codec_handle_t +find_codec(const char *name) +{ + codec_handle_t ret; + char *key = g_ascii_strup(name, -1); + + ret = (registered_codecs) ? (codec_handle_t)g_hash_table_lookup(registered_codecs, key) : NULL; + g_free(key); + return ret; +} + +/* Register a codec by name. */ +bool +register_codec(const char *name, codec_init_fn init_fn, codec_release_fn release_fn, + codec_get_channels_fn channels_fn, codec_get_frequency_fn frequency_fn, + codec_decode_fn decode_fn) +{ + struct codec_handle *handle; + char *key; + + /* Create our hash table if it doesn't already exist */ + if (registered_codecs == NULL) + registered_codecs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + + /* RFC 4855 3. Mapping to SDP Parameters "Note that the payload format + * (encoding) names... are commonly shown in upper case. These names + * are case-insensitive in both places." + */ + key = g_ascii_strup(name, -1); + + /* Make sure the registration is unique */ + if (g_hash_table_lookup(registered_codecs, key) != NULL) { + g_free(key); + return false; /* report an error, or have our caller do it? */ + } + + handle = g_new(struct codec_handle, 1); + handle->name = name; + handle->init_fn = init_fn; + handle->release_fn = release_fn; + handle->channels_fn = channels_fn; + handle->frequency_fn = frequency_fn; + handle->decode_fn = decode_fn; + + g_hash_table_insert(registered_codecs, (void *)key, (void *) handle); + return true; +} + +/* Deregister a codec by name. */ +bool +deregister_codec(const char *name) +{ + bool ret = false; + if (registered_codecs) { + char *key = g_ascii_strup(name, -1); + + ret = g_hash_table_remove(registered_codecs, key); + g_free(key); + } + return ret; +} + +void *codec_init(codec_handle_t codec, codec_context_t *context) +{ + if (!codec) return NULL; + return (codec->init_fn)(context); +} + +void codec_release(codec_handle_t codec, codec_context_t *context) +{ + if (!codec) return; + (codec->release_fn)(context); +} + +unsigned codec_get_channels(codec_handle_t codec, codec_context_t *context) +{ + if (!codec) return 0; + return (codec->channels_fn)(context); +} + +unsigned codec_get_frequency(codec_handle_t codec, codec_context_t *context) +{ + if (!codec) return 0; + return (codec->frequency_fn)(context); +} + +size_t codec_decode(codec_handle_t codec, codec_context_t *context, const void *input, size_t inputSizeBytes, void *output, size_t *outputSizeBytes) +{ + if (!codec) return 0; + return (codec->decode_fn)(context, input, inputSizeBytes, output, outputSizeBytes); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |