PJ_DEF(pj_status_t) pjmedia_codec_g7221_match_sdp(pj_pool_t *pool, pjmedia_sdp_media *offer, unsigned o_fmt_idx, pjmedia_sdp_media *answer, unsigned a_fmt_idx, unsigned option) { const pjmedia_sdp_attr *attr_ans; const pjmedia_sdp_attr *attr_ofr; pjmedia_sdp_fmtp fmtp; unsigned a_bitrate, o_bitrate; const pj_str_t bitrate = {"bitrate=", 8}; pj_status_t status; PJ_UNUSED_ARG(pool); PJ_UNUSED_ARG(option); /* Parse offer */ attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", &offer->desc.fmt[o_fmt_idx]); if (!attr_ofr) return PJMEDIA_SDP_EINFMTP; status = pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp); if (status != PJ_SUCCESS) return status; GET_FMTP_IVAL(o_bitrate, fmtp, bitrate, 0); /* Parse answer */ attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", &answer->desc.fmt[a_fmt_idx]); if (!attr_ans) return PJMEDIA_SDP_EINFMTP; status = pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp); if (status != PJ_SUCCESS) return status; GET_FMTP_IVAL(a_bitrate, fmtp, bitrate, 0); /* Compare bitrate in answer and offer. */ if (a_bitrate != o_bitrate) return PJMEDIA_SDP_EFORMATNOTEQUAL; return PJ_SUCCESS; }
/* Matching G722.1 bitrates between offer and answer. */ static pj_bool_t match_g7221( const pjmedia_sdp_media *offer, unsigned o_fmt_idx, const pjmedia_sdp_media *answer, unsigned a_fmt_idx) { const pjmedia_sdp_attr *attr_ans; const pjmedia_sdp_attr *attr_ofr; pjmedia_sdp_fmtp fmtp; unsigned a_bitrate, o_bitrate; const pj_str_t bitrate = {"bitrate=", 8}; /* Parse offer */ attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", &offer->desc.fmt[o_fmt_idx]); if (!attr_ofr) return PJ_FALSE; if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS) return PJ_FALSE; GET_FMTP_IVAL(o_bitrate, fmtp, bitrate, 0); /* Parse answer */ attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", &answer->desc.fmt[a_fmt_idx]); if (!attr_ans) return PJ_FALSE; if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS) return PJ_FALSE; GET_FMTP_IVAL(a_bitrate, fmtp, bitrate, 0); /* Compare bitrate in answer and offer. */ return (a_bitrate == o_bitrate); }
/* Negotiate AMR format params between offer and answer. Format params * to be matched are: octet-align, crc, robust-sorting, interleaving, * and channels (channels is negotiated by rtpmap line negotiation). * Note: For answerer, octet-align mode setting is adaptable to offerer * setting. In the case that octet-align mode need to be adjusted, * pt_need_adapt will be set to the format ID. * */ static pj_bool_t match_amr( const pjmedia_sdp_media *offer, unsigned o_fmt_idx, const pjmedia_sdp_media *answer, unsigned a_fmt_idx, pj_bool_t answerer, pj_str_t *pt_need_adapt) { /* Negotiated format-param field-names constants. */ const pj_str_t STR_OCTET_ALIGN = {"octet-align=", 12}; const pj_str_t STR_CRC = {"crc=", 4}; const pj_str_t STR_ROBUST_SORTING = {"robust-sorting=", 15}; const pj_str_t STR_INTERLEAVING = {"interleaving=", 13}; /* Negotiated params and their default values. */ unsigned a_octet_align = 0, o_octet_align = 0; unsigned a_crc = 0, o_crc = 0; unsigned a_robust_sorting = 0, o_robust_sorting = 0; unsigned a_interleaving = 0, o_interleaving = 0; const pjmedia_sdp_attr *attr_ans; const pjmedia_sdp_attr *attr_ofr; pjmedia_sdp_fmtp fmtp; pj_bool_t match; /* Parse offerer FMTP */ attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", &offer->desc.fmt[o_fmt_idx]); if (attr_ofr) { if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS) /* Invalid fmtp format. */ return PJ_FALSE; GET_FMTP_IVAL(o_octet_align, fmtp, STR_OCTET_ALIGN, 0); GET_FMTP_IVAL(o_crc, fmtp, STR_CRC, 0); GET_FMTP_IVAL(o_robust_sorting, fmtp, STR_ROBUST_SORTING, 0); GET_FMTP_IVAL(o_interleaving, fmtp, STR_INTERLEAVING, 0); } /* Parse answerer FMTP */ attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", &answer->desc.fmt[a_fmt_idx]); if (attr_ans) { if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS) /* Invalid fmtp format. */ return PJ_FALSE; GET_FMTP_IVAL(a_octet_align, fmtp, STR_OCTET_ALIGN, 0); GET_FMTP_IVAL(a_crc, fmtp, STR_CRC, 0); GET_FMTP_IVAL(a_robust_sorting, fmtp, STR_ROBUST_SORTING, 0); GET_FMTP_IVAL(a_interleaving, fmtp, STR_INTERLEAVING, 0); } if (answerer) { match = a_crc == o_crc && a_robust_sorting == o_robust_sorting && a_interleaving == o_interleaving; /* If answerer octet-align setting doesn't match to the offerer's, * set pt_need_adapt to this media format ID to signal the caller * that this format ID needs to be adjusted. */ if (a_octet_align != o_octet_align && match) { pj_assert(pt_need_adapt != NULL); *pt_need_adapt = answer->desc.fmt[a_fmt_idx]; } } else { match = (a_octet_align == o_octet_align && a_crc == o_crc && a_robust_sorting == o_robust_sorting && a_interleaving == o_interleaving); } return match; }
PJ_DEF(pj_status_t) pjmedia_codec_amr_match_sdp( pj_pool_t *pool, pjmedia_sdp_media *offer, unsigned o_fmt_idx, pjmedia_sdp_media *answer, unsigned a_fmt_idx, unsigned option) { /* Negotiated format-param field-names constants. */ const pj_str_t STR_OCTET_ALIGN = {"octet-align=", 12}; const pj_str_t STR_CRC = {"crc=", 4}; const pj_str_t STR_ROBUST_SORTING = {"robust-sorting=", 15}; const pj_str_t STR_INTERLEAVING = {"interleaving=", 13}; /* Negotiated params and their default values. */ unsigned a_octet_align = 0, o_octet_align = 0; unsigned a_crc = 0, o_crc = 0; unsigned a_robust_sorting = 0, o_robust_sorting = 0; unsigned a_interleaving = 0, o_interleaving = 0; const pjmedia_sdp_attr *attr_ans; const pjmedia_sdp_attr *attr_ofr; pjmedia_sdp_fmtp fmtp; pj_status_t status; /* Parse offerer FMTP */ attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp", &offer->desc.fmt[o_fmt_idx]); if (attr_ofr) { status = pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp); if (status != PJ_SUCCESS) return status; GET_FMTP_IVAL(o_octet_align, fmtp, STR_OCTET_ALIGN, 0); GET_FMTP_IVAL(o_crc, fmtp, STR_CRC, 0); GET_FMTP_IVAL(o_robust_sorting, fmtp, STR_ROBUST_SORTING, 0); GET_FMTP_IVAL(o_interleaving, fmtp, STR_INTERLEAVING, 0); } /* Parse answerer FMTP */ attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp", &answer->desc.fmt[a_fmt_idx]); if (attr_ans) { status = pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp); if (status != PJ_SUCCESS) return status; GET_FMTP_IVAL(a_octet_align, fmtp, STR_OCTET_ALIGN, 0); GET_FMTP_IVAL(a_crc, fmtp, STR_CRC, 0); GET_FMTP_IVAL(a_robust_sorting, fmtp, STR_ROBUST_SORTING, 0); GET_FMTP_IVAL(a_interleaving, fmtp, STR_INTERLEAVING, 0); } /* First, match crc, robust-sorting, interleaving settings */ if (a_crc != o_crc || a_robust_sorting != o_robust_sorting || a_interleaving != o_interleaving) { return PJMEDIA_SDP_EFORMATNOTEQUAL; } /* Match octet-align setting */ if (a_octet_align != o_octet_align) { /* Check if answer can be modified to match to the offer */ if (option & PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER) { status = amr_toggle_octet_align(pool, answer, a_fmt_idx); return status; } else { return PJMEDIA_SDP_EFORMATNOTEQUAL; } } return PJ_SUCCESS; }