Mercurial > mplayer.hg
comparison libmpdemux/network.c @ 3042:6b6fa2be9b97
Removed my buffer hack to use cache2.
Removed the network thread.
Changed the network layer to use cache2.
author | bertrand |
---|---|
date | Tue, 20 Nov 2001 22:20:20 +0000 |
parents | 66837325b929 |
children | 8dbc1954e49b |
comparison
equal
deleted
inserted
replaced
3041:6b31e121f36a | 3042:6b6fa2be9b97 |
---|---|
32 #include "network.h" | 32 #include "network.h" |
33 #include "http.h" | 33 #include "http.h" |
34 #include "url.h" | 34 #include "url.h" |
35 #include "asf.h" | 35 #include "asf.h" |
36 | 36 |
37 streaming_ctrl_t *streaming_ctrl; | 37 static struct { |
38 | 38 char *mime_type; |
39 static ASF_StreamType_e streaming_type = ASF_Unknown_e; | 39 int demuxer_type; |
40 | 40 } mime_type_table[] = { |
41 Net_Fifo * | 41 // MP3 streaming, some MP3 streaming server answer with audio/mpeg |
42 net_fifo_new() { | 42 { "audio/mpeg", DEMUXER_TYPE_MPEG_PS }, |
43 Net_Fifo *net_fifo; | 43 // MPEG streaming |
44 net_fifo = (Net_Fifo*)malloc(sizeof(Net_Fifo)); | 44 { "video/mpeg", DEMUXER_TYPE_MPEG_PS }, |
45 if( net_fifo==NULL ) { | 45 // AVI ??? => video/x-msvideo |
46 printf("Memory allocation failed\n"); | 46 { "video/x-msvideo", DEMUXER_TYPE_AVI }, |
47 return NULL; | 47 // MOV => video/quicktime |
48 } | 48 { "video/quicktime", DEMUXER_TYPE_MOV }, |
49 memset( net_fifo, 0, sizeof(Net_Fifo) ); | 49 // ASF |
50 return net_fifo; | 50 { "audio/x-ms-wax", DEMUXER_TYPE_ASF }, |
51 } | 51 { "audio/x-ms-wma", DEMUXER_TYPE_ASF }, |
52 | 52 { "video/x-ms-asf", DEMUXER_TYPE_ASF }, |
53 void | 53 { "video/x-ms-afs", DEMUXER_TYPE_ASF }, |
54 net_fifo_free( Net_Fifo *net_fifo ) { | 54 { "video/x-ms-wvx", DEMUXER_TYPE_ASF }, |
55 if( net_fifo->buffer!=NULL ) free( net_fifo->buffer ); | 55 { "video/x-ms-wmv", DEMUXER_TYPE_ASF }, |
56 free( net_fifo ); | 56 { "video/x-ms-wma", DEMUXER_TYPE_ASF }, |
57 } | 57 { "text/plain", DEMUXER_TYPE_ASF }, // This is the mime type that a web server send when sending a raw asf without streaming encapsulation. |
58 | 58 }; |
59 int | 59 |
60 net_fifo_push(Net_Fifo *net_fifo, char *buffer, int length ) { | 60 static struct { |
61 char *ptr; | 61 char *extension; |
62 if( net_fifo==NULL || buffer==NULL || length<0 ) return -1; | 62 int demuxer_type; |
63 | 63 } extensions_table[] = { |
64 ptr = (char*)malloc(length+net_fifo->length); | 64 { "mpeg", DEMUXER_TYPE_MPEG_PS }, |
65 if( ptr==NULL ) { | 65 { "mpg", DEMUXER_TYPE_MPEG_PS }, |
66 printf("Memory allocation failed\n"); | 66 { "avi", DEMUXER_TYPE_AVI }, |
67 return -1; | 67 { "mov", DEMUXER_TYPE_MOV }, |
68 } | 68 { "asx", DEMUXER_TYPE_ASF }, |
69 if( net_fifo->buffer!=NULL ) { | 69 { "asf", DEMUXER_TYPE_ASF }, |
70 memcpy( ptr, net_fifo->buffer, net_fifo->length ); | 70 { "wmv", DEMUXER_TYPE_ASF }, |
71 free( net_fifo->buffer ); | 71 { "wma", DEMUXER_TYPE_ASF }, |
72 } | 72 }; |
73 memcpy( ptr+net_fifo->length, buffer, length ); | |
74 net_fifo->buffer = ptr; | |
75 net_fifo->length += length; | |
76 return net_fifo->length; | |
77 } | |
78 | |
79 int | |
80 net_fifo_pop(Net_Fifo *net_fifo, char *buffer, int length ) { | |
81 char *ptr; | |
82 int len; | |
83 if( net_fifo==NULL || buffer==NULL || length<0 ) return -1; | |
84 if( net_fifo->buffer==NULL || net_fifo->length==0 ) return -1; | |
85 | |
86 len = MIN(net_fifo->length, length); | |
87 | |
88 ptr = (char*)malloc(net_fifo->length-len); | |
89 if( ptr==NULL ) { | |
90 printf("Memory allocation failed\n"); | |
91 return -1; | |
92 } | |
93 memcpy( buffer, net_fifo->buffer, len ); | |
94 if( net_fifo->length-len!=0 ) { | |
95 memcpy( ptr, net_fifo->buffer+len, net_fifo->length-len ); | |
96 free( net_fifo->buffer ); | |
97 net_fifo->buffer = ptr; | |
98 net_fifo->length -= len; | |
99 } else { | |
100 free( net_fifo->buffer ); | |
101 net_fifo->buffer = NULL; | |
102 net_fifo->length = 0; | |
103 } | |
104 return len; | |
105 } | |
106 | 73 |
107 streaming_ctrl_t * | 74 streaming_ctrl_t * |
108 streaming_ctrl_new( ) { | 75 streaming_ctrl_new( ) { |
109 streaming_ctrl_t *streaming_ctrl; | 76 streaming_ctrl_t *streaming_ctrl; |
110 streaming_ctrl = (streaming_ctrl_t*)malloc(sizeof(streaming_ctrl_t)); | 77 streaming_ctrl = (streaming_ctrl_t*)malloc(sizeof(streaming_ctrl_t)); |
111 if( streaming_ctrl==NULL ) { | 78 if( streaming_ctrl==NULL ) { |
112 printf("Failed to allocate memory\n"); | 79 printf("Failed to allocate memory\n"); |
113 return NULL; | 80 return NULL; |
114 } | 81 } |
115 memset( streaming_ctrl, 0, sizeof(streaming_ctrl_t) ); | 82 memset( streaming_ctrl, 0, sizeof(streaming_ctrl_t) ); |
116 streaming_ctrl->buffer = net_fifo_new(); | |
117 return streaming_ctrl; | 83 return streaming_ctrl; |
118 } | 84 } |
119 | 85 |
120 void | 86 void |
121 streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl ) { | 87 streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl ) { |
122 if( streaming_ctrl==NULL ) return; | 88 if( streaming_ctrl==NULL ) return; |
123 if( streaming_ctrl->buffer!=NULL ) net_fifo_free( streaming_ctrl->buffer ); | |
124 free( streaming_ctrl ); | 89 free( streaming_ctrl ); |
125 } | |
126 | |
127 int | |
128 readFromServer(int fd, char *buffer, int length) { | |
129 int ret; | |
130 int done=0; | |
131 fd_set set; | |
132 struct timeval tv; | |
133 if( buffer==NULL || length<0 ) return -1; | |
134 | |
135 | |
136 // fcntl( fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK ); | |
137 return read( fd, buffer, length ); | |
138 | |
139 do { | |
140 tv.tv_sec = 0; | |
141 tv.tv_usec = 10000; // 10 milli-seconds timeout | |
142 FD_ZERO( &set ); | |
143 FD_SET( fd, &set ); | |
144 ret = select( fd+1, &set, NULL, NULL, &tv ); | |
145 if( ret<0 ) { | |
146 perror("select"); | |
147 } else if( ret==0 ) { | |
148 printf("timeout\n"); | |
149 } | |
150 if( FD_ISSET(fd, &set) ) { | |
151 ret = read( fd, buffer, length ); | |
152 if( ret<0 ) { | |
153 if( errno!=EINPROGRESS ) { | |
154 } | |
155 } else { | |
156 done = 1; | |
157 } | |
158 } else { | |
159 return -1; | |
160 } | |
161 } while( !done ); | |
162 | |
163 return ret; | |
164 } | 90 } |
165 | 91 |
166 // Connect to a server using a TCP connection | 92 // Connect to a server using a TCP connection |
167 int | 93 int |
168 connect2Server(char *host, int port) { | 94 connect2Server(char *host, int port) { |
169 int socket_server_fd; | 95 int socket_server_fd; |
170 int err, err_len; | 96 int err, err_len; |
97 int ret; | |
171 fd_set set; | 98 fd_set set; |
172 struct timeval tv; | 99 struct timeval tv; |
173 struct sockaddr_in server_address; | 100 struct sockaddr_in server_address; |
174 | 101 |
175 printf("Connecting to server %s:%d ...\n", host, port ); | 102 printf("Connecting to server %s:%d ...\n", host, port ); |
176 | 103 |
177 socket_server_fd = socket(AF_INET, SOCK_STREAM, 0); | 104 socket_server_fd = socket(AF_INET, SOCK_STREAM, 0); |
178 // fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK ); | |
179 if( socket_server_fd==-1 ) { | 105 if( socket_server_fd==-1 ) { |
180 perror("Failed to create socket"); | 106 perror("Failed to create socket"); |
181 return -1; | 107 return -1; |
182 } | 108 } |
183 | 109 |
184 if( isalpha(host[0]) ) { | 110 if( isalpha(host[0]) ) { |
185 struct hostent *hp =(struct hostent*)gethostbyname( host ); | 111 struct hostent *hp; |
112 hp=(struct hostent*)gethostbyname( host ); | |
186 if( hp==NULL ) { | 113 if( hp==NULL ) { |
187 printf("Counldn't resolve name: %s\n", host); | 114 printf("Counldn't resolve name: %s\n", host); |
188 return -1; | 115 return -1; |
189 } | 116 } |
190 memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length ); | 117 memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length ); |
191 } else { | 118 } else { |
192 inet_pton(AF_INET, host, &server_address.sin_addr); | 119 inet_pton(AF_INET, host, &server_address.sin_addr); |
193 } | 120 } |
194 server_address.sin_family=AF_INET; | 121 server_address.sin_family=AF_INET; |
195 server_address.sin_port=htons(port); | 122 server_address.sin_port=htons(port); |
196 | 123 |
124 // Turn the socket as non blocking so we can timeout on the connection | |
125 fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK ); | |
197 if( connect( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) { | 126 if( connect( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) { |
198 if( errno!=EINPROGRESS ) { | 127 if( errno!=EINPROGRESS ) { |
199 perror("Failed to connect to server"); | 128 perror("Failed to connect to server"); |
200 close(socket_server_fd); | 129 close(socket_server_fd); |
201 return -1; | 130 return -1; |
202 } | 131 } |
203 } | 132 } |
204 | 133 tv.tv_sec = 5; // 5 seconds timeout on connection |
205 tv.tv_sec = 0; | 134 tv.tv_usec = 0; |
206 tv.tv_usec = 10000; // 10 milli-seconds timeout | |
207 FD_ZERO( &set ); | 135 FD_ZERO( &set ); |
208 FD_SET( socket_server_fd, &set ); | 136 FD_SET( socket_server_fd, &set ); |
209 if( select(socket_server_fd+1, NULL, &set, NULL, &tv)>0 ) { | 137 // When the connection will be made, we will have a writable fd |
210 err_len = sizeof( err ); | 138 ret = select(socket_server_fd+1, NULL, &set, NULL, &tv); |
211 getsockopt( socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len ); | 139 if( ret<=0 ) { |
212 if( err ) { | 140 if( ret<0 ) perror("select failed"); |
213 printf("Couldn't connect to host %s\n", host ); | 141 else printf("Connection timeout\n"); |
214 printf("Socket error: %d\n", err ); | 142 return -1; |
215 close(socket_server_fd); | 143 } |
216 return -1; | 144 |
217 } | 145 // Turn back the socket as blocking |
218 } | 146 fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) & ~O_NONBLOCK ); |
219 return socket_server_fd; | 147 return socket_server_fd; |
220 } | 148 } |
221 | 149 |
222 int | 150 int |
223 http_send_request( URL_t *url ) { | 151 http_send_request( URL_t *url ) { |
251 if( http_hdr==NULL ) { | 179 if( http_hdr==NULL ) { |
252 return NULL; | 180 return NULL; |
253 } | 181 } |
254 | 182 |
255 do { | 183 do { |
256 i = readFromServer( fd, response, BUFFER_SIZE ); | 184 i = read( fd, response, BUFFER_SIZE ); |
257 if( i<0 ) { | 185 if( i<0 ) { |
258 printf("Read failed\n"); | 186 printf("Read failed\n"); |
259 } | 187 } |
260 http_response_append( http_hdr, response, i ); | 188 http_response_append( http_hdr, response, i ); |
261 } while( !http_is_header_entire( http_hdr ) ); | 189 } while( !http_is_header_entire( http_hdr ) ); |
292 extension=(url->file)+i+1; | 220 extension=(url->file)+i+1; |
293 break; | 221 break; |
294 } | 222 } |
295 } | 223 } |
296 } | 224 } |
297 // extension=NULL; | 225 extension=NULL; |
298 if( extension!=NULL ) { | 226 if( extension!=NULL ) { |
299 printf("Extension: %s\n", extension ); | 227 printf("Extension: %s\n", extension ); |
300 if( !strcasecmp(extension, "asf") || | 228 // Look for the extension in the extensions table |
301 !strcasecmp(extension, "wmv") || | 229 for( i=0 ; i<(sizeof(extensions_table)/sizeof(extensions_table[0])) ; i++ ) { |
302 !strcasecmp(extension, "asx") ) { | 230 if( !strcasecmp(extension, extensions_table[i].extension) ) { |
303 if( url->port==0 ) url->port = 80; | 231 if( url->port==0 ) url->port = 80; |
304 return DEMUXER_TYPE_ASF; | 232 return extensions_table[i].demuxer_type; |
305 } | 233 } |
306 if( !strcasecmp(extension, "mpg") || | |
307 !strcasecmp(extension, "mpeg") ) { | |
308 if( url->port==0 ) url->port = 80; | |
309 return DEMUXER_TYPE_MPEG_PS; | |
310 } | |
311 if( !strcasecmp(extension, "avi") ) { | |
312 if( url->port==0 ) url->port = 80; | |
313 return DEMUXER_TYPE_AVI; | |
314 } | 234 } |
315 } | 235 } |
316 | 236 |
317 // Checking for RTSP | 237 // Checking for RTSP |
318 if( !strcasecmp(url->protocol, "rtsp") ) { | 238 if( !strcasecmp(url->protocol, "rtsp") ) { |
338 | 258 |
339 http_hdr = http_read_response( fd ); | 259 http_hdr = http_read_response( fd ); |
340 if( http_hdr==NULL ) { | 260 if( http_hdr==NULL ) { |
341 close( fd ); | 261 close( fd ); |
342 *fd_out=-1; | 262 *fd_out=-1; |
263 http_free( http_hdr ); | |
343 return DEMUXER_TYPE_UNKNOWN; | 264 return DEMUXER_TYPE_UNKNOWN; |
344 } | 265 } |
345 | 266 |
346 *fd_out=fd; | 267 *fd_out=fd; |
347 //http_debug_hdr( http_hdr ); | 268 http_debug_hdr( http_hdr ); |
348 | 269 |
349 // Check if the response is an ICY status_code reason_phrase | 270 // Check if the response is an ICY status_code reason_phrase |
350 if( !strcasecmp(http_hdr->protocol, "ICY") ) { | 271 if( !strcasecmp(http_hdr->protocol, "ICY") ) { |
351 // Ok, we have detected an mp3 streaming | 272 // Ok, we have detected an mp3 streaming |
273 http_free( http_hdr ); | |
352 return DEMUXER_TYPE_MPEG_PS; | 274 return DEMUXER_TYPE_MPEG_PS; |
353 } | 275 } |
354 | 276 |
355 switch( http_hdr->status_code ) { | 277 switch( http_hdr->status_code ) { |
356 case 200: // OK | 278 case 200: // OK |
357 // Look if we can use the Content-Type | 279 // Look if we can use the Content-Type |
358 content_type = http_get_field( http_hdr, "Content-Type" ); | 280 content_type = http_get_field( http_hdr, "Content-Type" ); |
359 if( content_type!=NULL ) { | 281 if( content_type!=NULL ) { |
360 printf("Content-Type: [%s]\n", content_type ); | 282 printf("Content-Type: [%s]\n", content_type ); |
361 printf("Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); | 283 printf("Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); |
362 // Check for ASF | 284 // Check in the mime type table for a demuxer type |
363 if( asf_http_streaming_type(content_type, NULL)!=ASF_Unknown_e ) { | 285 for( i=0 ; i<(sizeof(mime_type_table)/sizeof(mime_type_table[0])) ; i++ ) { |
364 return DEMUXER_TYPE_ASF; | 286 if( !strcasecmp( content_type, mime_type_table[i].mime_type ) ) { |
365 } | 287 http_free( http_hdr ); |
366 // Check for MP3 streaming | 288 return mime_type_table[i].demuxer_type; |
367 // Some MP3 streaming server answer with audio/mpeg | 289 } |
368 if( !strcasecmp(content_type, "audio/mpeg") ) { | |
369 return DEMUXER_TYPE_MPEG_PS; | |
370 } | |
371 // Check for MPEG streaming | |
372 if( !strcasecmp(content_type, "video/mpeg") ) { | |
373 return DEMUXER_TYPE_MPEG_PS; | |
374 } | |
375 // AVI ??? => video/x-msvideo | |
376 if( !strcasecmp(content_type, "video/x-msvideo") ) { | |
377 return DEMUXER_TYPE_AVI; | |
378 } | 290 } |
379 } | 291 } |
380 break; | 292 break; |
381 // Redirect | 293 // Redirect |
382 case 301: // Permanently | 294 case 301: // Permanently |
392 break; | 304 break; |
393 default: | 305 default: |
394 printf("Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); | 306 printf("Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); |
395 close( fd ); | 307 close( fd ); |
396 *fd_out=-1; | 308 *fd_out=-1; |
309 http_free( http_hdr ); | |
397 return DEMUXER_TYPE_UNKNOWN; | 310 return DEMUXER_TYPE_UNKNOWN; |
398 } | 311 } |
399 } | 312 } |
400 } while( redirect ); | 313 } while( redirect ); |
401 | 314 |
315 http_free( http_hdr ); | |
402 return DEMUXER_TYPE_UNKNOWN; | 316 return DEMUXER_TYPE_UNKNOWN; |
403 } | 317 } |
404 | 318 |
405 int | 319 int |
406 nop_streaming_read( streaming_ctrl_t *streaming_ctrl ) { | 320 streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size) { |
407 char *buffer; | 321 printf("streaming_bufferize\n"); |
408 int len; | 322 streaming_ctrl->buffer = (char*)malloc(size); |
409 if( streaming_ctrl==NULL ) return -1; | 323 if( streaming_ctrl->buffer==NULL ) { |
410 len = streaming_ctrl->buffer->length; | 324 printf("Memory allocation failed\n"); |
411 if( len==0 ) return 0; | 325 return -1; |
412 | 326 } |
413 buffer = (char*)malloc( len ); | 327 memcpy( streaming_ctrl->buffer, buffer, size ); |
414 if( buffer==NULL ) { | 328 streaming_ctrl->buffer_size = size; |
415 printf("Memory allocation failed\n"); | 329 } |
416 return -1; | 330 |
417 } | 331 int |
418 net_fifo_pop( streaming_ctrl->buffer, buffer, len ); | 332 nop_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { |
419 write( streaming_ctrl->fd_pipe_in, buffer, len ); | 333 int len=0; |
420 free( buffer ); | 334 //printf("nop_streaming_read\n"); |
335 if( stream_ctrl->buffer_size!=0 ) { | |
336 int buffer_len = stream_ctrl->buffer_size-stream_ctrl->buffer_pos; | |
337 printf("%d bytes in buffer\n", stream_ctrl->buffer_size); | |
338 len = (size<buffer_len)?size:buffer_len; | |
339 memcpy( buffer, (stream_ctrl->buffer)+(stream_ctrl->buffer_pos), len ); | |
340 stream_ctrl->buffer_pos += len; | |
341 printf("buffer_pos = %d\n", stream_ctrl->buffer_pos ); | |
342 if( stream_ctrl->buffer_pos>=stream_ctrl->buffer_size ) { | |
343 free( stream_ctrl->buffer ); | |
344 stream_ctrl->buffer = NULL; | |
345 stream_ctrl->buffer_size = 0; | |
346 stream_ctrl->buffer_pos = 0; | |
347 printf("buffer cleaned\n"); | |
348 } | |
349 printf("read %d bytes from buffer\n", len ); | |
350 } | |
351 | |
352 if( len<size ) { | |
353 len += read( fd, buffer+len, size-len ); | |
354 //printf("read %d bytes from network\n", len ); | |
355 } | |
356 | |
421 return len; | 357 return len; |
422 } | 358 } |
423 | 359 |
424 int | 360 int |
425 nop_streaming_start( streaming_ctrl_t *streaming_ctrl ) { | 361 nop_streaming_seek( int fd, off_t pos, streaming_ctrl_t *stream_ctrl ) { |
362 return -1; | |
363 } | |
364 | |
365 int | |
366 nop_streaming_start( stream_t *stream ) { | |
426 HTTP_header_t *http_hdr; | 367 HTTP_header_t *http_hdr; |
427 int fd; | 368 int fd; |
428 if( streaming_ctrl==NULL ) return -1; | 369 if( stream==NULL ) return -1; |
429 | 370 |
430 fd = streaming_ctrl->fd_net; | 371 fd = stream->fd; |
431 if( fd<0 ) { | 372 if( fd<0 ) { |
432 fd = http_send_request( *(streaming_ctrl->url) ); | 373 fd = http_send_request( stream->streaming_ctrl->url ); |
433 if( fd<0 ) return -1; | 374 if( fd<0 ) return -1; |
434 http_hdr = http_read_response( fd ); | 375 http_hdr = http_read_response( fd ); |
435 if( http_hdr==NULL ) return -1; | 376 if( http_hdr==NULL ) return -1; |
436 | 377 |
437 switch( http_hdr->status_code ) { | 378 switch( http_hdr->status_code ) { |
438 case 200: // OK | 379 case 200: // OK |
439 printf("Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") ); | 380 printf("Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") ); |
440 printf("Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); | 381 printf("Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); |
441 if( http_hdr->body_size>0 ) { | 382 if( http_hdr->body_size>0 ) { |
442 write( streaming_ctrl->fd_pipe_in, http_hdr->body, http_hdr->body_size ); | 383 if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { |
384 http_free( http_hdr ); | |
385 return -1; | |
386 } | |
443 } | 387 } |
444 break; | 388 break; |
445 default: | 389 default: |
446 printf("Server return %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); | 390 printf("Server return %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); |
447 close( fd ); | 391 close( fd ); |
448 fd = -1; | 392 fd = -1; |
449 } | 393 } |
450 streaming_ctrl->fd_net = fd; | 394 stream->fd = fd; |
451 } | 395 } |
452 | 396 |
453 http_free( http_hdr ); | 397 http_free( http_hdr ); |
454 | 398 |
455 streaming_ctrl->streaming_read = nop_streaming_read; | 399 stream->streaming_ctrl->streaming_read = nop_streaming_read; |
456 streaming_ctrl->prebuffer_size = 180000; | 400 stream->streaming_ctrl->streaming_seek = nop_streaming_seek; |
457 // streaming_ctrl->prebuffer_size = 0; | 401 stream->streaming_ctrl->prebuffer_size = 180000; |
458 streaming_ctrl->buffering = 1; | 402 // stream->streaming_ctrl->prebuffer_size = 0; |
459 // streaming_ctrl->buffering = 0; | 403 stream->streaming_ctrl->buffering = 1; |
460 streaming_ctrl->status = streaming_playing_e; | 404 // stream->streaming_ctrl->buffering = 0; |
405 stream->streaming_ctrl->status = streaming_playing_e; | |
461 return fd; | 406 return fd; |
462 } | 407 } |
463 | 408 |
464 void | 409 int |
465 network_streaming(void *arg) { | 410 streaming_start(stream_t *stream, URL_t *url, int demuxer_type) { |
466 char buffer[BUFFER_SIZE]; | 411 int ret=-1; |
467 fd_set fd_net_in; | 412 if( stream==NULL ) return -1; |
468 int ret; | 413 |
469 | 414 stream->streaming_ctrl = streaming_ctrl_new( ); |
470 arg = arg; | 415 if( stream->streaming_ctrl==NULL ) { |
471 | |
472 do { | |
473 FD_ZERO( &fd_net_in ); | |
474 FD_SET( streaming_ctrl->fd_net, &fd_net_in ); | |
475 | |
476 ret = select( streaming_ctrl->fd_net+1, &fd_net_in, NULL, NULL, NULL ); | |
477 if( ret<0 ) { | |
478 perror("select"); | |
479 return; //exit(1); // FIXME! | |
480 } | |
481 if( FD_ISSET( streaming_ctrl->fd_net, &fd_net_in ) ) { | |
482 ret = readFromServer( streaming_ctrl->fd_net, buffer, BUFFER_SIZE ); | |
483 if( ret<=0 ) { | |
484 streaming_ctrl->status=streaming_stopped_e; | |
485 } else { | |
486 //printf(" push: 0x%02X\n", *((unsigned int*)buffer) ); | |
487 net_fifo_push( streaming_ctrl->buffer, buffer, ret ); | |
488 if( !streaming_ctrl->buffering ) { | |
489 do { | |
490 ret = streaming_ctrl->streaming_read( streaming_ctrl ); | |
491 if( ret<0 && streaming_ctrl->buffer->length<streaming_ctrl->prebuffer_size ) { | |
492 // Need buffering | |
493 streaming_ctrl->buffering = 1; | |
494 } | |
495 } while( streaming_ctrl->buffer->length>streaming_ctrl->prebuffer_size ); | |
496 } else { | |
497 if( streaming_ctrl->buffer->length>streaming_ctrl->prebuffer_size ) { | |
498 streaming_ctrl->buffering = 0; | |
499 printf("\n"); | |
500 } else { | |
501 printf(" Buffering: %d \%\r", (int)((float)(((float)streaming_ctrl->buffer->length)/((float)streaming_ctrl->prebuffer_size))*100) ); | |
502 fflush(stdout); | |
503 } | |
504 } | |
505 } | |
506 } else { | |
507 printf("Network fd not set\n"); | |
508 } | |
509 } while( streaming_ctrl->status==streaming_playing_e ); | |
510 | |
511 // Flush the buffer | |
512 while( streaming_ctrl->buffer->length>0 ) { | |
513 ret = streaming_ctrl->streaming_read( streaming_ctrl ); | |
514 if( ret<0 ) break; | |
515 } | |
516 | |
517 printf("Network thread done\n"); | |
518 | |
519 // Close to the pipe to stop mplayer. | |
520 close( streaming_ctrl->fd_pipe_in ); | |
521 | |
522 } | |
523 | |
524 int | |
525 streaming_start(URL_t **url, int fd, int streaming_type) { | |
526 int fd_pipe[2]; | |
527 // Open the pipe | |
528 if( pipe(fd_pipe)<0 ) { | |
529 printf("Pipe creation failed\n"); | |
530 return -1; | 416 return -1; |
531 } | 417 } |
532 | 418 |
533 streaming_ctrl = streaming_ctrl_new( ); | 419 stream->streaming_ctrl->url = url_copy(url); |
534 if( streaming_ctrl==NULL ) { | 420 // stream->streaming_ctrl->demuxer_type = demuxer_type; |
535 return -1; | 421 stream->fd = -1; |
536 } | 422 |
537 streaming_ctrl->url = url; | 423 switch( demuxer_type ) { |
538 streaming_ctrl->fd_pipe_in = fd_pipe[1]; | |
539 streaming_ctrl->fd_net = fd; | |
540 | |
541 #ifdef DUMP2FILE | |
542 { | |
543 int fd_file; | |
544 fd_file = open("dump.stream", O_WRONLY | O_CREAT ); | |
545 if( fd_file<0 ) { | |
546 perror("open"); | |
547 } | |
548 streaming_ctrl->fd_pipe_in = fd_file; | |
549 } | |
550 #endif | |
551 | |
552 switch( streaming_type ) { | |
553 case DEMUXER_TYPE_ASF: | 424 case DEMUXER_TYPE_ASF: |
554 // Send the appropriate HTTP request | 425 // Send the appropriate HTTP request |
555 fd = asf_http_streaming_start( streaming_ctrl ); | 426 // Need to filter the network stream. |
427 // ASF raw stream is encapsulated. | |
428 ret = asf_streaming_start( stream ); | |
556 break; | 429 break; |
557 case DEMUXER_TYPE_AVI: | 430 case DEMUXER_TYPE_AVI: |
431 case DEMUXER_TYPE_MOV: | |
558 case DEMUXER_TYPE_MPEG_ES: | 432 case DEMUXER_TYPE_MPEG_ES: |
559 case DEMUXER_TYPE_MPEG_PS: | 433 case DEMUXER_TYPE_MPEG_PS: |
560 fd = nop_streaming_start( streaming_ctrl ); | 434 // Generic start, doesn't need to filter |
435 // the network stream, it's a raw stream | |
436 ret = nop_streaming_start( stream ); | |
561 break; | 437 break; |
562 case DEMUXER_TYPE_UNKNOWN: | 438 case DEMUXER_TYPE_UNKNOWN: |
563 default: | 439 default: |
564 printf("Unable to detect the streaming type\n"); | 440 printf("Unable to detect the streaming type\n"); |
565 close( fd ); | 441 ret = -1; |
566 free( streaming_ctrl ); | 442 } |
567 return -1; | 443 |
568 } | 444 if( ret<0 ) { |
569 | 445 free( stream->streaming_ctrl ); |
570 if( fd<0 ) { | 446 } else { |
571 free( streaming_ctrl ); | 447 // bufferize( stream ); |
572 return -1; | 448 } |
573 } | 449 |
574 | 450 return ret; |
575 // Start the network thread | 451 } |
576 if( pthread_create( &(streaming_ctrl->thread_id), NULL , (void*)network_streaming, (void*)NULL)<0 ) { | 452 |
577 printf("Unable to start the network thread.\n"); | 453 int |
578 close( fd ); | 454 streaming_stop( stream_t *stream ) { |
579 free( streaming_ctrl ); | 455 stream->streaming_ctrl->status = streaming_stopped_e; |
580 return -1; | |
581 } | |
582 printf("Network thread created with id: %d\n", streaming_ctrl->thread_id ); | |
583 | |
584 // streaming_ctrl->status = streaming_stopped_e; | |
585 | |
586 // return fd; | |
587 return fd_pipe[0]; | |
588 } | |
589 | |
590 int | |
591 streaming_stop( ) { | |
592 streaming_ctrl->status = streaming_stopped_e; | |
593 return 0; | 456 return 0; |
594 } | 457 } |