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    class definition for the generic reader and packetizer
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #pragma once
15 
16 #include "common/common_pch.h"
17 
18 #include <unordered_set>
19 
20 #include "common/file_types.h"
21 #include "common/chapters/chapters.h"
22 #include "common/math_fwd.h"
23 #include "common/translation.h"
24 #include "merge/file_status.h"
25 #include "merge/id_result.h"
26 #include "merge/packet.h"
27 #include "merge/probe_range_info.h"
28 #include "merge/timestamp_factory.h"
29 #include "merge/track_info.h"
30 #include "merge/webm.h"
31 
32 class generic_packetizer_c;
33 
34 constexpr auto DEFTRACK_TYPE_AUDIO = 0;
35 constexpr auto DEFTRACK_TYPE_VIDEO = 1;
36 constexpr auto DEFTRACK_TYPE_SUBS  = 2;
37 
38 class generic_reader_c {
39 public:
40   track_info_c m_ti;
41   mm_io_cptr m_in;
42   uint64_t m_size{};
43 
44   std::vector<std::shared_ptr<generic_packetizer_c>> m_reader_packetizers;
45   generic_packetizer_c *m_ptzr_first_packet{};
46   std::vector<int64_t> m_available_track_ids, m_used_track_ids;
47   std::unordered_set<int64_t> m_requested_track_ids;
48   int64_t m_max_timestamp_seen{};
49   mtx::chapters::kax_cptr m_chapters;
50   bool m_appending{};
51   int m_num_video_tracks{}, m_num_audio_tracks{}, m_num_subtitle_tracks{};
52 
53   int64_t m_reference_timestamp_tolerance{};
54 
55   probe_range_info_t m_probe_range_info{};
56 
57 protected:
58   id_result_t m_id_results_container;
59   std::vector<id_result_t> m_id_results_tracks, m_id_results_attachments, m_id_results_chapters, m_id_results_tags;
60 
61   timestamp_c m_restricted_timestamps_min, m_restricted_timestamps_max;
62 
63 public:
64   virtual ~generic_reader_c() = default;
65 
66   virtual mtx::file_type_e get_format_type() const = 0;
67   virtual translatable_string_c get_format_name() const;
is_providing_timestamps()68   virtual bool is_providing_timestamps() const {
69     return true;
70   }
71 
72   virtual void set_timestamp_restrictions(timestamp_c const &min, timestamp_c const &max);
73   virtual timestamp_c const &get_timestamp_restriction_min() const;
74   virtual timestamp_c const &get_timestamp_restriction_max() const;
75 
76   virtual void set_file_to_read(mm_io_cptr const &io);
77   virtual void set_probe_range_info(probe_range_info_t const &info);
78   virtual void set_track_info(track_info_c const &info);
79   virtual void read_headers() = 0;
80   virtual file_status_e read_next(generic_packetizer_c *packetizer, bool force = false);
81   virtual file_status_e read(generic_packetizer_c *packetizer, bool force = false) = 0;
82   virtual void read_all();
83   virtual int64_t get_progress();
84   virtual int64_t get_maximum_progress();
85   virtual void set_headers();
86   virtual void set_headers_for_track(int64_t tid);
87   virtual void identify() = 0;
88   virtual void create_packetizer(int64_t tid) = 0;
create_packetizers()89   virtual void create_packetizers() {
90     create_packetizer(0);
91   }
92 
93   virtual int add_packetizer(generic_packetizer_c *packetizer);
94   virtual size_t get_num_packetizers() const;
95   virtual generic_packetizer_c *find_packetizer_by_id(int64_t id) const;
96   virtual void set_timestamp_offset(int64_t offset);
97 
98   virtual void check_track_ids_and_packetizers();
99   virtual void add_requested_track_id(int64_t id);
100   virtual void add_available_track_id(int64_t id);
101   virtual void add_available_track_ids();
102   virtual void add_available_track_id_range(int64_t start, int64_t end);
add_available_track_id_range(int64_t num)103   virtual void add_available_track_id_range(int64_t num) {
104     add_available_track_id_range(0, num - 1);
105   }
106 
get_file_size()107   virtual int64_t get_file_size() {
108     return m_in->get_size();
109   }
110   virtual int64_t get_queued_bytes() const;
is_simple_subtitle_container()111   virtual bool is_simple_subtitle_container() {
112     return false;
113   }
114 
115   virtual file_status_e flush_packetizer(int num);
116   virtual file_status_e flush_packetizer(generic_packetizer_c *packetizer);
117   virtual file_status_e flush_packetizers();
118 
119   virtual attach_mode_e attachment_requested(int64_t id);
120 
121   virtual void display_identification_results();
122 
123   virtual int64_t calculate_probe_range(int64_t file_size, int64_t fixed_minimum) const;
124   virtual bool probe_file() = 0;
125 
126   virtual void show_packetizer_info(int64_t track_id, generic_packetizer_c const &packetizer);
127 
128 public:
129   static void set_probe_range_percentage(mtx_mp_rational_t const &probe_range_percentage);
130 
131 protected:
132   virtual void show_demuxer_info();
133 
134   virtual bool demuxing_requested(char type, int64_t id, mtx::bcp47::language_c const &language = {}) const;
135 
136   virtual void id_result_container(mtx::id::verbose_info_t const &verbose_info = mtx::id::verbose_info_t{});
137   virtual void id_result_track(int64_t track_id, const std::string &type, const std::string &info, mtx::id::verbose_info_t const &verbose_info = mtx::id::verbose_info_t{});
138   virtual void id_result_attachment(int64_t attachment_id, std::string const &type, int size, std::string const &file_name = {}, std::string const &description = {},
139                                     std::optional<uint64_t> id = std::optional<uint64_t>{});
140   virtual void id_result_chapters(int num_entries);
141   virtual void id_result_tags(int64_t track_id, int num_entries);
142 
143   virtual mm_io_c *get_underlying_input(mm_io_c *actual_in = nullptr) const;
144 
145   virtual void display_identification_results_as_json();
146   virtual void display_identification_results_as_text();
147 
148   virtual void add_track_tags_to_identification(libmatroska::KaxTags const &tags, mtx::id::info_c &info);
149 
150   virtual generic_packetizer_c &ptzr(int64_t track_idx);
151 };
152