- Timestamp:
- Jun 29, 2006 2:45:17 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/config.h
r518 r568 156 156 157 157 /** 158 * Support for sending and decoding RTCP port in SDP (RFC 3605). 159 * Default is yes. 160 */ 161 #ifndef PJMEDIA_HAS_RTCP_IN_SDP 162 # define PJMEDIA_HAS_RTCP_IN_SDP 1 163 #endif 164 165 166 167 /** 158 168 * @} 159 169 */ -
pjproject/trunk/pjmedia/include/pjmedia/errno.h
r518 r568 141 141 /** 142 142 * @hideinitializer 143 * Invalid fmtpattribute.143 * Invalid SDP "fmtp" attribute. 144 144 */ 145 145 #define PJMEDIA_SDP_EINFMTP (PJMEDIA_ERRNO_START+34) /* 220034 */ 146 /** 147 * @hideinitializer 148 * Invalid SDP "rtcp" attribute. 149 */ 150 #define PJMEDIA_SDP_EINRTCP (PJMEDIA_ERRNO_START+35) /* 220035 */ 146 151 147 152 -
pjproject/trunk/pjmedia/include/pjmedia/sdp.h
r518 r568 292 292 PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_fmtp(const pjmedia_sdp_attr *attr, 293 293 pjmedia_sdp_fmtp *fmtp); 294 295 296 /** 297 * This structure describes SDP \a rtcp attribute. 298 */ 299 typedef struct pjmedia_sdp_rtcp_attr 300 { 301 unsigned port; /**< RTCP port number. */ 302 pj_str_t net_type; /**< Optional network type. */ 303 pj_str_t addr_type; /**< Optional address type. */ 304 pj_str_t addr; /**< Optional address. */ 305 } pjmedia_sdp_rtcp_attr; 306 307 308 /** 309 * Parse a generic SDP attribute to get SDP rtcp attribute values. 310 * 311 * @param attr Generic attribute to be converted to rtcp, which 312 * name must be "rtcp". 313 * @param rtcp SDP rtcp attribute to be initialized. 314 * 315 * @return PJ_SUCCESS on success. 316 */ 317 PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr, 318 pjmedia_sdp_rtcp_attr *rtcp); 319 294 320 295 321 -
pjproject/trunk/pjmedia/include/pjmedia/stream.h
r518 r568 92 92 pjmedia_dir dir; /**< Media direction. */ 93 93 pj_sockaddr_in rem_addr; /**< Remote RTP address */ 94 pj_sockaddr_in rem_rtcp; /**< Optional remote RTCP address. If 95 sin_family is zero, the RTP address 96 will be calculated from RTP. */ 94 97 pjmedia_codec_info fmt; /**< Incoming codec format info. */ 95 98 pjmedia_codec_param *param; /**< Optional codec param. */ -
pjproject/trunk/pjmedia/include/pjmedia/transport.h
r539 r568 74 74 void *user_data, 75 75 const pj_sockaddr_t *rem_addr, 76 const pj_sockaddr_t *rem_rtcp, 76 77 unsigned addr_len, 77 78 void (*rtp_cb)(void *user_data, … … 155 156 * called. 156 157 * @param rem_addr Remote RTP address to send RTP packet to. 158 * @param rem_rtcp Optional remote RTCP address. If the argument is NULL 159 * or if the address is zero, the RTCP address will be 160 * calculated from the RTP address (which is RTP port 161 * plus one). 157 162 * @param addr_len Length of the remote address. 158 163 * @param rtp_cb Callback to be called when RTP packet is received on … … 166 171 void *user_data, 167 172 const pj_sockaddr_t *rem_addr, 173 const pj_sockaddr_t *rem_rtcp, 168 174 unsigned addr_len, 169 175 void (*rtp_cb)(void *user_data, … … 174 180 pj_ssize_t)) 175 181 { 176 return tp->op->attach(tp, user_data, rem_addr, addr_len, rtp_cb, rtcp_cb); 182 return tp->op->attach(tp, user_data, rem_addr, rem_rtcp, addr_len, 183 rtp_cb, rtcp_cb); 177 184 } 178 185 -
pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
r438 r568 328 328 pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP); 329 329 330 /* Add format and rtpmap for each codec. */330 /* Init media line and attribute list. */ 331 331 m->desc.fmt_count = 0; 332 332 m->attr_count = 0; 333 333 334 /* Add "rtcp" attribute */ 335 #if 1 336 { 337 attr = pj_pool_alloc(pool, sizeof(pjmedia_sdp_attr)); 338 attr->name = pj_str("rtcp"); 339 attr->value.ptr = pj_pool_alloc(pool, 80); 340 attr->value.slen = 341 pj_ansi_snprintf(attr->value.ptr, 80, 342 ":%u IN IP4 %s", 343 pj_ntohs(sock_info[0].rtp_addr_name.sin_port), 344 pj_inet_ntoa(sock_info[0].rtp_addr_name.sin_addr)); 345 pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr); 346 } 347 #endif 348 349 /* Add format and rtpmap for each codec */ 334 350 for (i=0; i<endpt->codec_mgr.codec_cnt; ++i) { 335 351 -
pjproject/trunk/pjmedia/src/pjmedia/errno.c
r534 r568 56 56 PJ_BUILD_ERR( PJMEDIA_SDP_EINPT, "Invalid SDP payload type in media line" ), 57 57 PJ_BUILD_ERR( PJMEDIA_SDP_EINFMTP, "Invalid SDP fmtp attribute" ), 58 PJ_BUILD_ERR( PJMEDIA_SDP_EINRTCP, "Invalid SDP rtcp attribyte" ), 58 59 59 60 /* SDP negotiator errors. */ -
pjproject/trunk/pjmedia/src/pjmedia/sdp.c
r366 r568 60 60 static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med, 61 61 parse_context *ctx); 62 62 static void on_scanner_error(pj_scanner *scanner); 63 63 64 64 /* … … 242 242 pjmedia_sdp_rtpmap *rtpmap) 243 243 { 244 const char *p = attr->value.ptr; 245 const char *end = attr->value.ptr + attr->value.slen; 244 pj_scanner scanner; 246 245 pj_str_t token; 246 pj_status_t status = -1; 247 PJ_USE_EXCEPTION; 247 248 248 249 PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, "rtpmap")==0, PJ_EINVALIDOP); 250 251 pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen, 252 PJ_SCAN_AUTOSKIP_WS, &on_scanner_error); 249 253 250 254 /* rtpmap sample: … … 252 256 */ 253 257 254 /* Eat the first ':' */ 255 if (*p != ':') return PJMEDIA_SDP_EINRTPMAP; 256 257 /* Get ':' */ 258 ++p; 259 260 /* Get payload type. */ 261 token.ptr = (char*)p; 262 while (pj_isdigit(*p) && p!=end) 263 ++p; 264 token.slen = p - token.ptr; 265 if (token.slen == 0) 266 return PJMEDIA_SDP_EINRTPMAP; 267 268 rtpmap->pt = token; 269 270 /* Expecting space after payload type. */ 271 if (*p != ' ') return PJMEDIA_SDP_EINRTPMAP; 272 273 /* Get space. */ 274 ++p; 275 276 /* Get encoding name. */ 277 token.ptr = (char*)p; 278 while (*p != '/' && p != end) 279 ++p; 280 token.slen = p - token.ptr; 281 if (token.slen == 0) 282 return PJMEDIA_SDP_EINRTPMAP; 283 rtpmap->enc_name = token; 284 285 /* Expecting '/' after encoding name. */ 286 if (*p != '/') return PJMEDIA_SDP_EINRTPMAP; 287 288 /* Get '/' */ 289 ++p; 290 291 /* Get the clock rate. */ 292 token.ptr = (char*)p; 293 while (p != end && pj_isdigit(*p)) 294 ++p; 295 token.slen = p - token.ptr; 296 if (token.slen == 0) 297 return PJMEDIA_SDP_EINRTPMAP; 298 299 rtpmap->clock_rate = pj_strtoul(&token); 300 301 /* Expecting either '/' or EOF */ 302 if (p != end && *p != '/') 303 return PJMEDIA_SDP_EINRTPMAP; 304 305 if (p != end) { 306 ++p; 307 token.ptr = (char*)p; 308 token.slen = end-p; 309 rtpmap->param = token; 310 } else { 311 rtpmap->param.ptr = NULL; 312 rtpmap->param.slen = 0; 313 } 314 315 return PJ_SUCCESS; 316 258 /* Init */ 259 rtpmap->pt.slen = rtpmap->param.slen = rtpmap->enc_name.slen = 0; 260 261 /* Parse */ 262 PJ_TRY { 263 /* Eat the first ':' */ 264 if (pj_scan_get_char(&scanner) != ':') { 265 status = PJMEDIA_SDP_EINRTPMAP; 266 goto on_return; 267 } 268 269 270 /* Get payload type. */ 271 pj_scan_get(&scanner, &cs_token, &rtpmap->pt); 272 273 274 /* Get encoding name. */ 275 pj_scan_get(&scanner, &cs_token, &rtpmap->enc_name); 276 277 /* Expecting '/' after encoding name. */ 278 if (pj_scan_get_char(&scanner) != '/') { 279 status = PJMEDIA_SDP_EINRTPMAP; 280 goto on_return; 281 } 282 283 284 /* Get the clock rate. */ 285 pj_scan_get(&scanner, &cs_token, &token); 286 rtpmap->clock_rate = pj_strtoul(&token); 287 288 /* Expecting either '/' or EOF */ 289 if (*scanner.curptr == '/') { 290 pj_scan_get_char(&scanner); 291 rtpmap->param.ptr = scanner.curptr; 292 rtpmap->param.slen = scanner.end - scanner.curptr; 293 } else { 294 rtpmap->param.slen = 0; 295 } 296 297 status = PJ_SUCCESS; 298 } 299 PJ_CATCH(SYNTAX_ERROR) { 300 status = PJMEDIA_SDP_EINRTPMAP; 301 } 302 PJ_END; 303 304 305 on_return: 306 pj_scan_fini(&scanner); 307 return status; 317 308 } 318 309 … … 359 350 } 360 351 352 353 PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr, 354 pjmedia_sdp_rtcp_attr *rtcp) 355 { 356 pj_scanner scanner; 357 pj_str_t token; 358 pj_status_t status = -1; 359 PJ_USE_EXCEPTION; 360 361 PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, "rtcp")==0, PJ_EINVALIDOP); 362 363 /* fmtp BNF: 364 * a=rtcp:<port> [nettype addrtype address] 365 */ 366 367 pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen, 368 PJ_SCAN_AUTOSKIP_WS, &on_scanner_error); 369 370 /* Init */ 371 rtcp->net_type.slen = rtcp->addr_type.slen = rtcp->addr.slen = 0; 372 373 /* Parse */ 374 PJ_TRY { 375 376 /* Get the first ":" */ 377 if (pj_scan_get_char(&scanner) != ':') 378 { 379 status = PJMEDIA_SDP_EINRTCP; 380 goto on_return; 381 } 382 383 /* Get the port */ 384 pj_scan_get(&scanner, &cs_token, &token); 385 rtcp->port = pj_strtoul(&token); 386 387 /* Have address? */ 388 if (!pj_scan_is_eof(&scanner)) { 389 390 /* Get network type */ 391 pj_scan_get(&scanner, &cs_token, &rtcp->net_type); 392 393 /* Get address type */ 394 pj_scan_get(&scanner, &cs_token, &rtcp->addr_type); 395 396 /* Get the address */ 397 pj_scan_get(&scanner, &cs_token, &rtcp->addr); 398 399 } 400 401 status = PJ_SUCCESS; 402 403 } 404 PJ_CATCH(SYNTAX_ERROR) { 405 status = PJMEDIA_SDP_EINRTCP; 406 } 407 PJ_END; 408 409 on_return: 410 pj_scan_fini(&scanner); 411 return status; 412 } 413 414 415 361 416 PJ_DEF(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool, 362 417 const pjmedia_sdp_attr *attr, … … 377 432 { 378 433 pjmedia_sdp_attr *attr; 379 char tempbuf[64] , *p, *endbuf;380 int i;434 char tempbuf[64]; 435 int len; 381 436 382 437 /* Check arguments. */ … … 387 442 PJMEDIA_SDP_EINRTPMAP); 388 443 389 /* Check size. */390 i = rtpmap->enc_name.slen + rtpmap->param.slen + 32;391 if (i >= sizeof(tempbuf)-1) {392 pj_assert(!"rtpmap attribute is too long");393 return PJMEDIA_SDP_ERTPMAPTOOLONG;394 }395 444 396 445 attr = pj_pool_alloc(pool, sizeof(pjmedia_sdp_attr)); … … 400 449 attr->name.slen = 6; 401 450 402 p = tempbuf; 403 endbuf = tempbuf+sizeof(tempbuf); 404 405 /* Add colon */ 406 *p++ = ':'; 407 408 /* Add payload type. */ 409 pj_memcpy(p, rtpmap->pt.ptr, rtpmap->pt.slen); 410 p += rtpmap->pt.slen; 411 *p++ = ' '; 412 413 /* Add encoding name. */ 414 for (i=0; i<rtpmap->enc_name.slen; ++i) 415 p[i] = rtpmap->enc_name.ptr[i]; 416 p += rtpmap->enc_name.slen; 417 *p++ = '/'; 418 419 /* Add clock rate. */ 420 p += pj_utoa(rtpmap->clock_rate, p); 421 422 /* Add parameter if necessary. */ 423 if (rtpmap->param.slen > 0) { 424 *p++ = '/'; 425 for (i=0; i<rtpmap->param.slen; ++i) 426 p[i] = rtpmap->param.ptr[i]; 427 p += rtpmap->param.slen; 428 } 429 430 *p = '\0'; 431 432 attr->value.slen = p-tempbuf; 451 /* Format: ":pt enc_name/clock_rate[/param]" */ 452 len = pj_ansi_snprintf(tempbuf, sizeof(tempbuf), 453 ":%.*s %.*s/%u%s%.*s", 454 (int)rtpmap->pt.slen, 455 rtpmap->pt.ptr, 456 (int)rtpmap->enc_name.slen, 457 rtpmap->enc_name.ptr, 458 rtpmap->clock_rate, 459 (rtpmap->param.slen ? "/" : ""), 460 rtpmap->param.slen, 461 rtpmap->param.ptr); 462 463 if (len < 1 || len > sizeof(tempbuf)) 464 return PJMEDIA_SDP_ERTPMAPTOOLONG; 465 466 attr->value.slen = len; 433 467 attr->value.ptr = pj_pool_alloc(pool, attr->value.slen); 434 468 pj_memcpy(attr->value.ptr, tempbuf, attr->value.slen); … … 441 475 static int print_connection_info( pjmedia_sdp_conn *c, char *buf, int len) 442 476 { 443 char *p = buf; 444 445 if (len < 8+c->net_type.slen+c->addr_type.slen+c->addr.slen) { 477 int printed; 478 479 printed = pj_ansi_snprintf(buf, len, "c=%.*s %.*s %.*s\r\n", 480 (int)c->net_type.slen, 481 c->net_type.ptr, 482 (int)c->addr_type.slen, 483 c->addr_type.ptr, 484 (int)c->addr.slen, 485 c->addr.ptr); 486 if (printed < 1 || printed > len) 446 487 return -1; 447 } 448 *p++ = 'c'; 449 *p++ = '='; 450 pj_memcpy(p, c->net_type.ptr, c->net_type.slen); 451 p += c->net_type.slen; 452 *p++ = ' '; 453 pj_memcpy(p, c->addr_type.ptr, c->addr_type.slen); 454 p += c->addr_type.slen; 455 *p++ = ' '; 456 pj_memcpy(p, c->addr.ptr, c->addr.slen); 457 p += c->addr.slen; 458 *p++ = '\r'; 459 *p++ = '\n'; 460 461 return p-buf; 462 } 488 489 return printed; 490 } 491 463 492 464 493 PJ_DEF(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone (pj_pool_t *pool, -
pjproject/trunk/pjmedia/src/pjmedia/session.c
r452 r568 79 79 pj_status_t status; 80 80 81 82 81 83 82 /* Validate arguments: */ … … 156 155 157 156 /* Set remote address: */ 158 159 si->rem_addr.sin_family = PJ_AF_INET; 160 si->rem_addr.sin_port = pj_htons(rem_m->desc.port); 161 if (pj_inet_aton(&rem_conn->addr, &si->rem_addr.sin_addr) == 0) { 162 157 status = pj_sockaddr_in_init(&si->rem_addr, &rem_conn->addr, 158 rem_m->desc.port); 159 if (status != PJ_SUCCESS) { 163 160 /* Invalid IP address. */ 164 161 return PJMEDIA_EINVALIDIP; 165 162 } 163 164 /* If "rtcp" attribute is present in the SDP, set the RTCP address 165 * from that attribute. Otherwise, calculate from RTP address. 166 */ 167 attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 168 "rtcp", NULL); 169 if (attr) { 170 pjmedia_sdp_rtcp_attr rtcp; 171 status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp); 172 if (status == PJ_SUCCESS) { 173 if (rtcp.addr.slen) { 174 status = pj_sockaddr_in_init(&si->rem_rtcp, &rtcp.addr, 175 (pj_uint16_t)rtcp.port); 176 } else { 177 pj_sockaddr_in_init(&si->rem_rtcp, NULL, 178 (pj_uint16_t)rtcp.port); 179 si->rem_rtcp.sin_addr.s_addr = si->rem_addr.sin_addr.s_addr; 180 } 181 } 182 } 183 184 if (si->rem_rtcp.sin_addr.s_addr == 0) { 185 int rtcp_port; 186 187 pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr_in)); 188 rtcp_port = pj_ntohs(si->rem_addr.sin_port) + 1; 189 si->rem_rtcp.sin_port = pj_htons((pj_uint16_t)rtcp_port); 190 } 191 166 192 167 193 /* And codec must be numeric! */ -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r538 r568 1068 1068 1069 1069 /* Only attach transport when stream is ready. */ 1070 status = (*tp->op->attach)(tp, stream, &info->rem_addr, 1070 status = (*tp->op->attach)(tp, stream, &info->rem_addr, &info->rem_rtcp, 1071 1071 sizeof(info->rem_addr), &on_rx_rtp, 1072 1072 &on_rx_rtcp); -
pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
r558 r568 72 72 pj_sock_t rtcp_sock; /**< RTCP socket */ 73 73 pj_sockaddr_in rtcp_addr_name; /**< Published RTCP address. */ 74 pj_sockaddr_in rtcp_src_addr; /**< Actual source RTCP address. */ 75 int rtcp_addr_len; /**< Length of RTCP src address. */ 74 76 pj_ioqueue_key_t *rtcp_key; /**< RTCP socket key in ioqueue */ 75 77 pj_ioqueue_op_key_t rtcp_read_op; /**< Pending read operation */ … … 90 92 void *user_data, 91 93 const pj_sockaddr_t *rem_addr, 94 const pj_sockaddr_t *rem_rtcp, 92 95 unsigned addr_len, 93 96 void (*rtp_cb)(void*, … … 276 279 /* Kick of pending RTCP read from the ioqueue */ 277 280 size = sizeof(tp->rtcp_pkt); 278 status = pj_ioqueue_recv(tp->rtcp_key, &tp->rtcp_read_op, 279 tp->rtcp_pkt, &size, PJ_IOQUEUE_ALWAYS_ASYNC); 281 tp->rtcp_addr_len = sizeof(tp->rtcp_src_addr); 282 status = pj_ioqueue_recvfrom( tp->rtcp_key, &tp->rtcp_read_op, 283 tp->rtcp_pkt, &size, PJ_IOQUEUE_ALWAYS_ASYNC, 284 &tp->rtcp_src_addr, &tp->rtcp_addr_len); 280 285 if (status != PJ_EPENDING) 281 286 goto on_error; … … 385 390 if (udp->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) { 386 391 387 pj_uint16_t port;388 389 392 /* Set remote RTP address to source address */ 390 393 udp->rem_rtp_addr = udp->rtp_src_addr; 391 392 /* Also update remote RTCP address */393 pj_memcpy(&udp->rem_rtcp_addr, &udp->rem_rtp_addr,394 sizeof(pj_sockaddr_in));395 port = (pj_uint16_t)396 (pj_ntohs(udp->rem_rtp_addr.sin_port)+1);397 udp->rem_rtcp_addr.sin_port = pj_htons(port);398 394 399 395 /* Reset counter */ … … 404 400 pj_inet_ntoa(udp->rtp_src_addr.sin_addr), 405 401 pj_ntohs(udp->rtp_src_addr.sin_port))); 402 403 /* Also update remote RTCP address if actual RTCP source 404 * address is not heard yet. 405 */ 406 if (udp->rtcp_src_addr.sin_addr.s_addr == 0) { 407 pj_uint16_t port; 408 409 pj_memcpy(&udp->rem_rtcp_addr, &udp->rem_rtp_addr, 410 sizeof(pj_sockaddr_in)); 411 port = (pj_uint16_t) 412 (pj_ntohs(udp->rem_rtp_addr.sin_port)+1); 413 udp->rem_rtcp_addr.sin_port = pj_htons(port); 414 415 pj_memcpy(&udp->rtcp_src_addr, &udp->rem_rtcp_addr, 416 sizeof(pj_sockaddr_in)); 417 418 PJ_LOG(4,(udp->base.name, 419 "Remote RTCP address switched to %s:%d", 420 pj_inet_ntoa(udp->rtcp_src_addr.sin_addr), 421 pj_ntohs(udp->rtcp_src_addr.sin_port))); 422 423 } 406 424 } 407 425 } … … 441 459 (*cb)(user_data, udp->rtcp_pkt, bytes_read); 442 460 461 /* Check if RTCP source address is the same as the configured 462 * remote address, and switch the address when they are 463 * different. 464 */ 465 if ((udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0 && 466 ((udp->rem_rtcp_addr.sin_addr.s_addr != 467 udp->rtcp_src_addr.sin_addr.s_addr) || 468 (udp->rem_rtcp_addr.sin_port != 469 udp->rtcp_src_addr.sin_port))) 470 { 471 pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr, 472 sizeof(pj_sockaddr_in)); 473 PJ_LOG(4,(udp->base.name, 474 "Remote RTCP address switched to %s:%d", 475 pj_inet_ntoa(udp->rtcp_src_addr.sin_addr), 476 pj_ntohs(udp->rtcp_src_addr.sin_port))); 477 } 478 443 479 bytes_read = sizeof(udp->rtcp_pkt); 444 status = pj_ioqueue_recv(udp->rtcp_key, &udp->rtcp_read_op, 445 udp->rtcp_pkt, &bytes_read, 0); 480 udp->rtcp_addr_len = sizeof(udp->rtcp_src_addr); 481 status = pj_ioqueue_recvfrom(udp->rtcp_key, &udp->rtcp_read_op, 482 udp->rtcp_pkt, &bytes_read, 0, 483 &udp->rtcp_src_addr, 484 &udp->rtcp_addr_len); 446 485 447 486 } while (status == PJ_SUCCESS); … … 453 492 void *user_data, 454 493 const pj_sockaddr_t *rem_addr, 494 const pj_sockaddr_t *rem_rtcp, 455 495 unsigned addr_len, 456 496 void (*rtp_cb)(void*, … … 462 502 { 463 503 struct transport_udp *udp = (struct transport_udp*) tp; 504 const pj_sockaddr_in *rtcp_addr; 464 505 465 506 /* Validate arguments */ … … 474 515 pj_memcpy(&udp->rem_rtp_addr, rem_addr, sizeof(pj_sockaddr_in)); 475 516 476 /* Guess RTCP address from RTP address */ 477 pj_memcpy(&udp->rem_rtcp_addr, rem_addr, sizeof(pj_sockaddr_in)); 478 udp->rem_rtcp_addr.sin_port = (pj_uint16_t) pj_htons((pj_uint16_t)( 479 pj_ntohs(udp->rem_rtp_addr.sin_port)+1)); 517 /* Copy remote RTP address, if one is specified. */ 518 rtcp_addr = rem_rtcp; 519 if (rtcp_addr && rtcp_addr->sin_addr.s_addr != 0) { 520 pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, sizeof(pj_sockaddr_in)); 521 522 } else { 523 int rtcp_port; 524 525 /* Otherwise guess the RTCP address from the RTP address */ 526 pj_memcpy(&udp->rem_rtcp_addr, rem_addr, sizeof(pj_sockaddr_in)); 527 rtcp_port = pj_ntohs(udp->rem_rtp_addr.sin_port) + 1; 528 udp->rem_rtcp_addr.sin_port = pj_htons((pj_uint16_t)rtcp_port); 529 } 480 530 481 531 /* Save the callbacks */ -
pjproject/trunk/pjsip-apps/src/samples/siprtp.c
r546 r568 1285 1285 status = pjmedia_transport_attach(audio->transport, audio, 1286 1286 &audio->si.rem_addr, 1287 &audio->si.rem_rtcp, 1287 1288 sizeof(pj_sockaddr_in), 1288 1289 &on_rx_rtp, -
pjproject/trunk/pjsip-apps/src/samples/siprtp_report.c
r565 r568 162 162 audio->rtcp.stat.rx.loss * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx.loss), 163 163 audio->rtcp.stat.rx.dup, 164 audio->rtcp.stat.rx.dup * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx. dup),164 audio->rtcp.stat.rx.dup * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx.loss), 165 165 audio->rtcp.stat.rx.reorder, 166 audio->rtcp.stat.rx.reorder * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx. reorder),166 audio->rtcp.stat.rx.reorder * 100.0 / (audio->rtcp.stat.rx.pkt + audio->rtcp.stat.rx.loss), 167 167 "", 168 168 audio->rtcp.stat.rx.loss_period.min / 1000.0, … … 205 205 audio->rtcp.stat.tx.loss * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx.loss), 206 206 audio->rtcp.stat.tx.dup, 207 audio->rtcp.stat.tx.dup * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx. dup),207 audio->rtcp.stat.tx.dup * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx.loss), 208 208 audio->rtcp.stat.tx.reorder, 209 audio->rtcp.stat.tx.reorder * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx. reorder),209 audio->rtcp.stat.tx.reorder * 100.0 / (audio->rtcp.stat.tx.pkt + audio->rtcp.stat.tx.loss), 210 210 "", 211 211 audio->rtcp.stat.tx.loss_period.min / 1000.0, -
pjproject/trunk/pjsip-apps/src/samples/streamutil.c
r565 r568 607 607 stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss), 608 608 stat.rx.dup, 609 stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx. dup),609 stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss), 610 610 stat.rx.reorder, 611 stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx. reorder),611 stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss), 612 612 "", 613 613 stat.rx.loss_period.min / 1000.0, … … 650 650 stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss), 651 651 stat.tx.dup, 652 stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx. dup),652 stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss), 653 653 stat.tx.reorder, 654 stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx. reorder),654 stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss), 655 655 "", 656 656 stat.tx.loss_period.min / 1000.0, -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r565 r568 1305 1305 stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss), 1306 1306 stat.rx.dup, 1307 stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx. dup),1307 stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss), 1308 1308 stat.rx.reorder, 1309 stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx. reorder),1309 stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss), 1310 1310 indent, indent, 1311 1311 stat.rx.loss_period.min / 1000.0, … … 1364 1364 stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss), 1365 1365 stat.tx.dup, 1366 stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx. dup),1366 stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss), 1367 1367 stat.tx.reorder, 1368 stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx. reorder),1368 stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss), 1369 1369 1370 1370 indent, indent,
Note: See TracChangeset
for help on using the changeset viewer.