Example #1
0
int ast_format_cache_set(struct ast_format *format)
{
	SCOPED_AO2WRLOCK(lock, formats);
	struct ast_format *old_format;

	ast_assert(format != NULL);

	if (ast_strlen_zero(ast_format_get_name(format))) {
		return -1;
	}

	old_format = ao2_find(formats, ast_format_get_name(format), OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (old_format) {
		ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
	}
	ao2_link_flags(formats, format, OBJ_NOLOCK);

	set_cached_format(ast_format_get_name(format), format);

	ast_verb(2, "%s cached format with name '%s'\n",
		old_format ? "Updated" : "Created",
		ast_format_get_name(format));

	ao2_cleanup(old_format);

	return 0;
}
Example #2
0
int __ast_format_interface_register(const char *codec, const struct ast_format_interface *interface, struct ast_module *mod)
{
	SCOPED_AO2WRLOCK(lock, interfaces);
	struct format_interface *format_interface;

	if (!interface->format_clone || !interface->format_destroy) {
		ast_log(LOG_ERROR, "Format interface for codec '%s' does not implement required callbacks\n", codec);
		return -1;
	}

	format_interface = ao2_find(interfaces, codec, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (format_interface) {
		ast_log(LOG_ERROR, "A format interface is already present for codec '%s'\n", codec);
		ao2_ref(format_interface, -1);
		return -1;
	}

	format_interface = ao2_alloc_options(sizeof(*format_interface) + strlen(codec) + 1,
		NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
	if (!format_interface) {
		return -1;
	}
	format_interface->interface = interface;
	strcpy(format_interface->codec, codec); /* Safe */

	/* Once registered a format interface cannot be unregistered. */
	ast_module_shutdown_ref(mod);
	ao2_link_flags(interfaces, format_interface, OBJ_NOLOCK);
	ao2_ref(format_interface, -1);

	ast_verb(2, "Registered format interface for codec '%s'\n", codec);

	return 0;
}
Example #3
0
int __ast_codec_register(struct ast_codec *codec, struct ast_module *mod)
{
	SCOPED_AO2WRLOCK(lock, codecs);
	struct ast_codec *codec_new;

	/* Some types have specific requirements */
	if (codec->type == AST_MEDIA_TYPE_UNKNOWN) {
		ast_log(LOG_ERROR, "A media type must be specified for codec '%s'\n", codec->name);
		return -1;
	} else if (codec->type == AST_MEDIA_TYPE_AUDIO) {
		if (!codec->sample_rate) {
			ast_log(LOG_ERROR, "A sample rate must be specified for codec '%s' of type '%s'\n",
				codec->name, ast_codec_media_type2str(codec->type));
			return -1;
		}
	}

	codec_new = ao2_find(codecs, codec, OBJ_SEARCH_OBJECT | OBJ_NOLOCK);
	if (codec_new) {
		ast_log(LOG_ERROR, "A codec with name '%s' of type '%s' and sample rate '%u' is already registered\n",
			codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate);
		ao2_ref(codec_new, -1);
		return -1;
	}

	codec_new = ao2_t_alloc_options(sizeof(*codec_new), codec_dtor,
		AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""));
	if (!codec_new) {
		ast_log(LOG_ERROR, "Could not allocate a codec with name '%s' of type '%s' and sample rate '%u'\n",
			codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate);
		return -1;
	}
	*codec_new = *codec;
	codec_new->id = codec_id++;

	ao2_link_flags(codecs, codec_new, OBJ_NOLOCK);

	/* Once registered a codec can not be unregistered, and the module must persist until shutdown */
	ast_module_shutdown_ref(mod);

	ast_verb(2, "Registered '%s' codec '%s' at sample rate '%u' with id '%u'\n",
		ast_codec_media_type2str(codec->type), codec->name, codec->sample_rate, codec_new->id);

	ao2_ref(codec_new, -1);

	return 0;
}