- Timestamp:
- Mar 15, 2011 11:28:24 AM (14 years ago)
- Location:
- pjproject/branches/projects/2.0-dev/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/endpoint.h
r3392 r3450 181 181 * also denotes the maximum number of streams (i.e. 182 182 * the "m=" lines) that will be created in the SDP. 183 * By convention, if this value is greater than one, 184 * the first media will be audio and the remaining 185 * media is video. 183 186 * @param sock_info Array of socket transport information. One 184 187 * transport is needed for each media stream, and … … 195 198 pjmedia_sdp_session **p_sdp ); 196 199 200 /** 201 * Create a "blank" SDP session description. The SDP will contain basic SDP 202 * fields such as origin, time, and name, but without any media lines. 203 * 204 * @param endpt The media endpoint. 205 * @param pool Pool to allocate memory from. 206 * @param sess_name Optional SDP session name, or NULL to use default 207 * value. 208 * @param origin Address to put in the origin field. 209 * @param p_sdp Pointer to receive the created SDP session. 210 * 211 * @return PJ_SUCCESS on success, or the appropriate error code. 212 */ 213 PJ_DECL(pj_status_t) pjmedia_endpt_create_base_sdp(pjmedia_endpt *endpt, 214 pj_pool_t *pool, 215 const pj_str_t *sess_name, 216 const pj_sockaddr *origin, 217 pjmedia_sdp_session **p_sdp); 218 219 /** 220 * Create SDP media line for audio media. 221 * 222 * @param endpt The media endpoint. 223 * @param pool Pool to allocate memory from. 224 * @param si Socket information. 225 * @param options Option flags, must be zero for now. 226 * @param p_m Pointer to receive the created SDP media. 227 * 228 * @return PJ_SUCCESS on success, or the appropriate error code. 229 */ 230 PJ_DECL(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt, 231 pj_pool_t *pool, 232 const pjmedia_sock_info*si, 233 unsigned options, 234 pjmedia_sdp_media **p_m); 235 236 /** 237 * Create SDP media line for video media. 238 * 239 * @param endpt The media endpoint. 240 * @param pool Pool to allocate memory from. 241 * @param si Socket information. 242 * @param options Option flags, must be zero for now. 243 * @param p_m Pointer to receive the created SDP media. 244 * 245 * @return PJ_SUCCESS on success, or the appropriate error code. 246 */ 247 PJ_DECL(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt, 248 pj_pool_t *pool, 249 const pjmedia_sock_info*si, 250 unsigned options, 251 pjmedia_sdp_media **p_m); 197 252 198 253 /** -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/endpoint.c
r3419 r3450 321 321 } 322 322 323 324 static pj_status_t init_sdp_media_audio_format(pj_pool_t *pool, 325 pjmedia_endpt *endpt, 326 pjmedia_sdp_media *m) 327 { 323 /* Common initialization for both audio and video SDP media line */ 324 static pj_status_t init_sdp_media(pjmedia_sdp_media *m, 325 pj_pool_t *pool, 326 const pj_str_t *media_type, 327 const pjmedia_sock_info *sock_info) 328 { 329 char tmp_addr[PJ_INET6_ADDRSTRLEN]; 330 pjmedia_sdp_attr *attr; 331 const pj_sockaddr *addr; 332 333 pj_strdup(pool, &m->desc.media, media_type); 334 335 addr = &sock_info->rtp_addr_name; 336 337 /* Validate address family */ 338 PJ_ASSERT_RETURN(addr->addr.sa_family == pj_AF_INET() || 339 addr->addr.sa_family == pj_AF_INET6(), 340 PJ_EAFNOTSUP); 341 342 /* SDP connection line */ 343 m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 344 m->conn->net_type = STR_IN; 345 m->conn->addr_type = (addr->addr.sa_family==pj_AF_INET())? STR_IP4:STR_IP6; 346 pj_sockaddr_print(addr, tmp_addr, sizeof(tmp_addr), 0); 347 pj_strdup2(pool, &m->conn->addr, tmp_addr); 348 349 /* Port and transport in media description */ 350 m->desc.port = pj_sockaddr_get_port(addr); 351 m->desc.port_count = 1; 352 pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP); 353 354 /* Add "rtcp" attribute */ 355 #if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0 356 if (sock_info->rtcp_addr_name.addr.sa_family != 0) { 357 attr = pjmedia_sdp_attr_create_rtcp(pool, &sock_info->rtcp_addr_name); 358 if (attr) 359 pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr); 360 } 361 #endif 362 363 /* Add sendrecv attribute. */ 364 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 365 attr->name = STR_SENDRECV; 366 m->attr[m->attr_count++] = attr; 367 368 return PJ_SUCCESS; 369 } 370 371 /* Create m=audio SDP media line */ 372 PJ_DEF(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt, 373 pj_pool_t *pool, 374 const pjmedia_sock_info *si, 375 unsigned options, 376 pjmedia_sdp_media **p_m) 377 { 378 const pj_str_t STR_AUDIO = { "audio", 5 }; 379 pjmedia_sdp_media *m; 328 380 pjmedia_sdp_attr *attr; 329 381 unsigned i; 382 pj_status_t status; 383 384 PJ_UNUSED_ARG(options); 330 385 331 386 /* Check that there are not too many codecs */ 332 387 PJ_ASSERT_RETURN(endpt->codec_mgr.codec_cnt <= PJMEDIA_MAX_SDP_FMT, 333 388 PJ_ETOOMANY); 389 390 /* Create and init basic SDP media */ 391 m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 392 status = init_sdp_media(m, pool, &STR_AUDIO, si); 393 if (status != PJ_SUCCESS) 394 return status; 334 395 335 396 /* Add format, rtpmap, and fmtp (when applicable) for each codec */ … … 466 527 #endif 467 528 468 return PJ_SUCCESS; 469 } 470 471 472 static pj_status_t init_sdp_media_video_format(pj_pool_t *pool, 473 pjmedia_endpt *endpt, 474 pjmedia_sdp_media *m) 475 { 529 *p_m = m; 530 return PJ_SUCCESS; 531 } 532 533 /* Create m=video SDP media line */ 534 PJ_DEF(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt, 535 pj_pool_t *pool, 536 const pjmedia_sock_info *si, 537 unsigned options, 538 pjmedia_sdp_media **p_m) 539 { 540 const pj_str_t STR_VIDEO = { "video", 5 }; 541 pjmedia_sdp_media *m; 476 542 pjmedia_vid_codec_info codec_info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]; 477 543 unsigned codec_prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]; … … 484 550 pjmedia_vid_codec_mgr_create(endpt->pool, NULL); 485 551 552 /* Create and init basic SDP media */ 553 m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 554 status = init_sdp_media(m, pool, &STR_VIDEO, si); 555 if (status != PJ_SUCCESS) 556 return status; 557 486 558 cnt = PJ_ARRAY_SIZE(codec_info); 487 559 status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, … … 494 566 /* Add format, rtpmap, and fmtp (when applicable) for each codec */ 495 567 for (i=0; i<cnt; ++i) { 496 497 pjmedia_sdp_rtpmap rtpmap = {0}; 568 pjmedia_sdp_rtpmap rtpmap; 498 569 pjmedia_vid_codec_param codec_param; 499 570 pj_str_t *fmt; 571 572 pj_bzero(&rtpmap, sizeof(rtpmap)); 500 573 501 574 if (codec_prio[i] == PJMEDIA_CODEC_PRIO_DISABLED) … … 506 579 * returning appropriate status code. 507 580 */ 508 PJ_LOG(3, (THIS_FILE, "Too many video codecs")); 581 PJ_PERROR(3,(THIS_FILE, PJ_ETOOMANY, 582 "Skipping some video codecs")); 509 583 break; 510 584 } … … 588 662 } 589 663 590 return PJ_SUCCESS; 591 } 592 593 594 static pj_status_t add_sdp_media(pjmedia_endpt *endpt, 595 pj_pool_t *pool, 596 pjmedia_type type, 597 const pjmedia_sock_info *sock_info, 598 pjmedia_sdp_session *sdp) 599 { 600 pjmedia_sdp_media *m; 601 pjmedia_sdp_attr *attr; 602 pjmedia_sdp_conn conn; 603 const pj_sockaddr *addr; 604 pj_status_t status; 605 606 addr = &sock_info->rtp_addr_name; 607 608 /* Validate address family */ 609 if (addr->addr.sa_family != pj_AF_INET() && 610 addr->addr.sa_family != pj_AF_INET6()) 611 { 612 pj_assert(!"Invalid address family"); 613 return PJ_EAFNOTSUP; 614 } 615 616 /* Validate media type */ 617 if (type != PJMEDIA_TYPE_AUDIO && type != PJMEDIA_TYPE_VIDEO) { 618 pj_assert(!"Invalid mediay type"); 619 return PJMEDIA_EINVALIMEDIATYPE; 620 } 621 622 /* Allocate SDP media */ 623 m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media); 624 625 /* Connection data, if not the same to one in the session level */ 626 { 627 char tmp_addr[PJ_INET6_ADDRSTRLEN]; 628 pj_bzero(&conn, sizeof(conn)); 629 conn.net_type = STR_IN; 630 conn.addr_type = (addr->addr.sa_family==pj_AF_INET())? STR_IP4:STR_IP6; 631 pj_sockaddr_print(addr, tmp_addr, sizeof(tmp_addr), 0); 632 pj_strset2(&conn.addr, tmp_addr); 633 634 if (pjmedia_sdp_conn_cmp(&conn, sdp->conn, 0) != PJ_SUCCESS) 635 m->conn = pjmedia_sdp_conn_clone(pool, &conn); 636 } 637 638 /* Port and transport in media description */ 639 m->desc.port = pj_sockaddr_get_port(addr); 640 m->desc.port_count = 1; 641 pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP); 642 643 /* Media formats and parameters */ 644 if (type == PJMEDIA_TYPE_AUDIO) { 645 pj_strdup(pool, &m->desc.media, &STR_AUDIO); 646 status = init_sdp_media_audio_format(pool, endpt, m); 664 *p_m = m; 665 return PJ_SUCCESS; 666 } 667 668 669 /** 670 * Create a "blank" SDP session description. The SDP will contain basic SDP 671 * fields such as origin, time, and name, but without any media lines. 672 */ 673 PJ_DEF(pj_status_t) pjmedia_endpt_create_base_sdp( pjmedia_endpt *endpt, 674 pj_pool_t *pool, 675 const pj_str_t *sess_name, 676 const pj_sockaddr *origin, 677 pjmedia_sdp_session **p_sdp) 678 { 679 pj_time_val tv; 680 pjmedia_sdp_session *sdp; 681 682 /* Sanity check arguments */ 683 PJ_ASSERT_RETURN(endpt && pool && p_sdp, PJ_EINVAL); 684 685 sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session); 686 687 pj_gettimeofday(&tv); 688 sdp->origin.user = pj_str("-"); 689 sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL; 690 sdp->origin.net_type = STR_IN; 691 692 if (origin->addr.sa_family == pj_AF_INET()) { 693 sdp->origin.addr_type = STR_IP4; 694 pj_strdup2(pool, &sdp->origin.addr, 695 pj_inet_ntoa(origin->ipv4.sin_addr)); 696 } else if (origin->addr.sa_family == pj_AF_INET6()) { 697 char tmp_addr[PJ_INET6_ADDRSTRLEN]; 698 699 sdp->origin.addr_type = STR_IP6; 700 pj_strdup2(pool, &sdp->origin.addr, 701 pj_sockaddr_print(origin, tmp_addr, sizeof(tmp_addr), 0)); 702 647 703 } else { 648 pj_strdup(pool, &m->desc.media, &STR_VIDEO); 649 status = init_sdp_media_video_format(pool, endpt, m); 650 } 651 if (status != PJ_SUCCESS) 652 return status; 653 654 /* Add "rtcp" attribute */ 655 #if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0 656 if (sock_info->rtcp_addr_name.addr.sa_family != 0) { 657 attr = pjmedia_sdp_attr_create_rtcp(pool, &sock_info->rtcp_addr_name); 658 if (attr) 659 pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr); 660 } 661 #endif 662 663 /* Add sendrecv attribute. */ 664 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 665 attr->name = STR_SENDRECV; 666 m->attr[m->attr_count++] = attr; 704 pj_assert(!"Invalid address family"); 705 return PJ_EAFNOTSUP; 706 } 707 708 if (sess_name) 709 pj_strdup(pool, &sdp->name, sess_name); 710 else 711 sdp->name = STR_SDP_NAME; 712 713 /* SDP time and attributes. */ 714 sdp->time.start = sdp->time.stop = 0; 715 sdp->attr_count = 0; 667 716 668 717 /* Done */ 669 sdp->media[sdp->media_count++] = m;718 *p_sdp = sdp; 670 719 671 720 return PJ_SUCCESS; … … 682 731 pjmedia_sdp_session **p_sdp ) 683 732 { 684 pj_time_val tv;685 unsigned i;686 733 const pj_sockaddr *addr0; 687 734 pjmedia_sdp_session *sdp; 688 pjmedia_type media_types[] = {PJMEDIA_TYPE_AUDIO, PJMEDIA_TYPE_VIDEO}; 735 pjmedia_sdp_media *m; 736 unsigned i; 737 pj_status_t status; 689 738 690 739 /* Sanity check arguments */ 691 740 PJ_ASSERT_RETURN(endpt && pool && p_sdp && stream_cnt, PJ_EINVAL); 692 PJ_ASSERT_RETURN(stream_cnt <= PJ_ARRAY_SIZE(media_types), PJ_ETOOMANY); 741 PJ_ASSERT_RETURN(stream_cnt < PJMEDIA_MAX_SDP_MEDIA, PJ_ETOOMANY); 742 743 addr0 = &sock_info[0].rtp_addr_name; 693 744 694 745 /* Create and initialize basic SDP session */ 695 sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session); 696 697 addr0 = &sock_info[0].rtp_addr_name; 698 699 pj_gettimeofday(&tv); 700 sdp->origin.user = pj_str("-"); 701 sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL; 702 sdp->origin.net_type = STR_IN; 703 704 if (addr0->addr.sa_family == pj_AF_INET()) { 705 sdp->origin.addr_type = STR_IP4; 706 pj_strdup2(pool, &sdp->origin.addr, 707 pj_inet_ntoa(addr0->ipv4.sin_addr)); 708 } else if (addr0->addr.sa_family == pj_AF_INET6()) { 709 char tmp_addr[PJ_INET6_ADDRSTRLEN]; 710 711 sdp->origin.addr_type = STR_IP6; 712 pj_strdup2(pool, &sdp->origin.addr, 713 pj_sockaddr_print(addr0, tmp_addr, sizeof(tmp_addr), 0)); 714 715 } else { 716 pj_assert(!"Invalid address family"); 717 return PJ_EAFNOTSUP; 718 } 719 720 sdp->name = STR_SDP_NAME; 721 722 /* SDP connection line in the session level. */ 723 sdp->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 724 sdp->conn->net_type = sdp->origin.net_type; 725 sdp->conn->addr_type = sdp->origin.addr_type; 726 sdp->conn->addr = sdp->origin.addr; 727 728 729 /* SDP time and attributes. */ 730 sdp->time.start = sdp->time.stop = 0; 731 sdp->attr_count = 0; 732 733 /* Add SDP media. */ 734 for (i = 0; i < stream_cnt; ++i) { 735 pj_status_t status; 736 737 status = add_sdp_media(endpt, pool, media_types[i], 738 &sock_info[i], sdp); 746 status = pjmedia_endpt_create_base_sdp(endpt, pool, NULL, addr0, &sdp); 747 if (status != PJ_SUCCESS) 748 return status; 749 750 /* Audio is first, by convention */ 751 status = pjmedia_endpt_create_audio_sdp(endpt, pool, 752 &sock_info[0], 0, &m); 753 if (status != PJ_SUCCESS) 754 return status; 755 sdp->media[sdp->media_count++] = m; 756 757 /* The remaining stream, if any, are videos (by convention as well) */ 758 for (i=1; i<stream_cnt; ++i) { 759 status = pjmedia_endpt_create_video_sdp(endpt, pool, 760 &sock_info[i], 0, &m); 739 761 if (status != PJ_SUCCESS) 740 762 return status; 763 sdp->media[sdp->media_count++] = m; 741 764 } 742 765 … … 745 768 746 769 return PJ_SUCCESS; 747 748 770 } 749 771
Note: See TracChangeset
for help on using the changeset viewer.