查看: 5101|回复: 13

[源码] 海思 RTP封包 发送

    [复制链接]
发表于 2013-11-15 12:45:46 | 显示全部楼层 |阅读模式
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #include <sys/types.h>   
  5. #include <sys/stat.h>   
  6. #include <sys/ioctl.h>   
  7. #include <sys/poll.h>   
  8. #include <fcntl.h>   
  9. #include <errno.h>   
  10. #include <pthread.h>   
  11. #include <sys/uio.h>   
  12.    
  13. #include <string.h>   
  14. #include <sys/select.h>   
  15. #include <sys/time.h>   
  16. #include <unistd.h>   
  17. #include <sys/socket.h>   
  18. #include <netinet/in.h>   
  19. #include <sys/socket.h>   
  20. #include <arpa/inet.h>   
  21. #include <hi_type.h>   
  22. #include "hi_common_api.h"   
  23.    
  24. #include "avcommon.h"   
  25. #include "av_type.h"   
  26. #include "dvs_pub.h"   
  27. #include "av_var.h"   
  28.    
  29. CHAR args[10][255];   
  30. /**********************************************************  
  31. Function     : HI_Socket  
  32. Description  : 创建socket  
  33. Input        : int af, int type, int protocol   
  34. Output       : 无  
  35. Return Value : int  
  36. Date         : 2007/10/10  
  37. Author       : cuixianwang  
  38. **********************************************************/   
  39. int HI_Socket(int af, int type, int protocol)   
  40. {   
  41.     return socket(af, type, protocol);   
  42. }   
  43. /**********************************************************  
  44. Function     : HI_SetSockOpt  
  45. Description  : 设置socket  
  46. Input        : int s, int level, int optname,   
  47.                const VOID *optval, HI_SockLen_T optlen   
  48. Output       : 无  
  49. Return Value : int  
  50. Date         : 2007/10/10  
  51. Author       : cuixianwang  
  52. **********************************************************/   
  53. int  HI_SetSockOpt(int s,   
  54.                       int level,   
  55.                       int optname,   
  56.                       const VOID *optval,   
  57.                       HI_SockLen_T optlen)   
  58. {   
  59.     return setsockopt(s, level, optname, optval, optlen);   
  60. }   
  61. /**********************************************************  
  62. Function     : HI_CloseSocket  
  63. Description  : 关闭socket  
  64. Input        : int ulSocket  
  65. Output       : 无  
  66. Return Value : int  
  67. Date         : 2007/9/25  
  68. Author       : cuixianwang  
  69. **********************************************************/   
  70. int HI_CloseSocket(int ulSocket)   
  71. {   
  72.     return close(ulSocket);   
  73. }   
  74. /**********************************************************  
  75. Function     : HI_Bind  
  76. Description  : 与特定socket的绑定地址  
  77. Input        : int s, const struct sockaddr *paddr,   
  78.                int addrlen   
  79. Output       : 无  
  80. Return Value : int  
  81. Date         : 2007/9/25  
  82. Author       : cuixianwang  
  83. **********************************************************/   
  84. int HI_Bind(int s, const struct sockaddr *paddr, int addrlen)   
  85. {   
  86.     return bind(s, (struct sockaddr *)paddr, addrlen);   
  87. }   
  88. /**********************************************************  
  89. Function     : HI_SOCKET_Udp_GetPort  
  90. Description  : 获取UDP socket端口  
  91. Input        : HI_SOCKET fd   
  92. Output       : 无  
  93. Return Value : USHORT  
  94. Date         : 2007/10/10  
  95. Author       : cuixianwang  
  96. **********************************************************/   
  97. USHORT HI_SOCKET_Udp_GetPort(HI_SOCKET fd)   
  98. {   
  99.     socklen_t namelen = sizeof(struct sockaddr_in);   
  100.     struct sockaddr_in *s;   
  101.       
  102.     if(getsockname(fd, (struct sockaddr *)s, &namelen))   
  103.     {   
  104.         return 0;   
  105.     }   
  106.       
  107.     return ntohs(s->sin_port);   
  108. }   
  109. /**********************************************************  
  110. Function     : HI_SOCKET_Udp_Open  
  111. Description  : 打开UDP socket  
  112. Input        : USHORT port   
  113. Output       : 无  
  114. Return Value : HI_SOCKET  
  115. Date         : 2007/10/10  
  116. Author       : cuixianwang  
  117. **********************************************************/   
  118. HI_SOCKET HI_SOCKET_Udp_Open(USHORT port)   
  119. {   
  120.     HI_SOCKET fd;   
  121.     struct sockaddr_in addr;   
  122.    
  123.     fd = socket(AF_INET, SOCK_DGRAM, 0);   
  124.     if(fd < 0)   
  125.     {   
  126.         printf("UDP Socket Open error: create socket error.\n");   
  127.         return -1;   
  128.     }   
  129.    
  130.     addr.sin_family = AF_INET;   
  131.     addr.sin_addr.s_addr = htonl(INADDR_ANY);   
  132.     addr.sin_port = htons(port);   
  133.     memset(&(addr.sin_zero), '\0', 8); // zero the rest of the struct   
  134.    
  135.     if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)))   
  136.     {   
  137.         HI_CloseSocket(fd);   
  138.         printf("UDP Socket Open error: bind socket error.\n");   
  139.         return -1;   
  140.     }   
  141.       
  142.     return fd;   
  143. }   
  144. /**********************************************************  
  145. Function     : RTP_Sender_Find  
  146. Description  : 查找是否已经存在目的主机  
  147. Input        : *pszRemoteHost, ip, port  
  148. Output       : 无  
  149. Return Value : 存在则返回REMOTEHOST_S类型指针;  
  150.                不存在则返回空指针  
  151. Date         : 2007/10/17  
  152. Author       : cuixianwang  
  153. **********************************************************/   
  154. REMOTEHOST_S* RTP_Sender_Find(REMOTEHOST_S *pszRemoteHost,   
  155.                               IN CHAR *ip,   
  156.                               IN USHORT port)   
  157. {   
  158.     ULONG ulCounter = 0;   
  159.    
  160.     /*输入参数合法性判断*/   
  161.     if(NULL == ip)   
  162.     {   
  163.         return NULL;   
  164.     }   
  165.    
  166.     /*查找目标主机是否已经存在*/   
  167.     for(ulCounter = 0; ulCounter < RTP_MAX_SENDER; ulCounter++)   
  168.     {   
  169.         if((strcmp(ip, pszRemoteHost[ulCounter].RemoteIp) == 0)   
  170.             && (port == pszRemoteHost[ulCounter].ReceivePort)   
  171.             && (pszRemoteHost[ulCounter].Active == TRUE))   
  172.         {   
  173.             return(&(pszRemoteHost[ulCounter]));   
  174.         }   
  175.     }   
  176.    
  177.     /*不存在该目标主机*/   
  178.     return NULL;   
  179. }   
  180. /**********************************************************  
  181. Function     : RTP_Sender_FindAvail  
  182. Description  : 在全局数组中查找插入位置  
  183. Input        : *pszRemoteHost   
  184. Output       : 无  
  185. Return Value : REMOTEHOST_S*  
  186. Date         : 2007/10/17  
  187. Author       : cuixianwang  
  188. **********************************************************/   
  189. REMOTEHOST_S* RTP_Sender_FindAvail(REMOTEHOST_S *pszRemoteHost)   
  190. {   
  191.     ULONG ulCounter = 0;   
  192.    
  193.     /*查找目标主机插入的位置*/   
  194.     for(ulCounter = 0; ulCounter < RTP_MAX_SENDER; ulCounter++)   
  195.     {   
  196.         if(pszRemoteHost[ulCounter].Active == FALSE)   
  197.         {   
  198.             return(&(pszRemoteHost[ulCounter]));   
  199.         }   
  200.     }   
  201.    
  202.     /*发送目标数量已经最大*/   
  203.     return NULL;   
  204. }   
  205. /**********************************************************  
  206. Function     : RTP_Sender_Add  
  207. Description  : 添加音视频发送的目的主机  
  208. Input        : *pszRemoteHost, *ip, port   
  209. Output       : 无  
  210. Return Value : int  
  211. Date         : 2007/10/17  
  212. Author       : cuixianwang  
  213. **********************************************************/   
  214. int RTP_Sender_Add(IN REMOTEHOST_S *pszRemoteHost,   
  215.                       OUT REMOTEHOST_S *pstHost,   
  216.                       IN CHAR *ip,   
  217.                       IN USHORT port)   
  218. {   
  219.     HI_SOCKET Sock;   
  220.     int inRetValue;   
  221.     int yes = 1;   
  222.     USHORT UdpPort = 0;   
  223.     REMOTEHOST_S *pstRemoteHost = NULL;   
  224.    
  225.     /*输入参数和法性判断*/   
  226.     if((NULL == ip) || (NULL == pszRemoteHost))   
  227.     {   
  228.         return FAILURE;   
  229.     }   
  230.       
  231.     /*查找目标机是否已经存在*/   
  232.     pstRemoteHost = RTP_Sender_Find(pszRemoteHost, ip, port);   
  233.    
  234.     /*不存在该目的主机*/   
  235.     if(NULL == pstRemoteHost)   
  236.     {           
  237.         /*查找该目的主机的插入位置*/   
  238.         pstRemoteHost = RTP_Sender_FindAvail(pszRemoteHost);   
  239.    
  240.         /*达到了支持最大用户数目*/   
  241.         if(NULL == pstRemoteHost)   
  242.         {   
  243.             return FAILURE;   
  244.         }   
  245.         memset(pstRemoteHost, 0, sizeof(REMOTEHOST_S));   
  246.         strcpy(pstRemoteHost->RemoteIp, ip);   
  247.         pstRemoteHost->ReceivePort = port;   
  248.         pstRemoteHost->RemoteAddr.sin_family = AF_INET; // host byte order   
  249.         pstRemoteHost->RemoteAddr.sin_port = htons(pstRemoteHost->ReceivePort); // SHORT, network byte order   
  250.         pstRemoteHost->RemoteAddr.sin_addr.s_addr = inet_addr(pstRemoteHost->RemoteIp);   
  251.         memset(&(pstRemoteHost->RemoteAddr.sin_zero), '\0', 8); // zero the rest of the struct   
  252.    
  253.         /*创建UDP socket*/   
  254.         Sock = HI_SOCKET_Udp_Open(0);   
  255.         if(Sock < 0)   
  256.         {   
  257.             printf("<RTP>create socket error.\n");   
  258.             return FAILURE;   
  259.         }   
  260.         UdpPort = HI_SOCKET_Udp_GetPort(Sock);   
  261.         pstRemoteHost->UdpPort = UdpPort;   
  262.         pstRemoteHost->Sock = Sock;   
  263.    
  264.         inRetValue = setsockopt(Sock,   
  265.                                 SOL_SOCKET,   
  266.                                 SO_REUSEADDR,   
  267.                                 &yes,   
  268.                                 sizeof(int));   
  269.         if(FAILURE == inRetValue)   
  270.         {   
  271.             return FAILURE;   
  272.         }   
  273.         pstRemoteHost->Active = TRUE;   
  274.     }   
  275.     pstRemoteHost->HostState = RTP_TARGETHOST_STATE_REQ_IFrame;   
  276.     memcpy(pstHost, pstRemoteHost, sizeof(REMOTEHOST_S));   
  277.       
  278.     return SUCCESS;   
  279. }   
  280. /**********************************************************  
  281. Function     : HI_RTP_Packet  
  282. Description  : 构造RTP报文  
  283. Input        : pRtpStream, ts_inc, marker, pPayload, len   
  284. Output       : 无  
  285. Return Value : int  
  286. Date         : 2007/10/10  
  287. Author       : cuixianwang  
  288. **********************************************************/   
  289. int HI_RTP_Packet(IN RTP_SENDER_S *pRtpStream,   
  290.                      int ts_inc,   
  291.                      UINT marker,   
  292.                      CHAR *pPayload,   
  293.                      int len)   
  294. {   
  295.     RTP_HDR_S *pRtpHdr = NULL;   
  296.    
  297.     /*输入参数合法性检查*/   
  298.     if((NULL == pRtpStream) || (NULL == pPayload))   
  299.     {   
  300.         return FAILURE;   
  301.     }   
  302.    
  303.     memset(pRtpStream->buff, 0, RPT_MAX_PACKET_BUFF);   
  304.     pRtpStream->buffLen = 0;   
  305.       
  306.     pRtpHdr = (RTP_HDR_S*)pRtpStream->buff;   
  307.     RTP_HDR_SET_VERSION(pRtpHdr, RTP_VERSION);   
  308.     RTP_HDR_SET_P(pRtpHdr, 0);   
  309.     RTP_HDR_SET_X(pRtpHdr, 1);   
  310.     RTP_HDR_SET_CC(pRtpHdr, 0);   
  311.     RTP_HDR_SET_M(pRtpHdr, marker);   
  312.     RTP_HDR_SET_PT(pRtpHdr, pRtpStream->pt);   
  313.     RTP_HDR_SET_SEQNO(pRtpHdr, htons(pRtpStream->last_sn));   
  314.     RTP_HDR_SET_TS(pRtpHdr, htonl(pRtpStream->last_ts));   
  315.     RTP_HDR_SET_SSRC(pRtpHdr, htonl(pRtpStream->ssrc));   
  316.     pRtpHdr->usProfile  = htons(1);   
  317.     pRtpHdr->usExtLen   = htons(2);   
  318.     pRtpHdr->uiVendorID = 0x7000 & 0xff00;   
  319.     pRtpHdr->uiPadding  = 0x0000;   
  320.    
  321.     pRtpStream->last_sn++;   
  322.     pRtpStream->last_ts += ts_inc;   
  323.     memcpy((pRtpStream->buff + RTP_HDR_LEN), pPayload, len);   
  324.     pRtpStream->buffLen = RTP_HDR_LEN + len;   
  325.    
  326.     return SUCCESS;   
  327. }   
  328. /**********************************************************  
  329. Function     : RTP_Send  
  330. Description  : 向各个目标机发送RTP报文  
  331. Input        : *pRtpStream, *pstRemoteHost   
  332. Output       : 无  
  333. Return Value : FAILURE 失败;  
  334.                SUCCESS 成功  
  335. Date         : 2007/10/17  
  336. Author       : cuixianwang  
  337. **********************************************************/   
  338. int RTP_Send(IN RTP_SENDER_S *pRtpStream, IN REMOTEHOST_S *pstRemoteHost)   
  339. {   
  340.     int iRetValue = 0;   
  341.     ULONG ulCounter = 0;   
  342.    
  343.     /*输入参数合法性检查*/   
  344.     if((NULL == pRtpStream) || (NULL == pstRemoteHost))   
  345.     {   
  346.         return FAILURE;   
  347.     }   
  348.    
  349.     /*向各个目标机发送RTP报文*/   
  350.     for(ulCounter = 0; ulCounter < RTP_MAX_SENDER; ulCounter++)   
  351.     {   
  352.         if((pstRemoteHost[ulCounter].Active == TRUE) && (pRtpStream->buffLen > 0))   
  353.         {      
  354.             iRetValue = sendto(pstRemoteHost[ulCounter].Sock,   
  355.                                pRtpStream->buff,   
  356.                                pRtpStream->buffLen,   
  357.                                0,   
  358.                                (struct sockaddr*)(&(pstRemoteHost[ulCounter].RemoteAddr)),   
  359.                                sizeof(struct sockaddr));   
  360.             if(iRetValue != pRtpStream->buffLen)   
  361.             {   
  362.                 perror("send rtp error.");   
  363.                 pRtpStream->stats.sent_error++;   
  364.                 printf("<RTP>send packet error. %s", strerror(errno));   
  365.             }   
  366.             else   
  367.             {   
  368.                 pRtpStream->stats.sent_byte += pRtpStream->buffLen;   
  369.                 pRtpStream->stats.sent_packet++;   
  370.             }   
  371.                
  372.             if(pRtpStream->buffLen <= 16)   
  373.             {   
  374.                 exit(-1);   
  375.             }   
  376.         }   
  377.     }   
  378.       
  379.     return SUCCESS;   
  380. }   
  381.    
复制代码
楼主热帖
发表于 2015-8-29 16:38:07 | 显示全部楼层

不错,学习收藏了,谢谢!
发表于 2015-4-21 09:43:47 | 显示全部楼层
非常感谢,收藏了
发表于 2015-6-22 17:32:33 | 显示全部楼层
正在学习中,多谢了 !!
发表于 2015-6-25 09:59:00 | 显示全部楼层
不错,学习收藏了,谢谢!
发表于 2017-6-5 09:34:13 | 显示全部楼层

不错,学习收藏了,谢谢!
发表于 2017-8-18 10:32:28 | 显示全部楼层
学习了。谢谢楼主
发表于 2017-8-18 12:09:35 | 显示全部楼层
学习了。谢谢楼主
发表于 2017-8-18 13:25:12 | 显示全部楼层
值得参考学习。。
发表于 2017-11-22 16:08:01 | 显示全部楼层
mark 学习   
发表于 2017-11-28 16:00:04 | 显示全部楼层
先收藏。谢谢楼主
发表于 2018-12-5 14:11:46 | 显示全部楼层
收藏了,不错,拿到办公室好好读读。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

© 2008-2017 当前位置 易百纳技术社区论坛 返回 易百纳技术社区 ( 苏ICP备14036084 )   Powered by Discuz! X3.1
快速回复 返回顶部 返回列表