From 213bf82b2667888155d20b73768cf3c59bbec950 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Fri, 17 Sep 2004 20:29:12 +0000 Subject: [PATCH] Merged 2182 --- ChangeLog | 5 ++ src/input/r_srt.cpp | 24 ++++++-- src/input/subtitles.cpp | 133 ++-------------------------------------- src/input/subtitles.h | 26 +++++--- 4 files changed, 45 insertions(+), 143 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52ba279f5..bc99ffb25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2004-09-17 Moritz Bunkus + * mkvmerge: bug fix: mkvmerge will show a nice warning if the + entries in a SRT have non-continuous timestamps. It'll also sort + the entries by their start timestamp instead of throwing the + generic "timecode < previous timecode" warning. + * mmg: bug fix: The 'Matroska file analysis' window that occurs when reading chapters from a Matroska file did not disappear if it was minimized when the process finished. diff --git a/src/input/r_srt.cpp b/src/input/r_srt.cpp index 325b19591..530a3859d 100644 --- a/src/input/r_srt.cpp +++ b/src/input/r_srt.cpp @@ -105,15 +105,17 @@ srt_reader_c::create_packetizer(int64_t) { int srt_reader_c::read(generic_packetizer_c *, bool) { - int64_t start, end; + int64_t start, end, previous_start; char *chunk; subtitles_c subs; string s, subtitles; int state, i, line_number; - bool non_number_found; + bool non_number_found, timecode_warning_printed; start = 0; end = 0; + previous_start = 0; + timecode_warning_printed = false; state = STATE_INITIAL; line_number = 0; subtitles = ""; @@ -137,8 +139,8 @@ srt_reader_c::read(generic_packetizer_c *, non_number_found = false; for (i = 0; i < s.length(); i++) if (!isdigit(s[i])) { - mxwarn("srt_reader: Error in line %d: expected subtitle number " - "and found some text.\n", line_number); + mxwarn(FMT_FN "Error in line %d: expected subtitle number " + "and found some text.\n", ti->fname, line_number); non_number_found = true; break; } @@ -148,9 +150,9 @@ srt_reader_c::read(generic_packetizer_c *, } else if (state == STATE_TIME) { if ((s.length() < 29) || !issrttimecode(s.c_str())) { - mxwarn("srt_reader: Error in line %d: expected a SRT timecode " + mxwarn(FMT_FN "Error in line %d: expected a SRT timecode " "line but found something else. Aborting this file.\n", - line_number); + ti->fname, line_number); break; } @@ -179,6 +181,15 @@ srt_reader_c::read(generic_packetizer_c *, atol(&chunk[23]) * 1000 + atol(&chunk[26]); end *= 1000000; + if (!timecode_warning_printed && (start < previous_start)) { + mxwarn(FMT_FN "Warning in line %d: The start timecode is smaller " + "than that of the previous entry. All entries from this file " + "will be sorted by their start time.\n", ti->fname, + line_number); + timecode_warning_printed = true; + } + previous_start = start; + safefree(chunk); subtitles = ""; @@ -212,6 +223,7 @@ srt_reader_c::read(generic_packetizer_c *, subs.add(start, end, subtitles.c_str()); } + subs.sort(); subs.process((textsubs_packetizer_c *)PTZR0); PTZR0->flush(); diff --git a/src/input/subtitles.cpp b/src/input/subtitles.cpp index 04bcda574..338c765ce 100644 --- a/src/input/subtitles.cpp +++ b/src/input/subtitles.cpp @@ -22,138 +22,15 @@ #include "common.h" #include "subtitles.h" -subtitles_c::subtitles_c() { - first = NULL; - last = NULL; -} - -subtitles_c::~subtitles_c() { - sub_t *current = first; - - while (current != NULL) { - if (current->subs != NULL) - safefree(current->subs); - last = current; - current = current->next; - safefree(last); - } -} - -void -subtitles_c::add(int64_t nstart, - int64_t nend, - const char *nsubs) { - sub_t *s; - - s = (sub_t *)safemalloc(sizeof(sub_t)); - s->subs = safestrdup(nsubs); - s->start = nstart; - s->end = nend; - s->next = NULL; - - if (last == NULL) { - first = s; - last = s; - } else { - last->next = s; - last = s; - } -} - -int -subtitles_c::check() { - sub_t *current; - int error = 0; - char *c; - - current = first; - while ((current != NULL) && (current->next != NULL)) { - if (current->end > current->next->start) { - if (verbose) { - char short_subs[21]; - - memset(short_subs, 0, 21); - strncpy(short_subs, current->subs, 20); - for (c = short_subs; *c != 0; c++) - if (*c == '\n') - *c = ' '; - mxwarn("subtitles: current entry ends after " - "the next one starts. This end: %02lld:%02lld:%02lld,%03lld" - " next start: %02lld:%02lld:%02lld,%03lld (\"%s\"...)\n", - current->end / (60 * 60 * 1000), - (current->end / (60 * 1000)) % 60, - (current->end / 1000) % 60, - current->end % 1000, - current->next->start / (60 * 60 * 1000), - (current->next->start / (60 * 1000)) % 60, - (current->next->start / 1000) % 60, - current->next->start % 1000, - short_subs); - } - current->end = current->next->start - 1; - } - current = current->next; - } - - current = first; - while (current != NULL) { - if (current->start > current->end) { - error = 1; - if (verbose) { - char short_subs[21]; - - memset(short_subs, 0, 21); - strncpy(short_subs, current->subs, 20); - for (c = short_subs; *c != 0; c++) - if (*c == '\n') - *c = ' '; - mxwarn("subtitles: after fixing the time the " - "current entry begins after it ends. This start: " - "%02lld:%02lld:%02lld,%03lld this end: %02lld:%02lld:" - "%02lld,%03lld (\"%s\"...)\n", - current->start / (60 * 60 * 1000), - (current->start / (60 * 1000)) % 60, - (current->start / 1000) % 60, - current->start % 1000, - current->end / (60 * 60 * 1000), - (current->end / (60 * 1000)) % 60, - (current->end / 1000) % 60, - current->end % 1000, - short_subs); - } - } - current = current->next; - } - - return error; -} - void subtitles_c::process(textsubs_packetizer_c *p) { - sub_t *current; + deque::iterator current; - while ((current = get_next()) != NULL) { - memory_c mem((unsigned char *)current->subs, 0, true); - p->process(mem, current->start, current->end - current->start); - safefree(current); + foreach(current, entries) { + memory_c mem((unsigned char *)(*current).subs.c_str(), 0, false); + p->process(mem, (*current).start, (*current).end - (*current).start); } -} - -sub_t * -subtitles_c::get_next() { - sub_t *current; - - if (first == NULL) - return NULL; - - current = first; - if (first == last) { - first = NULL; - last = NULL; - } else - first = first->next; - - return current; + entries.clear(); } #undef PFX diff --git a/src/input/subtitles.h b/src/input/subtitles.h index 0a94c950c..bb3bce6a7 100644 --- a/src/input/subtitles.h +++ b/src/input/subtitles.h @@ -22,21 +22,29 @@ typedef struct sub_t { int64_t start, end; - char *subs; - sub_t *next; + string subs; + + sub_t(int64_t _start, int64_t _end, const string &_subs): + start(_start), end(_end), subs(_subs) { + } + + bool operator < (const sub_t &cmp) const { + return start < cmp.start; + } } sub_t; class subtitles_c { private: - sub_t *first, *last; -public: - subtitles_c(); - ~subtitles_c(); + deque entries; - void add(int64_t, int64_t, const char *); - int check(); +public: + void add(int64_t start, int64_t end, const char *subs) { + entries.push_back(sub_t(start, end, subs)); + } void process(textsubs_packetizer_c *); - sub_t *get_next(); + void sort() { + std::sort(entries.begin(), entries.end()); + } }; int64_t spu_extract_duration(unsigned char *data, int buf_size,