Changeset 3419
- Timestamp:
- Feb 24, 2011 7:16:31 AM (14 years ago)
- Location:
- pjproject/branches/projects/2.0-dev/pjmedia
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/sdp.h
r3392 r3419 366 366 const pjmedia_sdp_conn *rhs); 367 367 368 369 /** 370 * Compare connection info. 371 * 372 * @param conn1 The first connection info to compare. 373 * @param conn1 The second connection info to compare. 374 * @param option Comparison option, which should be zero for now. 375 * 376 * @return PJ_SUCCESS when both connection info are equal, otherwise 377 * returns PJMEDIA_SDP_ECONNNOTEQUAL. 378 */ 379 PJ_DECL(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1, 380 const pjmedia_sdp_conn *conn2, 381 unsigned option); 368 382 369 383 -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/endpoint.c
r3360 r3419 21 21 #include <pjmedia/errno.h> 22 22 #include <pjmedia/sdp.h> 23 #include <pjmedia/vid_codec.h> 23 24 #include <pjmedia-audiodev/audiodev.h> 24 25 #include <pj/assert.h> … … 320 321 } 321 322 322 /** 323 * Create a SDP session description that describes the endpoint 324 * capability. 325 */ 326 PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt, 327 pj_pool_t *pool, 328 unsigned stream_cnt, 329 const pjmedia_sock_info sock_info[], 330 pjmedia_sdp_session **p_sdp ) 331 { 332 pj_time_val tv; 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 { 328 pjmedia_sdp_attr *attr; 333 329 unsigned i; 334 const pj_sockaddr *addr0;335 pjmedia_sdp_session *sdp;336 pjmedia_sdp_media *m;337 pjmedia_sdp_attr *attr;338 339 /* Sanity check arguments */340 PJ_ASSERT_RETURN(endpt && pool && p_sdp && stream_cnt, PJ_EINVAL);341 330 342 331 /* Check that there are not too many codecs */ … … 344 333 PJ_ETOOMANY); 345 334 346 /* Create and initialize basic SDP session */347 sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);348 349 addr0 = &sock_info[0].rtp_addr_name;350 351 pj_gettimeofday(&tv);352 sdp->origin.user = pj_str("-");353 sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL;354 sdp->origin.net_type = STR_IN;355 356 if (addr0->addr.sa_family == pj_AF_INET()) {357 sdp->origin.addr_type = STR_IP4;358 pj_strdup2(pool, &sdp->origin.addr,359 pj_inet_ntoa(addr0->ipv4.sin_addr));360 } else if (addr0->addr.sa_family == pj_AF_INET6()) {361 char tmp_addr[PJ_INET6_ADDRSTRLEN];362 363 sdp->origin.addr_type = STR_IP6;364 pj_strdup2(pool, &sdp->origin.addr,365 pj_sockaddr_print(addr0, tmp_addr, sizeof(tmp_addr), 0));366 367 } else {368 pj_assert(!"Invalid address family");369 return PJ_EAFNOTSUP;370 }371 372 sdp->name = STR_SDP_NAME;373 374 /* Since we only support one media stream at present, put the375 * SDP connection line in the session level.376 */377 sdp->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);378 sdp->conn->net_type = sdp->origin.net_type;379 sdp->conn->addr_type = sdp->origin.addr_type;380 sdp->conn->addr = sdp->origin.addr;381 382 383 /* SDP time and attributes. */384 sdp->time.start = sdp->time.stop = 0;385 sdp->attr_count = 0;386 387 /* Create media stream 0: */388 389 sdp->media_count = 1;390 m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);391 sdp->media[0] = m;392 393 /* Standard media info: */394 pj_strdup(pool, &m->desc.media, &STR_AUDIO);395 m->desc.port = pj_sockaddr_get_port(addr0);396 m->desc.port_count = 1;397 pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP);398 399 /* Init media line and attribute list. */400 m->desc.fmt_count = 0;401 m->attr_count = 0;402 403 /* Add "rtcp" attribute */404 #if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0405 if (sock_info->rtcp_addr_name.addr.sa_family != 0) {406 attr = pjmedia_sdp_attr_create_rtcp(pool, &sock_info->rtcp_addr_name);407 if (attr)408 pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);409 }410 #endif411 412 335 /* Add format, rtpmap, and fmtp (when applicable) for each codec */ 413 336 for (i=0; i<endpt->codec_mgr.codec_cnt; ++i) { … … 416 339 pjmedia_sdp_rtpmap rtpmap; 417 340 char tmp_param[3]; 418 pjmedia_sdp_attr *attr;419 341 pjmedia_codec_param codec_param; 420 342 pj_str_t *fmt; … … 520 442 } 521 443 522 /* Add sendrecv attribute. */523 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);524 attr->name = STR_SENDRECV;525 m->attr[m->attr_count++] = attr;526 527 444 #if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \ 528 445 PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0 … … 548 465 } 549 466 #endif 467 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 { 476 pjmedia_vid_codec_info codec_info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]; 477 unsigned codec_prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]; 478 pjmedia_sdp_attr *attr; 479 unsigned cnt, i; 480 pj_status_t status; 481 482 /* Make sure video codec manager is instantiated */ 483 if (!pjmedia_vid_codec_mgr_instance()) 484 pjmedia_vid_codec_mgr_create(endpt->pool, NULL); 485 486 cnt = PJ_ARRAY_SIZE(codec_info); 487 status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, 488 codec_info, codec_prio); 489 490 /* Check that there are not too many codecs */ 491 PJ_ASSERT_RETURN(0 <= PJMEDIA_MAX_SDP_FMT, 492 PJ_ETOOMANY); 493 494 /* Add format, rtpmap, and fmtp (when applicable) for each codec */ 495 for (i=0; i<cnt; ++i) { 496 497 pjmedia_sdp_rtpmap rtpmap = {0}; 498 pjmedia_vid_codec_param codec_param; 499 pj_str_t *fmt; 500 501 if (codec_prio[i] == PJMEDIA_CODEC_PRIO_DISABLED) 502 break; 503 504 if (i > PJMEDIA_MAX_SDP_FMT) { 505 /* Too many codecs, perhaps it is better to tell application by 506 * returning appropriate status code. 507 */ 508 PJ_LOG(3, (THIS_FILE, "Too many video codecs")); 509 break; 510 } 511 512 /* Payload type */ 513 if (codec_info[i].pt == 255) { 514 PJ_TODO(ALLOCATE_DYNAMIC_PAYLOAD_TYPE); 515 continue; 516 } 517 518 pjmedia_vid_codec_mgr_get_default_param(NULL, &codec_info[i], 519 &codec_param); 520 521 fmt = &m->desc.fmt[m->desc.fmt_count++]; 522 fmt->ptr = (char*) pj_pool_alloc(pool, 8); 523 fmt->slen = pj_utoa(codec_info[i].pt, fmt->ptr); 524 rtpmap.pt = *fmt; 525 526 /* Encoding name */ 527 rtpmap.enc_name = codec_info[i].encoding_name; 528 529 /* Clock rate */ 530 rtpmap.clock_rate = codec_info[i].clock_rate; 531 532 if (codec_info[i].pt >= 96 || pjmedia_add_rtpmap_for_static_pt) { 533 pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr); 534 m->attr[m->attr_count++] = attr; 535 } 536 537 /* Add fmtp params */ 538 if (codec_param.dec_fmtp.cnt > 0) { 539 enum { MAX_FMTP_STR_LEN = 160 }; 540 char buf[MAX_FMTP_STR_LEN]; 541 unsigned buf_len = 0, j; 542 pjmedia_codec_fmtp *dec_fmtp = &codec_param.dec_fmtp; 543 544 /* Print codec PT */ 545 buf_len += pj_ansi_snprintf(buf, 546 MAX_FMTP_STR_LEN - buf_len, 547 "%d", 548 codec_info[i].pt); 549 550 for (j = 0; j < dec_fmtp->cnt; ++j) { 551 unsigned test_len = 2; 552 553 /* Check if buf still available */ 554 test_len = dec_fmtp->param[j].val.slen + 555 dec_fmtp->param[j].name.slen; 556 if (test_len + buf_len >= MAX_FMTP_STR_LEN) 557 return PJ_ETOOBIG; 558 559 /* Print delimiter */ 560 buf_len += pj_ansi_snprintf(&buf[buf_len], 561 MAX_FMTP_STR_LEN - buf_len, 562 (j == 0?" ":";")); 563 564 /* Print an fmtp param */ 565 if (dec_fmtp->param[j].name.slen) 566 buf_len += pj_ansi_snprintf( 567 &buf[buf_len], 568 MAX_FMTP_STR_LEN - buf_len, 569 "%.*s=%.*s", 570 (int)dec_fmtp->param[j].name.slen, 571 dec_fmtp->param[j].name.ptr, 572 (int)dec_fmtp->param[j].val.slen, 573 dec_fmtp->param[j].val.ptr); 574 else 575 buf_len += pj_ansi_snprintf(&buf[buf_len], 576 MAX_FMTP_STR_LEN - buf_len, 577 "%.*s", 578 (int)dec_fmtp->param[j].val.slen, 579 dec_fmtp->param[j].val.ptr); 580 } 581 582 attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr); 583 584 attr->name = pj_str("fmtp"); 585 attr->value = pj_strdup3(pool, buf); 586 m->attr[m->attr_count++] = attr; 587 } 588 } 589 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); 647 } 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; 667 668 /* Done */ 669 sdp->media[sdp->media_count++] = m; 670 671 return PJ_SUCCESS; 672 } 673 674 /** 675 * Create a SDP session description that describes the endpoint 676 * capability. 677 */ 678 PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt, 679 pj_pool_t *pool, 680 unsigned stream_cnt, 681 const pjmedia_sock_info sock_info[], 682 pjmedia_sdp_session **p_sdp ) 683 { 684 pj_time_val tv; 685 unsigned i; 686 const pj_sockaddr *addr0; 687 pjmedia_sdp_session *sdp; 688 pjmedia_type media_types[] = {PJMEDIA_TYPE_AUDIO, PJMEDIA_TYPE_VIDEO}; 689 690 /* Sanity check arguments */ 691 PJ_ASSERT_RETURN(endpt && pool && p_sdp && stream_cnt, PJ_EINVAL); 692 PJ_ASSERT_RETURN(stream_cnt <= PJ_ARRAY_SIZE(media_types), PJ_ETOOMANY); 693 694 /* 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); 739 if (status != PJ_SUCCESS) 740 return status; 741 } 550 742 551 743 /* Done */ -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/sdp_cmp.c
r3198 r3419 296 296 297 297 298 PJ_DEF(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1, 299 const pjmedia_sdp_conn *conn2, 300 unsigned option) 301 { 302 PJ_UNUSED_ARG(option); 303 return compare_conn(conn1, conn2); 304 }
Note: See TracChangeset
for help on using the changeset viewer.