[FFmpeg-trac] #7592(avformat:new): FFmpeg download data twice

FFmpeg trac at avcodec.org
Tue Dec 4 17:51:00 EET 2018


#7592: FFmpeg download data twice
-------------------------------------+------------------------------------
             Reporter:  atrzcinski   |                    Owner:
                 Type:  defect       |                   Status:  new
             Priority:  normal       |                Component:  avformat
              Version:  unspecified  |               Resolution:
             Keywords:               |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+------------------------------------

Comment (by atrzcinski):

 This is a solution I used to solve this problem:

 diff --git a/third_party/ffmpeg/libavformat/avio.h
 b/third_party/ffmpeg/libavformat/avio.h
 index 75912ce6bed9..c44e1c7e9c9b 100644
 --- a/third_party/ffmpeg/libavformat/avio.h
 +++ b/third_party/ffmpeg/libavformat/avio.h
 @@ -225,6 +225,7 @@ typedef struct AVIOContext {
       */
      unsigned char *buffer;  /**< Start of the buffer. */
      int buffer_size;        /**< Maximum buffer size */
 +    int time_units_in_buffer; /**< Number of time units in buffer */
      unsigned char *buf_ptr; /**< Current position in the buffer */
      unsigned char *buf_end; /**< End of the data, may be less than
                                   buffer+buffer_size if the read function
 returned
 diff --git a/third_party/ffmpeg/libavformat/aviobuf.c
 b/third_party/ffmpeg/libavformat/aviobuf.c
 index 5a33f82950c3..afccc61491bd 100644
 --- a/third_party/ffmpeg/libavformat/aviobuf.c
 +++ b/third_party/ffmpeg/libavformat/aviobuf.c
 @@ -92,6 +92,7 @@ int ffio_init_context(AVIOContext *s,
      s->buffer      = buffer;
      s->orig_buffer_size =
      s->buffer_size = buffer_size;
 +    s->time_units_in_buffer = 0;
      s->buf_ptr     = buffer;
      s->buf_ptr_max = buffer;
      s->opaque      = opaque;
 @@ -550,9 +551,19 @@ static void fill_buffer(AVIOContext *s)
  {
      int max_buffer_size = s->max_packet_size ?
                            s->max_packet_size : IO_BUFFER_SIZE;
 -    uint8_t *dst        = s->buf_end - s->buffer + max_buffer_size <
 s->buffer_size ?
 -                          s->buf_end : s->buffer;
 -    int len             = s->buffer_size - (dst - s->buffer);
 +    int need_erase = !(s->buf_end - s->buffer + max_buffer_size <
 s->buffer_size);
 +    uint8_t *dst = need_erase ? s->buffer : s->buf_end;
 +    int len;
 +
 +    if (need_erase && s->time_units_in_buffer > 1) {
 +        const int bytes_in_time_unit = (s->buf_end - s->buffer) /
 s->time_units_in_buffer;
 +        const int offset = bytes_in_time_unit * (s->time_units_in_buffer
 - 1);
 +        memcpy(s->buffer, s->buffer + offset, bytes_in_time_unit);
 +        dst = s->buf_end = s->buffer + bytes_in_time_unit;
 +        s->buf_ptr = s->buf_ptr - s->buffer < offset ? s->buffer :
 s->buf_ptr - offset;
 +    }
 +
 +    len = s->buffer_size - (dst - s->buffer);

      /* can't fill the buffer without read_packet, just set EOF if
 appropriate */
      if (!s->read_packet && s->buf_ptr >= s->buf_end)
 @@ -562,7 +573,7 @@ static void fill_buffer(AVIOContext *s)
      if (s->eof_reached)
          return;

 -    if (s->update_checksum && dst == s->buffer) {
 +    if (s->update_checksum && need_erase) {
          if (s->buf_end > s->checksum_ptr)
              s->checksum = s->update_checksum(s->checksum,
 s->checksum_ptr,
                                               s->buf_end -
 s->checksum_ptr);
 @@ -571,7 +582,7 @@ static void fill_buffer(AVIOContext *s)

      /* make buffer smaller in case it ended up large after probing */
      if (s->read_packet && s->orig_buffer_size && s->buffer_size >
 s->orig_buffer_size) {
 -        if (dst == s->buffer && s->buf_ptr != dst) {
 +        if (need_erase  && s->buf_ptr != dst) {
              int ret = ffio_set_buf_size(s, s->orig_buffer_size);
              if (ret < 0)
                  av_log(s, AV_LOG_WARNING, "Failed to decrease buffer
 size\n");
 diff --git a/third_party/ffmpeg/libavformat/utils.c
 b/third_party/ffmpeg/libavformat/utils.c
 index c6901174432c..3d5040025cfb 100644
 --- a/third_party/ffmpeg/libavformat/utils.c
 +++ b/third_party/ffmpeg/libavformat/utils.c
 @@ -2137,6 +2137,7 @@ void ff_configure_buffers_for_index(AVFormatContext
 *s, int64_t time_tolerance)
          av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size
 %"PRId64"\n", pos_delta);
          ffio_set_buf_size(s->pb, pos_delta);
          s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold,
 pos_delta/2);
 +        s->pb->time_units_in_buffer = 2;
      }

      if (skip < (1<<23)) {

--
Ticket URL: <https://trac.ffmpeg.org/ticket/7592#comment:1>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list