rtpstuff.cpp
上传用户:hnnddl
上传日期:2007-01-06
资源大小:3580k
文件大小:22k
源码类别:

IP电话/视频会议

开发平台:

WINDOWS

  1. /*
  2.  * $Revision: 1.15 $
  3.  * $Date: 1998/11/03 19:29:00 $
  4.  */
  5. ////////////////////////////////////////////////////////////////
  6. //               Copyright (c) 1996-98 Lucent Technologies    //
  7. //                       All Rights Reserved                  //
  8. //                                                            //
  9. //                       THIS IS UNPUBLISHED                  //
  10. //                       PROPRIETARY SOURCE                   //
  11. //                   CODE OF Lucent Technologies              //
  12. // AND elemedia   //
  13. //                                                            //
  14. //           The copyright notice above does not evidence any //
  15. //          actual or intended publication of such source code//
  16. ////////////////////////////////////////////////////////////////
  17. //
  18. ////////////////////////////////////////////////////////////////
  19. // Example programs are provided soley to demonstrate one     //
  20. // possible use of the stack libraries and are included for   //
  21. // instructional purposes only.  You are free to use, modify  //
  22. // and/or redistribute any portion of code in the example     //
  23. // programs.  However, such examples are not intended to      //
  24. // represent production quality code.                         //
  25. //                                                            //
  26. // THE COPYRIGHT HOLDERS PROVIDE THESE EXAMPLE PROGRAMS       //
  27. // "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED     //
  28. // OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     //
  29. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A            //
  30. // PARTICULAR PURPOSE.                                        //
  31. ////////////////////////////////////////////////////////////////
  32. #include <stdio.h>
  33. #include <fcntl.h>
  34. #if (defined(WIN32))
  35. #include <windows.h>
  36. #include <winsock.h>
  37. #include <assert.h>
  38. #elif defined(VXWORKS)
  39. #include "vxWorks.h"
  40. #include "taskLib.h"
  41. #include "semLib.h"
  42. #include "selectLib.h"
  43. #include "fcntl.h"
  44. #include "sockLib.h"
  45. #include "inetLib.h"
  46. #include "hostLib.h"
  47. #else
  48. #include <sys/types.h>
  49. #include <sys/socket.h>
  50. #include <netdb.h>
  51. #include <netinet/in.h>
  52. #include <arpa/inet.h>
  53. #if (defined(__hpux))
  54. #include <pthread.h>
  55. #else
  56. #include <thread.h>
  57. #endif
  58. #include <unistd.h>
  59. #include <signal.h>
  60. #include <errno.h>
  61. #if (defined(USE_POLL))
  62. #include <stropts.h>
  63. #include <sys/poll.h>
  64. #endif
  65. #endif
  66. #include "exchange.h"
  67. #include "util/platform.h"
  68. #include "rtpstuff.h"
  69. #include "api/apierr.h"
  70. #if (!defined(WIN32))
  71. #define INVALID_SOCKET  -1
  72. #define INVALID_HANDLE_VALIE -1
  73. #define SOCKET_ERROR -1
  74. #endif
  75. #define RTCP_INTERVAL 60
  76. #define FRAMES_PER_RTP_PACKET 3
  77. #define AUDIO_FRAME_SIZE 24
  78. #define AUDIO_FRAME_SIZE_IN_MS 30
  79. #if (defined(VXWORKS))
  80. #define AUDIO_FILE "/tmp/sample.723"
  81. #else
  82. #define AUDIO_FILE "sample.723"
  83. #endif
  84. #define PORT_LOWER_LIMIT 8000
  85. #define PORT_UPPER_LIMIT 10000
  86. static unsigned short next_port = PORT_LOWER_LIMIT;
  87. // ip and port in netbyte order...
  88. int
  89. H245RTPSession::my_bind(SOCKET s, unsigned int ip, unsigned short *port)
  90. {
  91. sockaddr_in addr;
  92. int ret;
  93. addr.sin_family = AF_INET;
  94. addr.sin_port =  (*port) ? (*port) : htons(INADDR_ANY);
  95. #if (defined(VXWORKS)) // vxworks does not allow us to bind to a named address
  96. addr.sin_addr.s_addr =  htonl(INADDR_ANY);
  97. #else
  98. addr.sin_addr.s_addr = (ip) ? (ip) : htonl(INADDR_ANY);
  99. #endif
  100. {
  101. ret = bind(s, (sockaddr*)&addr, sizeof(addr));
  102. if (!ret)
  103. {
  104. #if(defined(__sun) || defined(WIN32))
  105. int address_length = sizeof(addr);
  106. #else
  107. size_t address_length = sizeof(addr);
  108. #endif
  109. #if defined(__hpux)
  110. ::getsockname(s, (sockaddr *)&addr, (int *)&address_length);
  111. #else
  112. ::getsockname(s, (sockaddr *)&addr, &address_length);
  113. #endif
  114. *port = addr.sin_port;
  115. }
  116. }
  117. return ret;
  118. }
  119. // ip and port in netbyte order..
  120. int
  121. H245RTPSession::my_connect(SOCKET s, unsigned int ip, unsigned short port)
  122. {
  123. sockaddr_in addr;
  124. addr.sin_family = AF_INET;
  125. addr.sin_port =  port;
  126. addr.sin_addr.s_addr = ip;
  127. return connect(s, (sockaddr*)&addr, sizeof(addr));
  128. }
  129. void 
  130. H245RTPSession::socket_error(SOCKET s, char *message)
  131. {
  132. LOG("H245RTPSession::socket_errorn");
  133. #if (defined(WIN32))
  134. LOG("H245RTPSession::socket = %d, errno = %d, %sn",
  135. s, WSAGetLastError(), message);
  136. #else
  137. LOG("H245RTPSession::socket = %d, errno = %d, %sn",
  138. s, errno, message);
  139. #endif
  140. }
  141. // return 0 on success, -1 on failure.
  142. H245RTPSession::H245RTPSession(char * session_name, int pt,int sr, int &status):
  143. RTPSession(session_name, pt, sr)
  144. {
  145. LOG("H245RTPSession::H245RTPSessionn");
  146. audio_fh = NULL;
  147. framer = deframer = NULL;
  148. rtcp_packet = NULL;
  149. status = 0;
  150. lrtp_port = 0;
  151. lrtcp_port = 0;
  152. rrtp_port = 0;
  153. rrtcp_port = 0;
  154. current_tc = 0;
  155. remote_address = 0;
  156. local_address = HTONS(INADDR_ANY);
  157. #if defined(WIN32)
  158. stop_rtpsession_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  159. #elif defined(VXWORKS)
  160. stop_rtpsession_socket = -1;
  161. #else
  162. if (pipe(stop_rtpsession_pipefds) < 0)
  163. {
  164. LOG("pipe creation failedn");
  165. }
  166. stop_rtpsession_socket = stop_rtpsession_pipefds[0];
  167. #endif
  168. lrtp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  169. lrtcp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  170. rrtp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  171. rrtcp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  172. if ( lrtp_socket == INVALID_SOCKET ||
  173. lrtcp_socket== INVALID_SOCKET ||
  174. rrtp_socket== INVALID_SOCKET ||
  175. rrtcp_socket== INVALID_SOCKET
  176. #if !defined(VXWORKS) && !defined(__hpux)
  177. || stop_rtpsession_socket == INVALID_SOCKET
  178. #endif
  179. )
  180. {
  181. status = -1;
  182. socket_error((unsigned int)-1,"Socket creation failedn");
  183. }
  184. #if (defined(VXWORKS))
  185. thread_id = ERROR;
  186. #elif (defined(__hpux))
  187. thread_id = cma_c_null;
  188. #else
  189. thread_id = 0;
  190. #if (defined(WIN32))
  191. thread_handle = INVALID_HANDLE_VALUE;
  192. #endif
  193. #endif
  194. }
  195. H245RTPSession::~H245RTPSession()
  196. {
  197. // Stop the RTP session...
  198. StopSession();
  199. #if (!defined(WIN32))
  200. #define closesocket close
  201. #endif
  202. if (lrtp_socket != INVALID_SOCKET)
  203. {
  204. closesocket(lrtp_socket);
  205. }
  206. if (lrtcp_socket != INVALID_SOCKET)
  207. {
  208. closesocket(lrtcp_socket);
  209. }
  210. if (rrtp_socket != INVALID_SOCKET)
  211. {
  212. closesocket(rrtp_socket);
  213. }
  214. if (rrtcp_socket != INVALID_SOCKET)
  215. {
  216. closesocket(rrtcp_socket);
  217. }
  218. #if !defined(WIN32)
  219. #undef closesocket
  220. #endif
  221. // Free up other resources..
  222. // asked to terminate ourselves;
  223. if (audio_fh != NULL)
  224. {
  225. fclose(audio_fh);
  226. audio_fh = NULL;
  227. }
  228. if (framer)
  229. {
  230. delete framer;
  231. }
  232. if (deframer)
  233. {
  234. delete deframer;
  235. }
  236. if (rtcp_packet)
  237. {
  238. delete rtcp_packet;
  239. }
  240. #if (!defined(WIN32) && !defined(VXWORKS))
  241. if (stop_rtpsession_pipefds[0] != INVALID_SOCKET)
  242. {
  243. close(stop_rtpsession_pipefds[0]);
  244. close(stop_rtpsession_pipefds[1]);
  245. }
  246. #endif
  247. }
  248. int 
  249. H245RTPSession::SetLocalPorts(unsigned int ip, unsigned short &rtp_port, 
  250. unsigned short &rtcp_port)
  251. {
  252. unsigned short tmp1, tmp2;
  253. local_address = ip;
  254. if (rtp_port == 0 || rtcp_port == 0)
  255. {
  256. tmp1 = htons(next_port);
  257. tmp2 = htons(next_port + 1);
  258. next_port += 2;
  259. if (next_port == PORT_UPPER_LIMIT)
  260. {
  261. next_port = PORT_LOWER_LIMIT;
  262. }
  263. }
  264. else
  265. {
  266. tmp1 = rtp_port;
  267. tmp2 = rtcp_port;
  268. }
  269. // Warning! if bind fails on the following, you should try binding 
  270. //          for the next consecutive pair of ports and not simply return error
  271. if (!lrtp_port)
  272. {
  273. lrtp_port = tmp1;
  274. if (my_bind(lrtp_socket, ip, &lrtp_port) == SOCKET_ERROR)
  275. {
  276. socket_error(lrtp_socket, "bind, lrtp_socket");
  277. return(-1);
  278. }
  279. rtp_port = lrtp_port;
  280. }
  281. else
  282. {
  283. rtp_port = lrtp_port;
  284. }
  285. if (!lrtcp_port)
  286. {
  287. lrtcp_port = tmp2;
  288. if (my_bind(lrtcp_socket, ip, &lrtcp_port) == SOCKET_ERROR)
  289. {
  290. socket_error(lrtp_socket, "bind, lrtp_socket");
  291. return(-1);
  292. }
  293. rtcp_port = lrtcp_port;
  294. }
  295. else
  296. {
  297. rtcp_port = lrtcp_port;
  298. }
  299. return(0);
  300. }
  301. void
  302. H245RTPSession::GetLocalPorts(unsigned int& ip, unsigned short &rtp_port,
  303. unsigned short &rtcp_port)
  304. {
  305. ip = local_address;
  306. rtp_port = lrtp_port;
  307. rtcp_port = lrtcp_port;
  308. }
  309. // assumes unicast ip address for now....
  310. int
  311. H245RTPSession::SetRemotePorts(unsigned int ip, unsigned short rtp_port, 
  312. unsigned short rtcp_port)
  313. {
  314. remote_address = ip;
  315. if (!rrtp_port && rtp_port) 
  316. {
  317. rrtp_port = rtp_port;
  318. if (my_connect(rrtp_socket, ip, rrtp_port) == SOCKET_ERROR)
  319. {
  320. socket_error(rrtp_socket, "connect, rrtp_socket");
  321. return(-1);
  322. }
  323. }
  324. if (!rrtcp_port && rtcp_port)
  325. {
  326. rrtcp_port = rtcp_port;
  327. if (my_connect(rrtcp_socket, ip, rrtcp_port) == SOCKET_ERROR)
  328. {
  329. socket_error(rrtp_socket, "connect, rrtp_socket");
  330. return(-1);
  331. }
  332. }
  333. return(0);
  334. }
  335. int
  336. H245RTPSession::StartSession()
  337. {
  338. static int first_time = 1;
  339. LOG("H245RTPSession::StartSessionn");
  340. if (init_rtp_session() != 0)
  341. {
  342. LOG("H245RTPSession:: cannot init h245 rtp sessionn");
  343. return(-1);
  344. }
  345. #if (defined(WIN32))
  346. thread_handle = (HANDLE) _beginthreadex(NULL, 
  347. 0 , 
  348. _begin_rtp_session,
  349. this, 
  350. 0,
  351. (unsigned *)&thread_id);
  352. if (thread_handle == INVALID_HANDLE_VALUE)
  353. {
  354. return(-1);
  355. }
  356. else
  357. {
  358. LOG("H245RTPSession::Successfully spawned rtp sessionn");
  359. }
  360. #elif (defined(VXWORKS))
  361. thread_id = taskSpawn("do_rtp",
  362. 90,
  363. 0,
  364. 8096,
  365. (FUNCPTR)_begin_rtp_session,
  366. (int)this,
  367. 0,0,0,0,0,0,0,0,0);
  368. if (thread_id == ERROR)
  369. {
  370. LOG("StartSession: taskSpawn failed, errno = 0x%xn", errno);
  371. return -1;
  372. }
  373. #elif (defined(__hpux))
  374.  
  375.     int ret = pthread_create(   &thread_id,
  376.                                 pthread_attr_default,
  377.                                 _begin_rtp_session,
  378.                                 this);
  379.  
  380.     LOG("StartSession: pthread_create returned for &thread_id: %xn",&thread_id)
  381. ;
  382.  
  383.     if (ret != 0)
  384.     {
  385.         LOG("StartSession: thread creation failed, errno = %dn", errno);
  386.         return(-1);
  387.     }
  388.     else
  389.     {
  390.         LOG("H245RTPSession::Successfully spawned rtp sessionn");
  391.     }
  392. #else
  393. int ret = thr_create(NULL, 
  394. 0 , 
  395. _begin_rtp_session,
  396. this, 
  397. 0,
  398. &thread_id);
  399. if (ret != 0)
  400. {
  401. LOG("StartSession: thread creation failed, errno = %dn", errno);
  402. return(-1);
  403. }
  404. else
  405. {
  406. LOG("H245RTPSession::Successfully spawned rtp sessionn");
  407. }
  408. #endif
  409. if (first_time)
  410. {
  411. first_time = 0;
  412. }
  413. return(0);
  414. }
  415. void 
  416. H245RTPSession::StopSession()
  417. {
  418. LOG("stopping session thread_id = %dn", thread_id);
  419. #if (defined(WIN32))
  420. if (thread_handle != INVALID_HANDLE_VALUE)
  421. {
  422. if (stop_rtpsession_socket != INVALID_SOCKET)
  423. {
  424. closesocket(stop_rtpsession_socket);
  425. stop_rtpsession_socket = INVALID_SOCKET;
  426. }
  427. // Wait for the thread to exit.
  428. if (WaitForSingleObject(thread_handle, 1000*5) == WAIT_TIMEOUT)
  429. {
  430. LOG("Wait for RTP thread timedoutn");
  431. TerminateThread(thread_handle,0);
  432. }
  433. CloseHandle(thread_handle);
  434. thread_handle = INVALID_HANDLE_VALUE;
  435. }
  436. #elif (defined(VXWORKS))
  437. if (thread_id != ERROR)
  438. {
  439. LOG("Calling taskIdVerify(%d)n",thread_id);
  440. if (taskIdVerify(thread_id) == OK)
  441. {
  442. LOG("Calling taskDelete(%d)n",thread_id);
  443. if (taskDelete(thread_id) == ERROR)
  444. {
  445. LOG("StopSession: taskDelete failed..n");
  446. }
  447. }
  448. }
  449. #elif (defined(__hpux))
  450.  
  451.     if (!pthread_equal(thread_id,cma_c_null))
  452.     {
  453.         pthread_t who_exited;
  454.         pthread_addr_t status;
  455.  
  456.         close (stop_rtpsession_pipefds[0]);
  457.         close (stop_rtpsession_pipefds[1]);
  458.  
  459.         stop_rtpsession_pipefds[0]=stop_rtpsession_pipefds[1] = INVALID_SOCKET;
  460.  
  461.         // Wait for the thread to exit.
  462.  
  463.         if (pthread_join(thread_id,&status) != 0)
  464.         {
  465.             LOG("Wait for RTP thread timedoutn");
  466.             pthread_cancel(thread_id);
  467.         }
  468.  
  469.         pthread_detach(&thread_id);
  470.  
  471.         thread_id = cma_c_null;
  472. }
  473. #else
  474. if (thread_id != 0)
  475. {
  476. thread_t who_exited;
  477. void *status;
  478. close (stop_rtpsession_pipefds[0]);
  479. close (stop_rtpsession_pipefds[1]);
  480. stop_rtpsession_pipefds[0]=stop_rtpsession_pipefds[1] = INVALID_SOCKET;
  481. // Wait for the thread to exit.
  482. if (thr_join(thread_id,&who_exited,&status) != 0)
  483. {
  484. LOG("Wait for RTP thread timedoutn");
  485. thr_kill(thread_id,SIGHUP);
  486. }
  487. thread_id = 0;
  488. }
  489. #endif
  490. }
  491. int 
  492. H245RTPSession::init_rtp_session()
  493. {
  494. LOG("H245RTPSession::init_rtp_sessionn");
  495. // assign port numbers and bind
  496. if (lrtp_port == 0 || lrtcp_port == 0)
  497. {
  498. if (SetLocalPorts(local_address, lrtp_port, lrtcp_port) 
  499. == -1)
  500. {
  501. LOG("H245RTPSession::SetLocalPorts failedn");
  502. return(-1);
  503. }
  504. }
  505. return(0);
  506. }
  507. void
  508. H245RTPSession::recv_rtcp_packet(SOCKET rtcp_sock,
  509. RTCPPacket *packet)
  510. {
  511. unsigned int ntp_sec;
  512. unsigned int ntp_frac;
  513. char buffer[4096];
  514. char *buf = buffer;
  515. int buf_len = sizeof(buffer);
  516. int length;
  517. length = recv(rtcp_sock, buf,buf_len,0);
  518. ntp64time(ntp_sec,ntp_frac);
  519. packet->Deframe(buf,length, ntp_sec,
  520. ntp_frac);
  521. #if (defined(__ENABLE_LOGGING__))
  522. RTCPSenderInfo *sender_info;
  523. packet->GetSenderInfo(sender_info);
  524. if (sender_info)
  525. {
  526. LOG("tSender infont{n");
  527. LOG("ttNum packets = %dn", sender_info->sr_np);
  528. LOG("ttNum bytes = %dnt}n", sender_info->sr_nb);
  529. }
  530. int rr;
  531. RTCPReceptionReport *rr_list;
  532. rr = packet->GetReceptionReports(rr_list);
  533. if (rr > 0)
  534. LOG("tReceiver report for %d receiversn",rr);
  535. while (rr > 0)
  536. {
  537. LOG("t{n"
  538. "ttrr_srcid = 0x%lxn"
  539. "ttrr_loss = %d:%dn"
  540. "ttrr_ehsr = %dn"
  541. "ttrr_dv = %dn"
  542. "ttrr_lsr = %dn"
  543. "ttrr_dlsr = %dn"
  544. "t}n",
  545. rr_list[rr - 1].rr_srcid,
  546. RTCP_GET_INCREMENTAL_LOSS(rr_list[rr - 1].rr_loss),
  547. RTCP_GET_CUMULATIVE_LOSS(rr_list[rr - 1].rr_loss),
  548. rr_list[rr - 1].rr_ehsr,
  549. rr_list[rr - 1].rr_dv,
  550. rr_list[rr - 1].rr_lsr,
  551. rr_list[rr - 1].rr_dlsr);
  552. --rr;
  553. }
  554. RTPEndpointInfo *e;
  555. e = GetParticipant(packet->GetSSRC());
  556. if (e)
  557. {
  558. RTPEndpointStats res;
  559. e->GetStatistics(res);
  560. if (res.es_received > 0)
  561. {
  562. LOG("tEndpoint stats for 0x%lxn"
  563. "t{n"
  564. "ttprobation = 0x%lxn"
  565. "ttmisorder = %dn"
  566. "ttreceived = %dn"
  567. "ttdelay_variance = %dn"
  568. "ttpackets_sent = %dn"
  569. "ttoctets_sent = %dn"
  570. "t}n",
  571. res.es_ssrc,
  572. res.es_probation,
  573. res.es_misorder,
  574. res.es_received,
  575. res.es_delay_variance,
  576. res.es_packets_sent,
  577. res.es_octets_sent);
  578. }
  579. }
  580. #endif
  581. }
  582. void
  583. H245RTPSession::send_rtcp_packet(SOCKET rtcp_sock,
  584. RTCPPacket *packet)
  585. {
  586. unsigned int ntp_sec;
  587. unsigned int ntp_frac;
  588. ntp64time(ntp_sec,ntp_frac);
  589. packet->Frame(current_tc, ntp_sec,
  590. ntp_frac, 0,0, NULL,0);
  591. send(rtcp_sock,packet->GetPacket(),
  592. packet->GetPacketLength(),0);
  593. }
  594. #if (defined(WIN32))
  595. unsigned __stdcall
  596. #elif (defined(VXWORKS))
  597. int
  598. #else
  599. void *
  600. #endif
  601. H245RTPSession::_begin_rtp_session(void *c)
  602. {
  603. H245RTPSession *s = (H245RTPSession *) c;
  604. s->do_rtp();
  605. return 0;
  606. }
  607. #if defined(USE_POLL)
  608. #define RTP_SOCKET_INDEX   0
  609. #define RTCP_SOCKET_INDEX  1
  610. #define INTERCONNECT_INDEX 2
  611. void 
  612. H245RTPSession::do_rtp()
  613. {
  614. int nfds;
  615. int length;
  616. char buffer[4096];
  617. char *buf = buffer;
  618. struct pollfd pfds[8];
  619. int packets_sent_count = 0;
  620. int packets_recd_count = 0;
  621. int buf_len = sizeof(buffer);
  622. int interconnect;
  623. struct timeval timeout;
  624. int tout = AUDIO_FRAME_SIZE_IN_MS * FRAMES_PER_RTP_PACKET; /*ms*/
  625. audio_fh = fopen(AUDIO_FILE, "r+b");
  626. if (audio_fh == NULL)
  627. {
  628. LOG("Error: do_rtp, failed to open %sn", AUDIO_FILE);
  629. }
  630. rtcp_packet = new RTCPPacket(this);
  631. deframer = new RTPPacket(this,0);
  632. timeout.tv_sec = 0;
  633. timeout.tv_usec = tout; 
  634. // Set the session payload type..
  635. SetPayloadType(local_pt);
  636. LOG("Begin _do_rtpn");
  637. interconnect = stop_rtpsession_socket;
  638. // First identify ourselves in the session..
  639. send_rtcp_packet(rrtcp_socket,  rtcp_packet);
  640. memset(pfds,0, sizeof(pfds));
  641. nfds = 2;
  642. pfds[RTP_SOCKET_INDEX].fd = lrtp_socket;
  643. pfds[RTP_SOCKET_INDEX].events = POLLIN;
  644. pfds[RTCP_SOCKET_INDEX].fd = lrtcp_socket;
  645. pfds[RTCP_SOCKET_INDEX].events = POLLIN;
  646. if (interconnect != INVALID_SOCKET)
  647. {
  648. nfds++;
  649. pfds[INTERCONNECT_INDEX].fd = interconnect;
  650. }
  651. while (1)
  652. {
  653. int ret;
  654. pfds[RTCP_SOCKET_INDEX].revents = 0;
  655. pfds[RTCP_SOCKET_INDEX].revents = 0;
  656. if ((poll(pfds,nfds,tout) == 0) && audio_fh != NULL)
  657. {
  658. // The two types of Frame functions have been demonstrated
  659. // below (within the #if 1 else #endif).
  660. #if 1
  661. if (!framer)
  662. {
  663. length = fread(buf, 1,
  664.  (AUDIO_FRAME_SIZE * FRAMES_PER_RTP_PACKET), audio_fh);
  665. if (length <= 0)
  666. {
  667. fclose(audio_fh);
  668. audio_fh = NULL;
  669. }
  670. framer = new RTPPacket(this,length);
  671. LOG("Framer created payload len = %d, packetlen = %dn",
  672. length, framer->GetMaxPacketLength());
  673. memcpy(framer->GetPayload(), buf, length);
  674. }
  675. else
  676. {
  677. length = fread(framer->GetPayload(), 1,
  678. (AUDIO_FRAME_SIZE * FRAMES_PER_RTP_PACKET),
  679.    audio_fh);
  680. if (length <= 0) 
  681. {
  682. rewind(audio_fh);
  683. continue;
  684. }
  685. }
  686. framer->Frame(current_tc, 0, length);
  687. send(rrtp_socket, framer->GetPacket(),
  688. framer->GetPacketLength(),0);
  689. #else
  690. // BEGIN: New RTPPacket::Frame demo
  691. // Following code demonstrates use of RTPPacket::Frame
  692. // with one less buffer copy.
  693. if (!framer)
  694. {
  695. // Don't let RTPPacket allocate any space for
  696. // the payload (max_payload = 0)
  697. framer = new RTPPacket(this,0);
  698. }
  699. // Leave just enough space at the beginning of the
  700. // buffer for RTPHeader..
  701. length = fread(buffer + framer->GetHeaderLength(),1,
  702.  (AUDIO_FRAME_SIZE * FRAMES_PER_RTP_PACKET), audio_fh);
  703. if (length <= 0) 
  704. {
  705. rewind(audio_fh);
  706. continue;
  707. }
  708. framer->Frame(buf,sizeof(buffer),current_tc,0,length);
  709. send(rrtp_socket, buffer,framer->GetPacketLength(),0);
  710. // END:: New RTPPacket::Frame demo
  711. #endif
  712. current_tc += (AUDIO_FRAME_SIZE_IN_MS * FRAMES_PER_RTP_PACKET)*8;
  713. packets_sent_count++;
  714. timeout.tv_sec = 0;
  715. timeout.tv_usec = tout;
  716. }
  717. if ((interconnect != INVALID_SOCKET) && 
  718. pfds[INTERCONNECT_INDEX].revents)
  719. {
  720. LOG("H245RTPSession::do_rtp "
  721. "pfds[INTERCONNECT_INDEX].revents = %xn", 
  722. pfds[INTERCONNECT_INDEX].revents);
  723. LOG("RTPThread:: exitingn");
  724. #if defined(__hpux)
  725. pthread_exit(NULL);
  726. #else
  727. thr_exit(NULL);
  728. #endif
  729. }
  730. if (pfds[RTP_SOCKET_INDEX].revents & POLLIN)
  731. {
  732. length = recv(lrtp_socket,buf,buf_len,0);
  733. if (length > 0)
  734. {
  735. int ret = deframer->Deframe(buf,length,current_tc);
  736. if (!PROT_IS_SUCCESS(ret))
  737. {
  738. LOG("RTPPacket::Deframe returned %dn",ret);
  739. }
  740. ++packets_recd_count;
  741. }
  742. }
  743. if (pfds[RTCP_SOCKET_INDEX].revents & POLLIN)
  744. {
  745. recv_rtcp_packet(lrtcp_socket, rtcp_packet);
  746. }
  747. if ((packets_recd_count == RTCP_INTERVAL) ||
  748. (packets_sent_count == RTCP_INTERVAL))
  749. {
  750. send_rtcp_packet(rrtcp_socket,  rtcp_packet);
  751. packets_recd_count = 0;
  752. packets_sent_count = 0;
  753. }
  754. }
  755. }
  756. #else // USE_POLL
  757. void 
  758. H245RTPSession::do_rtp()
  759. {
  760. int nfds;
  761. int length;
  762. char buffer[4096];
  763. char *buf = buffer;
  764. fd_set  read_fds;
  765. fd_set except_fds;
  766. int packets_sent_count = 0;
  767. int packets_recd_count = 0;
  768. int buf_len = sizeof(buffer);
  769. int interconnect;
  770. struct timeval timeout;
  771. int tout = AUDIO_FRAME_SIZE_IN_MS * FRAMES_PER_RTP_PACKET * 1000; /*us*/
  772. audio_fh = fopen(AUDIO_FILE, "r+b");
  773. if (audio_fh == NULL)
  774. {
  775. LOG("Error: do_rtp, failed to open %sn", AUDIO_FILE);
  776. }
  777. rtcp_packet = new RTCPPacket(this);
  778. deframer = new RTPPacket(this,0);
  779. timeout.tv_sec = 0;
  780. timeout.tv_usec = tout; 
  781. // Set the session payload type..
  782. SetPayloadType(local_pt);
  783. LOG("Begin _do_rtpn");
  784. interconnect = stop_rtpsession_socket;
  785. // First identify ourselves in the session..
  786. send_rtcp_packet(rrtcp_socket,  rtcp_packet);
  787. if (lrtp_socket > lrtcp_socket)
  788. {
  789. nfds = lrtp_socket;
  790. }
  791. else
  792. {
  793. nfds = lrtcp_socket;
  794. }
  795. if ((interconnect != INVALID_SOCKET) && (nfds < interconnect))
  796. {
  797. nfds = interconnect; 
  798. }
  799. ++nfds;
  800. while (1)
  801. {
  802. int select_ret;
  803. FD_ZERO(&read_fds);
  804. FD_ZERO(&except_fds);
  805. FD_SET(lrtp_socket, &read_fds);
  806. FD_SET(lrtcp_socket, &read_fds);
  807. if (interconnect != INVALID_SOCKET)
  808. {
  809. FD_SET(interconnect, &read_fds);
  810. FD_SET(interconnect, &except_fds);
  811. }
  812. select_ret = select(
  813. nfds,
  814. &read_fds, 
  815. NULL,
  816. &except_fds, 
  817. &timeout);
  818. #if (defined(WIN32))
  819. assert(SOCKET_ERROR == -1);
  820. #endif
  821. if (select_ret == -1)
  822. {
  823. LOG("RTPThread:: exitingn");
  824. #if (defined(WIN32))
  825. //closesocket(interconnect);
  826. //_endthreadex(2);
  827. return;
  828. #elif (defined(VXWORKS))
  829. return;
  830. #else
  831. thr_exit(NULL);
  832. #endif
  833. }
  834. else if (select_ret == 0 && audio_fh != NULL)
  835. {
  836. // The two types of Frame functions have been demonstrated
  837. // below (within the #if 1 else #endif).
  838. #if 1
  839. if (!framer)
  840. {
  841. length = fread(buf, 1,
  842.  (AUDIO_FRAME_SIZE * FRAMES_PER_RTP_PACKET), audio_fh);
  843. if (length <= 0)
  844. {
  845. fclose(audio_fh);
  846. audio_fh = NULL;
  847. }
  848. framer = new RTPPacket(this,length);
  849. LOG("Framer created payload len = %d, packetlen = %dn",
  850. length, framer->GetMaxPacketLength());
  851. memcpy(framer->GetPayload(), buf, length);
  852. }
  853. else
  854. {
  855. length = fread(framer->GetPayload(), 1,
  856. (AUDIO_FRAME_SIZE * FRAMES_PER_RTP_PACKET),
  857.    audio_fh);
  858. if (length <= 0) 
  859. {
  860. rewind(audio_fh);
  861. continue;
  862. }
  863. }
  864. framer->Frame(current_tc, 0, length);
  865. send(rrtp_socket, framer->GetPacket(),
  866. framer->GetPacketLength(),0);
  867. #else
  868. // BEGIN: New RTPPacket::Frame demo
  869. // Following code demonstrates use of RTPPacket::Frame
  870. // with one less buffer copy.
  871. if (!framer)
  872. {
  873. // Don't let RTPPacket allocate any space for
  874. // the payload (max_payload = 0)
  875. framer = new RTPPacket(this,0);
  876. }
  877. // Leave just enough space at the beginning of the
  878. // buffer for RTPHeader..
  879. length = fread(buffer + framer->GetHeaderLength(),1,
  880.  (AUDIO_FRAME_SIZE * FRAMES_PER_RTP_PACKET), audio_fh);
  881. if (length <= 0) 
  882. {
  883. rewind(audio_fh);
  884. continue;
  885. }
  886. framer->Frame(buf,sizeof(buffer),current_tc,0,length);
  887. send(rrtp_socket, buffer,framer->GetPacketLength(),0);
  888. // END:: New RTPPacket::Frame demo
  889. #endif
  890. current_tc += (AUDIO_FRAME_SIZE_IN_MS * FRAMES_PER_RTP_PACKET)*8;
  891. packets_sent_count++;
  892. timeout.tv_sec = 0;
  893. timeout.tv_usec = tout;
  894. }
  895. if (interconnect != INVALID_SOCKET && 
  896. FD_ISSET(interconnect, &except_fds))
  897. {
  898. // printf("do_rtp: exceptionn");
  899. LOG("RTPThread:: exitingn");
  900. #if (defined(WIN32))
  901. //closesocket(interconnect);
  902. //_endthreadex(2);
  903. return;
  904. #elif (defined(VXWORKS))
  905. return;
  906. #else
  907. thr_exit(NULL);
  908. #endif
  909. }
  910. if (FD_ISSET(lrtp_socket,&read_fds))
  911. {
  912. length = recv(lrtp_socket,buf,buf_len,0);
  913. if (length > 0)
  914. {
  915. int ret = deframer->Deframe(buf,length,current_tc);
  916. if (!PROT_IS_SUCCESS(ret))
  917. {
  918. LOG("RTPPacket::Deframe returned %dn",ret);
  919. }
  920. ++packets_recd_count;
  921. }
  922. }
  923. if (FD_ISSET(lrtcp_socket,&read_fds))
  924. {
  925. recv_rtcp_packet(lrtcp_socket, rtcp_packet);
  926. }
  927. if ((packets_recd_count == RTCP_INTERVAL) ||
  928. (packets_sent_count == RTCP_INTERVAL))
  929. {
  930. send_rtcp_packet(rrtcp_socket,  rtcp_packet);
  931. packets_recd_count = 0;
  932. packets_sent_count = 0;
  933. }
  934. }
  935. }
  936. #endif