From: Marton Balint <cus@passwd.hu> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH 2/2] aviobuf: Avoid clearing the whole buffer in fill_buffer Date: Tue, 21 Mar 2023 20:29:18 +0100 (CET) Message-ID: <4ce99489-4b19-3c7c-88aa-1080531f925d@passwd.hu> (raw) In-Reply-To: <20230321123729.74124-2-martin@martin.st> On Tue, 21 Mar 2023, Martin Storsjö wrote: > Normally, fill_buffer reads in one max_packet_size/IO_BUFFER_SIZE > worth of data into the buffer, slowly filling the buffer until it > is full. > > Previously, when the buffer was full, fill_buffer would start over > from the start, effectively discarding all the previously buffered > data. > > For files that are read linearly, the previous behaviour was fine. > > For files that exhibit some amount of nonlinear read patterns, > especially mov files (where ff_configure_buffers_for_index > increases the buffer size to accomodate for the nonlinear reading!) > we would mostly be able to seek within the buffer - but whenever > we've hit the maximum buffer size, we'd discard most of the buffer > and start over with a very small buffer, so the next seek backwards > would end up outside of the buffer. > > Keep one fourth of the buffered data, moving it to the start of > the buffer, freeing the rest to be refilled with future data. > > For mov files with nonlinear read patterns, this almost entirely > avoids doing seeks on the lower IO level, where we previously would > end up doing seeks occasionally. Maybe the demuxer should use ffio_ensure_seekback() instead if it knows that a seekback will happen? Unconditional memmove of even fourth of all data does not seem like a good idea. Regards, Marton > > Signed-off-by: Martin Storsjö <martin@martin.st> > --- > I'm open to suggestions on whether 1/4 of the buffer is a reasonable > amount to keep. It does of course incur some amount of overhead > for well behaved linear files, but is a decent improvement for > nonlinear mov files. > > Alternatively we could trigger this behaviour only after we've > observed a couple seeks backwards? > --- > libavformat/aviobuf.c | 46 +++++++++++++++++++++++++++++++++++++------ > 1 file changed, 40 insertions(+), 6 deletions(-) > > diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c > index 4ad734a3c3..dfc3e77016 100644 > --- a/libavformat/aviobuf.c > +++ b/libavformat/aviobuf.c > @@ -534,8 +534,7 @@ static void fill_buffer(AVIOContext *s) > FFIOContext *const ctx = (FFIOContext *)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; > + uint8_t *dst = s->buf_end; > int len = s->buffer_size - (dst - s->buffer); > > /* can't fill the buffer without read_packet, just set EOF if appropriate */ > @@ -546,11 +545,46 @@ static void fill_buffer(AVIOContext *s) > if (s->eof_reached) > return; > > - if (s->update_checksum && dst == s->buffer) { > - if (s->buf_end > s->checksum_ptr) > + if (len < max_buffer_size && s->buffer_size > max_buffer_size) { > + /* If the buffer is almost full and we're not trying to read > + one whole buffer worth of data at once; keep some amount of > + the currently buffered data, but move it to the start of the > + buffer, to allow filling the buffer with more data. */ > + int keep = (s->buf_end - s->buffer)/4; > + int shift = s->buf_end - keep - s->buffer; > + > + if (s->update_checksum && s->checksum_ptr - s->buffer < shift) { > + /* Checksum up to the buffer + shift position (that we're > + shifting out of the buffer. */ > s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, > - s->buf_end - s->checksum_ptr); > - s->checksum_ptr = s->buffer; > + s->buffer + shift - s->checksum_ptr); > + } > + > + memmove(s->buffer, s->buf_end - keep, keep); > + s->buf_end -= shift; > + s->buf_ptr -= shift; > + if (s->update_checksum) { > + if (s->checksum_ptr - s->buffer < shift) > + s->checksum_ptr = s->buffer; > + else > + s->checksum_ptr -= shift; > + } > + > + dst = s->buf_end; > + len = s->buffer_size - (dst - s->buffer); > + } else if (len < max_buffer_size) { > + /* If the buffer is full so we can't fit a whole write of max_buffer_size, > + just restart the pointers from the start of the buffer. */ > + dst = s->buffer; > + len = s->buffer_size; > + > + if (s->update_checksum) { > + /* Checksum all data that gets shifted out of the buffer. */ > + if (s->buf_end > s->checksum_ptr) > + s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, > + s->buf_end - s->checksum_ptr); > + s->checksum_ptr = s->buffer; > + } > } > > /* make buffer smaller in case it ended up large after probing */ > -- > 2.37.1 (Apple Git-137.1) > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-03-21 19:29 UTC|newest] Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-03-21 12:37 [FFmpeg-devel] [PATCH 1/2] libavformat: Improve ff_configure_buffers_for_index for excessive deltas Martin Storsjö 2023-03-21 12:37 ` [FFmpeg-devel] [PATCH 2/2] aviobuf: Avoid clearing the whole buffer in fill_buffer Martin Storsjö 2023-03-21 19:29 ` Marton Balint [this message] 2023-03-21 20:24 ` Martin Storsjö 2023-03-24 11:11 ` Anton Khirnov 2023-03-24 11:25 ` Martin Storsjö 2023-03-24 11:55 ` Anton Khirnov 2023-03-24 20:45 ` Marton Balint 2023-03-24 21:05 ` Martin Storsjö 2023-03-24 21:35 ` Marton Balint 2023-03-24 21:41 ` Martin Storsjö 2023-03-24 21:49 ` [FFmpeg-devel] [PATCH 1/2] libavformat: Improve ff_configure_buffers_for_index for excessive deltas Marton Balint 2023-03-25 0:37 ` Michael Niedermayer 2023-03-25 22:17 ` Martin Storsjö
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=4ce99489-4b19-3c7c-88aa-1080531f925d@passwd.hu \ --to=cus@passwd.hu \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git