diff --git a/mkvmuxer.cpp b/mkvmuxer.cpp index 27ea7de..35295d0 100644 --- a/mkvmuxer.cpp +++ b/mkvmuxer.cpp @@ -1461,6 +1461,7 @@ Segment::Segment() cluster_list_capacity_(0), cluster_list_size_(0), cues_track_(0), + force_new_cluster_(false), frames_(NULL), frames_capacity_(0), frames_size_(0), @@ -1695,7 +1696,7 @@ bool Segment::AddFrame(const uint8* frame, // If the segment has a video track hold onto audio frames to make sure the // audio that is associated with the start time of a video key-frame is // muxed into the same cluster. - if (has_video_ && tracks_.TrackIsAudio(track_number)) { + if (has_video_ && tracks_.TrackIsAudio(track_number) && !force_new_cluster_) { Frame* const new_frame = new Frame(); if (!new_frame->Init(frame, length)) return false; @@ -1875,6 +1876,10 @@ bool Segment::CuesTrack(uint64 track_number) { return true; } +void Segment::ForceNewClusterOnNextFrame() { + force_new_cluster_ = true; +} + Track* Segment::GetTrackByNumber(uint64 track_number) const { return tracks_.GetTrackByNumber(track_number); } @@ -1938,6 +1943,9 @@ bool Segment::WriteSegmentHeader() { int Segment::TestFrame(uint64 track_number, uint64 frame_timestamp_ns, bool is_key) const { + if (force_new_cluster_) + return 1; + // If no clusters have been created yet, then create a new cluster // and write this frame immediately, in the new cluster. This path // should only be followed once, the first time we attempt to write @@ -2090,9 +2098,12 @@ bool Segment::DoNewClusterProcessing(uint64 track_number, if (result < 0) // error return false; - // A non-zero result means create a new cluster. - if (result > 0 && !MakeNewCluster(frame_timestamp_ns)) - return false; + // Always set force_new_cluster_ to false after TestFrame. + force_new_cluster_ = false; + + // A non-zero result means create a new cluster. + if (result > 0 && !MakeNewCluster(frame_timestamp_ns)) + return false; // Write queued (audio) frames. const int frame_count = WriteFramesAll(); diff --git a/mkvmuxer.hpp b/mkvmuxer.hpp index 537361e..4c57d77 100644 --- a/mkvmuxer.hpp +++ b/mkvmuxer.hpp @@ -751,6 +751,10 @@ class Segment { // returned by the Add track functions. bool CuesTrack(uint64 track_number); + // This will force the muxer to create a new Cluster when the next frame is + // added. + void ForceNewClusterOnNextFrame(); + // Writes out any frames that have not been written out. Finalizes the last // cluster. May update the size and duration of the segment. May output the // Cues element. May finalize the SeekHead element. Returns true on success. @@ -889,6 +893,9 @@ class Segment { // Track number that is associated with the cues element for this segment. uint64 cues_track_; + // Tells the muxer to force a new cluster on the next Block. + bool force_new_cluster_; + // List of stored audio frames. These variables are used to store frames so // the muxer can follow the guideline "Audio blocks that contain the video // key frame's timecode should be in the same cluster as the video key frame diff --git a/mkvmuxerutil.cpp b/mkvmuxerutil.cpp index fddcc17..a71a7ca 100644 --- a/mkvmuxerutil.cpp +++ b/mkvmuxerutil.cpp @@ -497,7 +497,7 @@ uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) { void GetVersion(int32* major, int32* minor, int32* build, int32* revision) { *major = 0; *minor = 2; - *build = 0; + *build = 1; *revision = 0; }