mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +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