[Libav-user] buffered stream and FFmpeg seek

Baris Unal Baris.Unal at statsperform.com
Tue Sep 5 15:29:51 EEST 2023


Hello,
Due to memory usage, we need to use a buffered solution to load a small chunk of blocks of streams in memory instead of loading the whole stream with:


  avformat_network_init();
  std::uint8_t *avioc_buffer =
      static_cast<uint8_t *> (av_malloc(AV_BUFFER_BLOCK_SIZE));

 avioc_ = avio_alloc_context(
    avioc_buffer, AV_BUFFER_BLOCK_SIZE, 0, &data_provider_,
    &ReadAVBlockCallback, nullptr, nullptr);

  fmtc_ = avformat_alloc_context();
  fmtc_->pb = avioc_[idx];
  fmtc_->flags |= AVFMT_FLAG_CUSTOM_IO;
  avformat_open_input(&fmtc_, nullptr, nullptr, nullptr);


ReadAVBlockCallback is the callback provided to refill the new block.
AV_BUFFER_BLOCK_SIZE is 8Mytes.


The issue is that I need to implement the seek feature with av_seek_frame API and av_seek_frame is not calling the callback, "ReadAVBlockCallback" to fill the buffer when needed if the frame to seek is not in the current buffer block.
I am using FFmpeg 4.1 (and the same issue in 4.4).
I've rebuilt FFmpeg to look at it with the debugger.

What I have observed is that:

"av_index_search_timestamp" call is looking at "stream's index_entries" and if the entry for the seek point is found, and returned, it does not need to call the callback to refill the "stream buffer".
But the problem is that this buffer does not have the packet with this seek timestamp, therefore, it cannot seek to the correct keyframe.

Here is the code snap from matroskadec.c

    if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) { //if the index is valid, no need to refill the stream buffer but the current buffer does not always have the target frame.
        avio_seek(s->pb, st->index_entries[st->nb_index_entries - 1].pos,
                  SEEK_SET);
        matroska->current_id = 0;
        while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) {
            matroska_clear_queue(matroska);
            if (matroska_parse_cluster(matroska) < 0)  // this is where the new block is load
                break;
        }
    }

Can you please let me know how I can fix it? Is there a solution in the new releases?

Thank you, a lot.


[cid:image001.jpg at 01D9E002.97FCE4F0]
Baris Unal
Software Engineer III

baris.unal at statsperform.global<mailto:baris.unal at statsperform.global>

www.statsperform.com<http://www.statsperform.com>

This email is from Stats Perform. Perform Content Limited (Company No: 11562035) and Perform Content Services Limited (Company No: 11584111) are registered at The Point, 37 North Wharf Road, Paddington W2 1AF. Further information can be found at www.statsperform.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20230905/00d3ee03/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.jpg
Type: image/jpeg
Size: 5491 bytes
Desc: image001.jpg
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20230905/00d3ee03/attachment.jpg>


More information about the Libav-user mailing list