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