diff --git a/include/asterisk/format.h b/include/asterisk/format.h index a5ca038183..b01592d16e 100644 --- a/include/asterisk/format.h +++ b/include/asterisk/format.h @@ -298,6 +298,24 @@ void ast_format_set_attribute_data(struct ast_format *format, void *attribute_da */ const char *ast_format_get_name(const struct ast_format *format); +/*! + * \brief Get the channel count on a format + * + * \param The media format + * + * \return Currently set channel count + */ +unsigned int ast_format_get_channel_count(const struct ast_format *format); + +/*! + * \brief Set the channel count on a format + * + * \param format The media format + * \param channel_count The number of audio channels used + * + */ +void ast_format_set_channel_count(struct ast_format *format, unsigned int channel_count); + /*! * \brief Get the codec associated with a format * diff --git a/main/format.c b/main/format.c index b5e577913e..5ae5ad9862 100644 --- a/main/format.c +++ b/main/format.c @@ -49,6 +49,8 @@ struct ast_format { void *attribute_data; /*! \brief Pointer to the optional format interface */ const struct ast_format_interface *interface; + /*! \brief The number if audio channels used, if more than one an interleaved format is required */ + unsigned int channel_count; }; /*! \brief Structure used when registering a format interface */ @@ -175,6 +177,16 @@ void ast_format_set_attribute_data(struct ast_format *format, void *attribute_da format->attribute_data = attribute_data; } +unsigned int ast_format_get_channel_count(const struct ast_format *format) +{ + return format->channel_count; +} + +void ast_format_set_channel_count(struct ast_format *format, unsigned int channel_count) +{ + format->channel_count = channel_count; +} + /*! \brief Destructor for media formats */ static void format_destroy(void *obj) { @@ -199,6 +211,7 @@ struct ast_format *ast_format_create_named(const char *format_name, struct ast_c } format->name = format_name; format->codec = ao2_bump(codec); + format->channel_count = 1; format_interface = ao2_find(interfaces, codec->name, OBJ_SEARCH_KEY); if (format_interface) { diff --git a/res/res_format_attr_opus.c b/res/res_format_attr_opus.c index 81a07a1f6d..45aa5e5c67 100644 --- a/res/res_format_attr_opus.c +++ b/res/res_format_attr_opus.c @@ -94,6 +94,7 @@ static int opus_clone(const struct ast_format *src, struct ast_format *dst) ao2_bump(attr->data); ast_format_set_attribute_data(dst, attr); + ast_format_set_channel_count(dst, ast_format_get_channel_count(src)); return 0; } @@ -145,6 +146,9 @@ static struct ast_format *opus_parse_sdp_fmtp(const struct ast_format *format, c sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_PTIME, &attr->ptime); sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_MAX_AVERAGE_BITRATE, &attr->maxbitrate); sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_STEREO, &attr->stereo); + if (attr->stereo) { + ast_format_set_channel_count(cloned, 2); + } sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_SPROP_STEREO, &attr->spropstereo); sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_CBR, &attr->cbr); sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_FEC, &attr->fec); @@ -238,6 +242,10 @@ static struct ast_format *opus_getjoint(const struct ast_format *format1, const if (!jointformat) { return NULL; } + + if (ast_format_get_channel_count(format1) == 2 || ast_format_get_channel_count(format2) == 2) { + ast_format_set_channel_count(jointformat, 2); + } attr_res = ast_format_get_attribute_data(jointformat); attr_res->dtx = attr1->dtx || attr2->dtx ? 1 : 0;