- Timestamp:
- Jun 14, 2008 4:52:04 PM (16 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/config.h
r2007 r2020 395 395 396 396 /** 397 * Specify the maximum duration of silence period in the codec .397 * Specify the maximum duration of silence period in the codec, in msec. 398 398 * This is useful for example to keep NAT binding open in the firewall 399 399 * and to prevent server from disconnecting the call because no … … 406 406 * Use (-1) to disable this feature. 407 407 * 408 * Default: 8000 (one second on 8KHz).408 * Default: 500 ms 409 409 * 410 410 */ 411 411 #ifndef PJMEDIA_CODEC_MAX_SILENCE_PERIOD 412 # define PJMEDIA_CODEC_MAX_SILENCE_PERIOD 8000412 # define PJMEDIA_CODEC_MAX_SILENCE_PERIOD 500 413 413 #endif 414 414 -
pjproject/trunk/pjmedia/src/pjmedia-codec/g722.c
r1985 r2020 553 553 if (is_silence && 554 554 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 && 555 silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD )555 silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*16000/1000) 556 556 { 557 557 output->type = PJMEDIA_FRAME_TYPE_NONE; -
pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c
r2015 r2020 543 543 if (is_silence && 544 544 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 && 545 silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD )545 silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000) 546 546 { 547 547 output->type = PJMEDIA_FRAME_TYPE_NONE; -
pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c
r1985 r2020 540 540 if (is_silence && 541 541 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 && 542 silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD )542 silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000) 543 543 { 544 544 output->type = PJMEDIA_FRAME_TYPE_NONE; -
pjproject/trunk/pjmedia/src/pjmedia/g711.c
r1985 r2020 503 503 if (is_silence && 504 504 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 && 505 silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD )505 silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000) 506 506 { 507 507 output->type = PJMEDIA_FRAME_TYPE_NONE; -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r1985 r2020 84 84 pjmedia_dir dir; /**< Stream direction. */ 85 85 void *user_data; /**< User data. */ 86 pj_str_t cname; /**< SDES CNAME */ 86 87 87 88 pjmedia_transport *transport; /**< Stream transport. */ … … 116 117 pj_uint32_t rtcp_last_tx; /**< RTCP tx time in timestamp */ 117 118 pj_uint32_t rtcp_interval; /**< Interval, in timestamp. */ 119 pj_bool_t initial_rr; /**< Initial RTCP RR sent */ 118 120 119 121 /* RFC 2833 DTMF transmission queue: */ … … 177 179 'A', 'B', 'C', 'D'}; 178 180 181 /* Zero audio frame samples */ 182 static pj_int16_t zero_frame[30 * 16000 / 1000]; 183 179 184 /* 180 185 * Print error. … … 535 540 } 536 541 542 /* Build RTCP SDES packet */ 543 static unsigned create_rtcp_sdes(pjmedia_stream *stream, pj_uint8_t *pkt, 544 unsigned max_len) 545 { 546 pjmedia_rtcp_common hdr; 547 pj_uint8_t *p = pkt; 548 549 /* SDES header */ 550 hdr.version = 2; 551 hdr.p = 0; 552 hdr.count = 1; 553 hdr.pt = 202; 554 hdr.length = 2 + (4+stream->cname.slen+3)/4 - 1; 555 if (max_len < (hdr.length << 2)) { 556 pj_assert(!"Not enough buffer for SDES packet"); 557 return 0; 558 } 559 hdr.length = pj_htons((pj_uint16_t)hdr.length); 560 hdr.ssrc = stream->enc->rtp.out_hdr.ssrc; 561 pj_memcpy(p, &hdr, sizeof(hdr)); 562 p += sizeof(hdr); 563 564 /* CNAME item */ 565 *p++ = 1; 566 *p++ = (pj_uint8_t)stream->cname.slen; 567 pj_memcpy(p, stream->cname.ptr, stream->cname.slen); 568 p += stream->cname.slen; 569 570 /* END */ 571 *p++ = '\0'; 572 *p++ = '\0'; 573 574 /* Pad to 32bit */ 575 while ((p-pkt) % 4) 576 *p++ = '\0'; 577 578 return (p - pkt); 579 } 580 581 /* Build RTCP BYE packet */ 582 static unsigned create_rtcp_bye(pjmedia_stream *stream, pj_uint8_t *pkt, 583 unsigned max_len) 584 { 585 pjmedia_rtcp_common hdr; 586 587 /* BYE header */ 588 hdr.version = 2; 589 hdr.p = 0; 590 hdr.count = 1; 591 hdr.pt = 203; 592 hdr.length = 1; 593 if (max_len < (hdr.length << 2)) { 594 pj_assert(!"Not enough buffer for SDES packet"); 595 return 0; 596 } 597 hdr.length = pj_htons((pj_uint16_t)hdr.length); 598 hdr.ssrc = stream->enc->rtp.out_hdr.ssrc; 599 pj_memcpy(pkt, &hdr, sizeof(hdr)); 600 601 return sizeof(hdr); 602 } 603 537 604 538 605 /** … … 674 741 } 675 742 676 /* No need to encode if this is a zero frame. 677 * See http://www.pjsip.org/trac/ticket/439 678 */ 743 744 /* 745 * Special treatment for FRAME_TYPE_AUDIO but with frame->buf==NULL. 746 * This happens when stream input is disconnected from the bridge. 747 * In this case we periodically transmit RTP frame to keep NAT binding 748 * open, by giving zero PCM frame to the codec. 749 * 750 * This was originally done in http://trac.pjsip.org/repos/ticket/56, 751 * but then disabled in http://trac.pjsip.org/repos/ticket/439, but 752 * now it's enabled again. 753 */ 754 } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO && 755 frame->buf == NULL && 756 (stream->dir & PJMEDIA_DIR_ENCODING) && 757 stream->codec_param.info.frm_ptime * 758 stream->codec_param.info.clock_rate/1000 < 759 PJ_ARRAY_SIZE(zero_frame)) 760 { 761 pjmedia_frame silence_frame; 762 763 pj_bzero(&silence_frame, sizeof(silence_frame)); 764 silence_frame.buf = zero_frame; 765 silence_frame.size = stream->codec_param.info.frm_ptime * 2 * 766 stream->codec_param.info.clock_rate / 1000; 767 silence_frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 768 silence_frame.timestamp.u32.lo = pj_ntohl(stream->enc->rtp.out_hdr.ts); 769 770 /* Encode! */ 771 status = stream->codec->op->encode( stream->codec, &silence_frame, 772 channel->out_pkt_size - 773 sizeof(pjmedia_rtp_hdr), 774 &frame_out); 775 if (status != PJ_SUCCESS) { 776 LOGERR_((stream->port.info.name.ptr, 777 "Codec encode() error", status)); 778 return status; 779 } 780 781 /* Encapsulate. */ 782 status = pjmedia_rtp_encode_rtp( &channel->rtp, 783 channel->pt, 0, 784 frame_out.size, rtp_ts_len, 785 (const void**)&rtphdr, 786 &rtphdrlen); 787 788 789 /* Encode audio frame */ 679 790 } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE && 680 791 frame->buf != NULL) … … 697 808 (const void**)&rtphdr, 698 809 &rtphdrlen); 810 699 811 } else { 700 812 … … 1205 1317 pjmedia_rtcp_rx_rtp2(&stream->rtcp, pj_ntohs(hdr->seq), 1206 1318 pj_ntohl(hdr->ts), payloadlen, pkt_discarded); 1319 1320 /* Send RTCP RR and SDES after we receive some RTP packets */ 1321 if (stream->rtcp.received >= 10 && !stream->initial_rr) { 1322 void *sr_rr_pkt; 1323 pj_uint8_t *pkt; 1324 int len; 1325 1326 /* Build RR or SR */ 1327 pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 1328 pkt = (pj_uint8_t*) stream->enc->out_pkt; 1329 pj_memcpy(pkt, sr_rr_pkt, len); 1330 pkt += len; 1331 1332 /* Append SDES */ 1333 len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt, 1334 stream->enc->out_pkt_size - len); 1335 if (len > 0) { 1336 pkt += len; 1337 len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->out_pkt); 1338 pjmedia_transport_send_rtcp(stream->transport, 1339 stream->enc->out_pkt, len); 1340 } 1341 1342 stream->initial_rr = PJ_TRUE; 1343 } 1207 1344 } 1208 1345 … … 1302 1439 pjmedia_stream *stream; 1303 1440 pj_str_t name; 1304 unsigned jb_init, jb_max, jb_min_pre, jb_max_pre; 1441 unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len; 1442 char *p; 1305 1443 pj_status_t status; 1306 1444 … … 1340 1478 stream->dir = info->dir; 1341 1479 stream->user_data = user_data; 1342 stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL + (pj_rand() % 8000)) *1480 stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) * 1343 1481 info->fmt.clock_rate / 1000; 1344 1482 … … 1346 1484 stream->rx_event_pt = info->rx_event_pt ? info->rx_event_pt : -1; 1347 1485 stream->last_dtmf = -1; 1486 1487 /* Build random RTCP CNAME. CNAME has user@host format */ 1488 stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); 1489 pj_create_random_string(p, 5); 1490 p += 5; 1491 *p++ = '@'; *p++ = 'p'; *p++ = 'j'; 1492 pj_create_random_string(p, 6); 1493 p += 6; 1494 *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g'; 1495 stream->cname.slen = p - stream->cname.ptr; 1348 1496 1349 1497 … … 1610 1758 #endif 1611 1759 1760 /* Send RTCP SDES */ 1761 len = create_rtcp_sdes(stream, stream->enc->out_pkt, 1762 stream->enc->out_pkt_size); 1763 if (len != 0) { 1764 pjmedia_transport_send_rtcp(stream->transport, 1765 stream->enc->out_pkt, len); 1766 } 1767 1612 1768 /* Success! */ 1613 1769 *p_stream = stream; … … 1629 1785 PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream ) 1630 1786 { 1631 1787 unsigned len; 1632 1788 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 1633 1789 … … 1669 1825 } 1670 1826 #endif 1827 1828 /* Send RTCP BYE */ 1829 len = create_rtcp_bye(stream, stream->enc->out_pkt, 1830 stream->enc->out_pkt_size); 1831 if (len != 0) { 1832 pjmedia_transport_send_rtcp(stream->transport, 1833 stream->enc->out_pkt, len); 1834 } 1671 1835 1672 1836 /* Detach from transport
Note: See TracChangeset
for help on using the changeset viewer.