| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Unbuffered io for ffmpeg system | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * Copyright (c) 2001 Fabrice Bellard | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * This file is part of FFmpeg. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FFmpeg is free software; you can redistribute it and/or | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * FFmpeg is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * License along with FFmpeg; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2006-01-12 22:43:26 +00:00
										 |  |  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | #include "avformat.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-17 10:25:36 +00:00
										 |  |  | static int default_interrupt_cb(void); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | URLProtocol *first_protocol = NULL; | 
					
						
							| 
									
										
										
										
											2003-07-17 10:25:36 +00:00
										 |  |  | URLInterruptCB *url_interrupt_cb = default_interrupt_cb; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int register_protocol(URLProtocol *protocol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     URLProtocol **p; | 
					
						
							|  |  |  |     p = &first_protocol; | 
					
						
							|  |  |  |     while (*p != NULL) p = &(*p)->next; | 
					
						
							|  |  |  |     *p = protocol; | 
					
						
							|  |  |  |     protocol->next = NULL; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int url_open(URLContext **puc, const char *filename, int flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     URLContext *uc; | 
					
						
							|  |  |  |     URLProtocol *up; | 
					
						
							|  |  |  |     const char *p; | 
					
						
							|  |  |  |     char proto_str[128], *q; | 
					
						
							|  |  |  |     int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p = filename; | 
					
						
							|  |  |  |     q = proto_str; | 
					
						
							|  |  |  |     while (*p != '\0' && *p != ':') { | 
					
						
							| 
									
										
										
										
											2003-02-21 11:08:08 +00:00
										 |  |  |         /* protocols can only contain alphabetic chars */ | 
					
						
							|  |  |  |         if (!isalpha(*p)) | 
					
						
							|  |  |  |             goto file_proto; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         if ((q - proto_str) < sizeof(proto_str) - 1) | 
					
						
							|  |  |  |             *q++ = *p; | 
					
						
							|  |  |  |         p++; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-08-15 22:33:03 +00:00
										 |  |  |     /* if the protocol has length 1, we consider it is a dos drive */ | 
					
						
							|  |  |  |     if (*p == '\0' || (q - proto_str) <= 1) { | 
					
						
							| 
									
										
										
										
											2003-02-21 11:08:08 +00:00
										 |  |  |     file_proto: | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         strcpy(proto_str, "file"); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         *q = '\0'; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     up = first_protocol; | 
					
						
							|  |  |  |     while (up != NULL) { | 
					
						
							| 
									
										
										
										
											2001-08-15 22:33:03 +00:00
										 |  |  |         if (!strcmp(proto_str, up->name)) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |             goto found; | 
					
						
							|  |  |  |         up = up->next; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |     err = -ENOENT; | 
					
						
							|  |  |  |     goto fail; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  found: | 
					
						
							| 
									
										
										
										
											2007-01-14 22:07:19 +00:00
										 |  |  |     uc = av_malloc(sizeof(URLContext) + strlen(filename) + 1); | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |     if (!uc) { | 
					
						
							|  |  |  |         err = -ENOMEM; | 
					
						
							|  |  |  |         goto fail; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-01-14 22:07:19 +00:00
										 |  |  | #if LIBAVFORMAT_VERSION_INT >= (52<<16)
 | 
					
						
							|  |  |  |     uc->filename = (char *) &uc[1]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-01-11 04:59:17 +00:00
										 |  |  |     strcpy(uc->filename, filename); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     uc->prot = up; | 
					
						
							|  |  |  |     uc->flags = flags; | 
					
						
							|  |  |  |     uc->is_streamed = 0; /* default = not streamed */ | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |     uc->max_packet_size = 0; /* default: stream file */ | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     err = up->url_open(uc, filename, flags); | 
					
						
							|  |  |  |     if (err < 0) { | 
					
						
							| 
									
										
										
										
											2002-05-18 23:11:09 +00:00
										 |  |  |         av_free(uc); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         *puc = NULL; | 
					
						
							|  |  |  |         return err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     *puc = uc; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |  fail: | 
					
						
							|  |  |  |     *puc = NULL; | 
					
						
							|  |  |  |     return err; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int url_read(URLContext *h, unsigned char *buf, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  |     if (h->flags & URL_WRONLY) | 
					
						
							| 
									
										
										
										
											2004-06-19 03:59:34 +00:00
										 |  |  |         return AVERROR_IO; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     ret = h->prot->url_read(h, buf, size); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-21 18:36:32 +00:00
										 |  |  | #if defined(CONFIG_MUXERS) || defined(CONFIG_PROTOCOLS)
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | int url_write(URLContext *h, unsigned char *buf, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ret; | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |     if (!(h->flags & (URL_WRONLY | URL_RDWR))) | 
					
						
							| 
									
										
										
										
											2004-06-19 03:59:34 +00:00
										 |  |  |         return AVERROR_IO; | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |     /* avoid sending too big packets */ | 
					
						
							|  |  |  |     if (h->max_packet_size && size > h->max_packet_size) | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  |         return AVERROR_IO; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     ret = h->prot->url_write(h, buf, size); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-01-21 18:36:32 +00:00
										 |  |  | #endif //CONFIG_MUXERS || CONFIG_PROTOCOLS
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | offset_t url_seek(URLContext *h, offset_t pos, int whence) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     offset_t ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!h->prot->url_seek) | 
					
						
							|  |  |  |         return -EPIPE; | 
					
						
							|  |  |  |     ret = h->prot->url_seek(h, pos, whence); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int url_close(URLContext *h) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret = h->prot->url_close(h); | 
					
						
							| 
									
										
										
										
											2002-05-18 23:11:09 +00:00
										 |  |  |     av_free(h); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int url_exist(const char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     URLContext *h; | 
					
						
							|  |  |  |     if (url_open(&h, filename, URL_RDONLY) < 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     url_close(h); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | offset_t url_filesize(URLContext *h) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     offset_t pos, size; | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-01 21:49:09 +00:00
										 |  |  |     size= url_seek(h, 0, AVSEEK_SIZE); | 
					
						
							|  |  |  |     if(size<0){ | 
					
						
							| 
									
										
										
										
											2007-01-01 21:49:50 +00:00
										 |  |  |         pos = url_seek(h, 0, SEEK_CUR); | 
					
						
							|  |  |  |         size = url_seek(h, -1, SEEK_END)+1; | 
					
						
							|  |  |  |         url_seek(h, pos, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2007-01-01 21:49:09 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     return size; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |  * Return the maximum packet size associated to packetized file | 
					
						
							|  |  |  |  * handle. If the file is not packetized (stream like http or file on | 
					
						
							|  |  |  |  * disk), then 0 is returned. | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2002-07-24 17:50:23 +00:00
										 |  |  |  * @param h file handle | 
					
						
							|  |  |  |  * @return maximum packet size in bytes | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int url_get_max_packet_size(URLContext *h) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return h->max_packet_size; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-01-11 04:59:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void url_get_filename(URLContext *h, char *buf, int buf_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pstrcpy(buf, buf_size, h->filename); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-07-17 10:25:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int default_interrupt_cb(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2003-07-17 10:25:36 +00:00
										 |  |  |  * The callback is called in blocking functions to test regulary if | 
					
						
							|  |  |  |  * asynchronous interruption is needed. -EINTR is returned in this | 
					
						
							|  |  |  |  * case by the interrupted function. 'NULL' means no interrupt | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  |  * callback is given. | 
					
						
							| 
									
										
										
										
											2003-07-17 10:25:36 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | void url_set_interrupt_cb(URLInterruptCB *interrupt_cb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!interrupt_cb) | 
					
						
							|  |  |  |         interrupt_cb = default_interrupt_cb; | 
					
						
							|  |  |  |     url_interrupt_cb = interrupt_cb; | 
					
						
							|  |  |  | } |