Libav
|
00001 /* 00002 * Buffered file io for ffmpeg system 00003 * Copyright (c) 2001 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavutil/avstring.h" 00023 #include "avformat.h" 00024 #include <fcntl.h> 00025 #if HAVE_SETMODE 00026 #include <io.h> 00027 #endif 00028 #include <unistd.h> 00029 #include <sys/stat.h> 00030 #include <sys/time.h> 00031 #include <stdlib.h> 00032 #include "os_support.h" 00033 00034 00035 /* standard file protocol */ 00036 00037 static int file_open(URLContext *h, const char *filename, int flags) 00038 { 00039 int access; 00040 int fd; 00041 00042 av_strstart(filename, "file:", &filename); 00043 00044 if (flags & URL_RDWR) { 00045 access = O_CREAT | O_TRUNC | O_RDWR; 00046 } else if (flags & URL_WRONLY) { 00047 access = O_CREAT | O_TRUNC | O_WRONLY; 00048 } else { 00049 access = O_RDONLY; 00050 } 00051 #ifdef O_BINARY 00052 access |= O_BINARY; 00053 #endif 00054 fd = open(filename, access, 0666); 00055 if (fd == -1) 00056 return AVERROR(errno); 00057 h->priv_data = (void *) (intptr_t) fd; 00058 return 0; 00059 } 00060 00061 static int file_read(URLContext *h, unsigned char *buf, int size) 00062 { 00063 int fd = (intptr_t) h->priv_data; 00064 return read(fd, buf, size); 00065 } 00066 00067 static int file_write(URLContext *h, unsigned char *buf, int size) 00068 { 00069 int fd = (intptr_t) h->priv_data; 00070 return write(fd, buf, size); 00071 } 00072 00073 /* XXX: use llseek */ 00074 static int64_t file_seek(URLContext *h, int64_t pos, int whence) 00075 { 00076 int fd = (intptr_t) h->priv_data; 00077 if (whence == AVSEEK_SIZE) { 00078 struct stat st; 00079 int ret = fstat(fd, &st); 00080 return ret < 0 ? AVERROR(errno) : st.st_size; 00081 } 00082 return lseek(fd, pos, whence); 00083 } 00084 00085 static int file_close(URLContext *h) 00086 { 00087 int fd = (intptr_t) h->priv_data; 00088 return close(fd); 00089 } 00090 00091 static int file_get_handle(URLContext *h) 00092 { 00093 return (intptr_t) h->priv_data; 00094 } 00095 00096 URLProtocol file_protocol = { 00097 "file", 00098 file_open, 00099 file_read, 00100 file_write, 00101 file_seek, 00102 file_close, 00103 .url_get_file_handle = file_get_handle, 00104 }; 00105 00106 /* pipe protocol */ 00107 00108 static int pipe_open(URLContext *h, const char *filename, int flags) 00109 { 00110 int fd; 00111 char *final; 00112 av_strstart(filename, "pipe:", &filename); 00113 00114 fd = strtol(filename, &final, 10); 00115 if((filename == final) || *final ) {/* No digits found, or something like 10ab */ 00116 if (flags & URL_WRONLY) { 00117 fd = 1; 00118 } else { 00119 fd = 0; 00120 } 00121 } 00122 #if HAVE_SETMODE 00123 setmode(fd, O_BINARY); 00124 #endif 00125 h->priv_data = (void *) (intptr_t) fd; 00126 h->is_streamed = 1; 00127 return 0; 00128 } 00129 00130 URLProtocol pipe_protocol = { 00131 "pipe", 00132 pipe_open, 00133 file_read, 00134 file_write, 00135 .url_get_file_handle = file_get_handle, 00136 };