Mercurial > mplayer.hg
annotate libmpdemux/rtp.c @ 17197:0ab565f7ed60
Avoid gcc warnings:
'...' might be used uninitialized in this function
In this case 'H', 'N', 'D', and 'F' can indeed be
used unitialized, thus possibly causing all sorts of problems.
Patch by Peter Breitenlohner
author | rathann |
---|---|
date | Thu, 15 Dec 2005 20:39:59 +0000 |
parents | 5dcc5524cb68 |
children | 028e4c7a749e |
rev | line source |
---|---|
15178
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
1 /* Imported from the dvbstream-0.2 project |
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
2 * |
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
3 * Modified for use with MPlayer, for details see the CVS changelog at |
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
4 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
5 * $Id$ |
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
6 */ |
8dd7a656eaf8
Mark modified imported files as such to comply more closely with GPL ¡ø2a.
diego
parents:
12799
diff
changeset
|
7 |
3686 | 8 #include <stdlib.h> |
9 #include <string.h> | |
3716 | 10 #include <unistd.h> |
3686 | 11 #include <stdlib.h> |
12 #include <stdio.h> | |
13 #include <sys/types.h> | |
15585 | 14 #include <ctype.h> |
10281 | 15 #include "config.h" |
16 #ifndef HAVE_WINSOCK2 | |
17 #include <netinet/in.h> | |
3686 | 18 #include <sys/socket.h> |
19 #include <arpa/inet.h> | |
15585 | 20 #define closesocket close |
10281 | 21 #else |
22 #include <winsock2.h> | |
23 #include <ws2tcpip.h> | |
24 #endif | |
15585 | 25 #include <errno.h> |
26 #include "stream.h" | |
3686 | 27 |
28 /* MPEG-2 TS RTP stack */ | |
29 | |
30 #define DEBUG 1 | |
31 #include "rtp.h" | |
32 | |
15585 | 33 extern int network_bandwidth; |
34 | |
35 int read_rtp_from_server(int fd, char *buffer, int length) { | |
36 struct rtpheader rh; | |
37 char *data; | |
38 int len; | |
39 static int got_first = 0; | |
40 static unsigned short sequence; | |
41 | |
42 if( buffer==NULL || length<0 ) return -1; | |
43 | |
44 getrtp2(fd, &rh, &data, &len); | |
45 if( got_first && rh.b.sequence != (unsigned short)(sequence+1) ) | |
46 mp_msg(MSGT_NETWORK,MSGL_ERR,"RTP packet sequence error! Expected: %d, received: %d\n", | |
47 sequence+1, rh.b.sequence); | |
48 got_first = 1; | |
49 sequence = rh.b.sequence; | |
50 memcpy(buffer, data, len); | |
51 return(len); | |
52 } | |
53 | |
54 | |
55 // Start listening on a UDP port. If multicast, join the group. | |
56 static int rtp_open_socket( URL_t *url ) { | |
57 int socket_server_fd, rxsockbufsz; | |
58 int err, err_len; | |
59 fd_set set; | |
60 struct sockaddr_in server_address; | |
61 struct ip_mreq mcast; | |
62 struct timeval tv; | |
63 struct hostent *hp; | |
64 | |
65 mp_msg(MSGT_NETWORK,MSGL_V,"Listening for traffic on %s:%d ...\n", url->hostname, url->port ); | |
66 | |
67 socket_server_fd = socket(AF_INET, SOCK_DGRAM, 0); | |
68 // fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK ); | |
69 if( socket_server_fd==-1 ) { | |
70 mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create socket\n"); | |
71 return -1; | |
72 } | |
73 | |
74 if( isalpha(url->hostname[0]) ) { | |
75 #ifndef HAVE_WINSOCK2 | |
76 hp =(struct hostent*)gethostbyname( url->hostname ); | |
77 if( hp==NULL ) { | |
78 mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname); | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
79 goto err_out; |
15585 | 80 } |
81 memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length ); | |
82 #else | |
83 server_address.sin_addr.s_addr = htonl(INADDR_ANY); | |
84 #endif | |
85 } else { | |
86 #ifndef HAVE_WINSOCK2 | |
87 #ifdef USE_ATON | |
88 inet_aton(url->hostname, &server_address.sin_addr); | |
89 #else | |
90 inet_pton(AF_INET, url->hostname, &server_address.sin_addr); | |
91 #endif | |
92 #else | |
93 server_address.sin_addr.s_addr = htonl(INADDR_ANY); | |
94 #endif | |
95 } | |
96 server_address.sin_family=AF_INET; | |
97 server_address.sin_port=htons(url->port); | |
98 | |
99 if( bind( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) { | |
100 #ifndef HAVE_WINSOCK2 | |
101 if( errno!=EINPROGRESS ) { | |
102 #else | |
103 if( WSAGetLastError() != WSAEINPROGRESS ) { | |
104 #endif | |
105 mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server\n"); | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
106 goto err_out; |
15585 | 107 } |
108 } | |
109 | |
110 #ifdef HAVE_WINSOCK2 | |
111 if (isalpha(url->hostname[0])) { | |
112 hp =(struct hostent*)gethostbyname( url->hostname ); | |
113 if( hp==NULL ) { | |
114 mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname); | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
115 goto err_out; |
15585 | 116 } |
117 memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length ); | |
118 } else { | |
119 unsigned int addr = inet_addr(url->hostname); | |
120 memcpy( (void*)&server_address.sin_addr, (void*)&addr, sizeof(addr) ); | |
121 } | |
122 #endif | |
123 | |
124 // Increase the socket rx buffer size to maximum -- this is UDP | |
125 rxsockbufsz = 240 * 1024; | |
126 if( setsockopt( socket_server_fd, SOL_SOCKET, SO_RCVBUF, &rxsockbufsz, sizeof(rxsockbufsz))) { | |
127 mp_msg(MSGT_NETWORK,MSGL_ERR,"Couldn't set receive socket buffer size\n"); | |
128 } | |
129 | |
130 if((ntohl(server_address.sin_addr.s_addr) >> 28) == 0xe) { | |
131 mcast.imr_multiaddr.s_addr = server_address.sin_addr.s_addr; | |
132 //mcast.imr_interface.s_addr = inet_addr("10.1.1.2"); | |
133 mcast.imr_interface.s_addr = 0; | |
134 if( setsockopt( socket_server_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))) { | |
135 mp_msg(MSGT_NETWORK,MSGL_ERR,"IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n"); | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
136 goto err_out; |
15585 | 137 } |
138 } | |
139 | |
140 tv.tv_sec = 0; | |
141 tv.tv_usec = (1 * 1000000); // 1 second timeout | |
142 FD_ZERO( &set ); | |
143 FD_SET( socket_server_fd, &set ); | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
144 err = select(socket_server_fd+1, &set, NULL, NULL, &tv); |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
145 if (err < 0) { |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
146 mp_msg(MSGT_NETWORK, MSGL_FATAL, "Select failed: %s\n", strerror(errno)); |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
147 goto err_out; |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
148 } |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
149 if (err == 0) { |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
150 mp_msg(MSGT_NETWORK,MSGL_ERR,"Timeout! No data from host %s\n", url->hostname ); |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
151 goto err_out; |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
152 } |
15585 | 153 err_len = sizeof( err ); |
154 getsockopt( socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len ); | |
155 if( err ) { | |
156 mp_msg(MSGT_NETWORK,MSGL_DBG2,"Socket error: %d\n", err ); | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
157 goto err_out; |
15585 | 158 } |
159 return socket_server_fd; | |
15760
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
160 |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
161 err_out: |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
162 closesocket(socket_server_fd); |
5dcc5524cb68
fix wrong usage of select() (based on patch by Selwyn Tang selwyn hectrix com),
reimar
parents:
15585
diff
changeset
|
163 return -1; |
15585 | 164 } |
165 | |
166 static int rtp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl ) { | |
167 return read_rtp_from_server( fd, buffer, size ); | |
168 } | |
169 | |
170 static int rtp_streaming_start( stream_t *stream, int raw_udp ) { | |
171 streaming_ctrl_t *streaming_ctrl; | |
172 int fd; | |
173 | |
174 if( stream==NULL ) return -1; | |
175 streaming_ctrl = stream->streaming_ctrl; | |
176 fd = stream->fd; | |
177 | |
178 if( fd<0 ) { | |
179 fd = rtp_open_socket( (streaming_ctrl->url) ); | |
180 if( fd<0 ) return -1; | |
181 stream->fd = fd; | |
182 } | |
183 | |
184 if(raw_udp) | |
185 streaming_ctrl->streaming_read = nop_streaming_read; | |
186 else | |
187 streaming_ctrl->streaming_read = rtp_streaming_read; | |
188 streaming_ctrl->streaming_seek = nop_streaming_seek; | |
189 streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes | |
190 streaming_ctrl->buffering = 0; | |
191 streaming_ctrl->status = streaming_playing_e; | |
192 return 0; | |
193 } | |
194 | |
3686 | 195 |
196 int getrtp2(int fd, struct rtpheader *rh, char** data, int* lengthData) { | |
197 static char buf[1600]; | |
198 unsigned int intP; | |
199 char* charP = (char*) &intP; | |
200 int headerSize; | |
201 int lengthPacket; | |
202 lengthPacket=recv(fd,buf,1590,0); | |
203 if (lengthPacket==0) | |
204 exit(1); | |
205 if (lengthPacket<0) { | |
206 fprintf(stderr,"socket read error\n"); | |
207 exit(2); | |
208 } | |
209 if (lengthPacket<12) { | |
210 fprintf(stderr,"packet too small (%d) to be an rtp frame (>12bytes)\n", lengthPacket); | |
211 exit(3); | |
212 } | |
213 rh->b.v = (unsigned int) ((buf[0]>>6)&0x03); | |
214 rh->b.p = (unsigned int) ((buf[0]>>5)&0x01); | |
215 rh->b.x = (unsigned int) ((buf[0]>>4)&0x01); | |
216 rh->b.cc = (unsigned int) ((buf[0]>>0)&0x0f); | |
217 rh->b.m = (unsigned int) ((buf[1]>>7)&0x01); | |
218 rh->b.pt = (unsigned int) ((buf[1]>>0)&0x7f); | |
219 intP = 0; | |
220 memcpy(charP+2,&buf[2],2); | |
221 rh->b.sequence = ntohl(intP); | |
222 intP = 0; | |
223 memcpy(charP,&buf[4],4); | |
224 rh->timestamp = ntohl(intP); | |
225 | |
226 headerSize = 12 + 4*rh->b.cc; /* in bytes */ | |
227 | |
228 *lengthData = lengthPacket - headerSize; | |
229 *data = (char*) buf + headerSize; | |
230 | |
231 // 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); | |
232 | |
233 return(0); | |
234 } | |
235 | |
236 | |
15585 | 237 static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { |
238 URL_t *url; | |
239 int udp = 0; | |
240 | |
241 mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_RTP, URL: %s\n", stream->url); | |
242 stream->streaming_ctrl = streaming_ctrl_new(); | |
243 if( stream->streaming_ctrl==NULL ) { | |
244 return STREAM_ERROR; | |
245 } | |
246 stream->streaming_ctrl->bandwidth = network_bandwidth; | |
247 url = url_new(stream->url); | |
248 stream->streaming_ctrl->url = check4proxies(url); | |
249 | |
250 if( url->port==0 ) { | |
251 mp_msg(MSGT_NETWORK,MSGL_ERR,"You must enter a port number for RTP and UDP streams!\n"); | |
252 goto fail; | |
253 } | |
254 if(!strncmp(stream->url, "udp", 3)) | |
255 udp = 1; | |
256 | |
257 if(rtp_streaming_start(stream, udp) < 0) { | |
258 mp_msg(MSGT_NETWORK,MSGL_ERR,"rtp_streaming_start(rtp) failed\n"); | |
259 goto fail; | |
260 } | |
261 | |
262 stream->type = STREAMTYPE_STREAM; | |
263 fixup_network_stream_cache(stream); | |
264 return STREAM_OK; | |
265 | |
266 fail: | |
267 streaming_ctrl_free( stream->streaming_ctrl ); | |
268 stream->streaming_ctrl = NULL; | |
269 return STREAM_UNSUPORTED; | |
270 } | |
271 | |
272 | |
273 stream_info_t stream_info_rtp_udp = { | |
274 "mpeg rtp and upd streaming", | |
275 "rtp and udp", | |
276 "Dave Chapman", | |
277 "native rtp support", | |
278 open_s, | |
279 {"rtp", "udp", NULL}, | |
280 NULL, | |
281 0 // Urls are an option string | |
282 }; | |
283 | |
284 |