From 524e6da0c73b72c23b6bf5f46467594d1e98d772 Mon Sep 17 00:00:00 2001 From: Sauw Ming Date: Tue, 4 Feb 2025 10:20:52 +0800 Subject: [PATCH 1/2] Add API to register custom SDP comparison callback --- pjmedia/include/pjmedia/sdp_neg.h | 32 ++++++++++++++++++++++++++++++ pjmedia/src/pjmedia/sdp_neg.c | 33 +++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h index 1249fb6394..99c4c60efc 100644 --- a/pjmedia/include/pjmedia/sdp_neg.h +++ b/pjmedia/include/pjmedia/sdp_neg.h @@ -719,6 +719,38 @@ PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, pj_bool_t allow_asym); +/** + * The declaration of customized SDP session comparison callback. See + * #pjmedia_sdp_neg_register_sdp_cmp_cb() for more info. + * + * @param sd1 The first SDP session to compare. + * @param sd2 The second SDP session to compare. + * @param option Must be zero for now. + * @param status Status code to be returned for the SDP comparison result + * (PJ_SUCCESS meaning both SDPs are equal). + * On input, it contains the return status of our default + * SDP comparison implementation, i.e. + * #pjmedia_sdp_session_cmp(). + */ +typedef void (*pjmedia_sdp_neg_sdp_cmp_cb)(const pjmedia_sdp_session *sd1, + const pjmedia_sdp_session *sd2, + unsigned option, + pj_status_t *status); + + +/** + * Register customized SDP session comparison callback. + * To unregister, just call this function with parameter cb set to NULL. + * + * @param cb The customized SDP session comparison callback or + * NULL to unregister the callback. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_sdp_neg_register_sdp_cmp_cb(pjmedia_sdp_neg_sdp_cmp_cb cb); + + /** * Enumeration of customized SDP format matching option flags. See * #pjmedia_sdp_neg_register_fmt_match_cb() for more info. diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c index ecc1911281..ada75fe814 100644 --- a/pjmedia/src/pjmedia/sdp_neg.c +++ b/pjmedia/src/pjmedia/sdp_neg.c @@ -91,6 +91,9 @@ struct fmt_match_cb_t pjmedia_sdp_neg_fmt_match_cb cb; }; +/* The registered customized SDP session comparison callback */ +static pjmedia_sdp_neg_sdp_cmp_cb sdp_cmp_cb; + /* Number of registered customized SDP format negotiation callbacks */ static unsigned fmt_match_cb_cnt; @@ -368,6 +371,20 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool, return pjmedia_sdp_neg_modify_local_offer2(pool, neg, 0, local); } +static pj_status_t sdp_session_cmp(const pjmedia_sdp_session *sd1, + const pjmedia_sdp_session *sd2, + unsigned option) +{ + pj_status_t status; + + status = pjmedia_sdp_session_cmp(sd1, sd2, option); + if (sdp_cmp_cb) { + (*sdp_cmp_cb)(sd1, sd2, option, &status); + } + + return status; +} + PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2( pj_pool_t *pool, pjmedia_sdp_neg *neg, @@ -407,7 +424,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2( PJ_TRUE, PJ_FALSE); neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, neg->initial_sdp); - if (pjmedia_sdp_session_cmp(neg->last_sent, neg->neg_local_sdp, 0) != + if (sdp_session_cmp(neg->last_sent, neg->neg_local_sdp, 0) != PJ_SUCCESS) { ++neg->neg_local_sdp->origin.version; @@ -498,7 +515,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2( /* Assign PT numbers for our offer and update the mapping. */ assign_pt_and_update_map(pool, neg, new_offer, PJ_TRUE, PJ_FALSE); - if (pjmedia_sdp_session_cmp(neg->last_sent, new_offer, 0) != PJ_SUCCESS) { + if (sdp_session_cmp(neg->last_sent, new_offer, 0) != PJ_SUCCESS) { ++new_offer->origin.version; } neg->initial_sdp_tmp = neg->initial_sdp; @@ -541,7 +558,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool, neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER; new_offer = pjmedia_sdp_session_clone(pool, neg->active_local_sdp); - if (pjmedia_sdp_session_cmp(neg->last_sent, new_offer, 0) != + if (sdp_session_cmp(neg->last_sent, new_offer, 0) != PJ_SUCCESS) { ++new_offer->origin.version; @@ -2021,7 +2038,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, answer->origin.version = neg->last_sent->origin.version; if (!neg->last_sent || - pjmedia_sdp_session_cmp(neg->last_sent, answer, 0) != + sdp_session_cmp(neg->last_sent, answer, 0) != PJ_SUCCESS) { ++answer->origin.version; @@ -2058,6 +2075,14 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, } +/* Register customized SDP session comparison callback function. */ +PJ_DEF(pj_status_t) +pjmedia_sdp_neg_register_sdp_cmp_cb(pjmedia_sdp_neg_sdp_cmp_cb cb) +{ + sdp_cmp_cb = cb; + return PJ_SUCCESS; +} + static pj_status_t custom_fmt_match(pj_pool_t *pool, const pj_str_t *fmt_name, pjmedia_sdp_media *offer, From cb3af93c66f28f4082396452d41391717885eca7 Mon Sep 17 00:00:00 2001 From: Sauw Ming Date: Tue, 4 Feb 2025 11:19:59 +0800 Subject: [PATCH 2/2] Move to sdp_cmp --- pjmedia/include/pjmedia/sdp.h | 42 ++++++++++++++++++++++++++++++- pjmedia/include/pjmedia/sdp_neg.h | 32 ----------------------- pjmedia/src/pjmedia/sdp_cmp.c | 36 +++++++++++++++++++++----- pjmedia/src/pjmedia/sdp_neg.c | 33 +++--------------------- 4 files changed, 75 insertions(+), 68 deletions(-) diff --git a/pjmedia/include/pjmedia/sdp.h b/pjmedia/include/pjmedia/sdp.h index e2e325438d..ab25c10123 100644 --- a/pjmedia/include/pjmedia/sdp.h +++ b/pjmedia/include/pjmedia/sdp.h @@ -805,7 +805,13 @@ pjmedia_sdp_session_clone( pj_pool_t *pool, /** - * Compare two SDP session for equality. + * Compare two SDP session for equality, by comparing: + * - the fields origin, subject, connection, time + * - the attributes direction, fmtp, and rtpmap + * - the media descriptions (see #pjmedia_sdp_media_cmp()) + * + * The function will also call the callback + * \a pjmedia_sdp_session_cmp_cb() if registered. * * @param sd1 The first SDP session to compare. * @param sd2 The second SDP session to compare. @@ -814,12 +820,46 @@ pjmedia_sdp_session_clone( pj_pool_t *pool, * @return PJ_SUCCESS when both SDPs are equal, or otherwise * the status code indicates which part of the session * descriptors are not equal. + * If \a pjmedia_sdp_session_cmp_cb() is registered, + * will return the status output parameter of the callback. */ PJ_DECL(pj_status_t) pjmedia_sdp_session_cmp(const pjmedia_sdp_session *sd1, const pjmedia_sdp_session *sd2, unsigned option); +/** + * The declaration of customized SDP session comparison callback. See + * #pjmedia_sdp_session_register_cmp_cb() for more info. + * + * @param sd1 The first SDP session to compare. + * @param sd2 The second SDP session to compare. + * @param option Must be zero for now. + * @param status Status code to be returned for the SDP comparison result + * (PJ_SUCCESS meaning both SDPs are equal). + * On input, it contains the return status of + * #pjmedia_sdp_session_cmp(). + */ +typedef void (*pjmedia_sdp_session_cmp_cb)(const pjmedia_sdp_session *sd1, + const pjmedia_sdp_session *sd2, + unsigned option, + pj_status_t *status); + + +/** + * Register customized SDP session comparison callback. The callback will + * be called by #pjmedia_sdp_session_cmp(). + * To unregister, just call this function with parameter cb set to NULL. + * + * @param cb The customized SDP session comparison callback or + * NULL to unregister the callback. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) +pjmedia_sdp_session_register_cmp_cb(pjmedia_sdp_session_cmp_cb cb); + + /** * Add new attribute to the session descriptor. * diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h index 99c4c60efc..1249fb6394 100644 --- a/pjmedia/include/pjmedia/sdp_neg.h +++ b/pjmedia/include/pjmedia/sdp_neg.h @@ -719,38 +719,6 @@ PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, pj_bool_t allow_asym); -/** - * The declaration of customized SDP session comparison callback. See - * #pjmedia_sdp_neg_register_sdp_cmp_cb() for more info. - * - * @param sd1 The first SDP session to compare. - * @param sd2 The second SDP session to compare. - * @param option Must be zero for now. - * @param status Status code to be returned for the SDP comparison result - * (PJ_SUCCESS meaning both SDPs are equal). - * On input, it contains the return status of our default - * SDP comparison implementation, i.e. - * #pjmedia_sdp_session_cmp(). - */ -typedef void (*pjmedia_sdp_neg_sdp_cmp_cb)(const pjmedia_sdp_session *sd1, - const pjmedia_sdp_session *sd2, - unsigned option, - pj_status_t *status); - - -/** - * Register customized SDP session comparison callback. - * To unregister, just call this function with parameter cb set to NULL. - * - * @param cb The customized SDP session comparison callback or - * NULL to unregister the callback. - * - * @return PJ_SUCCESS on success. - */ -PJ_DECL(pj_status_t) -pjmedia_sdp_neg_register_sdp_cmp_cb(pjmedia_sdp_neg_sdp_cmp_cb cb); - - /** * Enumeration of customized SDP format matching option flags. See * #pjmedia_sdp_neg_register_fmt_match_cb() for more info. diff --git a/pjmedia/src/pjmedia/sdp_cmp.c b/pjmedia/src/pjmedia/sdp_cmp.c index dfa3f33970..1d2151e4d2 100644 --- a/pjmedia/src/pjmedia/sdp_cmp.c +++ b/pjmedia/src/pjmedia/sdp_cmp.c @@ -22,6 +22,9 @@ #include +/* The registered customized SDP session comparison callback */ +static pjmedia_sdp_session_cmp_cb sdp_cmp_cb; + /* Compare connection line. */ static pj_status_t compare_conn(const pjmedia_sdp_conn *c1, const pjmedia_sdp_conn *c2) @@ -218,12 +221,9 @@ PJ_DEF(pj_status_t) pjmedia_sdp_media_cmp( const pjmedia_sdp_media *sd1, return PJ_SUCCESS; } -/* - * Compare two SDP session for equality. - */ -PJ_DEF(pj_status_t) pjmedia_sdp_session_cmp( const pjmedia_sdp_session *sd1, - const pjmedia_sdp_session *sd2, - unsigned option) +static pj_status_t sdp_session_cmp(const pjmedia_sdp_session *sd1, + const pjmedia_sdp_session *sd2, + unsigned option) { unsigned i; pj_status_t status; @@ -295,6 +295,30 @@ PJ_DEF(pj_status_t) pjmedia_sdp_session_cmp( const pjmedia_sdp_session *sd1, return PJ_SUCCESS; } +/* + * Compare two SDP session for equality. + */ +PJ_DEF(pj_status_t) pjmedia_sdp_session_cmp( const pjmedia_sdp_session *sd1, + const pjmedia_sdp_session *sd2, + unsigned option) +{ + pj_status_t status; + + status = sdp_session_cmp(sd1, sd2, option); + if (sdp_cmp_cb) { + (*sdp_cmp_cb)(sd1, sd2, option, &status); + } + + return status; +} + +/* Register customized SDP session comparison callback function. */ +PJ_DEF(pj_status_t) +pjmedia_sdp_session_register_cmp_cb(pjmedia_sdp_session_cmp_cb cb) +{ + sdp_cmp_cb = cb; + return PJ_SUCCESS; +} PJ_DEF(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1, const pjmedia_sdp_conn *conn2, diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c index ada75fe814..ecc1911281 100644 --- a/pjmedia/src/pjmedia/sdp_neg.c +++ b/pjmedia/src/pjmedia/sdp_neg.c @@ -91,9 +91,6 @@ struct fmt_match_cb_t pjmedia_sdp_neg_fmt_match_cb cb; }; -/* The registered customized SDP session comparison callback */ -static pjmedia_sdp_neg_sdp_cmp_cb sdp_cmp_cb; - /* Number of registered customized SDP format negotiation callbacks */ static unsigned fmt_match_cb_cnt; @@ -371,20 +368,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool, return pjmedia_sdp_neg_modify_local_offer2(pool, neg, 0, local); } -static pj_status_t sdp_session_cmp(const pjmedia_sdp_session *sd1, - const pjmedia_sdp_session *sd2, - unsigned option) -{ - pj_status_t status; - - status = pjmedia_sdp_session_cmp(sd1, sd2, option); - if (sdp_cmp_cb) { - (*sdp_cmp_cb)(sd1, sd2, option, &status); - } - - return status; -} - PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2( pj_pool_t *pool, pjmedia_sdp_neg *neg, @@ -424,7 +407,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2( PJ_TRUE, PJ_FALSE); neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, neg->initial_sdp); - if (sdp_session_cmp(neg->last_sent, neg->neg_local_sdp, 0) != + if (pjmedia_sdp_session_cmp(neg->last_sent, neg->neg_local_sdp, 0) != PJ_SUCCESS) { ++neg->neg_local_sdp->origin.version; @@ -515,7 +498,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2( /* Assign PT numbers for our offer and update the mapping. */ assign_pt_and_update_map(pool, neg, new_offer, PJ_TRUE, PJ_FALSE); - if (sdp_session_cmp(neg->last_sent, new_offer, 0) != PJ_SUCCESS) { + if (pjmedia_sdp_session_cmp(neg->last_sent, new_offer, 0) != PJ_SUCCESS) { ++new_offer->origin.version; } neg->initial_sdp_tmp = neg->initial_sdp; @@ -558,7 +541,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool, neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER; new_offer = pjmedia_sdp_session_clone(pool, neg->active_local_sdp); - if (sdp_session_cmp(neg->last_sent, new_offer, 0) != + if (pjmedia_sdp_session_cmp(neg->last_sent, new_offer, 0) != PJ_SUCCESS) { ++new_offer->origin.version; @@ -2038,7 +2021,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, answer->origin.version = neg->last_sent->origin.version; if (!neg->last_sent || - sdp_session_cmp(neg->last_sent, answer, 0) != + pjmedia_sdp_session_cmp(neg->last_sent, answer, 0) != PJ_SUCCESS) { ++answer->origin.version; @@ -2075,14 +2058,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, } -/* Register customized SDP session comparison callback function. */ -PJ_DEF(pj_status_t) -pjmedia_sdp_neg_register_sdp_cmp_cb(pjmedia_sdp_neg_sdp_cmp_cb cb) -{ - sdp_cmp_cb = cb; - return PJ_SUCCESS; -} - static pj_status_t custom_fmt_match(pj_pool_t *pool, const pj_str_t *fmt_name, pjmedia_sdp_media *offer,