/[lwip]/contrib/apps/rtp/rtp.c
ViewVC logotype

Diff of /contrib/apps/rtp/rtp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by fbernon, Sat Apr 26 10:53:32 2008 UTC revision 1.5 by goldsimon, Sun May 16 16:05:41 2010 UTC
# Line 33  Line 33 
33    
34  #include "lwip/opt.h"  #include "lwip/opt.h"
35    
36  #if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */  #if LWIP_SOCKET && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
37    
38  #include "lwip/sys.h"  #include "lwip/sys.h"
39  #include "lwip/sockets.h"  #include "lwip/sockets.h"
40    
41  #include "rtpdata.h"  #include "rtpdata.h"
42    
43    #include <string.h>
44    
45  /** This is an example of a "RTP" client/server based on a MPEG4 bitstream (with socket API).  /** This is an example of a "RTP" client/server based on a MPEG4 bitstream (with socket API).
46   */   */
47    
# Line 97  Line 99 
99  #endif  #endif
100  PACK_STRUCT_BEGIN  PACK_STRUCT_BEGIN
101  struct rtp_hdr {  struct rtp_hdr {
102    u8_t  version;    PACK_STRUCT_FIELD(u8_t  version);
103    u8_t  payloadtype;    PACK_STRUCT_FIELD(u8_t  payloadtype);
104    u16_t seqNum;    PACK_STRUCT_FIELD(u16_t seqNum);
105    u32_t timestamp;    PACK_STRUCT_FIELD(u32_t timestamp);
106    u32_t ssrc;    PACK_STRUCT_FIELD(u32_t ssrc);
107  } PACK_STRUCT_STRUCT;  } PACK_STRUCT_STRUCT;
108  PACK_STRUCT_END  PACK_STRUCT_END
109  #ifdef PACK_STRUCT_USE_INCLUDES  #ifdef PACK_STRUCT_USE_INCLUDES
# Line 127  rtp_send_packets( int sock, struct socka Line 129  rtp_send_packets( int sock, struct socka
129    rtphdr = (struct rtp_hdr*)rtp_send_packet;    rtphdr = (struct rtp_hdr*)rtp_send_packet;
130    rtphdr->version     = RTP_VERSION;    rtphdr->version     = RTP_VERSION;
131    rtphdr->payloadtype = 0;    rtphdr->payloadtype = 0;
132    rtphdr->ssrc        = htonl(RTP_SSRC);    rtphdr->ssrc        = PP_HTONL(RTP_SSRC);
133    rtphdr->timestamp   = htonl(ntohl(rtphdr->timestamp)+RTP_TIMESTAMP_INCREMENT);    rtphdr->timestamp   = htonl(ntohl(rtphdr->timestamp) + RTP_TIMESTAMP_INCREMENT);
134    
135    /* send RTP stream packets */    /* send RTP stream packets */
136    rtp_data_index = 0;    rtp_data_index = 0;
137    do {    do {
138      rtp_payload      = rtp_send_packet+sizeof(struct rtp_hdr);      rtp_payload      = rtp_send_packet+sizeof(struct rtp_hdr);
139      rtp_payload_size = min( RTP_PAYLOAD_SIZE, (sizeof(rtp_data)-rtp_data_index));      rtp_payload_size = min(RTP_PAYLOAD_SIZE, (sizeof(rtp_data) - rtp_data_index));
140    
141      memcpy( rtp_payload, rtp_data+rtp_data_index, rtp_payload_size);      memcpy(rtp_payload, rtp_data + rtp_data_index, rtp_payload_size);
142    
143      /* set MARKER bit in RTP header on the last packet of an image */      /* set MARKER bit in RTP header on the last packet of an image */
144      rtphdr->payloadtype = RTP_PAYLOADTYPE | (((rtp_data_index+rtp_payload_size)>=sizeof(rtp_data))?RTP_MARKER_MASK:0);      rtphdr->payloadtype = RTP_PAYLOADTYPE | (((rtp_data_index + rtp_payload_size)
145          >= sizeof(rtp_data)) ? RTP_MARKER_MASK : 0);
146    
147      /* send RTP stream packet */      /* send RTP stream packet */
148      if (sendto( sock, rtp_send_packet, sizeof(struct rtp_hdr)+rtp_payload_size, 0, (struct sockaddr *)to, sizeof(struct sockaddr))>=0) {      if (sendto(sock, rtp_send_packet, sizeof(struct rtp_hdr) + rtp_payload_size,
149        rtphdr->seqNum  = htons(ntohs(rtphdr->seqNum)+1);          0, (struct sockaddr *)to, sizeof(struct sockaddr)) >= 0) {
150          rtphdr->seqNum  = htons(ntohs(rtphdr->seqNum) + 1);
151        rtp_data_index += rtp_payload_size;        rtp_data_index += rtp_payload_size;
152      } else {      } else {
153        LWIP_DEBUGF( RTP_DEBUG, ("rtp_sender: not sendto==%i\n", errno));        LWIP_DEBUGF(RTP_DEBUG, ("rtp_sender: not sendto==%i\n", errno));
154      }      }
155    }while (rtp_data_index<sizeof(rtp_data));    }while (rtp_data_index < sizeof(rtp_data));
156  }  }
157    
158  /**  /**
# Line 168  rtp_send_thread(void *arg) Line 172  rtp_send_thread(void *arg)
172    rtp_stream_address = RTP_STREAM_ADDRESS;    rtp_stream_address = RTP_STREAM_ADDRESS;
173    
174    /* if we got a valid RTP stream address... */    /* if we got a valid RTP stream address... */
175    if (rtp_stream_address!=0) {    if (rtp_stream_address != 0) {
176      /* create new socket */      /* create new socket */
177      sock = socket( AF_INET, SOCK_DGRAM, 0);      sock = socket(AF_INET, SOCK_DGRAM, 0);
178      if (sock>=0) {      if (sock >= 0) {
179        /* prepare local address */        /* prepare local address */
180        memset(&local, 0, sizeof(local));        memset(&local, 0, sizeof(local));
181        local.sin_family      = AF_INET;        local.sin_family      = AF_INET;
182        local.sin_port        = htons(INADDR_ANY);        local.sin_port        = PP_HTONS(INADDR_ANY);
183        local.sin_addr.s_addr = htonl(INADDR_ANY);        local.sin_addr.s_addr = PP_HTONL(INADDR_ANY);
184    
185        /* bind to local address */        /* bind to local address */
186        if (bind( sock, (struct sockaddr *)&local, sizeof(local))==0) {        if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) {
187          /* prepare RTP stream address */          /* prepare RTP stream address */
188          memset(&to, 0, sizeof(to));          memset(&to, 0, sizeof(to));
189          to.sin_family      = AF_INET;          to.sin_family      = AF_INET;
190          to.sin_port        = htons(RTP_STREAM_PORT);          to.sin_port        = PP_HTONS(RTP_STREAM_PORT);
191          to.sin_addr.s_addr = rtp_stream_address;          to.sin_addr.s_addr = rtp_stream_address;
192    
193          /* send RTP packets */          /* send RTP packets */
194          memset( rtp_send_packet, 0, sizeof(rtp_send_packet));          memset(rtp_send_packet, 0, sizeof(rtp_send_packet));
195          while(1) {          while (1) {
196            rtp_send_packets( sock, &to);            rtp_send_packets( sock, &to);
197            sys_msleep(RTP_SEND_DELAY);            sys_msleep(RTP_SEND_DELAY);
198          }          }
# Line 225  rtp_recv_thread(void *arg) Line 229  rtp_recv_thread(void *arg)
229    rtp_stream_address = RTP_STREAM_ADDRESS;    rtp_stream_address = RTP_STREAM_ADDRESS;
230    
231    /* if we got a valid RTP stream address... */    /* if we got a valid RTP stream address... */
232    if (rtp_stream_address!=0) {    if (rtp_stream_address != 0) {
233      /* create new socket */      /* create new socket */
234      sock = socket( AF_INET, SOCK_DGRAM, 0);      sock = socket(AF_INET, SOCK_DGRAM, 0);
235      if (sock>=0) {      if (sock >= 0) {
236        /* prepare local address */        /* prepare local address */
237        memset(&local, 0, sizeof(local));        memset(&local, 0, sizeof(local));
238        local.sin_family      = AF_INET;        local.sin_family      = AF_INET;
239        local.sin_port        = htons(RTP_STREAM_PORT);        local.sin_port        = PP_HTONS(RTP_STREAM_PORT);
240        local.sin_addr.s_addr = htonl(INADDR_ANY);        local.sin_addr.s_addr = PP_HTONL(INADDR_ANY);
241    
242        /* bind to local address */        /* bind to local address */
243        if (bind( sock, (struct sockaddr *)&local, sizeof(local))==0) {        if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) {
244          /* set recv timeout */          /* set recv timeout */
245          timeout = RTP_RECV_TIMEOUT;          timeout = RTP_RECV_TIMEOUT;
246          setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));          setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
247    
248          /* prepare multicast "ip_mreq" struct */          /* prepare multicast "ip_mreq" struct */
249          ipmreq.imr_multiaddr.s_addr = rtp_stream_address;          ipmreq.imr_multiaddr.s_addr = rtp_stream_address;
250          ipmreq.imr_interface.s_addr = htonl(INADDR_ANY);          ipmreq.imr_interface.s_addr = PP_HTONL(INADDR_ANY);
251    
252          /* join multicast group */          /* join multicast group */
253          if (setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmreq, sizeof(ipmreq))==0) {          if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmreq, sizeof(ipmreq)) == 0) {
254            /* receive RTP packets */            /* receive RTP packets */
255            while(1) {            while(1) {
256              fromlen = sizeof(from);              fromlen = sizeof(from);
257              result  = recvfrom( sock, rtp_recv_packet, sizeof(rtp_recv_packet), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen);              result  = recvfrom(sock, rtp_recv_packet, sizeof(rtp_recv_packet), 0,
258                  (struct sockaddr *)&from, (socklen_t *)&fromlen);
259              if (result >= sizeof(struct rtp_hdr)) {              if (result >= sizeof(struct rtp_hdr)) {
260                rtphdr = (struct rtp_hdr  *)rtp_recv_packet;                rtphdr = (struct rtp_hdr *)rtp_recv_packet;
261                recvrtppackets++;                recvrtppackets++;
262                if ((lastrtpseq == 0) || ((lastrtpseq+1) == ntohs(rtphdr->seqNum))) {                if ((lastrtpseq == 0) || ((lastrtpseq + 1) == ntohs(rtphdr->seqNum))) {
263                  RTP_RECV_PROCESSING((rtp_recv_packet+sizeof(rtp_hdr)),(result-sizeof(rtp_hdr)));                  RTP_RECV_PROCESSING((rtp_recv_packet + sizeof(rtp_hdr)),(result-sizeof(rtp_hdr)));
264                } else {                } else {
265                  lostrtppackets++;                  lostrtppackets++;
266                }                }
267                lastrtpseq = ntohs(rtphdr->seqNum);                lastrtpseq = ntohs(rtphdr->seqNum);
268                if ((recvrtppackets % RTP_RECV_STATS) == 0) {                if ((recvrtppackets % RTP_RECV_STATS) == 0) {
269                  LWIP_DEBUGF( RTP_DEBUG, ("rtp_recv_thread: recv %6i packet(s) / lost %4i packet(s) (%.4f%%)...\n", recvrtppackets, lostrtppackets, (lostrtppackets*100.0)/recvrtppackets));                  LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: recv %6i packet(s) / lost %4i packet(s) (%.4f%%)...\n", recvrtppackets, lostrtppackets, (lostrtppackets*100.0)/recvrtppackets));
270                }                }
271              } else {              } else {
272                LWIP_DEBUGF( RTP_DEBUG, ("rtp_recv_thread: recv timeout...\n"));                LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: recv timeout...\n"));
273              }              }
274            }            }
275    
276            /* leave multicast group */            /* leave multicast group */
277            setsockopt( sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipmreq, sizeof(ipmreq));            setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipmreq, sizeof(ipmreq));
278          }          }
279        }        }
280    
# Line 281  rtp_recv_thread(void *arg) Line 286  rtp_recv_thread(void *arg)
286    
287  void  void
288  rtp_init(void)  rtp_init(void)
289  { sys_thread_new("rtp_send_thread", rtp_send_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);  {
290      sys_thread_new("rtp_send_thread", rtp_send_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
291    sys_thread_new("rtp_recv_thread", rtp_recv_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);    sys_thread_new("rtp_recv_thread", rtp_recv_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
292  }  }
293    
294  #endif /* LWIP_SOCKET */  #endif /* LWIP_SOCKET && LWIP_IGMP */

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26