From 021d012c9782dbbfc876f69b9f150754d5bbeb72 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 26 Feb 2012 21:12:53 +0100 Subject: [PATCH] core: sort chapters Ensure that chapters are sorted by time. There are some broken mkv files that have chapters in random order. Using simple chapter skipping with the seek_chapter slave command is very confusing and just doesn't work if the chapters are not in order. The chapters are resorted every time a chapter is added, that would make the chapter list unsorted. While this is algorithmically very stupid, it doesn't require changes per demuxer, or reasoning when exactly chapters could be added. Turning this into an insertion sort isn't worth the code, and the added demuxer_sort_chapters() function could possibly be moved to the "right" place later. This is not done when ordered chapters are used, because timeline support uses different data structures for chapters. --- libmpdemux/demuxer.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index be4b2bb676..4e39cedb1a 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -1382,6 +1382,24 @@ int demuxer_add_attachment(demuxer_t *demuxer, struct bstr name, return demuxer->num_attachments++; } +static int chapter_compare(const void *p1, const void *p2) +{ + struct demux_chapter *c1 = (void *)p1; + struct demux_chapter *c2 = (void *)p2; + + if (c1->start > c2->start) + return 1; + else if (c1->start < c2->start) + return -1; + return 0; +} + +static void demuxer_sort_chapters(demuxer_t *demuxer) +{ + qsort(demuxer->chapters, demuxer->num_chapters, + sizeof(struct demux_chapter), chapter_compare); +} + int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name, uint64_t start, uint64_t end) { @@ -1396,7 +1414,14 @@ int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name, talloc_strndup(demuxer->chapters, name.start, name.len) : talloc_strdup(demuxer->chapters, mp_gtext("unknown")); - return demuxer->num_chapters++; + demuxer->num_chapters++; + + if (demuxer->num_chapters > 1 + && demuxer->chapters[demuxer->num_chapters - 2].start + < demuxer->chapters[demuxer->num_chapters - 1].start) + demuxer_sort_chapters(demuxer); + + return 0; } /**