X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/ffmpeg.git/blobdiff_plain/23aaaeffc5f7e17016fb82887779e0ba6e4dcfdf..77b0842e4959363e840f573192cccd6e4ac40cb9:/libavformat/aviobuf.c diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index b1e1b49a7..1dac20298 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -24,6 +24,8 @@ #include "avformat.h" #include "avio.h" #include +#include +#include #define IO_BUFFER_SIZE 32768 @@ -77,8 +79,53 @@ ByteIOContext *av_alloc_put_byte( return s; } +#define BLOCK_SIZE 512 + +static void flush_buffer_o_direct(ByteIOContext *s) +{ + size_t data_len = s->buf_ptr - s->buffer; + + /* Write all data in the buffer to the disk together with any + * additional space at the end of the buffer up to the first + * multiple of BLOCK_SIZE. The last block is always written to the + * disk despite not being fully filled. If the last block is not + * fully filled, we keep it (moved to the begginig of the buffer) + * and any subsequent call to this function will rewrite the block + * together with the additional data added to the buffer. */ + 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); + if (data_len > 0) { + if (s->write_packet && !s->error){ + int ret= s->write_packet(s->opaque, s->buffer, to_write); + if(ret < 0){ + s->error = ret; + } + } + if(s->update_checksum){ + av_log(NULL, AV_LOG_ERROR, "Checksumming not implemented in O_DIRECT patch\n"); + s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); + s->checksum_ptr= s->buffer; + } + s->pos += to_write; + memcpy(s->buffer, &s->buffer[whole_blocks], data_len - whole_blocks); + s->buf_ptr -= whole_blocks; + + if (s->seek) + res = s->seek(s->opaque, s->pos - to_write + whole_blocks, SEEK_SET); + if (res < 0) + av_log(NULL, AV_LOG_ERROR, "seek error inside %s: %lld\n", __func__, res); + //av_log(NULL, AV_LOG_ERROR, "ZZZ tw=%zu, pos=%zd\n", to_write, s->pos); + } +} + static void flush_buffer(ByteIOContext *s) { + av_log(NULL, AV_LOG_ERROR, "WRITE %p: pos=%zd len=%zd\n", s, s->pos, s->buf_ptr - s->buffer); + 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); @@ -146,11 +193,16 @@ int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } + //if (s->o_direct_flag) + av_log(NULL, AV_LOG_ERROR, "SEEK %p: from %llu to %llu\n", s, pos, offset); + offset1 = offset - pos; if (!s->must_flush && - offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) { + offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { /* can do the seek inside the buffer */ s->buf_ptr = s->buffer + offset1; + if (s->o_direct_flag) + 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) @@ -167,6 +219,7 @@ int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence) s->must_flush = 1; } #endif /* CONFIG_MUXERS || CONFIG_NETWORK */ +#warning TODO read the whole block from the file to the buffer if (!s->seek || (res = s->seek(s->opaque, offset, SEEK_SET)) < 0) return res; if (!s->write_flag) @@ -538,7 +591,13 @@ int url_fdopen(ByteIOContext **s, URLContext *h) } else { buffer_size = IO_BUFFER_SIZE; } - buffer = av_malloc(buffer_size); + if (h->flags & URL_DIRECT) { + 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); @@ -557,6 +616,7 @@ int url_fdopen(ByteIOContext **s, URLContext *h) } (*s)->is_streamed = h->is_streamed; (*s)->max_packet_size = max_packet_size; + (*s)->o_direct_flag = !!(h->flags & URL_DIRECT); if(h->prot) { (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; @@ -600,6 +660,7 @@ int url_fopen(ByteIOContext **s, const char *filename, int flags) URLContext *h; int err; + av_log(NULL, AV_LOG_ERROR, "%s: %p %s\n", __func__, s, filename); err = url_open(&h, filename, flags); if (err < 0) return err; @@ -783,12 +844,8 @@ static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) static int url_open_dyn_buf_internal(ByteIOContext **s, int max_packet_size) { DynBuffer *d; - int io_buffer_size, ret; - - if (max_packet_size) - io_buffer_size = max_packet_size; - else - io_buffer_size = 1024; + int ret; + unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size) return -1;