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 track info parameters class
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/compression.h"
20 #include "common/math.h"
21 #include "common/option_with_source.h"
22 #include "common/stereo_mode.h"
23 #include "merge/item_selector.h"
24 
25 namespace libmatroska {
26 class KaxTags;
27 }
28 
29 // CUE_STRATEGY_* control the creation of cue entries for a track.
30 // UNSPECIFIED: is used for command line parsing.
31 // NONE:        don't create any cue entries.
32 // IFRAMES:     Create cue entries for all I frames.
33 // ALL:         Create cue entries for all frames (not really useful).
34 // SPARSE:      Create cue entries for I frames if no video track exists, but
35 //              create at most one cue entries every two seconds. Used for
36 //              audio only files.
37 enum cue_strategy_e {
38   CUE_STRATEGY_UNSPECIFIED = -1,
39   CUE_STRATEGY_NONE,
40   CUE_STRATEGY_IFRAMES,
41   CUE_STRATEGY_ALL,
42   CUE_STRATEGY_SPARSE
43 };
44 
45 struct timestamp_sync_t {
46   int64_t displacement{};
47   mtx_mp_rational_t factor{1, 1};
48 };
49 
50 struct display_properties_t {
51   double aspect_ratio;
52   bool ar_factor;
53   int width, height;
54 
display_properties_tdisplay_properties_t55   display_properties_t()
56   : aspect_ratio(0)
57   , ar_factor(false)
58   , width(0)
59   , height(0)
60   {
61   }
62 };
63 
64 struct pixel_crop_t {
65   int left, top, right, bottom;
66 
pixel_crop_tpixel_crop_t67   pixel_crop_t()
68   : left{}
69   , top{}
70   , right{}
71   , bottom{}
72   {
73   }
74 
pixel_crop_tpixel_crop_t75   pixel_crop_t(int p_left, int p_top, int p_right, int p_bottom)
76   : left{p_left}
77   , top{p_top}
78   , right{p_right}
79   , bottom{p_bottom}
80   {
81   }
82 };
83 
84 struct chroma_subsample_t {
85   int hori, vert;
86 
chroma_subsample_tchroma_subsample_t87   chroma_subsample_t()
88   : hori{-1}
89   , vert{-1}
90   {
91   }
chroma_subsample_tchroma_subsample_t92   chroma_subsample_t(int p_hori, int p_vert)
93   : hori{p_hori}
94   , vert{p_vert}
95   {
96   }
chroma_subsample_tchroma_subsample_t97   chroma_subsample_t(std::vector<int> data)
98   : hori{data[0]}
99   , vert{data[1]}
100   {
101   }
102   static int const num_properties = 2;
103 };
104 
105 struct cb_subsample_t {
106   int hori, vert;
107 
cb_subsample_tcb_subsample_t108   cb_subsample_t()
109   : hori{-1}
110   , vert{-1}
111   {
112   }
cb_subsample_tcb_subsample_t113   cb_subsample_t(int p_hori, int p_vert)
114   : hori{p_hori}
115   , vert{p_vert}
116   {
117   }
cb_subsample_tcb_subsample_t118   cb_subsample_t(std::vector<int> data)
119   : hori{data[0]}
120   , vert{data[1]}
121   {
122   }
123   static int const num_properties = 2;
124 };
125 
126 
127 struct chroma_siting_t {
128   int hori, vert;
129 
chroma_siting_tchroma_siting_t130   chroma_siting_t()
131   : hori{-1}
132   , vert{-1}
133   {
134   }
chroma_siting_tchroma_siting_t135   chroma_siting_t(int p_hori, int p_vert)
136   : hori{p_hori}
137   , vert{p_vert}
138   {
139   }
chroma_siting_tchroma_siting_t140   chroma_siting_t(std::vector<int> data)
141   : hori{data[0]}
142   , vert{data[1]}
143   {
144   }
145   static int const num_properties = 2;
146 };
147 
148 struct chroma_coordinates_t {
149   double red_x, red_y, green_x, green_y, blue_x, blue_y;
150 
chroma_coordinates_tchroma_coordinates_t151   chroma_coordinates_t()
152   : red_x{-1.0}
153   , red_y{-1.0}
154   , green_x{-1.0}
155   , green_y{-1.0}
156   , blue_x{-1.0}
157   , blue_y{-1.0}
158   {
159   }
chroma_coordinates_tchroma_coordinates_t160   chroma_coordinates_t(double p_red_x,   double p_red_y,
161                        double p_green_x, double p_green_y,
162                        double p_blue_x,  double p_blue_y)
163   : red_x{p_red_x}
164   , red_y{p_red_y}
165   , green_x{p_green_x}
166   , green_y{p_green_y}
167   , blue_x{p_blue_x}
168   , blue_y{p_blue_y}
169   {
170   }
chroma_coordinates_tchroma_coordinates_t171   chroma_coordinates_t(std::vector<double> data)
172   : red_x{data[0]}
173   , red_y{data[1]}
174   , green_x{data[2]}
175   , green_y{data[3]}
176   , blue_x{data[4]}
177   , blue_y{data[5]}
178   {
179   }
180   static int const num_properties = 6;
181 };
182 
183 struct white_colour_coordinates_t {
184   double x, y;
185 
white_colour_coordinates_twhite_colour_coordinates_t186   white_colour_coordinates_t()
187   : x{-1.0}
188   , y{-1.0}
189   {
190   }
white_colour_coordinates_twhite_colour_coordinates_t191   white_colour_coordinates_t(double p_x, double p_y)
192   : x{p_x}
193   , y{p_y}
194   {
195   }
white_colour_coordinates_twhite_colour_coordinates_t196   white_colour_coordinates_t(std::vector<double> data)
197   : x{data[0]}
198   , y{data[1]}
199   {
200   }
201   static int const num_properties = 2;
202 };
203 
204 enum attach_mode_e {
205   ATTACH_MODE_SKIP,
206   ATTACH_MODE_TO_FIRST_FILE,
207   ATTACH_MODE_TO_ALL_FILES,
208 };
209 
210 class track_info_c {
211 protected:
212   bool m_initialized;
213 
214 public:
215   enum special_track_id_e {
216     all_tracks_id    = -1,
217     chapter_track_id = -2,
218   };
219 
220   // The track ID.
221   int64_t m_id;
222 
223   // Options used by the readers.
224   std::string m_fname;
225   item_selector_c<bool> m_atracks, m_vtracks, m_stracks, m_btracks, m_track_tags;
226   bool m_disable_multi_file;
227 
228   // Options used by the packetizers.
229   memory_cptr m_private_data;
230 
231   std::map<int64_t, std::string> m_all_fourccs;
232   std::string m_fourcc;
233   std::map<int64_t, display_properties_t> m_display_properties;
234   double m_aspect_ratio;
235   int m_display_width, m_display_height, m_display_unit;
236   bool m_aspect_ratio_given, m_aspect_ratio_is_factor, m_display_dimensions_given;
237   option_source_e m_display_dimensions_source;
238 
239   std::map<int64_t, timestamp_sync_t> m_timestamp_syncs; // As given on the command line
240   timestamp_sync_t m_tcsync;                       // For this very track
241 
242   std::map<int64_t, bool> m_reset_timestamps_specs;
243   bool m_reset_timestamps;
244 
245   std::map<int64_t, cue_strategy_e> m_cue_creations; // As given on the command line
246   cue_strategy_e m_cues;          // For this very track
247 
248   std::map<int64_t, bool> m_default_track_flags; // As given on the command line
249   std::optional<bool> m_default_track;    // For this very track
250 
251   std::map<int64_t, bool> m_fix_bitstream_frame_rate_flags; // As given on the command line
252   std::optional<bool> m_fix_bitstream_frame_rate;         // For this very track
253 
254   std::map<int64_t, bool> m_forced_track_flags; // As given on the command line
255   std::optional<bool> m_forced_track;    // For this very track
256 
257   std::map<int64_t, bool> m_enabled_track_flags; // As given on the command line
258   std::optional<bool> m_enabled_track;    // For this very track
259 
260   std::map<int64_t, bool> m_hearing_impaired_flags;
261   std::optional<bool> m_hearing_impaired_flag;
262 
263   std::map<int64_t, bool> m_visual_impaired_flags;
264   std::optional<bool> m_visual_impaired_flag;
265 
266   std::map<int64_t, bool> m_text_descriptions_flags;
267   std::optional<bool> m_text_descriptions_flag;
268 
269   std::map<int64_t, bool> m_original_flags;
270   std::optional<bool> m_original_flag;
271 
272   std::map<int64_t, bool> m_commentary_flags;
273   std::optional<bool> m_commentary_flag;
274 
275   std::map<int64_t, mtx::bcp47::language_c> m_languages; // As given on the command line
276   mtx::bcp47::language_c m_language;                     // For this very track
277 
278   std::map<int64_t, std::string> m_sub_charsets; // As given on the command line
279   std::string m_sub_charset;           // For this very track
280 
281   std::map<int64_t, std::string> m_all_tags;     // As given on the command line
282   std::string m_tags_file_name;        // For this very track
283   std::shared_ptr<libmatroska::KaxTags> m_tags;     // For this very track
284 
285   std::map<int64_t, bool> m_all_aac_is_sbr; // For AAC+/HE-AAC/SBR
286 
287   std::map<int64_t, compression_method_e> m_compression_list; // As given on the cmd line
288   compression_method_e m_compression; // For this very track
289 
290   std::map<int64_t, std::string> m_track_names; // As given on the command line
291   std::string m_track_name;            // For this very track
292 
293   std::map<int64_t, std::string> m_all_ext_timestamps; // As given on the command line
294   std::string m_ext_timestamps;         // For this very track
295 
296   std::map<int64_t, pixel_crop_t> m_pixel_crop_list; // As given on the command line
297   option_with_source_c<pixel_crop_t> m_pixel_cropping;  // For this very track
298 
299   std::map<int64_t, stereo_mode_c::mode> m_stereo_mode_list; // As given on the command line
300   option_with_source_c<stereo_mode_c::mode> m_stereo_mode;   // For this very track
301 
302   std::map<int64_t, uint64_t> m_field_order_list; // As given on the command line
303   option_with_source_c<uint64_t> m_field_order;   // For this very track
304 
305   std::map<int64_t, int> m_colour_matrix_coeff_list; // As given on the command line
306   option_with_source_c<int> m_colour_matrix_coeff; // For this very track
307 
308   std::map<int64_t, int> m_bits_per_channel_list; // As given on the command line
309   option_with_source_c<int> m_bits_per_channel; // For this very track
310 
311   std::map<int64_t, chroma_subsample_t> m_chroma_subsample_list; // As given on the command line
312   option_with_source_c<chroma_subsample_t> m_chroma_subsample; // For this very track
313 
314   std::map<int64_t, cb_subsample_t> m_cb_subsample_list; // As given on the command line
315   option_with_source_c<cb_subsample_t> m_cb_subsample; // For this very track
316 
317   std::map<int64_t, chroma_siting_t> m_chroma_siting_list; // As given on the command line
318   option_with_source_c<chroma_siting_t> m_chroma_siting; // For this very track
319 
320   std::map<int64_t, int> m_colour_range_list; // As given on the command line
321   option_with_source_c<int> m_colour_range; // For this very track
322 
323   std::map<int64_t, int> m_colour_transfer_list; // As given on the command line
324   option_with_source_c<int> m_colour_transfer; // For this very track
325 
326   std::map<int64_t, int> m_colour_primaries_list; // As given on the command line
327   option_with_source_c<int> m_colour_primaries; // For this very track
328 
329   std::map<int64_t, int> m_max_cll_list; // As given on the command line
330   option_with_source_c<int> m_max_cll; // For this very track
331 
332   std::map<int64_t, int> m_max_fall_list; // As given on the command line
333   option_with_source_c<int> m_max_fall; // For this very track
334 
335   std::map<int64_t, chroma_coordinates_t> m_chroma_coordinates_list; // As given on the command line
336   option_with_source_c<chroma_coordinates_t> m_chroma_coordinates; // For this very track
337 
338   std::map<int64_t, white_colour_coordinates_t> m_white_coordinates_list; // As given on the command line
339   option_with_source_c<white_colour_coordinates_t> m_white_coordinates; // For this very track
340 
341   std::map<int64_t, double> m_max_luminance_list; // As given on the command line
342   option_with_source_c<double> m_max_luminance; // For this very track
343 
344   std::map<int64_t, double> m_min_luminance_list; // As given on the command line
345   option_with_source_c<double> m_min_luminance; // For this very track
346 
347   std::map<int64_t, uint64_t> m_projection_type_list; // As given on the command line
348   option_with_source_c<uint64_t> m_projection_type; // For this very track
349 
350   std::map<int64_t, memory_cptr> m_projection_private_list; // As given on the command line
351   option_with_source_c<memory_cptr> m_projection_private; // For this very track
352 
353   std::map<int64_t, double> m_projection_pose_yaw_list; // As given on the command line
354   option_with_source_c<double> m_projection_pose_yaw; // For this very track
355 
356   std::map<int64_t, double> m_projection_pose_pitch_list; // As given on the command line
357   option_with_source_c<double> m_projection_pose_pitch; // For this very track
358 
359   std::map<int64_t, double> m_projection_pose_roll_list; // As given on the command line
360   option_with_source_c<double> m_projection_pose_roll; // For this very track
361 
362   std::map<int64_t, memory_cptr> m_colour_space_list; // As given on the command line
363   option_with_source_c<memory_cptr> m_colour_space; // For this very track
364 
365   std::map<int64_t, std::pair<int64_t, bool>> m_default_durations; // As given on the command line
366   std::map<int64_t, int> m_max_blockadd_ids; // As given on the command line
367 
368   item_selector_c<attach_mode_e> m_attach_mode_list; // As given on the command line
369 
370   std::map<int64_t, bool> m_reduce_to_core, m_remove_dialog_normalization_gain;
371 
372   bool m_no_chapters, m_no_global_tags;
373 
374   // Some file formats can contain chapters, but for some the charset
375   // cannot be identified unambiguously (*cough* OGM *cough*).
376   std::string m_chapter_charset;
377   mtx::bcp47::language_c m_chapter_language;
378 
379   bool m_avi_audio_sync_enabled;
380   int64_t m_avi_audio_data_rate;
381 
382 public:
383   track_info_c();
track_info_c(const track_info_c & src)384   track_info_c(const track_info_c &src) {
385     *this = src;
386   }
~track_info_c()387   virtual ~track_info_c() {
388   }
389 
390   track_info_c &operator =(const track_info_c &src);
391   virtual bool display_dimensions_or_aspect_ratio_set();
392 };
393 
394 template<typename T>
395 typename T::mapped_type
396 get_option_for_track(T const &options,
397                      int64_t track_id,
398                      typename T::mapped_type const &default_value = typename T::mapped_type{}) {
399   auto end = options.end();
400   auto itr = options.find(track_id);
401 
402   if (itr != end)
403     return itr->second;
404 
405   itr = options.find(-1ll);
406   if (itr != end)
407     return itr->second;
408 
409   return default_value;
410 }
411