Currently, the Matroska muxer reallocates its array of index entries each time another entry is added. This is bad performance-wise, especially on Windows where reallocations are slow. This is solved by switching to av_fast_realloc_array() which ensures that actual reallocations will happen only seldomly.
For an (admittedly extreme) example which consists of looping a video consisting of a single keyframe of size 4KB 540000 times this improved the time for writing a frame from 23524201 decicycles (516466 runs, 7822 skips) to 225240 decicycles (522122 runs, 2166 skips) on Windows. (Writing CRC-32 elements was disabled for these tests.) Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- The guy from ticket #8109 will probably be quite happy about this. libavformat/matroskaenc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 469b604de6..72d19a9f5a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -88,7 +88,8 @@ typedef struct mkv_cuepoint { typedef struct mkv_cues { int64_t segment_offset; mkv_cuepoint *entries; - int num_entries; + unsigned num_entries; + unsigned allocated_entries; } mkv_cues; typedef struct mkv_track { @@ -171,7 +172,7 @@ typedef struct MatroskaMuxContext { /** per-cuepoint-track - 5 1-byte EBML IDs, 5 1-byte EBML sizes, 3 8-byte uint max * and one 1-byte uint for the track number (this assumes MAX_TRACKS to be <= 255) */ -#define MAX_CUETRACKPOS_SIZE 35 +#define MAX_CUETRACKPOS_SIZE 35LL /** per-cuepoint - 1 1-byte EBML ID, 1 1-byte EBML size, 8-byte uint max */ #define MAX_CUEPOINT_CONTENT_SIZE(num_tracks) 10 + MAX_CUETRACKPOS_SIZE * num_tracks @@ -540,7 +541,8 @@ static int mkv_add_cuepoint(mkv_cues *cues, int stream, int tracknum, int64_t ts if (ts < 0) return 0; - entries = av_realloc_array(entries, cues->num_entries + 1, sizeof(mkv_cuepoint)); + entries = av_fast_realloc_array(entries, &cues->allocated_entries, + cues->num_entries + 1, sizeof(mkv_cuepoint)); if (!entries) return AVERROR(ENOMEM); cues->entries = entries; @@ -560,21 +562,21 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra MatroskaMuxContext *mkv = s->priv_data; AVIOContext *dyn_cp, *pb = s->pb; int64_t currentpos; - int i, j, ret; + int ret; currentpos = avio_tell(pb); ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CUES); if (ret < 0) return ret; - for (i = 0; i < cues->num_entries; i++) { + for (unsigned i = 0; i < cues->num_entries; i++) { ebml_master cuepoint, track_positions; mkv_cuepoint *entry = &cues->entries[i]; uint64_t pts = entry->pts; - int ctp_nb = 0; + unsigned ctp_nb = 0, j; // Calculate the number of entries, so we know the element size - for (j = 0; j < num_tracks; j++) + for (int j = 0; j < num_tracks; j++) tracks[j].has_cue = 0; for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { int idx = entry[j].stream_idx; @@ -591,7 +593,7 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra // put all the entries from different tracks that have the exact same // timestamp into the same CuePoint - for (j = 0; j < num_tracks; j++) + for (int j = 0; j < num_tracks; j++) tracks[j].has_cue = 0; for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { int idx = entry[j].stream_idx; -- 2.20.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-requ...@ffmpeg.org with subject "unsubscribe".