Changeset 350
- Timestamp:
- Mar 22, 2006 11:59:11 AM (19 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/endpoint.h
r189 r350 45 45 46 46 47 48 47 /** 49 48 * Create an instance of media endpoint. … … 51 50 * @param pf Pool factory, which will be used by the media endpoint 52 51 * throughout its lifetime. 52 * @param ioqueue Optional ioqueue instance to be registered to the 53 * endpoint. The ioqueue instance is used to poll all RTP 54 * and RTCP sockets. If this argument is NULL, the 55 * endpoint will create an internal ioqueue instance. 56 * @param worker_cnt Specify the number of worker threads to be created 57 * to poll the ioqueue. 53 58 * @param p_endpt Pointer to receive the endpoint instance. 54 59 * … … 56 61 */ 57 62 PJ_DECL(pj_status_t) pjmedia_endpt_create( pj_pool_factory *pf, 63 pj_ioqueue_t *ioqueue, 64 unsigned worker_cnt, 58 65 pjmedia_endpt **p_endpt); 59 66 … … 66 73 */ 67 74 PJ_DECL(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt); 75 76 77 78 /** 79 * Get the ioqueue instance of the media endpoint. 80 * 81 * @param endpt The media endpoint instance. 82 * 83 * @return The ioqueue instance of the media endpoint. 84 */ 85 PJ_DECL(pj_ioqueue_t*) pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt); 68 86 69 87 -
pjproject/trunk/pjmedia/src/pjmedia/endpoint.c
r321 r350 20 20 #include <pjmedia/errno.h> 21 21 #include <pjmedia/sdp.h> 22 #include <pj/assert.h> 23 #include <pj/ioqueue.h> 24 #include <pj/log.h> 25 #include <pj/os.h> 26 #include <pj/pool.h> 22 27 #include <pj/sock.h> 23 #include <pj/pool.h>24 28 #include <pj/string.h> 25 #include <pj/assert.h>26 #include <pj/os.h>27 #include <pj/log.h>28 29 29 30 … … 66 67 67 68 69 /* Worker thread proc. */ 70 static int PJ_THREAD_FUNC worker_proc(void*); 71 72 73 #define MAX_THREADS 16 74 68 75 69 76 /** Concrete declaration of media endpoint. */ … … 78 85 /** Codec manager. */ 79 86 pjmedia_codec_mgr codec_mgr; 87 88 /** IOqueue instance. */ 89 pj_ioqueue_t *ioqueue; 90 91 /** Do we own the ioqueue? */ 92 pj_bool_t own_ioqueue; 93 94 /** Number of threads. */ 95 unsigned thread_cnt; 96 97 /** IOqueue polling thread, if any. */ 98 pj_thread_t *thread[MAX_THREADS]; 99 100 /** To signal polling thread to quit. */ 101 pj_bool_t quit_flag; 80 102 }; 81 103 … … 84 106 */ 85 107 PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf, 108 pj_ioqueue_t *ioqueue, 109 unsigned worker_cnt, 86 110 pjmedia_endpt **p_endpt) 87 111 { 88 112 pj_pool_t *pool; 89 113 pjmedia_endpt *endpt; 114 unsigned i; 90 115 pj_status_t status; 91 116 … … 105 130 endpt->pool = pool; 106 131 endpt->pf = pf; 132 endpt->ioqueue = ioqueue; 133 endpt->thread_cnt = worker_cnt; 107 134 108 135 /* Sound */ … … 111 138 /* Init codec manager. */ 112 139 status = pjmedia_codec_mgr_init(&endpt->codec_mgr); 113 if (status != PJ_SUCCESS) { 114 pjmedia_snd_deinit(); 140 if (status != PJ_SUCCESS) 115 141 goto on_error; 116 } 117 118 /* Init and register G.711 codec. */ 119 #if 0 120 // Starting from 0.5.4, codec factory is registered by applications. 121 factory = pj_pool_alloc (endpt->pool, sizeof(pjmedia_codec_factory)); 122 123 status = g711_init_factory (factory, endpt->pool); 124 if (status != PJ_SUCCESS) { 125 pjmedia_snd_deinit(); 126 goto on_error; 127 } 128 129 status = pjmedia_codec_mgr_register_factory (&endpt->codec_mgr, factory); 130 if (status != PJ_SUCCESS) { 131 pjmedia_snd_deinit(); 132 goto on_error; 133 } 134 #endif 142 143 /* Create ioqueue if none is specified. */ 144 if (endpt->ioqueue == NULL) { 145 146 endpt->own_ioqueue = PJ_TRUE; 147 148 status = pj_ioqueue_create( endpt->pool, PJ_IOQUEUE_MAX_HANDLES, 149 &endpt->ioqueue); 150 if (status != PJ_SUCCESS) 151 goto on_error; 152 153 if (worker_cnt == 0) { 154 PJ_LOG(4,(THIS_FILE, "Warning: no worker thread is created in" 155 "media endpoint for internal ioqueue")); 156 } 157 } 158 159 /* Create worker threads if asked. */ 160 for (i=0; i<worker_cnt; ++i) { 161 status = pj_thread_create( endpt->pool, "media", &worker_proc, 162 endpt, 0, 0, &endpt->thread[i]); 163 if (status != PJ_SUCCESS) 164 goto on_error; 165 } 166 135 167 136 168 *p_endpt = endpt; … … 138 170 139 171 on_error: 172 173 /* Destroy threads */ 174 for (i=0; i<endpt->thread_cnt; ++i) { 175 if (endpt->thread[i]) { 176 pj_thread_destroy(endpt->thread[i]); 177 } 178 } 179 180 /* Destroy internal ioqueue */ 181 if (endpt->ioqueue && endpt->own_ioqueue) 182 pj_ioqueue_destroy(endpt->ioqueue); 183 184 pjmedia_snd_deinit(); 140 185 pj_pool_release(pool); 141 186 return status; … … 155 200 PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt) 156 201 { 202 unsigned i; 203 157 204 PJ_ASSERT_RETURN(endpt, PJ_EINVAL); 205 206 endpt->quit_flag = 1; 207 208 /* Destroy threads */ 209 for (i=0; i<endpt->thread_cnt; ++i) { 210 if (endpt->thread[i]) { 211 pj_thread_join(endpt->thread[i]); 212 pj_thread_destroy(endpt->thread[i]); 213 endpt->thread[i] = NULL; 214 } 215 } 216 217 /* Destroy internal ioqueue */ 218 if (endpt->ioqueue && endpt->own_ioqueue) { 219 pj_ioqueue_destroy(endpt->ioqueue); 220 endpt->ioqueue = NULL; 221 } 158 222 159 223 endpt->pf = NULL; … … 163 227 164 228 return PJ_SUCCESS; 229 } 230 231 232 /** 233 * Get the ioqueue instance of the media endpoint. 234 */ 235 PJ_DEF(pj_ioqueue_t*) pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt) 236 { 237 PJ_ASSERT_RETURN(endpt, NULL); 238 return endpt->ioqueue; 239 } 240 241 242 /** 243 * Worker thread proc. 244 */ 245 static int PJ_THREAD_FUNC worker_proc(void *arg) 246 { 247 pjmedia_endpt *endpt = arg; 248 249 while (!endpt->quit_flag) { 250 pj_time_val timeout = { 0, 500 }; 251 pj_ioqueue_poll(endpt->ioqueue, &timeout); 252 } 253 254 return 0; 165 255 } 166 256 -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r327 r350 27 27 #include <pj/compat/socket.h> 28 28 #include <pj/errno.h> 29 #include <pj/ioqueue.h> 29 30 #include <pj/log.h> 30 31 #include <pj/os.h> … … 79 80 struct pjmedia_stream 80 81 { 82 pjmedia_endpt *endpt; /**< Media endpoint. */ 83 pjmedia_codec_mgr *codec_mgr; /**< Codec manager instance. */ 84 81 85 pjmedia_port port; /**< Port interface. */ 82 86 pjmedia_channel *enc; /**< Encoding channel. */ … … 87 91 void *user_data; /**< User data. */ 88 92 89 pjmedia_codec_mgr *codec_mgr; /**< Codec manager instance. */90 93 pjmedia_codec *codec; /**< Codec instance being used. */ 91 94 pj_size_t frame_size; /**< Size of encoded frame. */ … … 97 100 pj_sockaddr_in rem_rtcp_addr; /**< Remote RTCP address. */ 98 101 99 pj_sockaddr_in rem_src_rtp; /**< addr of src pkt from remote*/100 unsigned rem_src_cnt; /**< if different, # of pkt rcv */101 102 102 103 pjmedia_rtcp_session rtcp; /**< RTCP for incoming RTP. */ 103 104 104 pj_bool_t quit_flag; /**< To signal thread exit. */ 105 pj_thread_t *thread; /**< Jitter buffer's thread. */ 105 pj_ioqueue_key_t *rtp_key; /**< RTP ioqueue key. */ 106 pj_ioqueue_op_key_t rtp_op_key; /**< The pending read op key. */ 107 pj_sockaddr_in rtp_src_addr; /**< addr of src pkt from remote*/ 108 unsigned rtp_src_cnt; /**< if different, # of pkt rcv */ 109 int rtp_addrlen; /**< Address length. */ 110 111 pj_ioqueue_key_t *rtcp_key; /**< RTCP ioqueue key. */ 112 pj_ioqueue_op_key_t rtcp_op_key; /**< The pending read op key. */ 113 106 114 107 115 /* RFC 2833 DTMF transmission queue: */ … … 152 160 pj_status_t status; 153 161 struct pjmedia_frame frame_in, frame_out; 154 155 /* Do nothing if we're quitting. */156 if (stream->quit_flag) {157 frame->type = PJMEDIA_FRAME_TYPE_NONE;158 return PJ_SUCCESS;159 }160 162 161 163 /* Lock jitter buffer mutex */ … … 272 274 pj_ssize_t sent; 273 275 274 /* Check if stream is quitting. */275 if (stream->quit_flag)276 return -1;277 278 276 /* Number of samples in the frame */ 279 277 ts_len = frame->size / 2; … … 439 437 440 438 /* 441 * This thread will poll the socket for incoming packets, and put 442 * the packets to jitter buffer. 443 */ 444 static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg) 445 { 446 pjmedia_stream *stream = arg; 439 * This callback is called by ioqueue framework on receipt of packets 440 * in the RTP socket. 441 */ 442 static void on_rx_rtp( pj_ioqueue_key_t *key, 443 pj_ioqueue_op_key_t *op_key, 444 pj_ssize_t bytes_read) 445 446 { 447 pjmedia_stream *stream = pj_ioqueue_get_user_data(key); 447 448 pjmedia_channel *channel = stream->dec; 448 449 450 while (!stream->quit_flag) { 451 pj_ssize_t len; 449 pj_status_t status; 450 451 452 PJ_UNUSED_ARG(op_key); 453 454 455 /* 456 * Loop while we have packet. 457 */ 458 do { 452 459 const pjmedia_rtp_hdr *hdr; 453 460 const void *payload; 454 461 unsigned payloadlen; 455 int addrlen; 456 int status; 457 458 /* Wait for packet. */ 459 pj_fd_set_t fds; 460 pj_time_val timeout; 461 462 PJ_FD_ZERO (&fds); 463 PJ_FD_SET (stream->skinfo.rtp_sock, &fds); 464 timeout.sec = 0; 465 timeout.msec = 1; 466 467 /* Wait with timeout. */ 468 status = pj_sock_select(FD_SETSIZE, &fds, NULL, NULL, &timeout); 469 if (status < 0) { 470 TRACE_((THIS_FILE, "Jitter buffer select() error", 471 pj_get_netos_error())); 472 pj_thread_sleep(500); 473 continue; 474 } else if (status == 0) 475 continue; 476 477 /* Get packet from socket. */ 478 len = channel->in_pkt_size; 479 addrlen = sizeof(stream->rem_src_rtp); 480 status = pj_sock_recvfrom(stream->skinfo.rtp_sock, 481 channel->in_pkt, &len, 0, 482 &stream->rem_src_rtp, &addrlen); 483 if (len < 1 || status != PJ_SUCCESS) { 484 if (pj_get_netos_error() == PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) { 485 /* On Win2K SP2 (or above) and WinXP, recv() will get 486 * WSAECONNRESET when the sending side receives ICMP port 487 * unreachable. 488 */ 489 continue; 490 } 491 pj_thread_sleep(1); 492 continue; 493 } 494 495 if (channel->paused) 496 continue; 462 463 /* Go straight to read next packet if bytes_read == 0. 464 */ 465 if (bytes_read == 0) 466 goto read_next_packet; 467 497 468 498 469 /* Update RTP and RTCP session. */ 499 status = pjmedia_rtp_decode_rtp(&channel->rtp, channel->in_pkt, len, 500 &hdr, &payload, &payloadlen); 470 status = pjmedia_rtp_decode_rtp(&channel->rtp, 471 channel->in_pkt, bytes_read, 472 &hdr, &payload, &payloadlen); 501 473 if (status != PJ_SUCCESS) { 502 474 TRACE_((THIS_FILE, "RTP decode error", status)); 503 continue;475 goto read_next_packet; 504 476 } 477 505 478 506 479 /* Handle incoming DTMF. */ 507 480 if (hdr->pt == stream->rx_event_pt) { 508 481 handle_incoming_dtmf(stream, payload, payloadlen); 509 continue;482 goto read_next_packet; 510 483 } 511 484 485 486 /* Update RTP session (also checks if RTP session can accept 487 * the incoming packet. 488 */ 512 489 status = pjmedia_rtp_session_update(&channel->rtp, hdr); 513 490 if (status != 0 && … … 519 496 PJ_LOG(4,(THIS_FILE,"RTP packet detail: pt=%d, seq=%d", 520 497 hdr->pt, pj_ntohs(hdr->seq))); 521 continue;498 goto read_next_packet; 522 499 } 523 pjmedia_rtcp_rx_rtp(&stream->rtcp, pj_ntohs(hdr->seq), pj_ntohl(hdr->ts)); 500 501 502 /* Update the RTCP session. */ 503 pjmedia_rtcp_rx_rtp(&stream->rtcp, pj_ntohs(hdr->seq), 504 pj_ntohl(hdr->ts)); 505 524 506 525 507 /* Update stat */ 526 508 stream->stat.dec.pkt++; 527 stream->stat.dec.bytes += len; 509 stream->stat.dec.bytes += bytes_read; 510 528 511 529 512 /* See if source address of RTP packet is different than the … … 531 514 */ 532 515 if ((stream->rem_rtp_addr.sin_addr.s_addr != 533 stream->r em_src_rtp.sin_addr.s_addr) ||534 (stream->rem_rtp_addr.sin_port != stream->r em_src_rtp.sin_port))516 stream->rtp_src_addr.sin_addr.s_addr) || 517 (stream->rem_rtp_addr.sin_port != stream->rtp_src_addr.sin_port)) 535 518 { 536 stream->r em_src_cnt++;537 538 if (stream->r em_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) {519 stream->rtp_src_cnt++; 520 521 if (stream->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) { 539 522 540 stream->rem_rtp_addr = stream->r em_src_rtp;541 stream->r em_src_cnt = 0;523 stream->rem_rtp_addr = stream->rtp_src_addr; 524 stream->rtp_src_cnt = 0; 542 525 543 526 PJ_LOG(4,(THIS_FILE,"Remote RTP address switched to %s:%d", 544 pj_inet_ntoa(stream->rem_src_rtp.sin_addr),545 pj_ntohs(stream->r em_src_rtp.sin_port)));527 pj_inet_ntoa(stream->rtp_src_addr.sin_addr), 528 pj_ntohs(stream->rtp_src_addr.sin_port))); 546 529 } 547 530 } 548 531 532 549 533 /* Put to jitter buffer. */ 550 534 pj_mutex_lock( stream->jb_mutex ); 551 status = pjmedia_jbuf_put_frame(stream->jb, payload, payloadlen, pj_ntohs(hdr->seq)); 535 status = pjmedia_jbuf_put_frame(stream->jb, payload, payloadlen, 536 pj_ntohs(hdr->seq)); 552 537 pj_mutex_unlock( stream->jb_mutex ); 553 538 554 539 if (status != 0) { 555 540 TRACE_((THIS_FILE, "Jitter buffer put() error", status)); 556 continue;541 goto read_next_packet; 557 542 } 558 } 559 560 return 0; 543 544 read_next_packet: 545 bytes_read = channel->in_pkt_size; 546 stream->rtp_addrlen = sizeof(stream->rtp_src_addr); 547 status = pj_ioqueue_recvfrom( stream->rtp_key, 548 &stream->rtp_op_key, 549 channel->in_pkt, 550 &bytes_read, 0, 551 &stream->rtp_src_addr, 552 &stream->rtp_addrlen); 553 554 } while (status == PJ_SUCCESS); 555 556 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 557 char errmsg[PJ_ERR_MSG_SIZE]; 558 559 pj_strerror(status, errmsg, sizeof(errmsg)); 560 PJ_LOG(4,(THIS_FILE, "Error reading RTP packet: %s [status=%d]", 561 errmsg, status)); 562 } 563 } 564 565 566 /* 567 * This callback is called by ioqueue framework on receipt of packets 568 * in the RTCP socket. 569 */ 570 static void on_rx_rtcp( pj_ioqueue_key_t *key, 571 pj_ioqueue_op_key_t *op_key, 572 pj_ssize_t bytes_read) 573 { 574 PJ_UNUSED_ARG(key); 575 PJ_UNUSED_ARG(op_key); 576 PJ_UNUSED_ARG(bytes_read); 561 577 } 562 578 … … 642 658 pjmedia_stream *stream; 643 659 pjmedia_codec_param codec_param; 660 pj_ioqueue_callback ioqueue_cb; 644 661 pj_status_t status; 645 662 … … 668 685 669 686 /* Init stream: */ 670 687 stream->endpt = endpt; 688 stream->codec_mgr = pjmedia_endpt_get_codec_mgr(endpt); 671 689 stream->dir = info->dir; 672 690 stream->user_data = user_data; 673 stream->codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);674 691 stream->skinfo = info->sock_info; 675 692 stream->rem_rtp_addr = info->rem_addr; … … 733 750 734 751 735 /* Create jitter buffer thread: */736 737 status = pj_thread_create(pool, "decode",738 &jitter_buffer_thread, stream,739 0, PJ_THREAD_SUSPENDED, &stream->thread);740 if (status != PJ_SUCCESS)741 goto err_cleanup;742 743 744 752 /* Create decoder channel: */ 745 753 … … 757 765 goto err_cleanup; 758 766 759 /* Resume jitter buffer thread. */ 760 status = pj_thread_resume( stream->thread ); 767 /* Register RTP socket to ioqueue */ 768 pj_memset(&ioqueue_cb, 0, sizeof(ioqueue_cb)); 769 ioqueue_cb.on_read_complete = &on_rx_rtp; 770 771 status = pj_ioqueue_register_sock( pool, 772 pjmedia_endpt_get_ioqueue(endpt), 773 stream->skinfo.rtp_sock, 774 stream, &ioqueue_cb, &stream->rtp_key); 761 775 if (status != PJ_SUCCESS) 762 776 goto err_cleanup; 777 778 /* Init pending operation key. */ 779 pj_ioqueue_op_key_init(&stream->rtp_op_key, sizeof(stream->rtp_op_key)); 780 781 /* Bootstrap the first recvfrom() operation. */ 782 on_rx_rtp( stream->rtp_key, &stream->rtp_op_key, 0); 783 784 785 /* Register RTCP socket to ioqueue. */ 786 if (stream->skinfo.rtcp_sock != PJ_INVALID_SOCKET) { 787 pj_memset(&ioqueue_cb, 0, sizeof(ioqueue_cb)); 788 ioqueue_cb.on_read_complete = &on_rx_rtcp; 789 790 status = pj_ioqueue_register_sock( pool, 791 pjmedia_endpt_get_ioqueue(endpt), 792 stream->skinfo.rtcp_sock, 793 stream, &ioqueue_cb, 794 &stream->rtcp_key); 795 if (status != PJ_SUCCESS) 796 goto err_cleanup; 797 } 798 799 /* Init pending operation key. */ 800 pj_ioqueue_op_key_init(&stream->rtcp_op_key, sizeof(stream->rtcp_op_key)); 801 802 /* Bootstrap the first recvfrom() operation. */ 803 on_rx_rtcp( stream->rtcp_key, &stream->rtcp_op_key, 0); 763 804 764 805 /* Success! */ … … 781 822 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 782 823 783 /* Signal threads to quit. */ 784 785 stream->quit_flag = 1; 786 787 788 /* Close encoding sound stream. */ 789 790 /* 791 if (stream->enc && stream->enc->snd_stream) { 792 793 pjmedia_snd_stream_stop(stream->enc->snd_stream); 794 pjmedia_snd_stream_close(stream->enc->snd_stream); 795 stream->enc->snd_stream = NULL; 796 797 } 798 */ 799 800 /* Close decoding sound stream. */ 801 802 /* 803 if (stream->dec && stream->dec->snd_stream) { 804 805 pjmedia_snd_stream_stop(stream->dec->snd_stream); 806 pjmedia_snd_stream_close(stream->dec->snd_stream); 807 stream->dec->snd_stream = NULL; 808 809 } 810 */ 811 812 /* Wait for jitter buffer thread to quit: */ 813 814 if (stream->thread) { 815 pj_thread_join(stream->thread); 816 pj_thread_destroy(stream->thread); 817 stream->thread = NULL; 824 825 /* This function may be called when stream is partly initialized. */ 826 if (stream->jb_mutex) 827 pj_mutex_lock(stream->jb_mutex); 828 829 830 /* Unregister from ioqueue. */ 831 if (stream->rtp_key) { 832 pj_ioqueue_unregister(stream->rtp_key); 833 stream->rtp_key = NULL; 834 } 835 if (stream->rtcp_key) { 836 pj_ioqueue_unregister(stream->rtcp_key); 837 stream->rtcp_key = NULL; 818 838 } 819 839 -
pjproject/trunk/pjsip-apps/build/samples.dsp
r347 r350 42 42 # PROP Output_Dir "./output/samples-i386-win32-vc6-release" 43 43 # PROP Intermediate_Dir "./output/samples-i386-win32-vc6-release" 44 # PROP Cmd_Line "nmake / f Samples-vc.mak BUILD_MODE=release"44 # PROP Cmd_Line "nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release" 45 45 # PROP Rebuild_Opt "/a" 46 # PROP Target_File "All samples built successfully"46 # PROP Target_File "All samples" 47 47 # PROP Bsc_Name "" 48 48 # PROP Target_Dir "" … … 65 65 # PROP Cmd_Line "nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug" 66 66 # PROP Rebuild_Opt "/a" 67 # PROP Target_File "All samples built successfully"67 # PROP Target_File "All samples" 68 68 # PROP Bsc_Name "" 69 69 # PROP Target_Dir "" -
pjproject/trunk/pjsip-apps/src/pjsip-perf/main.c
r315 r350 259 259 260 260 /* Init multimedia endpoint. */ 261 status = pjmedia_endpt_create(&settings.cp.factory, &settings.med_endpt); 261 status = pjmedia_endpt_create(&settings.cp.factory, 262 pjsip_endpt_get_ioqueue(settings.endpt), 0, 263 &settings.med_endpt); 262 264 if (status != PJ_SUCCESS) { 263 265 app_perror(THIS_FILE, "Unable to create media endpoint", -
pjproject/trunk/pjsip-apps/src/samples/confsample.c
r343 r350 159 159 * This will implicitly initialize PJMEDIA too. 160 160 */ 161 status = pjmedia_endpt_create(&cp.factory, &med_endpt);161 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt); 162 162 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 163 163 -
pjproject/trunk/pjsip-apps/src/samples/level.c
r344 r350 85 85 * This will implicitly initialize PJMEDIA too. 86 86 */ 87 status = pjmedia_endpt_create(&cp.factory, &med_endpt);87 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt); 88 88 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 89 89 -
pjproject/trunk/pjsip-apps/src/samples/playfile.c
r336 r350 92 92 * This will implicitly initialize PJMEDIA too. 93 93 */ 94 status = pjmedia_endpt_create(&cp.factory, &med_endpt);94 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt); 95 95 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 96 96 -
pjproject/trunk/pjsip-apps/src/samples/playsine.c
r342 r350 204 204 * This will implicitly initialize PJMEDIA too. 205 205 */ 206 status = pjmedia_endpt_create(&cp.factory, &med_endpt);206 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt); 207 207 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 208 208 -
pjproject/trunk/pjsip-apps/src/samples/simpleua.c
r332 r350 260 260 * This will implicitly initialize PJMEDIA too. 261 261 */ 262 status = pjmedia_endpt_create(&cp.factory, &g_med_endpt);262 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &g_med_endpt); 263 263 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 264 264 -
pjproject/trunk/pjsip-apps/src/samples/sndinfo.c
r342 r350 143 143 * This will implicitly initialize PJMEDIA too. 144 144 */ 145 status = pjmedia_endpt_create(&cp.factory, &med_endpt);145 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt); 146 146 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 147 147 -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r343 r350 99 99 call was triggered by xfer. */ 100 100 pjmedia_sock_info skinfo; /**< Preallocated media sockets. */ 101 102 101 void *app_data; /**< Application data. */ 103 102 pj_timer_entry refresh_tm;/**< Timer to send re-INVITE. */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r324 r350 95 95 pjsip_endpt_schedule_timer( pjsua.endpt, e, &timeout); 96 96 } 97 } 98 99 100 /* Close and reopen socket. */ 101 static pj_status_t reopen_sock( pj_sock_t *sock) 102 { 103 pj_sockaddr_in addr; 104 int addrlen; 105 pj_status_t status; 106 107 addrlen = sizeof(pj_sockaddr_in); 108 status = pj_sock_getsockname(*sock, &addr, &addrlen); 109 if (status != PJ_SUCCESS) { 110 pjsua_perror(THIS_FILE, "Error getting RTP/RTCP socket name", status); 111 return status; 112 } 113 114 pj_sock_close(*sock); 115 116 status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, sock); 117 if (status != PJ_SUCCESS) { 118 pjsua_perror(THIS_FILE, "Unable to create socket", status); 119 return status; 120 } 121 122 status = pj_sock_bind(*sock, &addr, sizeof(pj_sockaddr_in)); 123 if (status != PJ_SUCCESS) { 124 pjsua_perror(THIS_FILE, "Unable to re-bind RTP/RTCP socket", status); 125 return status; 126 } 127 128 return PJ_SUCCESS; 129 } 130 131 /* 132 * Destroy the call's media 133 */ 134 static pj_status_t call_destroy_media(int call_index) 135 { 136 pjsua_call *call = &pjsua.calls[call_index]; 137 138 if (call->conf_slot > 0) { 139 pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 140 call->conf_slot = 0; 141 } 142 143 if (call->session) { 144 145 /* Close and reopen RTP socket. 146 * This is necessary to get the socket unregistered from ioqueue, 147 * when IOCompletionPort is used. 148 */ 149 reopen_sock(&call->skinfo.rtp_sock); 150 151 /* Close and reopen RTCP socket too. */ 152 reopen_sock(&call->skinfo.rtcp_sock); 153 154 /* Must destroy session after socket is closed. */ 155 pjmedia_session_destroy(call->session); 156 call->session = NULL; 157 158 } 159 160 PJ_LOG(3,(THIS_FILE, "Media session for call %d is destroyed", 161 call_index)); 162 163 return PJ_SUCCESS; 97 164 } 98 165 … … 495 562 pj_assert(call != NULL); 496 563 497 if (call && call->session) { 498 pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 499 pjmedia_session_destroy(call->session); 500 call->session = NULL; 501 502 PJ_LOG(3,(THIS_FILE,"Media session is destroyed")); 503 } 564 if (call) 565 call_destroy_media(call->index); 504 566 505 567 /* Remove timers. */ … … 879 941 /* Destroy existing media session, if any. */ 880 942 881 if (call && call->session) { 882 pjmedia_conf_remove_port(pjsua.mconf, call->conf_slot); 883 pjmedia_session_destroy(call->session); 884 call->session = NULL; 885 } 943 if (call) 944 call_destroy_media(call->index); 886 945 887 946 /* Get local and remote SDP */ … … 948 1007 pjsua_perror(THIS_FILE, "Unable to create conference slot", 949 1008 status); 950 pjmedia_session_destroy(call->session); 951 call->session = NULL; 1009 call_destroy_media(call->index); 952 1010 //call_disconnect(inv, PJSIP_SC_INTERNAL_SERVER_ERROR); 953 1011 return; -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r343 r350 105 105 pjsua.calls[i].refresh_tm._timer_id = -1; 106 106 pjsua.calls[i].hangup_tm._timer_id = -1; 107 pjsua.calls[i].conf_slot = 0; 107 108 } 108 109 … … 537 538 /* Init media endpoint: */ 538 539 539 status = pjmedia_endpt_create(&pjsua.cp.factory, &pjsua.med_endpt); 540 status = pjmedia_endpt_create(&pjsua.cp.factory, 541 pjsip_endpt_get_ioqueue(pjsua.endpt), 0, 542 &pjsua.med_endpt); 540 543 if (status != PJ_SUCCESS) { 541 544 pj_caching_pool_destroy(&pjsua.cp);
Note: See TracChangeset
for help on using the changeset viewer.