mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
SDP: Update ast_get_topology_from_sdp() to keep RTP map.
* Add failure exits to ast_get_topology_from_sdp(). Change-Id: I4cc85c1ede8d712766ed20f544dbcef04c8c1049
This commit is contained in:
@@ -638,11 +638,12 @@ void ast_sdp_rtpmap_free(struct ast_sdp_rtpmap *rtpmap);
|
|||||||
* each m-line corresponding to a stream in the created topology.
|
* each m-line corresponding to a stream in the created topology.
|
||||||
*
|
*
|
||||||
* \param sdp The SDP to convert
|
* \param sdp The SDP to convert
|
||||||
|
* \param g726_non_standard Non-zero if G.726 is non-standard
|
||||||
*
|
*
|
||||||
* \retval NULL An error occurred when converting
|
* \retval NULL An error occurred when converting
|
||||||
* \retval non-NULL The generated stream topology
|
* \retval non-NULL The generated stream topology
|
||||||
*
|
*
|
||||||
* \since 15.0.0
|
* \since 15.0.0
|
||||||
*/
|
*/
|
||||||
struct ast_stream_topology *ast_get_topology_from_sdp(const struct ast_sdp *sdp);
|
struct ast_stream_topology *ast_get_topology_from_sdp(const struct ast_sdp *sdp, int g726_non_standard);
|
||||||
#endif /* _SDP_PRIV_H */
|
#endif /* _SDP_PRIV_H */
|
||||||
|
@@ -84,7 +84,7 @@ enum ast_stream_data_slot {
|
|||||||
/*!
|
/*!
|
||||||
* \brief Data slot for RTP instance
|
* \brief Data slot for RTP instance
|
||||||
*/
|
*/
|
||||||
AST_STREAM_DATA_RTP_INSTANCE = 0,
|
AST_STREAM_DATA_RTP_CODECS = 0,
|
||||||
/*!
|
/*!
|
||||||
* \brief Controls the size of the data pointer array
|
* \brief Controls the size of the data pointer array
|
||||||
*/
|
*/
|
||||||
|
64
main/sdp.c
64
main/sdp.c
@@ -693,6 +693,17 @@ static void process_fmtp(const struct ast_sdp_m_line *m_line, int payload,
|
|||||||
ao2_ref(format, -1);
|
ao2_ref(format, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needed so we don't have an external function referenced as data.
|
||||||
|
* The dynamic linker doesn't handle that very well.
|
||||||
|
*/
|
||||||
|
static void rtp_codecs_free(struct ast_rtp_codecs *codecs)
|
||||||
|
{
|
||||||
|
if (codecs) {
|
||||||
|
ast_rtp_codecs_payloads_destroy(codecs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Convert an SDP stream into an Asterisk stream
|
* \brief Convert an SDP stream into an Asterisk stream
|
||||||
*
|
*
|
||||||
@@ -700,16 +711,19 @@ static void process_fmtp(const struct ast_sdp_m_line *m_line, int payload,
|
|||||||
* This takes formats, as well as clock-rate and fmtp attributes into account.
|
* This takes formats, as well as clock-rate and fmtp attributes into account.
|
||||||
*
|
*
|
||||||
* \param m_line The SDP media section to convert
|
* \param m_line The SDP media section to convert
|
||||||
|
* \param g726_non_standard Non-zero if G.726 is non-standard
|
||||||
|
*
|
||||||
* \retval NULL An error occurred
|
* \retval NULL An error occurred
|
||||||
* \retval non-NULL The converted stream
|
* \retval non-NULL The converted stream
|
||||||
*/
|
*/
|
||||||
static struct ast_stream *get_stream_from_m(const struct ast_sdp_m_line *m_line)
|
static struct ast_stream *get_stream_from_m(const struct ast_sdp_m_line *m_line, int g726_non_standard)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int non_ast_fmts;
|
int non_ast_fmts;
|
||||||
struct ast_rtp_codecs codecs;
|
struct ast_rtp_codecs *codecs;
|
||||||
struct ast_format_cap *caps;
|
struct ast_format_cap *caps;
|
||||||
struct ast_stream *stream;
|
struct ast_stream *stream;
|
||||||
|
enum ast_rtp_options options;
|
||||||
|
|
||||||
caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
|
caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
|
||||||
if (!caps) {
|
if (!caps) {
|
||||||
@@ -724,8 +738,15 @@ static struct ast_stream *get_stream_from_m(const struct ast_sdp_m_line *m_line)
|
|||||||
switch (ast_stream_get_type(stream)) {
|
switch (ast_stream_get_type(stream)) {
|
||||||
case AST_MEDIA_TYPE_AUDIO:
|
case AST_MEDIA_TYPE_AUDIO:
|
||||||
case AST_MEDIA_TYPE_VIDEO:
|
case AST_MEDIA_TYPE_VIDEO:
|
||||||
ast_rtp_codecs_payloads_initialize(&codecs);
|
codecs = ast_calloc(1, sizeof(*codecs));
|
||||||
|
if (!codecs || ast_rtp_codecs_payloads_initialize(codecs)) {
|
||||||
|
rtp_codecs_free(codecs);
|
||||||
|
ast_stream_free(stream);
|
||||||
|
ao2_ref(caps, -1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
options = g726_non_standard ? AST_RTP_OPT_G726_NONSTANDARD : 0;
|
||||||
for (i = 0; i < ast_sdp_m_get_payload_count(m_line); ++i) {
|
for (i = 0; i < ast_sdp_m_get_payload_count(m_line); ++i) {
|
||||||
struct ast_sdp_payload *payload_s;
|
struct ast_sdp_payload *payload_s;
|
||||||
struct ast_sdp_rtpmap *rtpmap;
|
struct ast_sdp_rtpmap *rtpmap;
|
||||||
@@ -733,22 +754,25 @@ static struct ast_stream *get_stream_from_m(const struct ast_sdp_m_line *m_line)
|
|||||||
|
|
||||||
payload_s = ast_sdp_m_get_payload(m_line, i);
|
payload_s = ast_sdp_m_get_payload(m_line, i);
|
||||||
sscanf(payload_s->fmt, "%30d", &payload);
|
sscanf(payload_s->fmt, "%30d", &payload);
|
||||||
ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, payload);
|
|
||||||
|
|
||||||
rtpmap = sdp_payload_get_rtpmap(m_line, payload);
|
rtpmap = sdp_payload_get_rtpmap(m_line, payload);
|
||||||
if (!rtpmap) {
|
if (!rtpmap) {
|
||||||
|
/* No rtpmap attribute. Try static payload type format assignment */
|
||||||
|
ast_rtp_codecs_payloads_set_m_type(codecs, NULL, payload);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL,
|
|
||||||
payload, m_line->type, rtpmap->encoding_name, 0,
|
|
||||||
rtpmap->clock_rate);
|
|
||||||
ast_sdp_rtpmap_free(rtpmap);
|
|
||||||
|
|
||||||
process_fmtp(m_line, payload, &codecs);
|
if (!ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, payload,
|
||||||
|
m_line->type, rtpmap->encoding_name, options, rtpmap->clock_rate)) {
|
||||||
|
/* Successfully mapped the payload type to format */
|
||||||
|
process_fmtp(m_line, payload, codecs);
|
||||||
|
}
|
||||||
|
ast_sdp_rtpmap_free(rtpmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_rtp_codecs_payload_formats(&codecs, caps, &non_ast_fmts);
|
ast_rtp_codecs_payload_formats(codecs, caps, &non_ast_fmts);
|
||||||
ast_rtp_codecs_payloads_destroy(&codecs);
|
ast_stream_set_data(stream, AST_STREAM_DATA_RTP_CODECS, codecs,
|
||||||
|
(ast_stream_data_free_fn) rtp_codecs_free);
|
||||||
break;
|
break;
|
||||||
case AST_MEDIA_TYPE_IMAGE:
|
case AST_MEDIA_TYPE_IMAGE:
|
||||||
for (i = 0; i < ast_sdp_m_get_payload_count(m_line); ++i) {
|
for (i = 0; i < ast_sdp_m_get_payload_count(m_line); ++i) {
|
||||||
@@ -773,7 +797,7 @@ static struct ast_stream *get_stream_from_m(const struct ast_sdp_m_line *m_line)
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast_stream_topology *ast_get_topology_from_sdp(const struct ast_sdp *sdp)
|
struct ast_stream_topology *ast_get_topology_from_sdp(const struct ast_sdp *sdp, int g726_non_standard)
|
||||||
{
|
{
|
||||||
struct ast_stream_topology *topology;
|
struct ast_stream_topology *topology;
|
||||||
int i;
|
int i;
|
||||||
@@ -786,11 +810,21 @@ struct ast_stream_topology *ast_get_topology_from_sdp(const struct ast_sdp *sdp)
|
|||||||
for (i = 0; i < ast_sdp_get_m_count(sdp); ++i) {
|
for (i = 0; i < ast_sdp_get_m_count(sdp); ++i) {
|
||||||
struct ast_stream *stream;
|
struct ast_stream *stream;
|
||||||
|
|
||||||
stream = get_stream_from_m(ast_sdp_get_m(sdp, i));
|
stream = get_stream_from_m(ast_sdp_get_m(sdp, i), g726_non_standard);
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
continue;
|
/*
|
||||||
|
* The topology cannot match the SDP because
|
||||||
|
* we failed to create a corresponding stream.
|
||||||
|
*/
|
||||||
|
ast_stream_topology_free(topology);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (ast_stream_topology_append_stream(topology, stream) < 0) {
|
||||||
|
/* Failed to add stream to topology */
|
||||||
|
ast_stream_free(stream);
|
||||||
|
ast_stream_topology_free(topology);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
ast_stream_topology_append_stream(topology, stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return topology;
|
return topology;
|
||||||
|
@@ -1007,7 +1007,8 @@ static int merge_sdps(struct ast_sdp_state *sdp_state, const struct ast_sdp *rem
|
|||||||
struct ast_stream_topology *remote_capabilities;
|
struct ast_stream_topology *remote_capabilities;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
remote_capabilities = ast_get_topology_from_sdp(remote_sdp);
|
remote_capabilities = ast_get_topology_from_sdp(remote_sdp,
|
||||||
|
sdp_state->options->g726_non_standard);
|
||||||
if (!remote_capabilities) {
|
if (!remote_capabilities) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@@ -623,7 +623,11 @@ AST_TEST_DEFINE(sdp_to_topology)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
topology = ast_get_topology_from_sdp(sdp);
|
topology = ast_get_topology_from_sdp(sdp, 0);
|
||||||
|
if (!topology) {
|
||||||
|
res = AST_TEST_FAIL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (ast_stream_topology_get_count(topology) != 3) {
|
if (ast_stream_topology_get_count(topology) != 3) {
|
||||||
ast_test_status_update(test, "Unexpected topology count '%d'. Expecting 2\n",
|
ast_test_status_update(test, "Unexpected topology count '%d'. Expecting 2\n",
|
||||||
|
Reference in New Issue
Block a user