Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
7.3 KiB

  1. // RTPSession.h : Declaration of the CRTPSession
  2. #ifndef __RTPSESSION_H_
  3. #define __RTPSESSION_H_
  4. #include "resource.h" // main symbols
  5. #include "queue.h"
  6. #ifndef MAX_MISORDER
  7. const int MAX_MISORDER =20;
  8. #endif
  9. const int MAX_DROPPED =30;
  10. typedef short PORT;
  11. typedef unsigned __int64 NTP_TS;
  12. //typedef void (* PRTPRECVCALLBACK)(DWORD dwStatus, DWORD_PTR dwCallback, NETBUF *pNetBuf, DWORD ssrc, DWORD ts, UINT seq, BOOL fMark);
  13. typedef struct {
  14. UINT sessionId;
  15. UINT mediaId;
  16. BOOL fSend;
  17. PSOCKADDR_IN pLocalAddr;
  18. PSOCKADDR_IN pLocalRTCPAddr;
  19. PSOCKADDR_IN pRemoteAddr;
  20. PSOCKADDR_IN pRemoteRTCPAddr;
  21. } RTPCHANNELDESC;
  22. typedef struct {
  23. RTP_HDR_T hdr; // header template for quick formatting
  24. RTP_STATS sendStats; // statistics
  25. } RTP_SEND_STATE;
  26. typedef struct {
  27. RTP_STATS rcvStats; // statistics
  28. NTP_TS ntpTime;
  29. DWORD rtpTime;
  30. } RTP_RECV_STATE;
  31. // generic UDP socket wrapper
  32. // defined in its entirety here
  33. class UDPSOCKET {
  34. SOCKET Sock;
  35. SOCKADDR_IN local_sin;
  36. SOCKADDR_IN remote_sin;
  37. int local_sin_len;
  38. int remote_sin_len;
  39. public:
  40. UDPSOCKET() {
  41. ZeroMemory(&local_sin,sizeof(local_sin));
  42. ZeroMemory(&remote_sin,sizeof(remote_sin));
  43. Sock = INVALID_SOCKET;}
  44. ~UDPSOCKET()
  45. {
  46. Cleanup();
  47. }
  48. VOID SetRemoteAddr(PSOCKADDR_IN psin) {remote_sin = *psin;};
  49. VOID SetLocalAddress(PSOCKADDR_IN psin) {local_sin = *psin;};
  50. PSOCKADDR_IN GetLocalAddress() {return &local_sin;};
  51. PSOCKADDR_IN GetRemoteAddress() {return &remote_sin;};
  52. VOID SetRemotePort(PORT port) {remote_sin.sin_port = htons(port);};
  53. VOID SetLocalPort(PORT port) {local_sin.sin_port = htons(port);};
  54. PORT GetRemotePort() {return (ntohs(remote_sin.sin_port));};
  55. PORT GetLocalPort() {return(ntohs(local_sin.sin_port));};
  56. SOCKET GetSock() {return Sock;};
  57. BOOL NewSock()
  58. {
  59. if(Sock == INVALID_SOCKET)
  60. {
  61. Sock = (*RRCMws.WSASocket) (AF_INET,
  62. SOCK_DGRAM,
  63. WS2Enabled ? FROM_PROTOCOL_INFO : 0,
  64. &RRCMws.RTPProtInfo,
  65. 0,
  66. WSA_FLAG_OVERLAPPED);
  67. }
  68. return(Sock != INVALID_SOCKET);
  69. }
  70. VOID Cleanup()
  71. {
  72. if(Sock != INVALID_SOCKET)
  73. {
  74. (*RRCMws.closesocket)(Sock);
  75. Sock = INVALID_SOCKET;
  76. }
  77. }
  78. int BindMe()
  79. {
  80. return (*RRCMws.bind)(Sock, (LPSOCKADDR)&local_sin, sizeof (local_sin));
  81. }
  82. };
  83. /////////////////////////////////////////////////////////////////////////////
  84. // CRTPPacket (internal object representing a received RTPPacket)
  85. class CRTPPacket1
  86. {
  87. public:
  88. CRTPPacket1()
  89. {
  90. m_wsabuf.buf = NULL;
  91. m_wsabuf.len = 0;
  92. m_cbSize = 0;
  93. }
  94. ~CRTPPacket1();
  95. public:
  96. HRESULT Init(UINT cbMaxSize); // allocates buffer of size cbMaxSize
  97. WSAOVERLAPPED *GetOverlapped() {return &m_overlapped;}
  98. void SetActual(UINT len) {m_wsabuf.len = len;}
  99. void RestoreSize() {m_wsabuf.len = m_cbSize;}
  100. static CRTPPacket1 *GetRTPPacketFromOverlapped(WSAOVERLAPPED *pOverlapped)
  101. {
  102. return ( (CRTPPacket1 *)((char *)pOverlapped - (UINT_PTR)(&((CRTPPacket1 *)0)->m_overlapped)));
  103. }
  104. static CRTPPacket1 *GetRTPPacketFromWSABUF(WSABUF *pBuf)
  105. {
  106. return ( (CRTPPacket1 *)((char *)pBuf - (UINT_PTR)(&((CRTPPacket1 *)0)->m_wsabuf)));
  107. }
  108. WSABUF *GetWSABUF() {return &m_wsabuf;}
  109. DWORD GetTimestamp() {return (((RTP_HDR_T *)m_wsabuf.buf)->ts);}
  110. void SetTimestamp(DWORD timestamp) {((RTP_HDR_T *)m_wsabuf.buf)->ts = timestamp;}
  111. UINT GetSeq() {return (((RTP_HDR_T *)m_wsabuf.buf)->seq);}
  112. void SetSeq(UINT seq) {((RTP_HDR_T *)m_wsabuf.buf)->seq = (WORD)seq;}
  113. BOOL GetMarkBit() {return (((RTP_HDR_T *)m_wsabuf.buf)->m);}
  114. private:
  115. WSAOVERLAPPED m_overlapped;
  116. WSABUF m_wsabuf;
  117. UINT m_cbSize; // (max) size of packet
  118. };
  119. /////////////////////////////////////////////////////////////////////////////
  120. // CRTPSession
  121. class ATL_NO_VTABLE CRTPSession :
  122. public CComObjectRootEx<CComMultiThreadModel>,
  123. // public CComCoClass<CRTPSession, &CLSID_RTPSession>,
  124. public IRTPSend,
  125. public IRTPSession,
  126. public IRTPRecv
  127. {
  128. public:
  129. CRTPSession();
  130. HRESULT FinalRelease();
  131. //DECLARE_REGISTRY_RESOURCEID(IDR_RTPSESSION)
  132. BEGIN_COM_MAP(CRTPSession)
  133. COM_INTERFACE_ENTRY(IRTPSend)
  134. COM_INTERFACE_ENTRY(IRTPSession)
  135. COM_INTERFACE_ENTRY(IRTPRecv)
  136. END_COM_MAP()
  137. // IRTPSend
  138. public:
  139. STDMETHOD(Send)(
  140. WSABUF *pWsabufs,
  141. UINT nWsabufs,
  142. WSAOVERLAPPED *pOverlapped,
  143. LPWSAOVERLAPPED_COMPLETION_ROUTINE pWSAPC );
  144. STDMETHOD(GetSendStats)(RTP_STATS *pSendStats) {
  145. *pSendStats = m_ss.sendStats;return S_OK;
  146. }
  147. // IRTPRecv
  148. STDMETHOD(SetRecvNotification) (PRTPRECVCALLBACK , DWORD_PTR dwCallback, UINT nBufs);
  149. STDMETHOD(CancelRecvNotification) ();
  150. // called by CRTPMediaStream to free accumulated packets
  151. STDMETHOD (FreePacket)(WSABUF *pBuf) ;
  152. STDMETHOD(GetRecvStats)(RTP_STATS *pSendStats) {
  153. *pSendStats = m_rs.rcvStats;return S_OK;
  154. }
  155. // IRTPSession
  156. STDMETHOD(SetLocalAddress)(BYTE *sockaddr, UINT cbAddr);
  157. STDMETHOD(SetRemoteRTPAddress)(BYTE *sockaddr, UINT cbAddr);
  158. STDMETHOD(SetRemoteRTCPAddress)(BYTE *sockaddr, UINT cbAddr);
  159. STDMETHOD(GetLocalAddress)(const BYTE **sockaddr, UINT *pcbAddr);
  160. STDMETHOD(GetRemoteRTPAddress)(const BYTE **sockaddr, UINT *pcbAddr);
  161. STDMETHOD(GetRemoteRTCPAddress)(const BYTE **sockaddr, UINT *pcbAddr);
  162. STDMETHOD(CreateRecvRTPStream)(DWORD ssrc, IRTPRecv **ppIRTPRecv);
  163. STDMETHOD(SetSendFlowspec)(FLOWSPEC *pSendFlowspec);
  164. STDMETHOD(SetRecvFlowspec)(FLOWSPEC *pRecvFlowspec);
  165. STDMETHOD (SetMaxPacketSize) (UINT cbPacketSize);
  166. // other non-COM methods
  167. // called by CRTPMediaStream to request that receive buffers be posted
  168. HRESULT PostRecv();
  169. private:
  170. UDPSOCKET *m_rtpsock;
  171. UDPSOCKET *m_rtcpsock;
  172. UINT m_sessionId;
  173. UINT m_mediaId;
  174. class CRTPSession *m_pSessNext;
  175. static class CRTPSession *m_pSessFirst;
  176. HANDLE m_hRTPSession;
  177. QOS m_Qos;
  178. UINT m_clockRate;
  179. // receive stuff
  180. UINT m_uMaxPacketSize;
  181. QueueOf<CRTPPacket1 *> m_FreePkts;
  182. UINT m_nBufsPosted;
  183. // this should be per remote SSRC
  184. PRTPRECVCALLBACK m_pRTPCallback;
  185. DWORD_PTR m_dwCallback;
  186. RTP_RECV_STATE m_rs;
  187. // used by RTPRecvFrom()
  188. int m_rcvSockAddrLen;
  189. SOCKADDR m_rcvSockAddr;
  190. // send stuff
  191. DWORD m_numBytesSend;
  192. int m_lastSendError;
  193. WSAOVERLAPPED m_sOverlapped; // used only for synchronous Send()
  194. BOOL m_fSendingSync; // TRUE if m_sOverlapped is in use
  195. RTP_SEND_STATE m_ss;
  196. HRESULT Initialize(UINT sessionId, UINT mediaId,BYTE *sockaddr, UINT cbAddr);
  197. BOOL SelectPorts();
  198. HRESULT SetMulticastAddress(PSOCKADDR_IN );
  199. friend void RRCMNotification(int ,DWORD_PTR,DWORD_PTR,DWORD_PTR);
  200. friend void CALLBACK WS2SendCB (DWORD , DWORD, LPWSAOVERLAPPED, DWORD );
  201. friend void CALLBACK WS2RecvCB (DWORD , DWORD, LPWSAOVERLAPPED, DWORD );
  202. friend class CRTP;
  203. void RTCPNotify(int,DWORD_PTR dwSSRC,DWORD_PTR rtcpsock);
  204. BOOL GetRTCPReport();
  205. };
  206. typedef CComObject<CRTPSession> ObjRTPSession; // instantiable class
  207. /////////////////////////////////////////////////////////////////////////////
  208. // CRTP - top level RTP interface
  209. //
  210. class ATL_NO_VTABLE CRTP:
  211. public CComObjectRootEx<CComMultiThreadModel>,
  212. public CComCoClass<CRTP, &CLSID_RTP>,
  213. public IRTP
  214. {
  215. public:
  216. DECLARE_REGISTRY_RESOURCEID(IDR_RTP)
  217. BEGIN_COM_MAP(CRTP)
  218. COM_INTERFACE_ENTRY(IRTP)
  219. END_COM_MAP()
  220. // IRTP
  221. public:
  222. STDMETHOD(OpenSession)(
  223. UINT sessionId, // client specified unique identifier for the session
  224. DWORD flags, // SESSION_SEND, SESSION_RECV, SESSION_MULTICAST
  225. BYTE *localAddr, // Local socket interface addr to bind to
  226. UINT cbAddr, // sizeof(SOCKADDR)
  227. IRTPSession **ppIRTP); // [output] pointer to RTPSession
  228. // STDMETHOD(CreateSink)( IRTPSink **ppIRTPSink);
  229. private:
  230. static BOOL m_WSInitialized;
  231. };
  232. #endif //__RTPSINK_H_
  233.