From accc1d28c857b203ca6f9209ece0563063ead78c Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 15 Apr 2009 16:40:07 +0200 Subject: [PATCH] Do not overwrite the duration for some track types. Subtitle and button tracks must preserve their duration even if an external timecode file is used. Otherwise each subtitle frame's duration is set to the difference between the next frame's timecode and the current frame's timecode. Fix for bug 286. --- ChangeLog | 5 +++++ src/merge/pr_generic.cpp | 3 +++ src/merge/timecode_factory.cpp | 14 +++++++++----- src/merge/timecode_factory.h | 9 ++++++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3894ca10..2d99a9975 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-04-15 Moritz Bunkus + * mkvmerge: bug fix: The duration of subtitle frames was + overwritten with the difference between the next frame's timecode + and the current frame's timecode if a timecode file was used for + that track. Fix for bug 286. + * mmg: bug fix: Removed the option "always use simple blocks" from the preferences dialog as this option was already removed from mkvmerge. Fix for bug 370. diff --git a/src/merge/pr_generic.cpp b/src/merge/pr_generic.cpp index 737a0b3d1..f01072bb7 100644 --- a/src/merge/pr_generic.cpp +++ b/src/merge/pr_generic.cpp @@ -325,6 +325,9 @@ generic_packetizer_c::set_track_type(int type, else if (TFA_AUTOMATIC != tfa_mode) timecode_factory_application_mode = tfa_mode; + + if ((NULL != timecode_factory.get()) && (track_video != type) && (track_audio != type)) + timecode_factory->set_preserve_duration(true); } void diff --git a/src/merge/timecode_factory.cpp b/src/merge/timecode_factory.cpp index 3d337545e..d96b8624d 100644 --- a/src/merge/timecode_factory.cpp +++ b/src/merge/timecode_factory.cpp @@ -155,7 +155,8 @@ timecode_factory_v1_c::parse(mm_io_c &in) { bool timecode_factory_v1_c::get_next(packet_cptr &packet) { packet->assigned_timecode = get_at(m_frameno); - packet->duration = get_at(m_frameno + 1) - packet->assigned_timecode; + if (!m_preserve_duration || (0 >= packet->duration)) + packet->duration = get_at(m_frameno + 1) - packet->assigned_timecode; m_frameno++; if ((m_frameno > m_ranges[m_current_range].end_frame) && (m_current_range < (m_ranges.size() - 1))) @@ -247,18 +248,21 @@ timecode_factory_v2_c::get_next(packet_cptr &packet) { if (m_timecodes.empty()) { packet->assigned_timecode = 0; - packet->duration = 0; + if (!m_preserve_duration || (0 >= packet->duration)) + packet->duration = 0; } else { packet->assigned_timecode = m_timecodes.back(); - packet->duration = m_timecodes.back(); + if (!m_preserve_duration || (0 >= packet->duration)) + packet->duration = m_timecodes.back(); } return false; } packet->assigned_timecode = m_timecodes[m_frameno]; - packet->duration = m_durations[m_frameno]; + if (!m_preserve_duration || (0 >= packet->duration)) + packet->duration = m_durations[m_frameno]; m_frameno++; return false; @@ -364,7 +368,7 @@ timecode_factory_v3_c::get_next(packet_cptr &packet) { packet->assigned_timecode = m_current_offset + m_current_timecode; // If default_fps is 0 then the duration is unchanged, usefull for audio. - if (m_durations[m_current_duration].fps) + if (m_durations[m_current_duration].fps && (!m_preserve_duration || (0 >= packet->duration))) packet->duration = (int64_t)(1000000000.0 / m_durations[m_current_duration].fps); packet->duration /= packet->time_factor; diff --git a/src/merge/timecode_factory.h b/src/merge/timecode_factory.h index 43e7fab48..61e1b3aa7 100644 --- a/src/merge/timecode_factory.h +++ b/src/merge/timecode_factory.h @@ -58,15 +58,18 @@ protected: string m_file_name, m_source_name; int64_t m_tid; int m_version; + bool m_preserve_duration; public: timecode_factory_c(const string &file_name, const string &source_name, - int64_t tid, int version) + int64_t tid, + int version) : m_file_name(file_name) , m_source_name(source_name) , m_tid(tid) , m_version(version) + , m_preserve_duration(false) { } virtual ~timecode_factory_c() { @@ -87,6 +90,10 @@ public: return false; } + virtual void set_preserve_duration(bool preserve_duration) { + m_preserve_duration = preserve_duration; + } + static timecode_factory_cptr create(const string &file_name, const string &source_name, int64_t tid); };