From 3789d48fc4ed515fd4fc879b9cdb2c6ffcc46cad Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Fri, 7 May 2010 18:12:56 +0200 Subject: [PATCH] Use O_DIRECT buffer flushing only when we operate really on O_DIRECT file The flush_buffer function is called also when a tag is written at the end of the encoding and it operates over DynBufer structure instead of file. --- libavformat/avio.h | 2 ++ libavformat/aviobuf.c | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/libavformat/avio.h b/libavformat/avio.h index be02b06f6..b8b35afe8 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -64,6 +64,7 @@ typedef struct URLPollEntry { #define URL_RDONLY 0 #define URL_WRONLY 1 #define URL_RDWR 2 +#define URL_DIRECT 4 typedef int URLInterruptCB(void); @@ -197,6 +198,7 @@ typedef struct { int must_flush; /**< true if the next seek should flush */ int eof_reached; /**< true if eof reached */ int write_flag; /**< true if open for writing */ + int o_direct_flag; /**< true if the underlaying file is open with O_DIRECT */ int is_streamed; int max_packet_size; unsigned long checksum; diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 04e519916..8493e5532 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -81,7 +81,7 @@ ByteIOContext *av_alloc_put_byte( #define BLOCK_SIZE 512 -static void flush_buffer(ByteIOContext *s) +static void flush_buffer_o_direct(ByteIOContext *s) { size_t data_len = s->buf_ptr - s->buffer; @@ -95,7 +95,7 @@ static void flush_buffer(ByteIOContext *s) size_t to_write = (data_len + BLOCK_SIZE - 1) & ~(BLOCK_SIZE - 1); size_t whole_blocks = data_len & ~(BLOCK_SIZE - 1); int64_t res = AVERROR(EPIPE); - av_log(NULL, AV_LOG_ERROR, "YYY dl=%zd, tw=%zd\n", data_len, to_write); + //av_log(NULL, AV_LOG_ERROR, "%p: YYY dl=%zd, tw=%zd\n", s, data_len, to_write); if (data_len > 0) { if (s->write_packet && !s->error){ int ret= s->write_packet(s->opaque, s->buffer, to_write); @@ -116,8 +116,30 @@ static void flush_buffer(ByteIOContext *s) res = s->seek(s->opaque, s->pos, SEEK_SET); if (res < 0) av_log(NULL, AV_LOG_ERROR, "seek error inside flush_buffer: %lld\n", res); - av_log(NULL, AV_LOG_ERROR, "ZZZ tw=%zu, pos=%zd\n", to_write, s->pos); + //av_log(NULL, AV_LOG_ERROR, "ZZZ tw=%zu, pos=%zd\n", to_write, s->pos); + } +} + +static void flush_buffer(ByteIOContext *s) +{ + if (s->o_direct_flag) { + flush_buffer_o_direct(s); + return; + } + if (s->buf_ptr > s->buffer) { + if (s->write_packet && !s->error){ + int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer); + if(ret < 0){ + s->error = ret; + } + } + if(s->update_checksum){ + s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); + s->checksum_ptr= s->buffer; + } + s->pos += s->buf_ptr - s->buffer; } + s->buf_ptr = s->buffer; } void put_byte(ByteIOContext *s, int b) @@ -171,13 +193,14 @@ int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } - av_log(NULL, AV_LOG_ERROR, "SEEK to %llu\n", offset); + av_log(NULL, AV_LOG_ERROR, "%p: SEEK from %llu to %llu\n", s, pos, offset); offset1 = offset - pos; if (!s->must_flush && offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { /* can do the seek inside the buffer */ s->buf_ptr = s->buffer + offset1; + av_log(NULL, AV_LOG_ERROR, "Internal seek by %llu\n", offset1); } else if(s->is_streamed && !s->write_flag && offset1 >= 0 && offset1 < (s->buf_end - s->buffer) + (1<<16)){ while(s->pos < offset && !s->eof_reached) @@ -566,8 +589,14 @@ int url_fdopen(ByteIOContext **s, URLContext *h) } else { buffer_size = IO_BUFFER_SIZE; } - buffer_size = 2*buffer_size+BLOCK_SIZE; - buffer = memalign(sysconf(_SC_PAGESIZE), buffer_size); + (*s)->o_direct_flag = !!(h->flags & URL_DIRECT); + if ((*s)->o_direct_flag) { + buffer_size = 2*buffer_size+BLOCK_SIZE; + buffer = memalign(sysconf(_SC_PAGESIZE), buffer_size); + ; + } else { + buffer = av_malloc(buffer_size); + } if (!buffer) return AVERROR(ENOMEM); -- 2.39.2