Matroska reader: fix tag chapter UID targets when regenerating chapter UIDs

Fixes #2804.
This commit is contained in:
Moritz Bunkus 2020-05-01 08:46:38 +02:00
parent a8a608b103
commit 80b8135bd5
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
6 changed files with 31 additions and 9 deletions

View File

@ -39,6 +39,9 @@
frame). Fixes #2790.
* mkvmerge: MP4 reader: fixed a crash that could potentially happen while
trying to identify H.265/HEVC tracks.
* mkvmerge: when regenerating UIDs for chapters read from Matroska files
mkvmerge will now fix referencing tag chapter UID targets to have the same
values. Fixes #2804.
# Version 45.0.0 "Heaven in Pennies" 2020-04-04

View File

@ -1063,8 +1063,9 @@ align_uids(KaxChapters &reference,
}
}
void
regenerate_uids(EbmlMaster &master) {
static void
regenerate_uids_worker(EbmlMaster &master,
std::unordered_map<uint64_t, uint64_t> &new_chapter_uids) {
for (int idx = 0, end = master.ListSize(); end > idx; ++idx) {
auto element = master[idx];
auto edition_uid = dynamic_cast<KaxEditionUID *>(element);
@ -1077,16 +1078,28 @@ regenerate_uids(EbmlMaster &master) {
auto chapter_uid = dynamic_cast<KaxChapterUID *>(element);
if (chapter_uid) {
chapter_uid->SetValue(create_unique_number(UNIQUE_CHAPTER_IDS));
new_chapter_uids[chapter_uid->GetValue()] = create_unique_number(UNIQUE_CHAPTER_IDS);
chapter_uid->SetValue(new_chapter_uids[chapter_uid->GetValue()]);
continue;
}
auto sub_master = dynamic_cast<EbmlMaster *>(master[idx]);
if (sub_master)
regenerate_uids(*sub_master);
regenerate_uids_worker(*sub_master, new_chapter_uids);
}
}
void
regenerate_uids(EbmlMaster &master,
EbmlMaster *tags) {
std::unordered_map<uint64_t, uint64_t> new_chapter_uids;
regenerate_uids_worker(master, new_chapter_uids);
if (tags)
change_values<KaxTagChapterUID>(*tags, new_chapter_uids);
}
std::string
format_name_template(std::string const &name_template,
int chapter_number,

View File

@ -88,7 +88,7 @@ void move_by_edition(libmatroska::KaxChapters &dst, libmatroska::KaxChapters &sr
void adjust_timestamps(libebml::EbmlMaster &master, int64_t offset, int64_t numerator = 1, int64_t denominator = 1);
void merge_entries(libebml::EbmlMaster &master);
int count_atoms(libebml::EbmlMaster &master);
void regenerate_uids(libebml::EbmlMaster &master);
void regenerate_uids(libebml::EbmlMaster &master, libebml::EbmlMaster *tags = nullptr);
void align_uids(libmatroska::KaxChapters *chapters);
void align_uids(libmatroska::KaxChapters &reference, libmatroska::KaxChapters &modify);

View File

@ -892,7 +892,7 @@ kax_reader_c::handle_chapters(mm_io_c *io,
delete element_found;
if (m_regenerate_chapter_uids)
mtx::chapters::regenerate_uids(*tmp_chapters);
mtx::chapters::regenerate_uids(*tmp_chapters, m_tags.get());
if (!m_chapters)
m_chapters = mtx::chapters::kax_cptr{new KaxChapters};
@ -1470,13 +1470,13 @@ kax_reader_c::read_deferred_level1_elements(KaxSegment &segment) {
for (auto position : m_deferred_l1_positions[dl1t_attachments])
handle_attachments(m_in.get(), &segment, position);
for (auto position : m_deferred_l1_positions[dl1t_tags])
handle_tags(m_in.get(), &segment, position);
if (!m_ti.m_no_chapters)
for (auto position : m_deferred_l1_positions[dl1t_chapters])
handle_chapters(m_in.get(), &segment, position);
for (auto position : m_deferred_l1_positions[dl1t_tags])
handle_tags(m_in.get(), &segment, position);
handle_track_statistics_tags();
if (!m_ti.m_no_global_tags)

View File

@ -539,3 +539,4 @@ T_690mp4_single_video_frame_duration:ff234c76e7626f78aded30b3c2ad6669:passed:202
T_691hevc_in_mp4_no_ctts_atom_no_sei_nalus:c387b9839708d0e9e8fe1595f42b873d:passed:20200412-163012:0.114639239
T_692splitting_chapter_name_in_file_name:f90456eacc7f481da6c37f3e0fc897ff:passed:20200425-145924:0.063961157
T_693keeping_source_id_tags:d3e6334130baa038d7108fe94bc4e7fe:passed:20200426-123650:0.067781165
T_694fix_tags_when_regenerating_chapter_uids:6a126f4bc74051802aac90369addec15:passed:20200501-084512:0.046681713

View File

@ -0,0 +1,5 @@
#!/usr/bin/ruby -w
# T_694fix_tags_when_regenerating_chapter_uids
describe "mkvmerge / regenerate chapter UIDs but fix tag chapter UIDs in the process"
test_merge "data/mkv/chapters_tags_max_size_field_size.mkv"