summaryrefslogtreecommitdiff
path: root/main/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/stream.c')
-rw-r--r--main/stream.c135
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)
{