diff --git a/ChangeLog b/ChangeLog index 340d8dbd4..8902e1fbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2008-11-03 Moritz Bunkus + * mkvmerge: bug fix: Changed the way mkvmerge calculates the + timecodes when appending files. Should result in better + audio/video synchronization. + * mkvmerge: new feature: Added support for reading SRT and SSA/ASS subtitles from AVI files (fix for bug 64). diff --git a/src/merge/mkvmerge.cpp b/src/merge/mkvmerge.cpp index 6421760e0..891599f3e 100644 --- a/src/merge/mkvmerge.cpp +++ b/src/merge/mkvmerge.cpp @@ -146,6 +146,9 @@ set_usage() { " that controls which track of a file is\n" " appended to another track of the preceding\n" " file.\n" + " --append-mode \n" + " Selects how mkvmerge calculates timecodes when\n" + " appending files.\n" " --timecode-scale Force the timecode scale factor to n.\n" "\n File splitting and linking (more global options):\n" " --split \n" @@ -1207,6 +1210,19 @@ parse_arg_append_to(const string &s, } } +static void +parse_arg_append_mode(const string &s, + track_info_c &ti) { + if ((s == "track") || (s == "track-based")) + g_append_mode = APPEND_MODE_TRACK_BASED; + + else if ((s == "file") || (s == "file-based")) + g_append_mode = APPEND_MODE_FILE_BASED; + + else + mxerror(boost::format(Y("'%1%' is not a valid append mode in '--append-mode %1%'.\n")) % s); +} + /** \brief Parse the argument for \c --default-duration The argument must be a tuple consisting of a track ID and the default @@ -1962,6 +1978,13 @@ parse_args(vector args) { parse_arg_append_to(next_arg, *ti); sit++; + } else if (this_arg == "--append-mode") { + if (no_next_arg) + mxerror(Y("'--append-mode' lacks its argument.\n")); + + parse_arg_append_mode(next_arg, *ti); + sit++; + } else if (this_arg == "--default-duration") { if (no_next_arg) mxerror(Y("'--default-duration' lacks its argument.\n")); diff --git a/src/merge/output_control.cpp b/src/merge/output_control.cpp index fe90180f2..545f97418 100644 --- a/src/merge/output_control.cpp +++ b/src/merge/output_control.cpp @@ -175,6 +175,8 @@ int g_file_num = 1; int g_split_max_num_files = 65535; +append_mode_e g_append_mode = APPEND_MODE_FILE_BASED; + string g_default_language = "und"; bitvalue_cptr g_seguid_link_previous; @@ -1519,8 +1521,9 @@ append_track(packetizer_t &ptzr, // chapters then we have to suck the previous file dry. See below for the // reason (short version: we need all max_timecode_seen values). if ( !dst_file.done - && ( ((*gptzr)->get_track_type() == track_subtitle) - || (NULL != src_file.reader->chapters))) { + && ( (APPEND_MODE_FILE_BASED == g_append_mode) + || ((*gptzr)->get_track_type() == track_subtitle) + || (NULL != src_file.reader->chapters))) { dst_file.reader->read_all(); dst_file.num_unfinished_packetizers = 0; dst_file.old_num_unfinished_packetizers = 0; @@ -1588,7 +1591,11 @@ append_track(packetizer_t &ptzr, // But then again I don't expect that people will try to concatenate such // files if they've been split before. int64_t timecode_adjustment = dst_file.reader->max_timecode_seen; - if (ptzr.deferred && (NULL != deferred_file)) + if (APPEND_MODE_FILE_BASED == g_append_mode) + // Intentionally left empty. + ; + + else if (ptzr.deferred && (NULL != deferred_file)) timecode_adjustment = src_file.deferred_max_timecode_seen; else if ( (track_subtitle == ptzr.packetizer->get_track_type()) @@ -1617,13 +1624,15 @@ append_track(packetizer_t &ptzr, } } - if (ptzr.packetizer->get_track_type() == track_subtitle) { - mxverb(2, boost::format(Y("append_track: new timecode_adjustment for subtitle track: %1% for %2%\n")) % timecode_adjustment % ptzr.packetizer->ti.id); + if ((APPEND_MODE_FILE_BASED == g_append_mode) || (ptzr.packetizer->get_track_type() == track_subtitle)) { + mxverb(2, boost::format(Y("append_track: new timecode_adjustment for append_mode == FILE_BASED or subtitle track: %1% for %2%\n")) + % format_timecode(timecode_adjustment) % ptzr.packetizer->ti.id); // The actual connection. ptzr.packetizer->connect(old_packetizer, timecode_adjustment); } else { - mxverb(2, boost::format(Y("append_track: new timecode_adjustment for NON subtitle track: %1% for %2%\n")) % timecode_adjustment % ptzr.packetizer->ti.id); + mxverb(2, boost::format(Y("append_track: new timecode_adjustment for append_mode == TRACK_BASED and NON subtitle track: %1% for %2%\n")) + % format_timecode(timecode_adjustment) % ptzr.packetizer->ti.id); // The actual connection. ptzr.packetizer->connect(old_packetizer); } diff --git a/src/merge/output_control.h b/src/merge/output_control.h index 07f0259f5..242b988e6 100644 --- a/src/merge/output_control.h +++ b/src/merge/output_control.h @@ -125,6 +125,11 @@ enum timecode_scale_mode_e { TIMECODE_SCALE_MODE_AUTO }; +enum append_mode_e { + APPEND_MODE_TRACK_BASED, + APPEND_MODE_FILE_BASED, +}; + class family_uids_c: public vector { public: bool add_family_uid(const KaxSegmentFamily &family); @@ -187,6 +192,8 @@ extern int g_default_tracks[3], g_default_tracks_priority[3]; extern bool g_splitting; extern int g_split_max_num_files; +extern append_mode_e g_append_mode; + void get_file_type(filelist_t &file); void create_readers();