Statistics
| Branch: | Tag: | Revision:

dvbd / src / rtp.c @ c6bfc590

History | View | Annotate | Download (7.53 KB)

1
#include <stdlib.h>
2
#include <string.h>
3
#include <netinet/in.h>
4
#include <unistd.h>
5
#include <stdlib.h>
6
#include <stdio.h>
7
#include <sys/types.h>
8
#include <sys/socket.h>
9
#include <arpa/inet.h>
10

    
11
/* MPEG-2 TS RTP stack */
12

    
13
#define DEBUG        1
14
#include "rtp.h"
15

    
16
/* Payload types (from RFC 1890):
17

18
      PT         encoding      audio/video    clock rate    channels
19
                 name          (A/V)          (Hz)          (audio)
20
      _______________________________________________________________
21
      0          PCMU          A              8000          1
22
      1          1016          A              8000          1
23
      2          G721          A              8000          1
24
      3          GSM           A              8000          1
25
      4          unassigned    A              8000          1
26
      5          DVI4          A              8000          1
27
      6          DVI4          A              16000         1
28
      7          LPC           A              8000          1
29
      8          PCMA          A              8000          1
30
      9          G722          A              8000          1
31
      10         L16           A              44100         2
32
      11         L16           A              44100         1
33
      12         unassigned    A
34
      13         unassigned    A
35
      14         MPA           A              90000        (see text)
36
      15         G728          A              8000          1
37
      16--23     unassigned    A
38
      24         unassigned    V
39
      25         CelB          V              90000
40
      26         JPEG          V              90000
41
      27         unassigned    V
42
      28         nv            V              90000
43
      29         unassigned    V
44
      30         unassigned    V
45
      31         H261          V              90000
46
      32         MPV           V              90000
47
      33         MP2T          AV             90000
48
      34--71     unassigned    ?
49
      72--76     reserved      N/A            N/A           N/A
50
      77--95     unassigned    ?
51
      96--127    dynamic       ?
52

53
*/
54

    
55

    
56
void initrtp(struct rtpheader *foo,int pt) { /* fill in the MPEG-2 TS deefaults */
57
  /* Note: MPEG-2 TS defines a timestamping base frequency of 90000 Hz. */
58
  foo->b.v=2;
59
  foo->b.p=0;
60
  foo->b.x=0;
61
  foo->b.cc=0;
62
  foo->b.m=0;
63
  foo->b.pt=pt;
64
  foo->b.sequence=rand() & 65535;
65
  foo->timestamp=rand();
66
  foo->ssrc=rand();
67
}
68

    
69
/* Send a single RTP packet, converting the RTP header to network byte order. */
70
int sendrtp(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, char *data, int len) {
71
  char *buf=(char*)alloca(len+sizeof(struct rtpheader));
72
  int *cast=(int *)foo;
73
  int *outcast=(int *)buf;
74
  outcast[0]=htonl(cast[0]);
75
  outcast[1]=htonl(cast[1]);
76
  memmove(outcast+2,data,len);
77
  fprintf(stderr,"v=%x %x\n",foo->b.v,buf[0]);
78
  return sendto(fd,buf,len+3,0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr));
79
}
80

    
81
int getrtp2(int fd, struct rtpheader *rh, char** data, int* lengthData) {
82
  static char buf[1600];
83
  unsigned int intP;
84
  char* charP = (char*) &intP;
85
  int headerSize;
86
  int lengthPacket;
87
  lengthPacket=recv(fd,buf,1590,0);
88
  if (lengthPacket==0)
89
    exit(1);
90
  if (lengthPacket<0) {
91
    fprintf(stderr,"socket read error\n");
92
    exit(2);
93
  }
94
  if (lengthPacket<12) {
95
    fprintf(stderr,"packet too small (%d) to be an rtp frame (>12bytes)\n",lengthPacket);
96
    exit(3);
97
  }
98
  rh->b.v  = (unsigned int) ((buf[0]>>6)&0x03);
99
  rh->b.p  = (unsigned int) ((buf[0]>>5)&0x01);
100
  rh->b.x  = (unsigned int) ((buf[0]>>4)&0x01);
101
  rh->b.cc = (unsigned int) ((buf[0]>>0)&0x0f);
102
  rh->b.m  = (unsigned int) ((buf[1]>>7)&0x01);
103
  rh->b.pt = (unsigned int) ((buf[1]>>0)&0x7f);
104
  intP = 0;
105
  memcpy(charP+2,&buf[2],2);
106
  rh->b.sequence = ntohl(intP);
107
  intP = 0;
108
  memcpy(charP,&buf[4],4);
109
  rh->timestamp = ntohl(intP);
110

    
111
  headerSize = 12 + 4*rh->b.cc; /* in bytes */
112

    
113
  *lengthData = lengthPacket - headerSize;
114
  *data = (char*) buf + headerSize;
115

    
116
  //  fprintf(stderr,"Reading rtp: v=%x p=%x x=%x cc=%x m=%x pt=%x seq=%x ts=%x lgth=%d\n",rh->b.v,rh->b.p,rh->b.x,rh->b.cc,rh->b.m,rh->b.pt,rh->b.sequence,rh->timestamp,lengthPacket);
117

    
118
  return(0);
119
}
120

    
121

    
122
/* Send a single RTP packet, converting the RTP header to network byte order. */
123
int sendrtp2(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, char *data, int len) {
124
  char *buf=(char*)alloca(len+72);
125
  unsigned int intP;
126
  char* charP = (char*) &intP;
127
  int headerSize;
128
  buf[0]  = 0x00;
129
  buf[0] |= ((((char) foo->b.v)<<6)&0xc0);
130
  buf[0] |= ((((char) foo->b.p)<<5)&0x20);
131
  buf[0] |= ((((char) foo->b.x)<<4)&0x10);
132
  buf[0] |= ((((char) foo->b.cc)<<0)&0x0f);
133
  buf[1]  = 0x00;
134
  buf[1] |= ((((char) foo->b.m)<<7)&0x80);
135
  buf[1] |= ((((char) foo->b.pt)<<0)&0x7f);
136
  intP = htonl(foo->b.sequence);
137
  memcpy(&buf[2],charP+2,2);
138
  intP = htonl(foo->timestamp);
139
  memcpy(&buf[4],&intP,4);
140
  /* SSRC: not implemented */
141
  buf[8]  = 0x0f;
142
  buf[9]  = 0x0f;
143
  buf[10] = 0x0f;
144
  buf[11] = 0x0f;
145
  headerSize = 12 + 4*foo->b.cc; /* in bytes */
146
  memcpy(buf+headerSize,data,len);
147

    
148
  //  fprintf(stderr,"Sending rtp: v=%x p=%x x=%x cc=%x m=%x pt=%x seq=%x ts=%x lgth=%d\n",foo->b.v,foo->b.p,foo->b.x,foo->b.cc,foo->b.m,foo->b.pt,foo->b.sequence,foo->timestamp,len+headerSize);
149

    
150
  foo->b.sequence++;
151
  return sendto(fd,buf,len+headerSize,0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr));
152
}
153

    
154

    
155
int getrtp(int fd, struct rtpheader *rh, char** data, int* lengthData) {
156
  static char buf[1600];
157
  int headerSize;
158
  int lengthPacket;
159

    
160
  lengthPacket=recv(fd,buf,1590,0);
161
  headerSize = 3;
162
  *lengthData = lengthPacket - headerSize;
163
  *data = (char*) buf + headerSize;
164
  fprintf(stderr,"[%d] %02x %x\n",lengthPacket,buf[8],buf[0]);
165
  return(0);
166
}
167

    
168
/* create a sender socket. */
169
int makesocket(char *szAddr,unsigned short port,int TTL,struct sockaddr_in *sSockAddr) {
170
  int          iRet, iLoop = 1;
171
  struct       sockaddr_in sin;
172
  char         cTtl = (char)TTL;
173
  char         cLoop=0;
174

    
175
  int iSocket = socket( AF_INET, SOCK_DGRAM, 0 );
176

    
177
  if (iSocket < 0) {
178
    fprintf(stderr,"socket() failed.\n");
179
    exit(1);
180
  }
181

    
182
  sSockAddr->sin_family = sin.sin_family = AF_INET;
183
  sSockAddr->sin_port = sin.sin_port = htons(port);
184
  sSockAddr->sin_addr.s_addr = inet_addr(szAddr);
185

    
186
  iRet = setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, &iLoop, sizeof(int));
187
  if (iRet < 0) {
188
    fprintf(stderr,"setsockopt SO_REUSEADDR failed\n");
189
    exit(1);
190
  }
191

    
192
  iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_TTL, &cTtl, sizeof(char));
193
  if (iRet < 0) {
194
    fprintf(stderr,"setsockopt IP_MULTICAST_TTL failed.  multicast in kernel?\n");
195
    exit(1);
196
  }
197

    
198
  cLoop = 1;        /* !? */
199
  iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
200
                    &cLoop, sizeof(char));
201
  if (iRet < 0) {
202
    fprintf(stderr,"setsockopt IP_MULTICAST_LOOP failed.  multicast in kernel?\n");
203
    exit(1);
204
  }
205

    
206
  return iSocket;
207
}
208

    
209
/* create a receiver socket, i.e. join the multicast group. */
210
int makeclientsocket(char *szAddr,unsigned short port,int TTL,struct sockaddr_in *sSockAddr) {
211
  int socket=makesocket(szAddr,port,TTL,sSockAddr);
212
  struct ip_mreq blub;
213
  struct sockaddr_in sin;
214
  unsigned int tempaddr;
215
  sin.sin_family=AF_INET;
216
  sin.sin_port=htons(port);
217
  sin.sin_addr.s_addr=inet_addr(szAddr);
218
  if (bind(socket,(struct sockaddr *)&sin,sizeof(sin))) {
219
    perror("bind failed");
220
    exit(1);
221
  }
222
  tempaddr=inet_addr(szAddr);
223
  if ((ntohl(tempaddr) >> 28) == 0xe) {
224
    blub.imr_multiaddr.s_addr = inet_addr(szAddr);
225
    blub.imr_interface.s_addr = 0;
226
    if (setsockopt(socket,IPPROTO_IP,IP_ADD_MEMBERSHIP,&blub,sizeof(blub))) {
227
      perror("setsockopt IP_ADD_MEMBERSHIP failed (multicast kernel?)");
228
      exit(1);
229
    }
230
  }
231
  return socket;
232
}