1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 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;
#endif
static GSList *codecs_plugins;
#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;
/* 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:
*/
|