diff options
Diffstat (limited to 'ffmpeg1/libavformat/file.c')
| -rw-r--r-- | ffmpeg1/libavformat/file.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/ffmpeg1/libavformat/file.c b/ffmpeg1/libavformat/file.c new file mode 100644 index 0000000..e09a64b --- /dev/null +++ b/ffmpeg1/libavformat/file.c @@ -0,0 +1,218 @@ +/* + * buffered file I/O + * Copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avstring.h" +#include "libavutil/opt.h" +#include "avformat.h" +#include <fcntl.h> +#if HAVE_IO_H +#include <io.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <sys/stat.h> +#include <stdlib.h> +#include "os_support.h" +#include "url.h" + +/* Some systems may not have S_ISFIFO */ +#ifndef S_ISFIFO +# ifdef S_IFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# else +# define S_ISFIFO(m) 0 +# endif +#endif + +/* standard file protocol */ + +typedef struct FileContext { + const AVClass *class; + int fd; + int trunc; +} FileContext; + +static const AVOption file_options[] = { + { "truncate", "Truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, + { NULL } +}; + +static const AVClass file_class = { + .class_name = "file", + .item_name = av_default_item_name, + .option = file_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static int file_read(URLContext *h, unsigned char *buf, int size) +{ + FileContext *c = h->priv_data; + int r = read(c->fd, buf, size); + return (-1 == r)?AVERROR(errno):r; +} + +static int file_write(URLContext *h, const unsigned char *buf, int size) +{ + FileContext *c = h->priv_data; + int r = write(c->fd, buf, size); + return (-1 == r)?AVERROR(errno):r; +} + +static int file_get_handle(URLContext *h) +{ + FileContext *c = h->priv_data; + return c->fd; +} + +static int file_check(URLContext *h, int mask) +{ +#if HAVE_ACCESS && defined(R_OK) + int ret = 0; + if (access(h->filename, F_OK) < 0) + return AVERROR(errno); + if (mask&AVIO_FLAG_READ) + if (access(h->filename, R_OK) >= 0) + ret |= AVIO_FLAG_READ; + if (mask&AVIO_FLAG_WRITE) + if (access(h->filename, W_OK) >= 0) + ret |= AVIO_FLAG_WRITE; +#else + struct stat st; + int ret = stat(h->filename, &st); + if (ret < 0) + return AVERROR(errno); + + ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0; + ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0; +#endif + return ret; +} + +#if CONFIG_FILE_PROTOCOL + +static int file_open(URLContext *h, const char *filename, int flags) +{ + FileContext *c = h->priv_data; + int access; + int fd; + struct stat st; + + av_strstart(filename, "file:", &filename); + + if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) { + access = O_CREAT | O_RDWR; + if (c->trunc) + access |= O_TRUNC; + } else if (flags & AVIO_FLAG_WRITE) { + access = O_CREAT | O_WRONLY; + if (c->trunc) + access |= O_TRUNC; + } else { + access = O_RDONLY; + } +#ifdef O_BINARY + access |= O_BINARY; +#endif + fd = open(filename, access, 0666); + if (fd == -1) + return AVERROR(errno); + c->fd = fd; + + h->is_streamed = !fstat(fd, &st) && S_ISFIFO(st.st_mode); + + return 0; +} + +/* XXX: use llseek */ +static int64_t file_seek(URLContext *h, int64_t pos, int whence) +{ + FileContext *c = h->priv_data; + int64_t ret; + + if (whence == AVSEEK_SIZE) { + struct stat st; + ret = fstat(c->fd, &st); + return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size); + } + + ret = lseek(c->fd, pos, whence); + + return ret < 0 ? AVERROR(errno) : ret; +} + +static int file_close(URLContext *h) +{ + FileContext *c = h->priv_data; + return close(c->fd); +} + +URLProtocol ff_file_protocol = { + .name = "file", + .url_open = file_open, + .url_read = file_read, + .url_write = file_write, + .url_seek = file_seek, + .url_close = file_close, + .url_get_file_handle = file_get_handle, + .url_check = file_check, + .priv_data_size = sizeof(FileContext), + .priv_data_class = &file_class, +}; + +#endif /* CONFIG_FILE_PROTOCOL */ + +#if CONFIG_PIPE_PROTOCOL + +static int pipe_open(URLContext *h, const char *filename, int flags) +{ + FileContext *c = h->priv_data; + int fd; + char *final; + av_strstart(filename, "pipe:", &filename); + + fd = strtol(filename, &final, 10); + if((filename == final) || *final ) {/* No digits found, or something like 10ab */ + if (flags & AVIO_FLAG_WRITE) { + fd = 1; + } else { + fd = 0; + } + } +#if HAVE_SETMODE + setmode(fd, O_BINARY); +#endif + c->fd = fd; + h->is_streamed = 1; + return 0; +} + +URLProtocol ff_pipe_protocol = { + .name = "pipe", + .url_open = pipe_open, + .url_read = file_read, + .url_write = file_write, + .url_get_file_handle = file_get_handle, + .url_check = file_check, + .priv_data_size = sizeof(FileContext), +}; + +#endif /* CONFIG_PIPE_PROTOCOL */ |
