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    retrieves and displays information about a Matroska file
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #pragma once
15 
16 #include "common/common_pch.h"
17 
18 #include <matroska/KaxCluster.h>
19 
20 namespace mtx {
21 
22 namespace kax_info {
23 
24 class exception: public std::runtime_error {
25 public:
exception(std::string const & error)26   exception(std::string const &error)
27     : std::runtime_error{error}
28   {
29   }
30 };
31 
32 struct track_t;
33 class private_c;
34 
35 }
36 
37 class kax_info_c {
38 protected:
39   MTX_DECLARE_PRIVATE(kax_info::private_c)
40 
41   std::unique_ptr<kax_info::private_c> const p_ptr;
42 
43   explicit kax_info_c(kax_info::private_c &p);
44 
45 public:
46   enum class result_e {
47     succeeded,
48     failed,
49     aborted,
50   };
51 
52 public:
53   kax_info_c();
54   virtual ~kax_info_c();
55 
56   void set_use_gui(bool enable);
57   void set_calc_checksums(bool enable);
58   void set_continue_at_cluster(bool enable);
59   void set_show_all_elements(bool enable);
60   void set_show_summary(bool enable);
61   void set_show_hexdump(bool enable);
62   void set_show_positions(bool enable);
63   void set_show_size(bool enable);
64   void set_show_track_info(bool enable);
65   void set_hex_positions(bool enable);
66   void set_hexdump_max_size(int max_size);
67   void set_destination_file_name(std::string const &file_name);
68   void set_source_file(mm_io_cptr const &file);
69   void set_source_file_name(std::string const &file_name);
70   void set_retain_elements(bool enable);
71 
72   void reset();
73   virtual result_e open_and_process_file(std::string const &file_name);
74   virtual result_e open_and_process_file();
75   virtual result_e process_file();
76   void abort();
77 
78   std::string create_element_text(std::string const &text, std::optional<int64_t> position, std::optional<int64_t> size, std::optional<int64_t> data_size);
79   std::string create_unknown_element_text(libebml::EbmlElement &e);
80   std::string create_known_element_but_not_allowed_here_text(libebml::EbmlElement &e);
81   std::string create_hexdump(unsigned char const *buf, int size);
82   std::string create_codec_dependent_private_info(libmatroska::KaxCodecPrivate &c_priv, char track_type, std::string const &codec_id);
83   std::string create_text_representation(libebml::EbmlElement &e);
84   std::string format_binary(libebml::EbmlBinary &bin);
85   std::string format_binary_as_hex(libebml::EbmlElement &e);
86   std::string format_element_size(libebml::EbmlElement &e);
87   std::string format_element_value(libebml::EbmlElement &e);
88   std::string format_element_value_default(libebml::EbmlElement &e);
89   std::string format_unsigned_integer_as_timestamp(libebml::EbmlElement &e);
90   std::string format_unsigned_integer_as_scaled_timestamp(libebml::EbmlElement &e);
91   std::string format_signed_integer_as_timestamp(libebml::EbmlElement &e);
92   std::string format_signed_integer_as_scaled_timestamp(libebml::EbmlElement &e);
93   std::string format_block(libebml::EbmlElement &e);
94   std::string format_simple_block(libebml::EbmlElement &e);
95 
96   bool pre_block_group(libebml::EbmlElement &e);
97   bool pre_block(libebml::EbmlElement &e);
98   bool pre_simple_block(libebml::EbmlElement &e);
99 
100   void post_block_group(libebml::EbmlElement &e);
101   void post_block(libebml::EbmlElement &e);
102   void post_simple_block(libebml::EbmlElement &e);
103 
104   bool run_generic_pre_processors(libebml::EbmlElement &e);
105   void run_generic_post_processors(libebml::EbmlElement &e);
106 
107   virtual void ui_show_error(std::string const &error);
108   virtual void ui_show_element_info(int level, std::string const &text, std::optional<int64_t> position, std::optional<int64_t> size, std::optional<int64_t> data_size);
109   virtual void ui_show_element(libebml::EbmlElement &e);
110   virtual void ui_show_progress(int percentage, std::string const &text);
111 
112   void discard_retained_element(libebml::EbmlElement &element_to_remove);
113 
114 protected:
115   void init();
116   void init_custom_element_value_formatters_and_processors();
117 
118   void show_element(libebml::EbmlElement *l, int level, std::string const &info, std::optional<int64_t> position = {}, std::optional<int64_t> size = {});
119   void show_frame_summary(libebml::EbmlElement &e);
120 
121   void add_track(std::shared_ptr<kax_info::track_t> const &t);
122   kax_info::track_t *find_track(int tnum);
123 
124   void read_master(libebml::EbmlMaster *m, libebml::EbmlSemanticContext const &ctx, int &upper_lvl_el, libebml::EbmlElement *&l2);
125 
126   void handle_block_group(libebml::EbmlElement *&l2, libmatroska::KaxCluster *&cluster);
127   void handle_elements_generic(libebml::EbmlElement &e);
128   result_e handle_segment(libebml::EbmlElement *l0);
129 
130   void display_track_info();
131 
132   void retain_element(std::shared_ptr<libebml::EbmlElement> const &element);
133 
134 public:
135   static std::string format_ebml_id_as_hex(libebml::EbmlElement &e);
136   static std::string format_ebml_id_as_hex(libebml::EbmlId const &id);
137   static std::string format_ebml_id_as_hex(uint32_t id);
138 };
139 using kax_info_cptr = std::shared_ptr<kax_info_c>;
140 
141 }
142