Changeset 539 for pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
- Timestamp:
- Jun 22, 2006 6:49:45 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
r533 r539 31 31 #define RTCP_LEN 600 32 32 33 /* Maximum pending write operations */ 34 #define MAX_PENDING 4 35 36 /* Pending write buffer */ 37 typedef struct pending_write 38 { 39 char buffer[RTP_LEN]; 40 pj_ioqueue_op_key_t op_key; 41 } pending_write; 42 33 43 34 44 struct transport_udp … … 38 48 pj_pool_t *pool; /**< Memory pool */ 39 49 unsigned options; /**< Transport options. */ 40 pjmedia_stream *stream; /**< Stream user (may be NULL) */ 50 void *user_data; /**< Only valid when attached */ 51 pj_bool_t attached; /**< Has attachment? */ 41 52 pj_sockaddr_in rem_rtp_addr; /**< Remote RTP address */ 42 53 pj_sockaddr_in rem_rtcp_addr; /**< Remote RTCP address */ … … 52 63 pj_ioqueue_key_t *rtp_key; /**< RTP socket key in ioqueue */ 53 64 pj_ioqueue_op_key_t rtp_read_op; /**< Pending read operation */ 54 pj_ioqueue_op_key_t rtp_write_op; /**< Pending write operation */ 65 unsigned rtp_write_op_id;/**< Next write_op to use */ 66 pending_write rtp_pending_write[MAX_PENDING]; /**< Pending write */ 55 67 pj_sockaddr_in rtp_src_addr; /**< Actual packet src addr. */ 56 68 unsigned rtp_src_cnt; /**< How many pkt from this addr. */ … … 76 88 77 89 static pj_status_t transport_attach( pjmedia_transport *tp, 78 pjmedia_stream *strm,90 void *user_data, 79 91 const pj_sockaddr_t *rem_addr, 80 92 unsigned addr_len, 81 void (*rtp_cb)( pjmedia_stream*,93 void (*rtp_cb)(void*, 82 94 const void*, 83 95 pj_ssize_t), 84 void (*rtcp_cb)( pjmedia_stream*,96 void (*rtcp_cb)(void*, 85 97 const void*, 86 98 pj_ssize_t)); 87 99 static void transport_detach( pjmedia_transport *tp, 88 pjmedia_stream*strm);100 void *strm); 89 101 static pj_status_t transport_send_rtp( pjmedia_transport *tp, 90 102 const void *pkt, … … 114 126 pjmedia_transport **p_tp) 115 127 { 128 return pjmedia_transport_udp_create2(endpt, name, NULL, port, options, 129 p_tp); 130 } 131 132 /** 133 * Create UDP stream transport. 134 */ 135 PJ_DEF(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt, 136 const char *name, 137 const pj_str_t *addr, 138 int port, 139 unsigned options, 140 pjmedia_transport **p_tp) 141 { 116 142 pjmedia_sock_info si; 117 143 pj_status_t status; … … 131 157 132 158 /* Bind RTP socket */ 133 si.rtp_addr_name.sin_family = PJ_AF_INET; 134 si.rtp_addr_name.sin_port = pj_htons((pj_uint16_t)port); 135 159 pj_sockaddr_in_init(&si.rtp_addr_name, addr, (pj_uint16_t)port); 136 160 status = pj_sock_bind(si.rtp_sock, &si.rtp_addr_name, 137 161 sizeof(si.rtp_addr_name)); … … 146 170 147 171 /* Bind RTCP socket */ 148 si.rtcp_addr_name.sin_family = PJ_AF_INET; 149 si.rtcp_addr_name.sin_port = pj_htons((pj_uint16_t)(port+1)); 150 172 pj_sockaddr_in_init(&si.rtcp_addr_name, addr, (pj_uint16_t)(port+1)); 151 173 status = pj_sock_bind(si.rtcp_sock, &si.rtcp_addr_name, 152 174 sizeof(si.rtcp_addr_name)); … … 182 204 pj_ioqueue_callback rtp_cb, rtcp_cb; 183 205 pj_ssize_t size; 206 unsigned i; 184 207 pj_status_t status; 185 208 … … 224 247 225 248 pj_ioqueue_op_key_init(&tp->rtp_read_op, sizeof(tp->rtp_read_op)); 226 pj_ioqueue_op_key_init(&tp->rtcp_write_op, sizeof(tp->rtcp_write_op)); 249 for (i=0; i<PJ_ARRAY_SIZE(tp->rtp_pending_write); ++i) 250 pj_ioqueue_op_key_init(&tp->rtp_pending_write[i].op_key, 251 sizeof(tp->rtp_pending_write[i].op_key)); 227 252 228 253 /* Kick of pending RTP read from the ioqueue */ … … 271 296 * Get media socket info. 272 297 */ 273 PJ_DEF(pj_status_t) pjmedia_transport_udp_get_sock_info(pjmedia_transport *tp, 274 pjmedia_sock_info *inf) 298 PJ_DEF(pj_status_t) 299 pjmedia_transport_udp_get_info( pjmedia_transport *tp, 300 pjmedia_transport_udp_info *inf) 275 301 { 276 302 struct transport_udp *udp = (struct transport_udp*)tp; 277 303 PJ_ASSERT_RETURN(tp && inf, PJ_EINVAL); 278 304 279 inf-> rtp_sock = udp->rtp_sock;280 inf-> rtp_addr_name = udp->rtp_addr_name;281 inf-> rtcp_sock = udp->rtcp_sock;282 inf-> rtcp_addr_name = udp->rtcp_addr_name;305 inf->skinfo.rtp_sock = udp->rtp_sock; 306 inf->skinfo.rtp_addr_name = udp->rtp_addr_name; 307 inf->skinfo.rtcp_sock = udp->rtcp_sock; 308 inf->skinfo.rtcp_addr_name = udp->rtcp_addr_name; 283 309 284 310 return PJ_SUCCESS; … … 297 323 298 324 /* Must not close while stream is using this */ 299 PJ_ASSERT_RETURN( udp->stream == NULL, PJ_EINVALIDOP);325 PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP); 300 326 301 327 … … 335 361 336 362 do { 337 void (*cb)( pjmedia_stream*,const void*,pj_ssize_t);338 pjmedia_stream *stream;363 void (*cb)(void*,const void*,pj_ssize_t); 364 void *user_data; 339 365 340 366 cb = udp->rtp_cb; 341 stream = udp->stream;342 343 if ( bytes_read > 0 && cb && stream)344 (*cb)( stream, udp->rtp_pkt, bytes_read);367 user_data = udp->user_data; 368 369 if (udp->attached && cb) 370 (*cb)(user_data, udp->rtp_pkt, bytes_read); 345 371 346 372 /* See if source address of RTP packet is different than the … … 406 432 407 433 do { 408 void (*cb)( pjmedia_stream*,const void*,pj_ssize_t);409 pjmedia_stream *stream;434 void (*cb)(void*,const void*,pj_ssize_t); 435 void *user_data; 410 436 411 437 cb = udp->rtcp_cb; 412 stream = udp->stream;413 414 if ( bytes_read > 0 && cb && stream)415 (*cb)( stream, udp->rtcp_pkt, bytes_read);438 user_data = udp->user_data; 439 440 if (udp->attached && cb) 441 (*cb)(user_data, udp->rtcp_pkt, bytes_read); 416 442 417 443 bytes_read = sizeof(udp->rtcp_pkt); … … 425 451 /* Called by stream to initialize the transport */ 426 452 static pj_status_t transport_attach( pjmedia_transport *tp, 427 pjmedia_stream *strm,453 void *user_data, 428 454 const pj_sockaddr_t *rem_addr, 429 455 unsigned addr_len, 430 void (*rtp_cb)( pjmedia_stream*,456 void (*rtp_cb)(void*, 431 457 const void*, 432 458 pj_ssize_t), 433 void (*rtcp_cb)( pjmedia_stream*,459 void (*rtcp_cb)(void*, 434 460 const void*, 435 461 pj_ssize_t)) … … 438 464 439 465 /* Validate arguments */ 440 PJ_ASSERT_RETURN(tp && strm &&rem_addr && addr_len, PJ_EINVAL);466 PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); 441 467 442 468 /* Must not be "attached" to existing stream */ 443 PJ_ASSERT_RETURN( udp->stream == NULL, PJ_EINVALIDOP);469 PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP); 444 470 445 471 /* "Attach" the stream: */ … … 456 482 udp->rtp_cb = rtp_cb; 457 483 udp->rtcp_cb = rtcp_cb; 458 459 /* Last, save the stream to mark that we have a "client" */ 460 udp->stream = strm; 484 udp->user_data = user_data; 485 486 /* Last, mark transport as attached */ 487 udp->attached = PJ_TRUE; 461 488 462 489 return PJ_SUCCESS; … … 466 493 /* Called by stream when it no longer needs the transport */ 467 494 static void transport_detach( pjmedia_transport *tp, 468 pjmedia_stream *strm)495 void *user_data) 469 496 { 470 497 struct transport_udp *udp = (struct transport_udp*) tp; 471 498 472 pj_assert(tp && strm); 473 474 PJ_UNUSED_ARG(strm); 499 pj_assert(tp); 500 501 /* User data is unreferenced on Release build */ 502 PJ_UNUSED_ARG(user_data); 503 504 /* As additional checking, check if the same user data is specified */ 505 pj_assert(user_data == udp->user_data); 506 507 /* First, mark stream as unattached */ 508 udp->attached = PJ_FALSE; 475 509 476 510 /* Clear up stream infos from transport */ 477 udp->stream = NULL;478 511 udp->rtp_cb = NULL; 479 512 udp->rtcp_cb = NULL; 513 udp->user_data = NULL; 480 514 } 481 515 … … 488 522 struct transport_udp *udp = (struct transport_udp*)tp; 489 523 pj_ssize_t sent; 524 unsigned id; 525 struct pending_write *pw; 490 526 pj_status_t status; 491 527 492 PJ_ASSERT_RETURN(udp->stream, PJ_EINVALIDOP); 528 /* Must be attached */ 529 PJ_ASSERT_RETURN(udp->attached, PJ_EINVALIDOP); 530 531 /* Check that the size is supported */ 532 PJ_ASSERT_RETURN(size <= RTP_LEN, PJ_ETOOBIG); 533 534 id = udp->rtp_write_op_id; 535 pw = &udp->rtp_pending_write[id]; 536 537 /* We need to copy packet to our buffer because when the 538 * operation is pending, caller might write something else 539 * to the original buffer. 540 */ 541 pj_memcpy(pw->buffer, pkt, size); 493 542 494 543 sent = size; 495 status = pj_ioqueue_sendto( udp->rtp_key, &udp->rtp_write_op, 496 pkt, &sent, 0, 497 &udp->rem_rtp_addr, sizeof(pj_sockaddr_in)); 544 status = pj_ioqueue_sendto( udp->rtp_key, 545 &udp->rtp_pending_write[id].op_key, 546 pw->buffer, &sent, 0, 547 &udp->rem_rtp_addr, 548 sizeof(pj_sockaddr_in)); 549 550 udp->rtp_write_op_id = (udp->rtp_write_op_id + 1) % 551 PJ_ARRAY_SIZE(udp->rtp_pending_write); 498 552 499 553 if (status==PJ_SUCCESS || status==PJ_EPENDING) … … 512 566 pj_status_t status; 513 567 514 PJ_ASSERT_RETURN(udp-> stream, PJ_EINVALIDOP);568 PJ_ASSERT_RETURN(udp->attached, PJ_EINVALIDOP); 515 569 516 570 sent = size;
Note: See TracChangeset
for help on using the changeset viewer.