Changeset 3911 for pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
- Timestamp:
- Dec 15, 2011 6:45:23 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
r3869 r3911 53 53 }; 54 54 55 #define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \56 do { \57 pj_str_t s; \58 char *p; \59 p = pj_stristr(&fmtp.fmt_param, ¶m); \60 if (!p) { \61 ival = default_val; \62 break; \63 } \64 pj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \65 (p - fmtp.fmt_param.ptr) - param.slen); \66 ival = pj_strtoul2(&s, NULL, base); \67 } while (0)68 69 #define GET_FMTP_IVAL(ival, fmtp, param, default_val) \70 GET_FMTP_IVAL_BASE(ival, 10, fmtp, param, default_val)71 72 73 55 /* Definition of customized SDP format negotiation callback */ 74 56 struct fmt_match_cb_t … … 611 593 } 612 594 613 /* Matching G722.1 bitrates between offer and answer.614 */615 static pj_bool_t match_g7221( const pjmedia_sdp_media *offer,616 unsigned o_fmt_idx,617 const pjmedia_sdp_media *answer,618 unsigned a_fmt_idx)619 {620 const pjmedia_sdp_attr *attr_ans;621 const pjmedia_sdp_attr *attr_ofr;622 pjmedia_sdp_fmtp fmtp;623 unsigned a_bitrate, o_bitrate;624 const pj_str_t bitrate = {"bitrate=", 8};625 626 /* Parse offer */627 attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp",628 &offer->desc.fmt[o_fmt_idx]);629 if (!attr_ofr)630 return PJ_FALSE;631 632 if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS)633 return PJ_FALSE;634 635 GET_FMTP_IVAL(o_bitrate, fmtp, bitrate, 0);636 637 /* Parse answer */638 attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp",639 &answer->desc.fmt[a_fmt_idx]);640 if (!attr_ans)641 return PJ_FALSE;642 643 if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS)644 return PJ_FALSE;645 646 GET_FMTP_IVAL(a_bitrate, fmtp, bitrate, 0);647 648 /* Compare bitrate in answer and offer. */649 return (a_bitrate == o_bitrate);650 }651 652 /* Negotiate AMR format params between offer and answer. Format params653 * to be matched are: octet-align, crc, robust-sorting, interleaving,654 * and channels (channels is negotiated by rtpmap line negotiation).655 * Note: For answerer, octet-align mode setting is adaptable to offerer656 * setting. In the case that octet-align mode need to be adjusted,657 * pt_need_adapt will be set to the format ID.658 *659 */660 static pj_bool_t match_amr( const pjmedia_sdp_media *offer,661 unsigned o_fmt_idx,662 const pjmedia_sdp_media *answer,663 unsigned a_fmt_idx,664 pj_bool_t answerer,665 pj_str_t *pt_need_adapt)666 {667 /* Negotiated format-param field-names constants. */668 const pj_str_t STR_OCTET_ALIGN = {"octet-align=", 12};669 const pj_str_t STR_CRC = {"crc=", 4};670 const pj_str_t STR_ROBUST_SORTING = {"robust-sorting=", 15};671 const pj_str_t STR_INTERLEAVING = {"interleaving=", 13};672 673 /* Negotiated params and their default values. */674 unsigned a_octet_align = 0, o_octet_align = 0;675 unsigned a_crc = 0, o_crc = 0;676 unsigned a_robust_sorting = 0, o_robust_sorting = 0;677 unsigned a_interleaving = 0, o_interleaving = 0;678 679 const pjmedia_sdp_attr *attr_ans;680 const pjmedia_sdp_attr *attr_ofr;681 pjmedia_sdp_fmtp fmtp;682 pj_bool_t match;683 684 /* Parse offerer FMTP */685 attr_ofr = pjmedia_sdp_media_find_attr2(offer, "fmtp",686 &offer->desc.fmt[o_fmt_idx]);687 if (attr_ofr) {688 if (pjmedia_sdp_attr_get_fmtp(attr_ofr, &fmtp) != PJ_SUCCESS)689 /* Invalid fmtp format. */690 return PJ_FALSE;691 692 GET_FMTP_IVAL(o_octet_align, fmtp, STR_OCTET_ALIGN, 0);693 GET_FMTP_IVAL(o_crc, fmtp, STR_CRC, 0);694 GET_FMTP_IVAL(o_robust_sorting, fmtp, STR_ROBUST_SORTING, 0);695 GET_FMTP_IVAL(o_interleaving, fmtp, STR_INTERLEAVING, 0);696 }697 698 /* Parse answerer FMTP */699 attr_ans = pjmedia_sdp_media_find_attr2(answer, "fmtp",700 &answer->desc.fmt[a_fmt_idx]);701 if (attr_ans) {702 if (pjmedia_sdp_attr_get_fmtp(attr_ans, &fmtp) != PJ_SUCCESS)703 /* Invalid fmtp format. */704 return PJ_FALSE;705 706 GET_FMTP_IVAL(a_octet_align, fmtp, STR_OCTET_ALIGN, 0);707 GET_FMTP_IVAL(a_crc, fmtp, STR_CRC, 0);708 GET_FMTP_IVAL(a_robust_sorting, fmtp, STR_ROBUST_SORTING, 0);709 GET_FMTP_IVAL(a_interleaving, fmtp, STR_INTERLEAVING, 0);710 }711 712 if (answerer) {713 match = a_crc == o_crc &&714 a_robust_sorting == o_robust_sorting &&715 a_interleaving == o_interleaving;716 717 /* If answerer octet-align setting doesn't match to the offerer's,718 * set pt_need_adapt to this media format ID to signal the caller719 * that this format ID needs to be adjusted.720 */721 if (a_octet_align != o_octet_align && match) {722 pj_assert(pt_need_adapt != NULL);723 *pt_need_adapt = answer->desc.fmt[a_fmt_idx];724 }725 } else {726 match = (a_octet_align == o_octet_align &&727 a_crc == o_crc &&728 a_robust_sorting == o_robust_sorting &&729 a_interleaving == o_interleaving);730 }731 732 return match;733 }734 735 736 /* Toggle AMR octet-align setting in the fmtp.737 */738 static pj_status_t amr_toggle_octet_align(pj_pool_t *pool,739 pjmedia_sdp_media *media,740 unsigned fmt_idx)741 {742 pjmedia_sdp_attr *attr;743 pjmedia_sdp_fmtp fmtp;744 const pj_str_t STR_OCTET_ALIGN = {"octet-align=", 12};745 746 enum { MAX_FMTP_STR_LEN = 160 };747 748 attr = pjmedia_sdp_media_find_attr2(media, "fmtp",749 &media->desc.fmt[fmt_idx]);750 /* Check if the AMR media format has FMTP attribute */751 if (attr) {752 char *p;753 pj_status_t status;754 755 status = pjmedia_sdp_attr_get_fmtp(attr, &fmtp);756 if (status != PJ_SUCCESS)757 return status;758 759 /* Check if the fmtp has octet-align field. */760 p = pj_stristr(&fmtp.fmt_param, &STR_OCTET_ALIGN);761 if (p) {762 /* It has, just toggle the value */763 unsigned octet_align;764 pj_str_t s;765 766 pj_strset(&s, p + STR_OCTET_ALIGN.slen, fmtp.fmt_param.slen -767 (p - fmtp.fmt_param.ptr) - STR_OCTET_ALIGN.slen);768 octet_align = pj_strtoul(&s);769 *(p + STR_OCTET_ALIGN.slen) = (char)(octet_align? '0' : '1');770 } else {771 /* It doesn't, append octet-align field */772 char buf[MAX_FMTP_STR_LEN];773 774 pj_ansi_snprintf(buf, MAX_FMTP_STR_LEN, "%.*s;octet-align=1",775 (int)fmtp.fmt_param.slen, fmtp.fmt_param.ptr);776 attr->value = pj_strdup3(pool, buf);777 }778 } else {779 /* Add new attribute for the AMR media format with octet-align780 * field set.781 */782 char buf[MAX_FMTP_STR_LEN];783 784 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);785 attr->name = pj_str("fmtp");786 pj_ansi_snprintf(buf, MAX_FMTP_STR_LEN, "%.*s octet-align=1",787 (int)media->desc.fmt[fmt_idx].slen,788 media->desc.fmt[fmt_idx].ptr);789 attr->value = pj_strdup3(pool, buf);790 media->attr[media->attr_count++] = attr;791 }792 793 return PJ_SUCCESS;794 }795 796 595 797 596 /* Update single local media description to after receiving answer … … 931 730 (ar.param.slen==1 && *ar.param.ptr=='1'))) 932 731 { 933 /* Further check for G7221, negotiate bitrate. */934 if (pj_stricmp2(&or_.enc_name, "G7221") == 0)935 {936 if (match_g7221(offer, i, answer, j))937 break;938 } else939 940 /* Further check for AMR, negotiate fmtp. */941 if (pj_stricmp2(&or_.enc_name, "AMR") == 0 ||942 pj_stricmp2(&or_.enc_name, "AMR-WB") == 0)943 {944 if (match_amr(offer, i, answer, j, PJ_FALSE,945 NULL))946 break;947 } else948 949 732 /* Call custom format matching callbacks */ 950 733 if (custom_fmt_match(pool, &or_.enc_name, … … 1218 1001 pjmedia_sdp_media *answer; 1219 1002 const pjmedia_sdp_media *master, *slave; 1220 pj_str_t pt_amr_need_adapt = {NULL, 0};1221 1003 1222 1004 /* If offer has zero port, just clone the offer */ … … 1355 1137 { 1356 1138 continue; 1357 } else1358 1359 /* Further check for G7221, negotiate bitrate */1360 if (pj_stricmp2(&or_.enc_name, "G7221") == 0 &&1361 !match_g7221(master, i, slave, j))1362 {1363 continue;1364 } else1365 1366 /* Further check for AMR, negotiate fmtp */1367 if (pj_stricmp2(&or_.enc_name, "AMR")==0 ||1368 pj_stricmp2(&or_.enc_name, "AMR-WB")==0)1369 {1370 unsigned o_med_idx, a_med_idx;1371 1372 o_med_idx = prefer_remote_codec_order? i:j;1373 a_med_idx = prefer_remote_codec_order? j:i;1374 if (!match_amr(offer, o_med_idx,1375 preanswer, a_med_idx,1376 PJ_TRUE, &pt_amr_need_adapt))1377 continue;1378 1139 } 1379 1380 1140 found_matching_codec = 1; 1381 1141 } else { … … 1454 1214 pj_assert(j != answer->desc.fmt_count); 1455 1215 str_swap(&answer->desc.fmt[i], &answer->desc.fmt[j]); 1456 1457 /* For AMR/AMRWB format, adapt octet-align setting if required. */1458 if (!pj_strcmp(&pt_amr_need_adapt, &pt_answer[i]))1459 amr_toggle_octet_align(pool, answer, i);1460 1216 } 1461 1217 … … 1784 1540 } 1785 1541 1786 /* Further check for G7221, negotiate bitrate. */1787 if (pj_stricmp2(&o_rtpmap.enc_name, "G7221") == 0) {1788 if (match_g7221(offer, o_fmt_idx, answer, a_fmt_idx))1789 return PJ_SUCCESS;1790 else1791 return PJMEDIA_SDP_EFORMATNOTEQUAL;1792 } else1793 /* Further check for AMR, negotiate fmtp. */1794 if (pj_stricmp2(&o_rtpmap.enc_name, "AMR") == 0 ||1795 pj_stricmp2(&o_rtpmap.enc_name, "AMR-WB") == 0)1796 {1797 if (match_amr(offer, o_fmt_idx, answer, a_fmt_idx, PJ_FALSE, NULL))1798 return PJ_SUCCESS;1799 else1800 return PJMEDIA_SDP_EFORMATNOTEQUAL;1801 }1802 PJ_TODO(replace_hardcoded_fmt_match_in_sdp_neg_with_custom_fmt_match_cb);1803 1804 1542 return custom_fmt_match(pool, &o_rtpmap.enc_name, 1805 1543 offer, o_fmt_idx, answer, a_fmt_idx, option);
Note: See TracChangeset
for help on using the changeset viewer.