Changeset 6103
- Timestamp:
- Nov 8, 2019 10:17:16 AM (5 years ago)
- Location:
- pjproject/trunk/pjmedia/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
r5311 r6103 417 417 unsigned max_bitrate = 0; 418 418 pj_status_t status; 419 #if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \ 420 PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0 421 unsigned televent_num = 0; 422 unsigned televent_clockrates[8]; 423 unsigned used_pt_num = 0; 424 unsigned used_pt[PJMEDIA_MAX_SDP_FMT]; 425 #endif 419 426 420 427 PJ_UNUSED_ARG(options); … … 541 548 if (max_bitrate < codec_param.info.max_bps) 542 549 max_bitrate = codec_param.info.max_bps; 543 } 544 550 551 /* List clock rate & channel count of audio codecs for generating 552 * telephone-event later. 553 */ 545 554 #if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \ 546 PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0 555 PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0 556 { 557 unsigned j; 558 559 /* Take a note of used dynamic PT */ 560 if (codec_info->pt >= 96) 561 used_pt[used_pt_num++] = codec_info->pt; 562 563 for (j=0; j<televent_num; ++j) { 564 if (televent_clockrates[j] == rtpmap.clock_rate) 565 break; 566 } 567 if (j==televent_num && 568 televent_num<PJ_ARRAY_SIZE(televent_clockrates)) 569 { 570 /* List this clockrate for tel-event generation */ 571 televent_clockrates[televent_num++] = rtpmap.clock_rate; 572 } 573 } 574 #endif 575 } 576 577 #if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \ 578 PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0 547 579 /* 548 580 * Add support telephony event 549 581 */ 550 582 if (endpt->has_telephone_event) { 551 m->desc.fmt[m->desc.fmt_count++] = 552 pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR); 553 554 /* Add rtpmap. */ 555 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 556 attr->name = pj_str("rtpmap"); 557 attr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR 558 " telephone-event/8000"); 559 m->attr[m->attr_count++] = attr; 560 561 /* Add fmtp */ 562 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 563 attr->name = pj_str("fmtp"); 583 for (i=0; i<televent_num; i++) { 584 char buf[160]; 585 unsigned j = 0; 586 unsigned pt = PJMEDIA_RTP_PT_TELEPHONE_EVENTS; 587 588 /* Find PT for this tel-event */ 589 while (j < used_pt_num && pt <= 127) { 590 if (pt == used_pt[j]) { 591 pt++; 592 j = 0; 593 } else { 594 j++; 595 } 596 } 597 if (pt > 127) { 598 /* No more available PT */ 599 break; 600 } 601 used_pt[used_pt_num++] = pt; 602 603 /* Print tel-event PT */ 604 pj_ansi_snprintf(buf, sizeof(buf), "%d", pt); 605 m->desc.fmt[m->desc.fmt_count++] = pj_strdup3(pool, buf); 606 607 /* Add rtpmap. */ 608 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 609 attr->name = pj_str("rtpmap"); 610 pj_ansi_snprintf(buf, sizeof(buf), "%d telephone-event/%d", 611 pt, televent_clockrates[i]); 612 attr->value = pj_strdup3(pool, buf); 613 m->attr[m->attr_count++] = attr; 614 615 /* Add fmtp */ 616 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 617 attr->name = pj_str("fmtp"); 564 618 #if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0 565 attr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR " 0-16");619 pj_ansi_snprintf(buf, sizeof(buf), "%d 0-16", pt); 566 620 #else 567 attr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR " 0-15");621 pj_ansi_snprintf(buf, sizeof(buf), "%d 0-15", pt); 568 622 #endif 569 m->attr[m->attr_count++] = attr; 623 attr->value = pj_strdup3(pool, buf); 624 m->attr[m->attr_count++] = attr; 625 } 570 626 } 571 627 #endif -
pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c
r5828 r6103 1071 1071 pjmedia_sdp_media *answer; 1072 1072 const pjmedia_sdp_media *master, *slave; 1073 unsigned nclockrate = 0, clockrate[PJMEDIA_MAX_SDP_FMT]; 1073 1074 1074 1075 /* If offer has zero port, just clone the offer */ … … 1131 1132 p = pj_strtoul(&slave->desc.fmt[j]); 1132 1133 if (p == pt && pj_isdigit(*slave->desc.fmt[j].ptr)) { 1134 unsigned k; 1135 1133 1136 found_matching_codec = 1; 1134 1137 pt_offer[pt_answer_count] = slave->desc.fmt[j]; 1135 1138 pt_answer[pt_answer_count++] = slave->desc.fmt[j]; 1139 1140 /* Take note of clock rate for tel-event. Note: for 1141 * static PT, we assume the clock rate is 8000. 1142 */ 1143 for (k=0; k<nclockrate; ++k) 1144 if (clockrate[k] == 8000) 1145 break; 1146 if (k == nclockrate) 1147 clockrate[nclockrate++] = 8000; 1136 1148 break; 1137 1149 } … … 1145 1157 const pjmedia_sdp_attr *a; 1146 1158 pjmedia_sdp_rtpmap or_; 1147 pj_bool_t is_codec ;1159 pj_bool_t is_codec = 0; 1148 1160 1149 1161 /* Get the rtpmap for the payload type in the master. */ … … 1156 1168 pjmedia_sdp_attr_get_rtpmap(a, &or_); 1157 1169 1158 if (!pj_stricmp2(&or_.enc_name, "telephone-event")) { 1159 if (found_matching_telephone_event) 1160 continue; 1161 is_codec = 0; 1162 } else { 1170 if (pj_stricmp2(&or_.enc_name, "telephone-event")) { 1163 1171 master_has_codec = 1; 1164 1172 if (!answer_with_multiple_codecs && found_matching_codec) … … 1192 1200 pjmedia_sdp_media *o_med, *a_med; 1193 1201 unsigned o_fmt_idx, a_fmt_idx; 1202 unsigned k; 1194 1203 1195 1204 o_med = (pjmedia_sdp_media*)offer; … … 1208 1217 } 1209 1218 found_matching_codec = 1; 1219 1220 /* Take note of clock rate for tel-event */ 1221 for (k=0; k<nclockrate; ++k) 1222 if (clockrate[k] == or_.clock_rate) 1223 break; 1224 if (k == nclockrate) 1225 clockrate[nclockrate++] = or_.clock_rate; 1210 1226 } else { 1211 1227 found_matching_telephone_event = 1; … … 1270 1286 } 1271 1287 1272 /* Seems like everything is in order. 1273 * Build the answer by cloning from preanswer, but rearrange the payload 1288 /* Seems like everything is in order. */ 1289 1290 /* Remove unwanted telephone-event formats. */ 1291 if (found_matching_telephone_event) { 1292 pj_str_t first_televent_offer = {0}; 1293 pj_str_t first_televent_answer = {0}; 1294 unsigned matched_cnt = 0; 1295 1296 for (i=0; i<pt_answer_count; ) { 1297 const pjmedia_sdp_attr *a; 1298 pjmedia_sdp_rtpmap r; 1299 unsigned j; 1300 1301 /* Skip static PT, as telephone-event uses dynamic PT */ 1302 if (!pj_isdigit(*pt_answer[i].ptr) || pj_strtol(&pt_answer[i])<96) 1303 { 1304 ++i; 1305 continue; 1306 } 1307 1308 /* Get the rtpmap for format. */ 1309 a = pjmedia_sdp_media_find_attr2(preanswer, "rtpmap", 1310 &pt_answer[i]); 1311 pj_assert(a); 1312 pjmedia_sdp_attr_get_rtpmap(a, &r); 1313 1314 /* Only care for telephone-event format */ 1315 if (pj_stricmp2(&r.enc_name, "telephone-event")) { 1316 ++i; 1317 continue; 1318 } 1319 1320 if (first_televent_offer.slen == 0) { 1321 first_televent_offer = pt_offer[i]; 1322 first_televent_answer = pt_answer[i]; 1323 } 1324 1325 for (j=0; j<nclockrate; ++j) { 1326 if (r.clock_rate==clockrate[j]) 1327 break; 1328 } 1329 1330 /* This tel-event's clockrate is unwanted, remove the tel-event */ 1331 if (j==nclockrate) { 1332 pj_array_erase(pt_answer, sizeof(pt_answer[0]), 1333 pt_answer_count, i); 1334 pj_array_erase(pt_offer, sizeof(pt_offer[0]), 1335 pt_answer_count, i); 1336 pt_answer_count--; 1337 } else { 1338 ++matched_cnt; 1339 ++i; 1340 } 1341 } 1342 1343 /* Tel-event is wanted, but no matched clock rate (to the selected 1344 * audio codec), just put back any first matched tel-event formats. 1345 */ 1346 if (!matched_cnt) { 1347 pt_offer[pt_answer_count] = first_televent_offer; 1348 pt_answer[pt_answer_count++] = first_televent_answer; 1349 } 1350 } 1351 1352 /* Build the answer by cloning from preanswer, and reorder the payload 1274 1353 * to suit the offer. 1275 1354 */ -
pjproject/trunk/pjmedia/src/test/sdp_neg_test.c
r5619 r6103 1246 1246 }, 1247 1247 1248 /* test 17: */ 1249 { 1250 /********************************************************************* 1251 * Ticket #2088: : Handle multiple telephone-event formats. 1252 */ 1253 1254 "Ticket #2088: Handle multiple telephone-event formats", 1255 2, 1256 { 1257 { 1258 REMOTE_OFFER, 1259 /* Bob sends offer: */ 1260 "v=0\r\n" 1261 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n" 1262 "s=bob\r\n" 1263 "c=IN IP4 host.biloxi.example.com\r\n" 1264 "t=0 0\r\n" 1265 "m=audio 3000 RTP/AVP 97 0 98 99\r\n" 1266 "a=rtpmap:97 Speex/16000\r\n" 1267 "a=rtpmap:0 PCMU/8000\r\n" 1268 "a=rtpmap:98 telephone-event/8000\r\n" 1269 "a=rtpmap:99 telephone-event/16000\r\n" 1270 "", 1271 /* Alice initial capability: */ 1272 "v=0\r\n" 1273 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n" 1274 "s=alice\r\n" 1275 "c=IN IP4 host.atlanta.example.com\r\n" 1276 "t=0 0\r\n" 1277 "m=audio 4000 RTP/AVP 0 100 96 98\r\n" 1278 "a=rtpmap:0 PCMU/8000\r\n" 1279 "a=rtpmap:100 Speex/16000\r\n" 1280 "a=rtpmap:96 telephone-event/8000\r\n" 1281 "a=rtpmap:98 telephone-event/16000\r\n" 1282 "", 1283 /* Alice's local SDP should be: */ 1284 "v=0\r\n" 1285 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n" 1286 "s=alice\r\n" 1287 "c=IN IP4 host.atlanta.example.com\r\n" 1288 "t=0 0\r\n" 1289 "m=audio 4000 RTP/AVP 97 99\r\n" 1290 "a=rtpmap:97 Speex/16000\r\n" 1291 "a=rtpmap:99 telephone-event/16000\r\n" 1292 "", 1293 }, 1294 { 1295 LOCAL_OFFER, 1296 /* Alice updates offer */ 1297 "v=0\r\n" 1298 "o=alice 2890844526 2890844528 IN IP4 host.atlanta.example.com\r\n" 1299 "s=alice\r\n" 1300 "c=IN IP4 host.atlanta.example.com\r\n" 1301 "t=0 0\r\n" 1302 "m=audio 4000 RTP/AVP 0 97 98 99\r\n" 1303 "a=rtpmap:0 PCMU/8000\r\n" 1304 "a=rtpmap:97 Speex/16000\r\n" 1305 "a=rtpmap:98 telephone-event/8000\r\n" 1306 "a=rtpmap:99 telephone-event/16000\r\n" 1307 "", 1308 /* Receive Bob's answer: */ 1309 "v=0\r\n" 1310 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n" 1311 "s=bob\r\n" 1312 "c=IN IP4 host.biloxi.example.com\r\n" 1313 "t=0 0\r\n" 1314 "m=audio 3000 RTP/AVP 99 100\r\n" 1315 "a=rtpmap:99 Speex/16000\r\n" 1316 "a=rtpmap:100 telephone-event/16000\r\n" 1317 "", 1318 /* Alice's local SDP should be: */ 1319 "v=0\r\n" 1320 "o=alice 2890844526 2890844528 IN IP4 host.atlanta.example.com\r\n" 1321 "s=alice\r\n" 1322 "c=IN IP4 host.atlanta.example.com\r\n" 1323 "t=0 0\r\n" 1324 "m=audio 4000 RTP/AVP 97 99\r\n" 1325 "a=rtpmap:97 Speex/16000\r\n" 1326 "a=rtpmap:99 telephone-event/16000\r\n" 1327 "", 1328 } 1329 } 1330 }, 1331 1248 1332 }; 1249 1333
Note: See TracChangeset
for help on using the changeset viewer.