Mercurial > mplayer.hg
comparison libmpdemux/rtp.c @ 3686:bed6226ffb46
RTP support patch by Brian Kuschak <bkuschak@yahoo.com>
author | arpi |
---|---|
date | Sun, 23 Dec 2001 22:09:02 +0000 |
parents | |
children | f3f2566fa4aa |
comparison
equal
deleted
inserted
replaced
3685:3062f68d3fa2 | 3686:bed6226ffb46 |
---|---|
1 /* Imported from the dvbstream-0.2 project */ | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <netinet/in.h> | |
5 #include <unistd.h> | |
6 #include <stdlib.h> | |
7 #include <stdio.h> | |
8 #include <sys/types.h> | |
9 #include <sys/socket.h> | |
10 #include <arpa/inet.h> | |
11 | |
12 /* MPEG-2 TS RTP stack */ | |
13 | |
14 #define DEBUG 1 | |
15 #include "rtp.h" | |
16 | |
17 void initrtp(struct rtpheader *foo) { /* fill in the MPEG-2 TS deefaults */ | |
18 /* Note: MPEG-2 TS defines a timestamping base frequency of 90000 Hz. */ | |
19 foo->b.v=2; | |
20 foo->b.p=0; | |
21 foo->b.x=0; | |
22 foo->b.cc=0; | |
23 foo->b.m=0; | |
24 foo->b.pt=33; /* MPEG-2 TS */ | |
25 foo->b.sequence=rand() & 65535; | |
26 foo->timestamp=rand(); | |
27 foo->ssrc=rand(); | |
28 } | |
29 | |
30 /* Send a single RTP packet, converting the RTP header to network byte order. */ | |
31 int sendrtp(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, char *data, int len) { | |
32 char *buf=(char*)alloca(len+sizeof(struct rtpheader)); | |
33 int *cast=(int *)foo; | |
34 int *outcast=(int *)buf; | |
35 outcast[0]=htonl(cast[0]); | |
36 outcast[1]=htonl(cast[1]); | |
37 memmove(outcast+2,data,len); | |
38 fprintf(stderr,"v=%x %x\n",foo->b.v,buf[0]); | |
39 return sendto(fd,buf,len+3,0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr)); | |
40 } | |
41 | |
42 int getrtp2(int fd, struct rtpheader *rh, char** data, int* lengthData) { | |
43 static char buf[1600]; | |
44 unsigned int intP; | |
45 char* charP = (char*) &intP; | |
46 int headerSize; | |
47 int lengthPacket; | |
48 lengthPacket=recv(fd,buf,1590,0); | |
49 if (lengthPacket==0) | |
50 exit(1); | |
51 if (lengthPacket<0) { | |
52 fprintf(stderr,"socket read error\n"); | |
53 exit(2); | |
54 } | |
55 if (lengthPacket<12) { | |
56 fprintf(stderr,"packet too small (%d) to be an rtp frame (>12bytes)\n", lengthPacket); | |
57 exit(3); | |
58 } | |
59 rh->b.v = (unsigned int) ((buf[0]>>6)&0x03); | |
60 rh->b.p = (unsigned int) ((buf[0]>>5)&0x01); | |
61 rh->b.x = (unsigned int) ((buf[0]>>4)&0x01); | |
62 rh->b.cc = (unsigned int) ((buf[0]>>0)&0x0f); | |
63 rh->b.m = (unsigned int) ((buf[1]>>7)&0x01); | |
64 rh->b.pt = (unsigned int) ((buf[1]>>0)&0x7f); | |
65 intP = 0; | |
66 memcpy(charP+2,&buf[2],2); | |
67 rh->b.sequence = ntohl(intP); | |
68 intP = 0; | |
69 memcpy(charP,&buf[4],4); | |
70 rh->timestamp = ntohl(intP); | |
71 | |
72 headerSize = 12 + 4*rh->b.cc; /* in bytes */ | |
73 | |
74 *lengthData = lengthPacket - headerSize; | |
75 *data = (char*) buf + headerSize; | |
76 | |
77 // 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); | |
78 | |
79 return(0); | |
80 } | |
81 | |
82 /* Send a single RTP packet, converting the RTP header to network byte order. */ | |
83 int sendrtp2(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, char *data, int len) { | |
84 char *buf=(char*)alloca(len+72); | |
85 unsigned int intP; | |
86 char* charP = (char*) &intP; | |
87 int headerSize; | |
88 buf[0] = 0x00; | |
89 buf[0] |= ((((char) foo->b.v)<<6)&0xc0); | |
90 buf[0] |= ((((char) foo->b.p)<<5)&0x20); | |
91 buf[0] |= ((((char) foo->b.x)<<4)&0x10); | |
92 buf[0] |= ((((char) foo->b.cc)<<0)&0x0f); | |
93 buf[1] = 0x00; | |
94 buf[1] |= ((((char) foo->b.m)<<7)&0x80); | |
95 buf[1] |= ((((char) foo->b.pt)<<0)&0x7f); | |
96 intP = htonl(foo->b.sequence); | |
97 memcpy(&buf[2],charP+2,2); | |
98 intP = htonl(foo->timestamp); | |
99 memcpy(&buf[4],&intP,4); | |
100 /* SSRC: not implemented */ | |
101 buf[8] = 0x0f; | |
102 buf[9] = 0x0f; | |
103 buf[10] = 0x0f; | |
104 buf[11] = 0x0f; | |
105 headerSize = 12 + 4*foo->b.cc; /* in bytes */ | |
106 memcpy(buf+headerSize,data,len); | |
107 | |
108 // 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); | |
109 | |
110 foo->b.sequence++; | |
111 return sendto(fd,buf,len+headerSize,0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr)); | |
112 } | |
113 | |
114 | |
115 int getrtp(int fd, struct rtpheader *rh, char** data, int* lengthData) { | |
116 static char buf[1600]; | |
117 int headerSize; | |
118 int lengthPacket; | |
119 int i; | |
120 | |
121 lengthPacket=recv(fd,buf,1590,0); | |
122 headerSize = 3; | |
123 *lengthData = lengthPacket - headerSize; | |
124 *data = (char*) buf + headerSize; | |
125 fprintf(stderr,"[%d] %02x %x\n",lengthPacket,buf[8],buf[0]); | |
126 } | |
127 | |
128 /* create a sender socket. */ | |
129 int makesocket(char *szAddr,unsigned short port,int TTL,struct sockaddr_in *sSockAddr) { | |
130 int iRet, iLoop = 1; | |
131 struct sockaddr_in sin; | |
132 char cTtl = (char)TTL; | |
133 char cLoop=0; | |
134 | |
135 int iSocket = socket( AF_INET, SOCK_DGRAM, 0 ); | |
136 | |
137 if (iSocket < 0) { | |
138 fprintf(stderr,"socket() failed.\n"); | |
139 exit(1); | |
140 } | |
141 | |
142 sSockAddr->sin_family = sin.sin_family = AF_INET; | |
143 sSockAddr->sin_port = sin.sin_port = htons(port); | |
144 sSockAddr->sin_addr.s_addr = inet_addr(szAddr); | |
145 | |
146 iRet = setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, &iLoop, sizeof(int)); | |
147 if (iRet < 0) { | |
148 fprintf(stderr,"setsockopt SO_REUSEADDR failed\n"); | |
149 exit(1); | |
150 } | |
151 | |
152 iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_TTL, &cTtl, sizeof(char)); | |
153 if (iRet < 0) { | |
154 fprintf(stderr,"setsockopt IP_MULTICAST_TTL failed. multicast in kernel?\n"); | |
155 exit(1); | |
156 } | |
157 | |
158 cLoop = 1; /* !? */ | |
159 iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_LOOP, | |
160 &cLoop, sizeof(char)); | |
161 if (iRet < 0) { | |
162 fprintf(stderr,"setsockopt IP_MULTICAST_LOOP failed. multicast in kernel?\n"); | |
163 exit(1); | |
164 } | |
165 | |
166 return iSocket; | |
167 } | |
168 | |
169 /* create a receiver socket, i.e. join the multicast group. */ | |
170 int makeclientsocket(char *szAddr,unsigned short port,int TTL,struct sockaddr_in *sSockAddr) { | |
171 int socket=makesocket(szAddr,port,TTL,sSockAddr); | |
172 struct ip_mreq blub; | |
173 struct sockaddr_in sin; | |
174 unsigned int tempaddr; | |
175 sin.sin_family=AF_INET; | |
176 sin.sin_port=htons(port); | |
177 sin.sin_addr.s_addr=inet_addr(szAddr); | |
178 if (bind(socket,&sin,sizeof(sin))) { | |
179 perror("bind failed"); | |
180 exit(1); | |
181 } | |
182 tempaddr=inet_addr(szAddr); | |
183 if ((ntohl(tempaddr) >> 28) == 0xe) { | |
184 blub.imr_multiaddr.s_addr = inet_addr(szAddr); | |
185 blub.imr_interface.s_addr = 0; | |
186 if (setsockopt(socket,IPPROTO_IP,IP_ADD_MEMBERSHIP,&blub,sizeof(blub))) { | |
187 perror("setsockopt IP_ADD_MEMBERSHIP failed (multicast kernel?)"); | |
188 exit(1); | |
189 } | |
190 } | |
191 return socket; | |
192 } | |
193 |