diff options
Diffstat (limited to 'main/format_cap.c')
-rw-r--r-- | main/format_cap.c | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/main/format_cap.c b/main/format_cap.c index c8bdd4fa3..3ef0e74d3 100644 --- a/main/format_cap.c +++ b/main/format_cap.c @@ -99,7 +99,7 @@ void *ast_format_cap_destroy(struct ast_format_cap *cap) return NULL; } -void ast_format_cap_add(struct ast_format_cap *cap, struct ast_format *format) +void ast_format_cap_add(struct ast_format_cap *cap, const struct ast_format *format) { struct ast_format *fnew; @@ -122,26 +122,26 @@ void ast_format_cap_add_all_by_type(struct ast_format_cap *cap, enum ast_format_ { int x; size_t f_len = 0; - struct ast_format tmp_fmt; - const struct ast_format_list *f_list = ast_get_format_list(&f_len); + const struct ast_format_list *f_list = ast_format_list_get(&f_len); for (x = 0; x < f_len; x++) { - if (AST_FORMAT_GET_TYPE(f_list[x].id) == type) { - ast_format_cap_add(cap, ast_format_set(&tmp_fmt, f_list[x].id, 0)); + if (AST_FORMAT_GET_TYPE(f_list[x].format.id) == type) { + ast_format_cap_add(cap, &f_list[x].format); } } + ast_format_list_destroy(f_list); } void ast_format_cap_add_all(struct ast_format_cap *cap) { int x; size_t f_len = 0; - struct ast_format tmp_fmt; - const struct ast_format_list *f_list = ast_get_format_list(&f_len); + const struct ast_format_list *f_list = ast_format_list_get(&f_len); for (x = 0; x < f_len; x++) { - ast_format_cap_add(cap, ast_format_set(&tmp_fmt, f_list[x].id, 0)); + ast_format_cap_add(cap, &f_list[x].format); } + ast_format_list_destroy(f_list); } static int append_cb(void *obj, void *arg, int flag) @@ -288,6 +288,21 @@ void ast_format_cap_set(struct ast_format_cap *cap, struct ast_format *format) ast_format_cap_add(cap, format); } +int ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format, struct ast_format *result) +{ + struct ast_format *f; + struct ast_format_cap *tmp_cap = (struct ast_format_cap *) cap; + f = ao2_find(tmp_cap->formats, (struct ast_format *) format, OBJ_POINTER | tmp_cap->nolock); + + if (f) { + ast_format_copy(result, f); + ao2_ref(f, -1); + return 1; + } + ast_format_clear(result); + return 0; +} + int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct ast_format *format) { struct ast_format *f; @@ -302,6 +317,38 @@ int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct a return 0; } +struct byid_data { + struct ast_format *result; + enum ast_format_id id; +}; +static int find_best_byid_cb(void *obj, void *arg, int flag) +{ + struct ast_format *format = obj; + struct byid_data *data = arg; + + if (data->id != format->id) { + return 0; + } + if (!data->result->id || (ast_format_rate(data->result) < ast_format_rate(format))) { + ast_format_copy(data->result, format); + } + return 0; +} + +int ast_format_cap_best_byid(const struct ast_format_cap *cap, enum ast_format_id id, struct ast_format *result) +{ + struct byid_data data; + data.result = result; + data.id = id; + + ast_format_clear(result); + ao2_callback(cap->formats, + OBJ_MULTIPLE | OBJ_NODATA | cap->nolock, + find_best_byid_cb, + &data); + return result->id ? 1 : 0; +} + /*! \internal * \brief this struct is just used for the ast_format_cap_joint function so we can provide * both a format and a result ast_format_cap structure as arguments to the find_joint_cb @@ -525,6 +572,42 @@ int ast_format_cap_iter_next(struct ast_format_cap *cap, struct ast_format *form return 0; } +char *ast_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *cap) +{ + int x; + unsigned len; + char *start, *end = buf; + struct ast_format tmp_fmt; + size_t f_len; + const struct ast_format_list *f_list = ast_format_list_get(&f_len); + + if (!size) { + f_list = ast_format_list_destroy(f_list); + return buf; + } + snprintf(end, size, "("); + len = strlen(end); + end += len; + size -= len; + start = end; + for (x = 0; x < f_len; x++) { + ast_format_copy(&tmp_fmt, &f_list[x].format); + if (ast_format_cap_iscompatible(cap, &tmp_fmt)) { + snprintf(end, size, "%s|", f_list[x].name); + len = strlen(end); + end += len; + size -= len; + } + } + if (start == end) { + ast_copy_string(start, "nothing)", size); + } else if (size > 1) { + *(end - 1) = ')'; + } + f_list = ast_format_list_destroy(f_list); + return buf; +} + uint64_t ast_format_cap_to_old_bitfield(const struct ast_format_cap *cap) { uint64_t res = 0; |