avformat/mov: Only read the mfra size once during sidx parsing

On files with more than one sidx box, like live fragmented MP4
files, it was previously re-reading and seeking on every singl
sidx box, leading to extremely poor performance on larger files,
especially over the network.

Only do it on the first one, and stash its result.

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
This commit is contained in:
Derek Buitenhuis 2020-09-01 15:33:47 +01:00
parent 19064a36e3
commit 97fa669a6f
2 changed files with 11 additions and 7 deletions

View File

@ -291,6 +291,8 @@ typedef struct MOVContext {
int decryption_key_len;
int enable_drefs;
int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd
int have_read_mfra_size;
uint32_t mfra_size;
} MOVContext;
int ff_mp4_read_descr_len(AVIOContext *pb);

View File

@ -5097,14 +5097,16 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
int64_t ret;
int64_t original_pos = avio_tell(pb);
int32_t mfra_size;
if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
return ret;
mfra_size = avio_rb32(pb);
if (offset + mfra_size == stream_size)
if (!c->have_read_mfra_size) {
if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
return ret;
c->mfra_size = avio_rb32(pb);
c->have_read_mfra_size = 1;
if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
return ret;
}
if (offset + c->mfra_size == stream_size)
is_complete = 1;
if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
return ret;
}
if (is_complete) {