1 /*
2 mkvmerge -- utility for splicing together matroska files
3 from component media subtypes
4
5 Distributed under the GPL v2
6 see the file COPYING for details
7 or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8
9 definition of functions helping dealing with tags
10
11 Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13
14 #pragma once
15
16 #include "common/common_pch.h"
17
18 #include "common/bcp47.h"
19 #include "common/ebml.h"
20 #include "common/strings/utf8.h"
21 #include "common/tags/target_type.h"
22
23 namespace libmatroska {
24 class KaxTags;
25 class KaxTag;
26 class KaxTagSimple;
27 class KaxChapters;
28 }
29
30 namespace libebml {
31 class EbmlElement;
32 class EbmlMaster;
33 }
34
35 namespace mtx::tags {
36
37 void remove_track_uid_targets(libebml::EbmlMaster *tag);
38 void remove_elements_unsupported_by_webm(libebml::EbmlMaster &master);
39 bool remove_track_statistics(libmatroska::KaxTags *tags, std::optional<uint64_t> track_uid);
40
41 libmatroska::KaxTags *select_for_chapters(libmatroska::KaxTags &tags, libmatroska::KaxChapters &chapters);
42
43 libmatroska::KaxTagSimple &find_simple(const std::string &name, libebml::EbmlMaster &m);
44 libmatroska::KaxTagSimple &find_simple(const UTFstring &name, libebml::EbmlMaster &m);
45 std::string get_simple_value(const std::string &name, libebml::EbmlMaster &m);
46 int64_t get_tuid(const libmatroska::KaxTag &tag);
47 int64_t get_cuid(const libmatroska::KaxTag &tag);
48
49 std::string get_simple_name(const libmatroska::KaxTagSimple &tag);
50 std::string get_simple_value(const libmatroska::KaxTagSimple &tag);
51
52 void set_simple_name(libmatroska::KaxTagSimple &tag, const std::string &name);
53 void set_simple_value(libmatroska::KaxTagSimple &tag, const std::string &value);
54 void set_simple(libmatroska::KaxTagSimple &tag, const std::string &name, const std::string &value);
55 void set_simple(libmatroska::KaxTag &tag, std::string const &name, std::string const &value, mtx::bcp47::language_c const &language = {});
56 void set_target_type(libmatroska::KaxTag &tag, target_type_e target_type_value, std::string const &target_type);
57
58 int count_simple(libebml::EbmlMaster &master);
59
60 void convert_old(libmatroska::KaxTags &tags);
61
62 template<typename T>
63 bool
remove_simple_tags_for(libmatroska::KaxTags & tags,std::optional<uint64_t> id,std::string const & name_to_remove)64 remove_simple_tags_for(libmatroska::KaxTags &tags,
65 std::optional<uint64_t> id,
66 std::string const &name_to_remove) {
67 auto removed_something = false;
68 auto tag_idx = 0u;
69 while (tag_idx < tags.ListSize()) {
70 auto tag = dynamic_cast<libmatroska::KaxTag *>(tags[tag_idx]);
71 if (!tag) {
72 ++tag_idx;
73 continue;
74 }
75
76 if (id) {
77 auto targets = FindChild<libmatroska::KaxTagTargets>(*tag);
78 auto actual_id = targets ? std::optional<uint64_t>{ FindChildValue<T>(*targets, 0llu) } : std::optional<uint64_t>{ std::nullopt };
79
80 if (!targets || !actual_id || (*actual_id != *id)) {
81 ++tag_idx;
82 continue;
83 }
84 }
85
86 auto simple_idx = 0u;
87 while (simple_idx < tag->ListSize()) {
88 auto simple = dynamic_cast<libmatroska::KaxTagSimple *>((*tag)[simple_idx]);
89 if (!simple || (to_utf8(get_simple_name(*simple)) != name_to_remove))
90 ++simple_idx;
91
92 else {
93 tag->Remove(simple_idx);
94 delete simple;
95 removed_something = true;
96 }
97 }
98
99 if (0 < count_simple(*tag))
100 ++tag_idx;
101
102 else {
103 tags.Remove(tag_idx);
104 delete tag;
105 removed_something = true;
106 }
107 }
108
109 return removed_something;
110 }
111
112 std::shared_ptr<libmatroska::KaxTags> merge(std::shared_ptr<libmatroska::KaxTags> const &t1, std::shared_ptr<libmatroska::KaxTags> const &t2);
113
114 }
115