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.
This commit is contained in:
wm4 2012-02-26 21:12:53 +01:00
parent 8a10f587fc
commit 021d012c97
1 changed files with 26 additions and 1 deletions

View File

@ -1382,6 +1382,24 @@ int demuxer_add_attachment(demuxer_t *demuxer, struct bstr name,
return demuxer->num_attachments++; 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, int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
uint64_t start, uint64_t end) 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_strndup(demuxer->chapters, name.start, name.len) :
talloc_strdup(demuxer->chapters, mp_gtext("unknown")); 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;
} }
/** /**