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 definitions for the Quicktime & MP4 reader
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/ac3.h"
19 #include "common/codec.h"
20 #include "common/dts.h"
21 #include "common/fourcc.h"
22 #include "input/qtmp4_atoms.h"
23 #include "merge/generic_reader.h"
24 #include "output/p_pcm.h"
25 #include "output/p_video_for_windows.h"
26 
27 constexpr auto QTMP4_TKHD_FLAG_ENABLED            = 0x00000001;
28 
29 constexpr auto QTMP4_TFHD_BASE_DATA_OFFSET        = 0x000001;
30 constexpr auto QTMP4_TFHD_SAMPLE_DESCRIPTION_ID   = 0x000002;
31 constexpr auto QTMP4_TFHD_DEFAULT_DURATION        = 0x000008;
32 constexpr auto QTMP4_TFHD_DEFAULT_SIZE            = 0x000010;
33 constexpr auto QTMP4_TFHD_DEFAULT_FLAGS           = 0x000020;
34 constexpr auto QTMP4_TFHD_DURATION_IS_EMPTY       = 0x010000;
35 constexpr auto QTMP4_TFHD_DEFAULT_BASE_IS_MOOF    = 0x020000;
36 
37 constexpr auto QTMP4_TRUN_DATA_OFFSET             = 0x000001;
38 constexpr auto QTMP4_TRUN_FIRST_SAMPLE_FLAGS      = 0x000004;
39 constexpr auto QTMP4_TRUN_SAMPLE_DURATION         = 0x000100;
40 constexpr auto QTMP4_TRUN_SAMPLE_SIZE             = 0x000200;
41 constexpr auto QTMP4_TRUN_SAMPLE_FLAGS            = 0x000400;
42 constexpr auto QTMP4_TRUN_SAMPLE_CTS_OFFSET       = 0x000800;
43 
44 constexpr auto QTMP4_FRAG_SAMPLE_FLAG_IS_NON_SYNC = 0x00010000;
45 constexpr auto QTMP4_FRAG_SAMPLE_FLAG_DEPENDS_YES = 0x01000000;
46 
47 struct qt_durmap_t {
48   uint32_t number;
49   uint32_t duration;
50 
qt_durmap_tqt_durmap_t51   qt_durmap_t()
52     : number{}
53     , duration{}
54   {
55   }
56 
qt_durmap_tqt_durmap_t57   qt_durmap_t(uint32_t p_number, uint32_t p_duration)
58     : number{p_number}
59     , duration{p_duration}
60   {
61   }
62 };
63 
64 struct qt_chunk_t {
65   uint32_t samples;
66   uint32_t size;
67   uint32_t desc;
68   uint64_t pos;
69 
qt_chunk_tqt_chunk_t70   qt_chunk_t()
71     : samples{}
72     , size{}
73     , desc{}
74     , pos{}
75   {
76   }
77 
qt_chunk_tqt_chunk_t78   qt_chunk_t(uint32_t p_size, uint64_t p_pos)
79     : samples{}
80     , size{p_size}
81     , desc{}
82     , pos{p_pos}
83   {
84   }
85 };
86 
87 struct qt_chunkmap_t {
88   uint32_t first_chunk;
89   uint32_t samples_per_chunk;
90   uint32_t sample_description_id;
91 
qt_chunkmap_tqt_chunkmap_t92   qt_chunkmap_t()
93     : first_chunk{}
94     , samples_per_chunk{}
95     , sample_description_id{}
96   {
97   }
98 };
99 
100 struct qt_editlist_t {
101   int64_t  segment_duration{}, media_time{};
102   uint16_t media_rate_integer{}, media_rate_fraction{};
103 
104   bool operator ==(qt_editlist_t const &other) const {
105     return (segment_duration    == other.segment_duration)
106         && (media_time          == other.media_time)
107         && (media_rate_integer  == other.media_rate_integer)
108         && (media_rate_fraction == other.media_rate_fraction);
109   };
110 };
111 
112 struct qt_sample_t {
113   int64_t  pts;
114   uint32_t size;
115   int64_t  pos;
116 
qt_sample_tqt_sample_t117   qt_sample_t()
118     : pts{}
119     , size{}
120     , pos{}
121   {
122   }
123 
qt_sample_tqt_sample_t124   qt_sample_t(uint32_t p_size)
125     : pts{}
126     , size{p_size}
127     , pos{}
128   {
129   }
130 };
131 
132 struct qt_frame_offset_t {
133   unsigned int count;
134   int64_t offset;
135 
qt_frame_offset_tqt_frame_offset_t136   qt_frame_offset_t()
137     : count{}
138     , offset{}
139   {
140   }
141 
qt_frame_offset_tqt_frame_offset_t142   qt_frame_offset_t(unsigned int p_count, int64_t p_offset)
143     : count{p_count}
144     , offset{p_offset}
145   {
146   }
147 };
148 
149 struct qt_index_t {
150   int64_t file_pos, size;
151   int64_t timestamp, duration;
152   bool    is_keyframe;
153 
qt_index_tqt_index_t154   qt_index_t()
155     : file_pos{}
156     , size{}
157     , timestamp{}
158     , duration{}
159     , is_keyframe{}
160   {
161   };
162 
qt_index_tqt_index_t163   qt_index_t(int64_t p_file_pos, int64_t p_size, int64_t p_timestamp, int64_t p_duration, bool p_is_keyframe)
164     : file_pos{p_file_pos}
165     , size{p_size}
166     , timestamp{p_timestamp}
167     , duration{p_duration}
168     , is_keyframe{p_is_keyframe}
169   {
170   }
171 };
172 
173 struct qt_track_defaults_t {
174   unsigned int sample_description_id, sample_duration, sample_size, sample_flags;
175 
qt_track_defaults_tqt_track_defaults_t176   qt_track_defaults_t()
177     : sample_description_id{}
178     , sample_duration{}
179     , sample_size{}
180     , sample_flags{}
181   {
182   }
183 };
184 
185 struct qt_fragment_t {
186   unsigned int track_id, sample_description_id, sample_duration, sample_size, sample_flags;
187   uint64_t base_data_offset, moof_offset, implicit_offset;
188 
qt_fragment_tqt_fragment_t189   qt_fragment_t()
190     : track_id{}
191     , sample_description_id{}
192     , sample_duration{}
193     , sample_size{}
194     , sample_flags{}
195     , base_data_offset{}
196     , moof_offset{}
197     , implicit_offset{}
198   {}
199 };
200 
201 struct qt_random_access_point_t {
202   bool num_leading_samples_known{};
203   unsigned int num_leading_samples{};
204 
qt_random_access_point_tqt_random_access_point_t205   qt_random_access_point_t(bool p_num_leading_samples_known, unsigned int p_num_leading_samples)
206     : num_leading_samples_known{p_num_leading_samples_known}
207     , num_leading_samples{p_num_leading_samples}
208   {
209   }
210 };
211 
212 struct qt_sample_to_group_t {
213   uint32_t sample_count{}, group_description_index{};
214 
qt_sample_to_group_tqt_sample_to_group_t215   qt_sample_to_group_t(uint32_t p_sample_count, uint32_t p_group_description_index)
216     : sample_count{p_sample_count}
217     , group_description_index{p_group_description_index}
218   {
219   }
220 };
221 
222 class qtmp4_reader_c;
223 
224 struct qtmp4_demuxer_c {
225   qtmp4_reader_c &m_reader;
226 
227   bool ok{}, m_tables_updated{}, m_timestamps_calculated{}, m_enabled{true};
228 
229   char type;
230   uint32_t id, container_id;
231   fourcc_c fourcc;
232   uint32_t pos;
233 
234   codec_c codec;
235   pcm_packetizer_c::pcm_format_e m_pcm_format;
236 
237   int64_t time_scale, track_duration, global_duration, num_frames_from_trun;
238   uint32_t sample_size;
239 
240   std::vector<qt_sample_t> sample_table;
241   std::vector<qt_chunk_t> chunk_table;
242   std::vector<qt_chunkmap_t> chunkmap_table;
243   std::vector<qt_durmap_t> durmap_table;
244   std::vector<uint32_t> keyframe_table;
245   std::vector<qt_editlist_t> editlist_table;
246   std::vector<qt_frame_offset_t> raw_frame_offset_table;
247   std::vector<int32_t> frame_offset_table;
248   std::vector<qt_random_access_point_t> random_access_point_table;
249   std::unordered_map<uint32_t, std::vector<qt_sample_to_group_t> > sample_to_group_tables;
250 
251   std::vector<int64_t> timestamps, durations, frame_indices;
252 
253   std::vector<qt_index_t> m_index;
254   std::vector<qt_fragment_t> m_fragments;
255 
256   mtx_mp_rational_t frame_rate;
257   std::optional<int64_t> m_use_frame_rate_for_duration;
258 
259   std::vector<block_addition_mapping_t> m_block_addition_mappings;
260 
261   esds_t esds;
262   bool esds_parsed;
263 
264   memory_cptr stsd;
265   unsigned int stsd_non_priv_struct_size;
266   uint32_t v_width, v_height, v_bitdepth, v_display_width_flt{}, v_display_height_flt{};
267   uint16_t v_colour_primaries, v_colour_transfer_characteristics, v_colour_matrix_coefficients;
268   bool m_hevc_is_annex_b{};
269   std::deque<int64_t> references;
270   uint32_t a_channels, a_bitdepth;
271   double a_samplerate;
272   std::optional<mtx::aac::audio_config_t> a_aac_audio_config;
273   mtx::ac3::frame_c m_ac3_header;
274   mtx::dts::header_t m_dts_header;
275 
276   std::vector<memory_cptr> priv;
277 
278   bool warning_printed;
279 
280   int ptzr;
281 
282   mtx::bcp47::language_c language;
283 
284   debugging_option_c m_debug_tables, m_debug_tables_full, m_debug_frame_rate, m_debug_headers, m_debug_editlists, m_debug_indexes, m_debug_indexes_full;
285 
qtmp4_demuxer_cqtmp4_demuxer_c286   qtmp4_demuxer_c(qtmp4_reader_c &reader)
287     : m_reader(reader)
288     , type{'?'}
289     , id{0}
290     , container_id{0}
291     , pos{0}
292     , m_pcm_format{pcm_packetizer_c::little_endian_integer}
293     , time_scale{1}
294     , track_duration{0}
295     , global_duration{0}
296     , num_frames_from_trun{}
297     , sample_size{0}
298     , esds_parsed{false}
299     , stsd_non_priv_struct_size{}
300     , v_width{0}
301     , v_height{0}
302     , v_bitdepth{0}
303     , v_colour_primaries{2}
304     , v_colour_transfer_characteristics{2}
305     , v_colour_matrix_coefficients{2}
306     , a_channels{0}
307     , a_bitdepth{0}
308     , a_samplerate{0.0}
309     , warning_printed{false}
310     , ptzr{-1}
311     , m_debug_tables{            "qtmp4_full|qtmp4_tables|qtmp4_tables_full"}
312     , m_debug_tables_full{                               "qtmp4_tables_full"}
313     , m_debug_frame_rate{"qtmp4|qtmp4_full|qtmp4_frame_rate"}
314     , m_debug_headers{   "qtmp4|qtmp4_full|qtmp4_headers"}
315     , m_debug_editlists{ "qtmp4|qtmp4_full|qtmp4_editlists"}
316     , m_debug_indexes{         "qtmp4_full|qtmp4_indexes|qtmp4_indexes_full"}
317     , m_debug_indexes_full{                             "qtmp4_indexes_full"}
318   {
319   }
320 
~qtmp4_demuxer_cqtmp4_demuxer_c321   ~qtmp4_demuxer_c() {
322   }
323 
324   void calculate_frame_rate();
325   int64_t to_nsecs(int64_t value, std::optional<int64_t> time_scale_to_use = std::nullopt);
326   void calculate_timestamps();
327   void adjust_timestamps(int64_t delta);
328 
329   bool update_tables();
330   void apply_edit_list();
331 
332   void build_index();
333 
334   memory_cptr read_first_bytes(int num_bytes);
335 
336   bool is_audio() const;
337   bool is_video() const;
338   bool is_subtitles() const;
339   bool is_chapters() const;
340   bool is_unknown() const;
341 
342   void handle_stsd_atom(uint64_t atom_size, int level);
343   void handle_audio_stsd_atom(uint64_t atom_size, int level);
344   void handle_video_stsd_atom(uint64_t atom_size, int level);
345   void handle_subtitles_stsd_atom(uint64_t atom_size, int level);
346   void handle_colr_atom(memory_cptr const &atom_content, int level);
347 
348   void parse_audio_header_priv_atoms(uint64_t atom_size, int level);
349   void parse_audio_header_priv_atoms(mm_mem_io_c &mio, uint64_t size, int level);
350   void parse_video_header_priv_atoms(uint64_t atom_size, int level);
351   void parse_subtitles_header_priv_atoms(uint64_t atom_size, int level);
352 
353   void parse_esds_audio_header_priv_atom(mm_io_c &io, int level);
354   void parse_dops_audio_header_priv_atom(mm_io_c &io, int level);
355   void parse_aac_esds_decoder_config();
356   void parse_vorbis_esds_decoder_config();
357 
358   bool verify_audio_parameters();
359   bool verify_alac_audio_parameters();
360   bool verify_dts_audio_parameters();
361   bool verify_mp4a_audio_parameters();
362 
363   bool verify_video_parameters();
364   bool verify_avc_video_parameters();
365   bool verify_hevc_video_parameters();
366   bool verify_mp4v_video_parameters();
367 
368   bool verify_subtitles_parameters();
369   bool verify_vobsub_subtitles_parameters();
370 
371   void derive_track_params_from_ac3_audio_bitstream();
372   bool derive_track_params_from_avc_bitstream();
373   void derive_track_params_from_dts_audio_bitstream();
374   void derive_track_params_from_mp3_audio_bitstream();
375   bool derive_track_params_from_opus_private_data();
376   bool derive_track_params_from_vorbis_private_data();
377   void check_for_hevc_video_annex_b_bitstream();
378 
379   void set_packetizer_display_dimensions();
380   void set_packetizer_colour_properties();
381   void set_packetizer_block_addition_mappings();
382 
383 
384   std::optional<int64_t> min_timestamp() const;
385 
386   void determine_codec();
387 
388 private:
389   void build_index_chunk_mode();
390   void build_index_constant_sample_size_mode();
391   void dump_index_entries(std::string const &message) const;
392   void mark_key_frames_from_key_frame_table();
393   void mark_open_gop_random_access_points_as_key_frames();
394 
395   void calculate_timestamps_constant_sample_size();
396   void calculate_timestamps_variable_sample_size();
397 
398   bool parse_esds_atom(mm_io_c &io, int level);
399   void add_data_as_block_addition(uint32_t atom_type, memory_cptr const &data);
400 };
401 using qtmp4_demuxer_cptr = std::shared_ptr<qtmp4_demuxer_c>;
402 
403 struct qt_atom_t {
404   fourcc_c fourcc;
405   uint64_t size;
406   uint64_t pos;
407   uint32_t hsize;
408 
qt_atom_tqt_atom_t409   qt_atom_t()
410     : fourcc{}
411     , size{}
412     , pos{}
413     , hsize{}
414   {
415   }
416 
to_parentqt_atom_t417   qt_atom_t to_parent() const {
418     qt_atom_t parent;
419 
420     parent.fourcc = fourcc;
421     parent.size   = size - hsize;
422     parent.pos    = pos  + hsize;
423     return parent;
424   }
425 };
426 
427 inline std::ostream &
428 operator <<(std::ostream &out,
429             qt_atom_t const &atom) {
430   out << fmt::format("<{0} at {1} size {2} hsize {3}>", atom.fourcc, atom.pos, atom.size, atom.hsize);
431   return out;
432 }
433 
434 struct qtmp4_chapter_entry_t {
435   std::string m_name;
436   int64_t m_timestamp;
437 
qtmp4_chapter_entry_tqtmp4_chapter_entry_t438   qtmp4_chapter_entry_t()
439     : m_timestamp{}
440   {
441   }
442 
qtmp4_chapter_entry_tqtmp4_chapter_entry_t443   qtmp4_chapter_entry_t(const std::string &name,
444                         int64_t timestamp)
445     : m_name{name}
446     , m_timestamp{timestamp}
447   {
448   }
449 
450   bool operator <(const qtmp4_chapter_entry_t &cmp) const {
451     return m_timestamp < cmp.m_timestamp;
452   }
453 };
454 
455 class qtmp4_reader_c: public generic_reader_c {
456 private:
457   std::vector<qtmp4_demuxer_cptr> m_demuxers;
458   std::unordered_map<unsigned int, bool> m_chapter_track_ids;
459   std::unordered_map<unsigned int, qt_track_defaults_t> m_track_defaults;
460 
461   int64_t m_time_scale{1};
462   fourcc_c m_compression_algorithm;
463   int m_main_dmx{-1};
464 
465   unsigned int m_audio_encoder_delay_samples{};
466 
467   uint64_t m_moof_offset{}, m_fragment_implicit_offset{};
468   qt_fragment_t *m_fragment{};
469   qtmp4_demuxer_c *m_track_for_fragment{};
470 
471   bool m_timestamps_calculated{};
472   std::optional<uint64_t> m_duration;
473 
474   uint64_t m_attachment_id{};
475 
476   int64_t m_bytes_to_process{}, m_bytes_processed{};
477 
478   debugging_option_c
479       m_debug_chapters{    "qtmp4|qtmp4_full|qtmp4_chapters"}
480     , m_debug_headers{     "qtmp4|qtmp4_full|qtmp4_headers"}
481     , m_debug_tables{            "qtmp4_full|qtmp4_tables|qtmp4_tables_full"}
482     , m_debug_tables_full{                               "qtmp4_tables_full"}
483     , m_debug_interleaving{"qtmp4|qtmp4_full|qtmp4_interleaving"}
484     , m_debug_resync{      "qtmp4|qtmp4_full|qtmp4_resync"};
485 
486   friend class qtmp4_demuxer_c;
487 
488 public:
get_format_type()489   virtual mtx::file_type_e get_format_type() const {
490     return mtx::file_type_e::qtmp4;
491   }
492 
493   virtual void read_headers();
494   virtual int64_t get_progress() override;
495   virtual int64_t get_maximum_progress() override;
496   virtual void identify();
497   virtual void create_packetizers();
498   virtual void create_packetizer(int64_t tid);
499   virtual void add_available_track_ids();
500 
501   virtual bool probe_file() override;
502 
503 protected:
504   virtual file_status_e read(generic_packetizer_c *packetizer, bool force = false) override;
505 
506   virtual void parse_headers();
507   virtual void verify_track_parameters_and_update_indexes();
508   virtual void calculate_timestamps();
509   virtual std::optional<int64_t> calculate_global_min_timestamp() const;
510   virtual void calculate_num_bytes_to_process();
511 
512   virtual qt_atom_t read_atom(mm_io_c *read_from = nullptr, bool exit_on_error = true);
513   virtual bool resync_to_top_level_atom(uint64_t start_pos);
514   virtual void parse_itunsmpb(std::string data);
515 
516   virtual void handle_cmov_atom(qt_atom_t parent, int level);
517   virtual void handle_cmvd_atom(qt_atom_t parent, int level);
518   virtual void handle_ctts_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
519   virtual void handle_sgpd_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
520   virtual void handle_sbgp_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
521   virtual void handle_dcom_atom(qt_atom_t parent, int level);
522   virtual void handle_hdlr_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
523   virtual void handle_mdhd_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
524   virtual void handle_mdia_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
525   virtual void handle_minf_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
526   virtual void handle_moov_atom(qt_atom_t parent, int level);
527   virtual void handle_mvhd_atom(qt_atom_t parent, int level);
528   virtual void handle_udta_atom(qt_atom_t parent, int level);
529   virtual void handle_chpl_atom(qt_atom_t parent, int level);
530   virtual void handle_meta_atom(qt_atom_t parent, int level);
531   virtual void handle_ilst_atom(qt_atom_t parent, int level);
532   virtual void handle_4dashes_atom(qt_atom_t parent, int level);
533   virtual void handle_covr_atom(qt_atom_t parent, int level);
534   virtual void handle_mvex_atom(qt_atom_t parent, int level);
535   virtual void handle_trex_atom(qt_atom_t parent, int level);
536   virtual void handle_moof_atom(qt_atom_t parent, int level, qt_atom_t const &moof_atom);
537   virtual void handle_traf_atom(qt_atom_t parent, int level);
538   virtual void handle_tfhd_atom(qt_atom_t parent, int level);
539   virtual void handle_trun_atom(qt_atom_t parent, int level);
540   virtual void handle_stbl_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
541   virtual void handle_stco_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
542   virtual void handle_co64_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
543   virtual void handle_stsc_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
544   virtual void handle_stsd_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
545   virtual void handle_stss_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
546   virtual void handle_stsz_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
547   virtual void handle_sttd_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
548   virtual void handle_stts_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
549   virtual void handle_tkhd_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
550   virtual void handle_trak_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
551   virtual void handle_edts_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
552   virtual void handle_elst_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
553   virtual void handle_tref_atom(qtmp4_demuxer_c &new_dmx, qt_atom_t parent, int level);
554 
555   virtual memory_cptr create_bitmap_info_header(qtmp4_demuxer_c &dmx, const char *fourcc, size_t extra_size = 0, const void *extra_data = nullptr);
556 
557   virtual void create_audio_packetizer_aac(qtmp4_demuxer_c &dmx);
558   virtual bool create_audio_packetizer_ac3(qtmp4_demuxer_c &dmx);
559   virtual bool create_audio_packetizer_alac(qtmp4_demuxer_c &dmx);
560   virtual bool create_audio_packetizer_dts(qtmp4_demuxer_c &dmx);
561   virtual void create_audio_packetizer_mp3(qtmp4_demuxer_c &dmx);
562   virtual void create_audio_packetizer_opus(qtmp4_demuxer_c &dmx);
563   virtual void create_audio_packetizer_passthrough(qtmp4_demuxer_c &dmx);
564   virtual void create_audio_packetizer_pcm(qtmp4_demuxer_c &dmx);
565   virtual void create_audio_packetizer_vorbis(qtmp4_demuxer_c &dmx);
566 
567   virtual void create_video_packetizer_av1(qtmp4_demuxer_c &dmx);
568   virtual void create_video_packetizer_avc(qtmp4_demuxer_c &dmx);
569   virtual void create_video_packetizer_mpeg1_2(qtmp4_demuxer_c &dmx);
570   virtual void create_video_packetizer_mpeg4_p2(qtmp4_demuxer_c &dmx);
571   virtual void create_video_packetizer_mpegh_p2(qtmp4_demuxer_c &dmx);
572   virtual void create_video_packetizer_mpegh_p2_es(qtmp4_demuxer_c &dmx);
573   virtual void create_video_packetizer_standard(qtmp4_demuxer_c &dmx);
574   virtual void create_video_packetizer_svq1(qtmp4_demuxer_c &dmx);
575   virtual void create_video_packetizer_prores(qtmp4_demuxer_c &dmx);
576   virtual void create_video_packetizer_vpx(qtmp4_demuxer_c &dmx);
577 
578   virtual void create_subtitles_packetizer_vobsub(qtmp4_demuxer_c &dmx);
579 
580   virtual void handle_audio_encoder_delay(qtmp4_demuxer_c &dmx);
581 
582   virtual mtx::bcp47::language_c decode_and_verify_language(uint16_t coded_language);
583   virtual void read_chapter_track();
584   virtual void recode_chapter_entries(std::vector<qtmp4_chapter_entry_t> &entries);
585   virtual void process_chapter_entries(int level, std::vector<qtmp4_chapter_entry_t> &entries);
586 
587   virtual void detect_interleaving();
588 
589   virtual std::string read_string_atom(qt_atom_t atom, size_t num_skipped);
590 
591   virtual void process_atom(qt_atom_t const &parent, int level, std::function<void(qt_atom_t const &)> const &handler);
592 };
593