summaryrefslogtreecommitdiff
path: root/libavformat/file.c
diff options
context:
space:
mode:
authorAndrey Utkin <andrey.krieger.utkin@gmail.com>2013-07-31 15:22:01 +0300
committerMichael Niedermayer <michaelni@gmx.at>2013-07-31 21:16:54 +0200
commita8f171151f0f027abb06f72e48c44929616a84cb (patch)
tree63ed93dc504dc78b3945a4d221bf3b594a811d2f /libavformat/file.c
parent3b3c1ed0768af874c624cc555fbbd1fcea370200 (diff)
downloadffmpeg-a8f171151f0f027abb06f72e48c44929616a84cb.tar.gz
file: Add 'blocksize' option
Interruptibility of file operations is strongly desirable in case of slow storage access, e.g. mounted network share. This commit introduces possibility to limit data quantity transferred by 'file' protocol at once. By default, old behaviour is preserved and data is still tried to be transferred without block size limitation. Note that file I/O operation still may block (or even freeze) inside of single read(2) or write(2) operation. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/file.c')
-rw-r--r--libavformat/file.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/libavformat/file.c b/libavformat/file.c
index e09a64b37c..946f058903 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -49,10 +49,17 @@ typedef struct FileContext {
const AVClass *class;
int fd;
int trunc;
+ int blocksize;
} 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 },
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVOption pipe_options[] = {
+ { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }
};
@@ -63,17 +70,28 @@ static const AVClass file_class = {
.version = LIBAVUTIL_VERSION_INT,
};
+static const AVClass pipe_class = {
+ .class_name = "pipe",
+ .item_name = av_default_item_name,
+ .option = pipe_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);
+ int r;
+ size = FFMIN(size, c->blocksize);
+ 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);
+ int r;
+ size = FFMIN(size, c->blocksize);
+ r = write(c->fd, buf, size);
return (-1 == r)?AVERROR(errno):r;
}
@@ -213,6 +231,7 @@ URLProtocol ff_pipe_protocol = {
.url_get_file_handle = file_get_handle,
.url_check = file_check,
.priv_data_size = sizeof(FileContext),
+ .priv_data_class = &pipe_class,
};
#endif /* CONFIG_PIPE_PROTOCOL */