Why does the new version of ffmpeg play non-interleaved http files so stuck?

Stack Overflow Asked by fredirty2017 on August 1, 2020

  • I use MAC’s AVAssetWriter/AVAssetWriterInput to generate MP4, then upload it to the website, and then use the latest version (ffmpeg4.2 or 4.3) of ffplay to play the file as https file on Windows, but I find it is very stuck. I use the old version of ffmpeg For example, the 3.4 version is normal. By analyzing the old and new ffmpeg source code, the general problem is basically located, but the deeper reason is still unclear.

  • The audio and video frames recorded by MAC are partially (within 3 seconds) non-interleaved

  • The latest version of Window’s ffplay will continue to reconnect http to Seek
    In the mov.c file, it is found that the number of AVIndexEntry created by the new and old versions ffmpeg is different, because the read buffer size is determined by the calculation of ff_configure_buffers_for_index: the buffer_size of the new version of AVIOContext is only the default 16k, so the pre-step of mov_read_packet avio_seek finds that the pos of the next frame is not within the 16k range, which leads to reconnecting to http and seeking to a new position; while the AVIOContext.buffer_size of the old version of ffmpeg has a size of M Bytes level, it will not trigger reconnection of http.

  • Further analysis found that ff_configure_buffers_for_index will be calculated based on the relative maximum offset of the AVIndexEntry of each stream, because the new version skips the opportunity to adjust the buffer_size because the pos_delta is greater than 1<<24.

  • But I don’t know why the new version of AVIndexEntry has this situation. Do you know why the "new" version has made this change? And how to make the player plays as smoothly as the old version?

     void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
         int ist1, ist2;
         int64_t pos_delta = 0;
         int64_t skip = 0;
         //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
         const char *proto = avio_find_protocol_name(s->filename);
         if (!proto) {
             av_log(s, AV_LOG_INFO,
                "Protocol name not provided, cannot determine if input is local or "
                "a network protocol, buffers and access patterns cannot be configured "
                "optimally without knowing the protocoln");
         if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache")))
         for (ist1 = 0; ist1 < s->nb_streams; ist1++) {
             AVStream *st1 = s->streams[ist1];
             for (ist2 = 0; ist2 < s->nb_streams; ist2++) {
                 AVStream *st2 = s->streams[ist2];
                 int i1, i2;
                 if (ist1 == ist2)
                 for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
                     AVIndexEntry *e1 = &st1->index_entries[i1];
                     int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
                     skip = FFMAX(skip, e1->size);
                     for (; i2 < st2->nb_index_entries; i2++) {
                         AVIndexEntry *e2 = &st2->index_entries[i2];
                         int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
                         if (e2_pts - e1_pts < time_tolerance)
                         pos_delta = FFMAX(pos_delta, e1->pos - e2->pos);
                         av_log(s, AV_LOG_VERBOSE, "ff_configure_buffers_for_index  [%d, %d]  (%"PRId64", %"PRId64"):    %"PRId64"n",  i1, i2, e1_pts, e2_pts, pos_delta);
         pos_delta *= 2;
         /* XXX This could be adjusted depending on protocol*/
         if (s->pb->buffer_size < pos_delta && pos_delta < (1<<24)) {
             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);
         if (skip < (1<<23)) {
             s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, skip);

Add your own answers!

Related Questions

Add AWS Cognito to angular application

1  Asked on November 16, 2021 by captainmorgan


How to analize which object owns the max memory

0  Asked on November 16, 2021 by loverszhaokai


enable_if, SFINAE and template parameters?

2  Asked on November 16, 2021


Dynamic ‘wait’ arg in Scrapy-splash

0  Asked on November 16, 2021 by winters


Grab a decimal between 2 strings regex

1  Asked on November 15, 2021 by lenny-gonzalez


Django , models object not displayed in views

2  Asked on November 15, 2021 by mxzero-mxzero


Re-render a sibling component using hooks

3  Asked on November 15, 2021 by programmer1


filter method returns empty array

3  Asked on November 15, 2021


Fit container inside image

1  Asked on November 15, 2021


Ask a Question

Get help from others!

© 2022 All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP, SolveDir