diff options
author | Matt Jordan <mjordan@digium.com> | 2015-08-08 08:07:18 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2015-08-08 08:07:18 -0500 |
commit | c3bd7fb83583b357add3638ea1022040197ad250 (patch) | |
tree | 185f0afb430ff5150462a6ee5a89635316a7bdb9 | |
parent | df9ce3636695781be6ab2479f90766a56747dbd7 (diff) | |
parent | aeeb170fc4fe4e681a96b87f8e81ade717aa2426 (diff) |
Merge "rtp_engine.c: Fix performance issue with several channel drivers that use RTP." into 13
-rw-r--r-- | main/rtp_engine.c | 108 |
1 files changed, 57 insertions, 51 deletions
diff --git a/main/rtp_engine.c b/main/rtp_engine.c index c46370de4..8ad3d9e77 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -229,7 +229,7 @@ static int mime_types_len = 0; * See http://www.iana.org/assignments/rtp-parameters for a list of * assigned values */ -static struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT]; +static struct ast_rtp_payload_type *static_RTP_PT[AST_RTP_MAX_PT]; static ast_rwlock_t static_RTP_PT_lock; /*! \brief \ref stasis topic for RTP related messages */ @@ -651,23 +651,23 @@ void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct as return; } - new_type = ast_rtp_engine_alloc_payload_type(); + ast_rwlock_rdlock(&static_RTP_PT_lock); + new_type = ao2_bump(static_RTP_PT[payload]); + ast_rwlock_unlock(&static_RTP_PT_lock); if (!new_type) { + ast_debug(1, "Don't have a default tx payload type %d format for m type on %p\n", + payload, codecs); return; } - ast_rwlock_rdlock(&static_RTP_PT_lock); + ast_debug(1, "Setting tx payload type %d based on m type on %p\n", + payload, codecs); + ast_rwlock_wrlock(&codecs->codecs_lock); + if (payload < AST_VECTOR_SIZE(&codecs->payloads)) { ao2_t_cleanup(AST_VECTOR_GET(&codecs->payloads, payload), "cleaning up replaced payload type"); } - - new_type->asterisk_format = static_RTP_PT[payload].asterisk_format; - new_type->rtp_code = static_RTP_PT[payload].rtp_code; - new_type->payload = payload; - new_type->format = ao2_bump(static_RTP_PT[payload].format); - - ast_debug(1, "Setting payload %d (%p) based on m type on %p\n", payload, new_type, codecs); AST_VECTOR_REPLACE(&codecs->payloads, payload, new_type); if (instance && instance->engine && instance->engine->payload_set) { @@ -675,7 +675,6 @@ void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct as } ast_rwlock_unlock(&codecs->codecs_lock); - ast_rwlock_unlock(&static_RTP_PT_lock); } int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, @@ -791,15 +790,8 @@ struct ast_rtp_payload_type *ast_rtp_codecs_get_payload(struct ast_rtp_codecs *c ast_rwlock_unlock(&codecs->codecs_lock); if (!type) { - type = ast_rtp_engine_alloc_payload_type(); - if (!type) { - return NULL; - } ast_rwlock_rdlock(&static_RTP_PT_lock); - type->asterisk_format = static_RTP_PT[payload].asterisk_format; - type->rtp_code = static_RTP_PT[payload].rtp_code; - type->payload = payload; - type->format = ao2_bump(static_RTP_PT[payload].format); + type = ao2_bump(static_RTP_PT[payload]); ast_rwlock_unlock(&static_RTP_PT_lock); } @@ -810,17 +802,24 @@ int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int pay { struct ast_rtp_payload_type *type; - if (payload < 0 || payload >= AST_RTP_MAX_PT) { + if (payload < 0 || payload >= AST_RTP_MAX_PT || !format) { + return -1; + } + + type = ast_rtp_engine_alloc_payload_type(); + if (!type) { return -1; } + ao2_ref(format, +1); + type->format = format; + type->asterisk_format = 1; + type->payload = payload; ast_rwlock_wrlock(&codecs->codecs_lock); if (payload < AST_VECTOR_SIZE(&codecs->payloads)) { - type = AST_VECTOR_GET(&codecs->payloads, payload); - if (type && type->asterisk_format) { - ao2_replace(type->format, format); - } + ao2_cleanup(AST_VECTOR_GET(&codecs->payloads, payload)); } + AST_VECTOR_REPLACE(&codecs->payloads, payload, type); ast_rwlock_unlock(&codecs->codecs_lock); return 0; @@ -923,12 +922,15 @@ int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_form if (payload < 0) { ast_rwlock_rdlock(&static_RTP_PT_lock); for (i = 0; i < AST_RTP_MAX_PT; i++) { - if (static_RTP_PT[i].asterisk_format && asterisk_format && format && - (ast_format_cmp(format, static_RTP_PT[i].format) != AST_FORMAT_CMP_NOT_EQUAL)) { + if (!static_RTP_PT[i]) { + continue; + } + if (static_RTP_PT[i]->asterisk_format && asterisk_format && format && + (ast_format_cmp(format, static_RTP_PT[i]->format) != AST_FORMAT_CMP_NOT_EQUAL)) { payload = i; break; - } else if (!static_RTP_PT[i].asterisk_format && !asterisk_format && - (static_RTP_PT[i].rtp_code == code)) { + } else if (!static_RTP_PT[i]->asterisk_format && !asterisk_format && + (static_RTP_PT[i]->rtp_code == code)) { payload = i; break; } @@ -1695,16 +1697,6 @@ void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg) /*! \internal * \brief Small helper routine that cleans up entry i in - * \c static_RTP_PT. - */ -static void rtp_engine_static_RTP_PT_cleanup(int i) -{ - ao2_cleanup(static_RTP_PT[i].format); - memset(&static_RTP_PT[i], 0, sizeof(struct ast_rtp_payload_type)); -} - -/*! \internal - * \brief Small helper routine that cleans up entry i in * \c ast_rtp_mime_types. */ static void rtp_engine_mime_type_cleanup(int i) @@ -1744,6 +1736,7 @@ static void set_next_mime_type(struct ast_format *format, int rtp_code, const ch static void add_static_payload(int map, struct ast_format *format, int rtp_code) { int x; + struct ast_rtp_payload_type *type; ast_assert(map < ARRAY_LEN(static_RTP_PT)); @@ -1751,24 +1744,36 @@ static void add_static_payload(int map, struct ast_format *format, int rtp_code) if (map < 0) { /* find next available dynamic payload slot */ for (x = AST_RTP_PT_FIRST_DYNAMIC; x < AST_RTP_MAX_PT; ++x) { - if (!static_RTP_PT[x].asterisk_format && !static_RTP_PT[x].rtp_code) { + if (!static_RTP_PT[x]) { map = x; break; } } if (map < 0) { - ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n", - ast_format_get_name(format)); + if (format) { + ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n", + ast_format_get_name(format)); + } else { + ast_log(LOG_WARNING, "No Dynamic RTP mapping available for RTP code %d\n", + rtp_code); + } ast_rwlock_unlock(&static_RTP_PT_lock); return; } } - if (format) { - static_RTP_PT[map].asterisk_format = 1; - static_RTP_PT[map].format = ao2_bump(format); - } else { - static_RTP_PT[map].rtp_code = rtp_code; + type = ast_rtp_engine_alloc_payload_type(); + if (type) { + if (format) { + ao2_ref(format, +1); + type->format = format; + type->asterisk_format = 1; + } else { + type->rtp_code = rtp_code; + } + type->payload = map; + ao2_cleanup(static_RTP_PT[map]); + static_RTP_PT[map] = type; } ast_rwlock_unlock(&static_RTP_PT_lock); } @@ -1797,8 +1802,10 @@ int ast_rtp_engine_unload_format(struct ast_format *format) ast_rwlock_wrlock(&static_RTP_PT_lock); /* remove everything pertaining to this format id from the lists */ for (x = 0; x < AST_RTP_MAX_PT; x++) { - if (ast_format_cmp(static_RTP_PT[x].format, format) == AST_FORMAT_CMP_EQUAL) { - rtp_engine_static_RTP_PT_cleanup(x); + if (static_RTP_PT[x] + && ast_format_cmp(static_RTP_PT[x]->format, format) == AST_FORMAT_CMP_EQUAL) { + ao2_ref(static_RTP_PT[x], -1); + static_RTP_PT[x] = NULL; } } ast_rwlock_unlock(&static_RTP_PT_lock); @@ -2087,9 +2094,8 @@ static void rtp_engine_shutdown(void) ast_rwlock_wrlock(&static_RTP_PT_lock); for (x = 0; x < AST_RTP_MAX_PT; x++) { - if (static_RTP_PT[x].format) { - rtp_engine_static_RTP_PT_cleanup(x); - } + ao2_cleanup(static_RTP_PT[x]); + static_RTP_PT[x] = NULL; } ast_rwlock_unlock(&static_RTP_PT_lock); |