Changeset 1813
- Timestamp:
- Feb 21, 2008 4:46:34 PM (17 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/config.h
r1735 r1813 486 486 487 487 /** 488 * SRTP Transport 488 * Enable support for SRTP media transport. This will require linking 489 * with libsrtp from the third_party directory. 490 * 489 491 * By default it is enabled. 490 492 */ … … 495 497 496 498 /** 499 * Enable support to handle codecs with inconsistent clock rate 500 * between clock rate in SDP/RTP & the clock rate that is actually used. 501 * This happens for example with G.722 and MPEG audio codecs. 502 * See: 503 * - G.722 : RFC 3551 4.5.2 504 * - MPEG audio : RFC 3551 4.5.13 & RFC 3119 505 * 506 * Also when this feature is enabled, some handling will be performed 507 * to deal with clock rate incompatibilities of some phones. 508 * 509 * By default it is enabled. 510 */ 511 #ifndef PJMEDIA_HANDLE_G722_MPEG_BUG 512 # define PJMEDIA_HANDLE_G722_MPEG_BUG 1 513 #endif 514 515 516 /** 497 517 * @} 498 518 */ -
pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
r1615 r1813 413 413 414 414 rtpmap.pt = *fmt; 415 rtpmap.enc_name = codec_info->encoding_name; 416 417 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0) 418 if (codec_info->pt == PJMEDIA_RTP_PT_G722) 419 rtpmap.clock_rate = 8000; 420 else 421 rtpmap.clock_rate = codec_info->clock_rate; 422 #else 415 423 rtpmap.clock_rate = codec_info->clock_rate; 416 rtpmap.enc_name = codec_info->encoding_name; 417 424 #endif 425 418 426 /* For audio codecs, rtpmap parameters denotes the number 419 427 * of channels, which can be omited if the value is 1. -
pjproject/trunk/pjmedia/src/pjmedia/session.c
r1810 r1813 389 389 si->fmt.clock_rate = rtpmap->clock_rate; 390 390 391 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0) 392 /* The session info should have the actual clock rate, because 393 * this info is used for calculationg buffer size, etc in stream */ 394 if (si->fmt.pt == PJMEDIA_RTP_PT_G722) 395 si->fmt.clock_rate = 16000; 396 #endif 397 391 398 /* For audio codecs, rtpmap parameters denotes the number of 392 399 * channels. -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r1809 r1813 93 93 Otherwise it's NULL. */ 94 94 95 unsigned enc_samples_per_ frame;95 unsigned enc_samples_per_pkt; 96 96 unsigned enc_buf_size; /**< Encoding buffer size, in 97 97 samples. */ … … 132 132 void (*dtmf_cb)(pjmedia_stream*, void*, int); 133 133 void *dtmf_cb_user_data; 134 135 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0) 136 /* Enable support to handle codecs with inconsistent clock rate 137 * between clock rate in SDP/RTP & the clock rate that is actually used. 138 * This happens for example with G.722 and MPEG audio codecs. 139 */ 140 pj_bool_t has_g722_mpeg_bug; 141 /**< Flag to specify whether 142 normalization process 143 is needed */ 144 unsigned rtp_tx_samples_per_pkt; 145 /**< Normalized samples per packet 146 transmitted according to 147 'erroneous' definition */ 148 unsigned rtp_rx_samples_per_frame; 149 /**< Normalized samples per frame 150 received according to 151 'erroneous' definition */ 152 pj_uint32_t rtp_rx_last_ts;/**< Last received RTP timestamp 153 for timestamp checking */ 154 unsigned rtp_rx_last_cnt;/**< Nb of frames in last pkt */ 155 unsigned rtp_rx_check_cnt; 156 /**< Counter of remote timestamp 157 checking */ 158 #endif 159 134 160 }; 135 161 … … 522 548 pj_status_t status = 0; 523 549 pjmedia_frame frame_out; 524 unsigned ts_len, samples_per_frame;550 unsigned ts_len, rtp_ts_len, samples_per_frame; 525 551 void *rtphdr; 526 552 int rtphdrlen; … … 542 568 stream->tx_duration += ts_len; 543 569 570 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0) 571 /* Handle special case for audio codec with RTP timestamp inconsistence 572 * e.g: G722, MPEG audio. 573 */ 574 if (stream->has_g722_mpeg_bug) 575 rtp_ts_len = stream->rtp_tx_samples_per_pkt; 576 else 577 rtp_ts_len = ts_len; 578 #else 579 rtp_ts_len = ts_len; 580 #endif 581 544 582 /* Init frame_out buffer. */ 545 583 frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr); … … 547 585 548 586 /* Calculate number of samples per frame */ 549 samples_per_frame = stream->enc_samples_per_ frame;587 samples_per_frame = stream->enc_samples_per_pkt; 550 588 551 589 … … 564 602 status = pjmedia_rtp_encode_rtp( &channel->rtp, 565 603 stream->tx_event_pt, first, 566 frame_out.size, (first?ts_len:0), 604 frame_out.size, 605 (first ? rtp_ts_len : 0), 567 606 (const void**)&rtphdr, 568 607 &rtphdrlen); … … 573 612 * RTP packets. 574 613 */ 575 inc_timestamp = PJMEDIA_DTMF_DURATION - ts_len;614 inc_timestamp = PJMEDIA_DTMF_DURATION - rtp_ts_len; 576 615 } 577 616 … … 641 680 status = pjmedia_rtp_encode_rtp( &channel->rtp, 642 681 channel->pt, 0, 643 frame_out.size, ts_len,682 frame_out.size, rtp_ts_len, 644 683 (const void**)&rtphdr, 645 684 &rtphdrlen); … … 649 688 status = pjmedia_rtp_encode_rtp( &channel->rtp, 650 689 0, 0, 651 0, ts_len,690 0, rtp_ts_len, 652 691 (const void**)&rtphdr, 653 692 &rtphdrlen); … … 730 769 unsigned samples_per_frame; 731 770 732 samples_per_frame = stream->enc_samples_per_ frame;771 samples_per_frame = stream->enc_samples_per_pkt; 733 772 734 773 /* http://www.pjsip.org/trac/ticket/56: … … 807 846 * rebuffer() with NULL frame. 808 847 */ 809 if (stream->enc_buf_count >= stream->enc_samples_per_ frame) {848 if (stream->enc_buf_count >= stream->enc_samples_per_pkt) { 810 849 811 850 tmp_rebuffer_frame.type = PJMEDIA_FRAME_TYPE_NONE; … … 1027 1066 pj_timestamp ts; 1028 1067 unsigned i, count = MAX; 1029 unsigned samples_per_frame;1068 unsigned ts_span; 1030 1069 pjmedia_frame frames[MAX]; 1031 1070 … … 1047 1086 } 1048 1087 1088 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0) 1089 /* This code is used to learn the samples per frame value that is put 1090 * by remote endpoint, for codecs with inconsistent clock rate such 1091 * as G.722 or MPEG audio. We need to learn the samples per frame 1092 * value as it is used as divider when inserting frames into the 1093 * jitter buffer. 1094 */ 1095 if (stream->has_g722_mpeg_bug) { 1096 if (stream->rtp_rx_check_cnt) { 1097 /* Make sure the detection performed only on two consecutive 1098 * packets with valid RTP sequence and no wrapped timestamp. 1099 */ 1100 if (seq_st.diff == 1 && stream->rtp_rx_last_ts && 1101 ts.u64 > stream->rtp_rx_last_ts) 1102 { 1103 unsigned peer_frm_ts_diff; 1104 1105 peer_frm_ts_diff = 1106 ((pj_uint32_t)ts.u64-stream->rtp_rx_last_ts) / 1107 stream->rtp_rx_last_cnt; 1108 1109 /* Possibilities remote's samples per frame for G.722 1110 * are only 160 and 320, this validation is needed 1111 * to avoid wrong decision because of silence frames. 1112 */ 1113 if (stream->codec_param.info.pt == PJMEDIA_RTP_PT_G722 && 1114 (peer_frm_ts_diff==stream->port.info.samples_per_frame 1115 || peer_frm_ts_diff == 1116 stream->port.info.samples_per_frame >> 1)) 1117 { 1118 if (peer_frm_ts_diff < stream->rtp_rx_samples_per_frame) 1119 stream->rtp_rx_samples_per_frame = peer_frm_ts_diff; 1120 1121 if (--stream->rtp_rx_check_cnt == 0) { 1122 PJ_LOG(4, (THIS_FILE, "G722 codec used, remote" 1123 " samples per frame detected = %d", 1124 stream->rtp_rx_samples_per_frame)); 1125 1126 /* Reset jitter buffer once detection done */ 1127 pjmedia_jbuf_reset(stream->jb); 1128 } 1129 } 1130 } 1131 1132 stream->rtp_rx_last_ts = (pj_uint32_t)ts.u64; 1133 stream->rtp_rx_last_cnt = count; 1134 } 1135 1136 ts_span = stream->rtp_rx_samples_per_frame; 1137 1138 } else { 1139 ts_span = stream->codec_param.info.frm_ptime * 1140 stream->codec_param.info.clock_rate * 1141 stream->codec_param.info.channel_cnt / 1142 1000; 1143 } 1144 #else 1145 ts_span = stream->codec_param.info.frm_ptime * 1146 stream->codec_param.info.clock_rate * 1147 stream->codec_param.info.channel_cnt / 1148 1000; 1149 #endif 1150 1049 1151 /* Put each frame to jitter buffer. */ 1050 samples_per_frame = stream->codec_param.info.frm_ptime *1051 stream->codec_param.info.clock_rate *1052 stream->codec_param.info.channel_cnt /1053 1000;1054 1055 1152 for (i=0; i<count; ++i) { 1056 1153 unsigned ext_seq; 1057 1154 1058 ext_seq = (unsigned)(frames[i].timestamp.u64 / 1059 samples_per_frame); 1155 ext_seq = (unsigned)(frames[i].timestamp.u64 / ts_span); 1060 1156 pjmedia_jbuf_put_frame(stream->jb, frames[i].buf, 1061 1157 frames[i].size, ext_seq); … … 1190 1286 name.ptr = (char*) pj_pool_alloc(pool, M); 1191 1287 name.slen = pj_ansi_snprintf(name.ptr, M, "strm%p", stream); 1192 1193 1288 1194 1289 /* Init some port-info. Some parts of the info will be set later … … 1264 1359 1000; 1265 1360 1266 1267 1361 /* Open the codec: */ 1268 1362 … … 1280 1374 unsigned ptime; 1281 1375 1282 stream->enc_samples_per_ frame= stream->codec_param.info.enc_ptime *1283 1376 stream->enc_samples_per_pkt = stream->codec_param.info.enc_ptime * 1377 stream->port.info.clock_rate / 1000; 1284 1378 1285 1379 /* Set buffer size as twice the largest ptime value between … … 1304 1398 1305 1399 } else { 1306 stream->enc_samples_per_frame = stream->port.info.samples_per_frame; 1307 } 1400 stream->enc_samples_per_pkt = stream->port.info.samples_per_frame; 1401 } 1402 1308 1403 1309 1404 /* Initially disable the VAD in the stream, to help traverse NAT better */ … … 1322 1417 1323 1418 1419 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0) 1420 stream->rtp_rx_check_cnt = 5; 1421 stream->has_g722_mpeg_bug = PJ_FALSE; 1422 stream->rtp_rx_last_ts = 0; 1423 stream->rtp_rx_last_cnt = 0; 1424 stream->rtp_tx_samples_per_pkt = stream->enc_samples_per_pkt; 1425 stream->rtp_rx_samples_per_frame = stream->port.info.samples_per_frame; 1426 1324 1427 /* Init RTCP session: */ 1325 1428 1429 /* Special case for G.722 */ 1430 if (info->fmt.pt == PJMEDIA_RTP_PT_G722) { 1431 pjmedia_rtcp_init(&stream->rtcp, stream->port.info.name.ptr, 1432 8000, 1433 160, 1434 info->ssrc); 1435 stream->has_g722_mpeg_bug = PJ_TRUE; 1436 /* RTP clock rate = 1/2 real clock rate */ 1437 stream->rtp_tx_samples_per_pkt >>= 1; 1438 } else { 1439 pjmedia_rtcp_init(&stream->rtcp, stream->port.info.name.ptr, 1440 info->fmt.clock_rate, 1441 stream->port.info.samples_per_frame, 1442 info->ssrc); 1443 } 1444 #else 1326 1445 pjmedia_rtcp_init(&stream->rtcp, stream->port.info.name.ptr, 1327 1446 info->fmt.clock_rate, 1328 1447 stream->port.info.samples_per_frame, 1329 1448 info->ssrc); 1330 1449 #endif 1331 1450 1332 1451 /* Init jitter buffer parameters: */
Note: See TracChangeset
for help on using the changeset viewer.