mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +00:00 
			
		
		
		
	streams: Add string metadata capability
Replaces the never used opaque data array. Updated stream tests to include get/set metadata and stream clone with metadata. Added stream metadata dump to "core show channel" Change-Id: Id7473aa4b374d7ab53046c20e321037ba9a56863
This commit is contained in:
		
							
								
								
									
										137
									
								
								main/stream.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								main/stream.c
									
									
									
									
									
								
							@@ -34,6 +34,15 @@
 | 
			
		||||
#include "asterisk/strings.h"
 | 
			
		||||
#include "asterisk/format.h"
 | 
			
		||||
#include "asterisk/format_cap.h"
 | 
			
		||||
#include "asterisk/vector.h"
 | 
			
		||||
#include "asterisk/config.h"
 | 
			
		||||
#include "asterisk/rtp_engine.h"
 | 
			
		||||
 | 
			
		||||
struct ast_stream_metadata_entry {
 | 
			
		||||
	size_t length;
 | 
			
		||||
	int value_start;
 | 
			
		||||
	char name_value[0];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ast_stream {
 | 
			
		||||
	/*!
 | 
			
		||||
@@ -57,20 +66,20 @@ struct ast_stream {
 | 
			
		||||
	enum ast_stream_state state;
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief Opaque stream data
 | 
			
		||||
	 * \brief Stream metadata vector
 | 
			
		||||
	 */
 | 
			
		||||
	void *data[AST_STREAM_DATA_SLOT_MAX];
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief What to do with data when the stream is freed
 | 
			
		||||
	 */
 | 
			
		||||
	ast_stream_data_free_fn data_free_fn[AST_STREAM_DATA_SLOT_MAX];
 | 
			
		||||
	struct ast_variable *metadata;
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief The group that the stream is part of
 | 
			
		||||
	 */
 | 
			
		||||
	int group;
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief The rtp_codecs used by the stream
 | 
			
		||||
	 */
 | 
			
		||||
	struct ast_rtp_codecs *rtp_codecs;
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief Name for the stream within the context of the channel it is on
 | 
			
		||||
	 */
 | 
			
		||||
@@ -105,7 +114,6 @@ struct ast_stream *ast_stream_clone(const struct ast_stream *stream, const char
 | 
			
		||||
{
 | 
			
		||||
	struct ast_stream *new_stream;
 | 
			
		||||
	size_t stream_size;
 | 
			
		||||
	int idx;
 | 
			
		||||
	const char *stream_name;
 | 
			
		||||
 | 
			
		||||
	if (!stream) {
 | 
			
		||||
@@ -126,27 +134,23 @@ struct ast_stream *ast_stream_clone(const struct ast_stream *stream, const char
 | 
			
		||||
		ao2_ref(new_stream->formats, +1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* We cannot clone the opaque data because we don't know how. */
 | 
			
		||||
	for (idx = 0; idx < AST_STREAM_DATA_SLOT_MAX; ++idx) {
 | 
			
		||||
		new_stream->data[idx] = NULL;
 | 
			
		||||
		new_stream->data_free_fn[idx] = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	new_stream->metadata = ast_stream_get_metadata_list(stream);
 | 
			
		||||
 | 
			
		||||
	/* rtp_codecs aren't cloned */
 | 
			
		||||
 | 
			
		||||
	return new_stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ast_stream_free(struct ast_stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (!stream) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < AST_STREAM_DATA_SLOT_MAX; i++) {
 | 
			
		||||
		if (stream->data_free_fn[i]) {
 | 
			
		||||
			stream->data_free_fn[i](stream->data[i]);
 | 
			
		||||
		}
 | 
			
		||||
	ast_variables_destroy(stream->metadata);
 | 
			
		||||
 | 
			
		||||
	if (stream->rtp_codecs) {
 | 
			
		||||
		ast_rtp_codecs_payloads_destroy(stream->rtp_codecs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ao2_cleanup(stream->formats);
 | 
			
		||||
@@ -238,22 +242,81 @@ enum ast_stream_state ast_stream_str2state(const char *str)
 | 
			
		||||
	return AST_STREAM_STATE_REMOVED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *ast_stream_get_data(struct ast_stream *stream, enum ast_stream_data_slot slot)
 | 
			
		||||
const char *ast_stream_get_metadata(const struct ast_stream *stream, const char *m_key)
 | 
			
		||||
{
 | 
			
		||||
	ast_assert(stream != NULL);
 | 
			
		||||
	struct ast_variable *v;
 | 
			
		||||
 | 
			
		||||
	return stream->data[slot];
 | 
			
		||||
	ast_assert_return(stream != NULL, NULL);
 | 
			
		||||
	ast_assert_return(m_key != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	for (v = stream->metadata; v; v = v->next) {
 | 
			
		||||
		if (strcmp(v->name, m_key) == 0) {
 | 
			
		||||
			return v->value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *ast_stream_set_data(struct ast_stream *stream, enum ast_stream_data_slot slot,
 | 
			
		||||
	void *data, ast_stream_data_free_fn data_free_fn)
 | 
			
		||||
struct ast_variable *ast_stream_get_metadata_list(const struct ast_stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	ast_assert(stream != NULL);
 | 
			
		||||
	struct ast_variable *v;
 | 
			
		||||
	struct ast_variable *vout = NULL;
 | 
			
		||||
 | 
			
		||||
	stream->data[slot] = data;
 | 
			
		||||
	stream->data_free_fn[slot] = data_free_fn;
 | 
			
		||||
	ast_assert_return(stream != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	return data;
 | 
			
		||||
	for (v = stream->metadata; v; v = v->next) {
 | 
			
		||||
		struct ast_variable *vt = ast_variable_new(v->name, v->value, "");
 | 
			
		||||
 | 
			
		||||
		if (!vt) {
 | 
			
		||||
			ast_variables_destroy(vout);
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ast_variable_list_append(&vout, vt);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return vout;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
 | 
			
		||||
{
 | 
			
		||||
	struct ast_variable *v;
 | 
			
		||||
	struct ast_variable *prev;
 | 
			
		||||
 | 
			
		||||
	ast_assert_return(stream != NULL, -1);
 | 
			
		||||
	ast_assert_return(m_key != NULL, -1);
 | 
			
		||||
 | 
			
		||||
	prev = NULL;
 | 
			
		||||
	v = stream->metadata;
 | 
			
		||||
	while(v) {
 | 
			
		||||
		struct ast_variable *next = v->next;
 | 
			
		||||
		if (strcmp(v->name, m_key) == 0) {
 | 
			
		||||
			if (prev) {
 | 
			
		||||
				prev->next = next;
 | 
			
		||||
			} else {
 | 
			
		||||
				stream->metadata = next;
 | 
			
		||||
			}
 | 
			
		||||
			ast_free(v);
 | 
			
		||||
			break;
 | 
			
		||||
		} else {
 | 
			
		||||
			prev = v;
 | 
			
		||||
		}
 | 
			
		||||
		v = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!value) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v = ast_variable_new(m_key, value, "");
 | 
			
		||||
	if (!v) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ast_variable_list_append(&stream->metadata, v);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ast_stream_get_position(const struct ast_stream *stream)
 | 
			
		||||
@@ -263,6 +326,24 @@ int ast_stream_get_position(const struct ast_stream *stream)
 | 
			
		||||
	return stream->position;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ast_rtp_codecs *ast_stream_get_rtp_codecs(const struct ast_stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	ast_assert(stream != NULL);
 | 
			
		||||
 | 
			
		||||
	return stream->rtp_codecs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ast_stream_set_rtp_codecs(struct ast_stream *stream, struct ast_rtp_codecs *rtp_codecs)
 | 
			
		||||
{
 | 
			
		||||
	ast_assert(stream != NULL);
 | 
			
		||||
 | 
			
		||||
	if (stream->rtp_codecs) {
 | 
			
		||||
		ast_rtp_codecs_payloads_destroy(rtp_codecs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stream->rtp_codecs = rtp_codecs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define TOPOLOGY_INITIAL_STREAM_COUNT 2
 | 
			
		||||
struct ast_stream_topology *ast_stream_topology_alloc(void)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user