diff options
Diffstat (limited to 'main/stream.c')
-rw-r--r-- | main/stream.c | 135 |
1 files changed, 108 insertions, 27 deletions
diff --git a/main/stream.c b/main/stream.c index 61eef2504..dd3e765f6 100644 --- a/main/stream.c +++ b/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,19 +66,19 @@ struct ast_stream { enum ast_stream_state state; /*! - * \brief Opaque stream data + * \brief Stream metadata vector */ - void *data[AST_STREAM_DATA_SLOT_MAX]; + struct ast_variable *metadata; /*! - * \brief What to do with data when the stream is freed + * \brief The group that the stream is part of */ - ast_stream_data_free_fn data_free_fn[AST_STREAM_DATA_SLOT_MAX]; + int group; /*! - * \brief The group that the stream is part of + * \brief The rtp_codecs used by the stream */ - int group; + 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; + + ast_assert_return(stream != NULL, NULL); + ast_assert_return(m_key != NULL, NULL); - return stream->data[slot]; + 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; + + ast_assert_return(stream != NULL, NULL); + + 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); + } - stream->data[slot] = data; - stream->data_free_fn[slot] = data_free_fn; + return vout; +} - return data; +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) { |