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    MPEG TS (transport stream) demultiplexer module
10 
11    Written by Massimo Callegari <massimocallegari@yahoo.it>
12    and Moritz Bunkus <moritz@bunkus.org>.
13 */
14 
15 #include "common/common_pch.h"
16 
17 #include <iostream>
18 
19 #include "common/at_scope_exit.h"
20 #include "common/avc/es_parser.h"
21 #include "common/bluray/clpi.h"
22 #include "common/bluray/util.h"
23 #include "common/bswap.h"
24 #include "common/chapters/bluray.h"
25 #include "common/checksums/crc.h"
26 #include "common/checksums/base_fwd.h"
27 #include "common/endian.h"
28 #include "common/hdmv_textst.h"
29 #include "common/mp3.h"
30 #include "common/mm_file_io.h"
31 #include "common/mm_mpls_multi_file_io.h"
32 #include "common/ac3.h"
33 #include "common/id_info.h"
34 #include "common/list_utils.h"
35 #include "common/mm_mem_io.h"
36 #include "common/mm_proxy_io.h"
37 #include "common/mm_text_io.h"
38 #include "common/mpeg1_2.h"
39 #include "common/mpeg4_p2.h"
40 #include "common/path.h"
41 #include "common/qt.h"
42 #include "common/strings/formatting.h"
43 #include "input/aac_framing_packet_converter.h"
44 #include "input/bluray_pcm_channel_layout_packet_converter.h"
45 #include "input/dvbsub_pes_framing_removal_packet_converter.h"
46 #include "input/r_mpeg_ts.h"
47 #include "input/teletext_to_srt_packet_converter.h"
48 #include "input/truehd_ac3_splitting_packet_converter.h"
49 #include "merge/cluster_helper.h"
50 #include "merge/output_control.h"
51 #include "output/p_aac.h"
52 #include "output/p_ac3.h"
53 #include "output/p_avc_es.h"
54 #include "output/p_dts.h"
55 #include "output/p_dvbsub.h"
56 #include "output/p_hdmv_pgs.h"
57 #include "output/p_hdmv_textst.h"
58 #include "output/p_hevc_es.h"
59 #include "output/p_mp3.h"
60 #include "output/p_mpeg1_2.h"
61 #include "output/p_pcm.h"
62 #include "output/p_textsubs.h"
63 #include "output/p_truehd.h"
64 #include "output/p_vc1.h"
65 
66 // This is ISO/IEC 13818-1.
67 
68 namespace mtx::mpeg_ts {
69 
70 constexpr auto TS_PACKET_SIZE     = 188;
71 constexpr auto TS_MAX_PACKET_SIZE = 204;
72 
73 constexpr auto TS_PAT_PID         = 0x0000;
74 constexpr auto TS_SDT_PID         = 0x0011;
75 
76 constexpr auto TS_SDT_TID         = 0x42;
77 
78 int reader_c::potential_packet_sizes[] = { 188, 192, 204, 0 };
79 
80 // ------------------------------------------------------------
81 
track_c(reader_c & p_reader,pid_type_e p_type)82 track_c::track_c(reader_c &p_reader,
83                  pid_type_e p_type)
84   : reader{p_reader}
85   , m_file_num{p_reader.m_current_file}
86   , m_id{}
87   , processed{}
88   , type{p_type}
89   , pid{}
90   , program_number{}
91   , pes_payload_size_to_read{}
92   , pes_payload_read{new mtx::bytes::buffer_c}
93   , probed_ok{}
94   , ptzr{-1}
95   , m_timestamp_wrap_add{timestamp_c::ns(0)}
96   , m_subtitle_timestamp_correction{timestamp_c::ns(0)}
97   , v_interlaced{}
98   , v_version{}
99   , v_width{}
100   , v_height{}
101   , v_dwidth{}
102   , v_dheight{}
103   , a_channels{}
104   , a_sample_rate{}
105   , a_bits_per_sample{}
106   , a_bsid{}
107   , m_aac_multiplex_type{aac::parser_c::unknown_multiplex}
108   , m_apply_dts_timestamp_fix{}
109   , m_use_dts{}
110   , m_timestamps_wrapped{}
111   , m_truehd_found_truehd{}
112   , m_truehd_found_ac3{}
113   , m_master{}
114   , skip_packet_data_bytes{}
115   , m_debug_delivery{}
116   , m_debug_timestamp_wrapping{}
117   , m_debug_headers{"mpeg_ts|mpeg_ts_headers"}
118 {
119 }
120 
121 void
process(packet_cptr const & packet)122 track_c::process(packet_cptr const &packet) {
123   if (!converter || !converter->convert(packet))
124     reader.m_reader_packetizers[ptzr]->process(packet);
125 }
126 
127 void
send_to_packetizer()128 track_c::send_to_packetizer() {
129   auto &f                 = reader.file();
130   auto timestamp_to_use   = !m_timestamp.valid()                                               ? timestamp_c{}
131                           : reader.m_dont_use_audio_pts && (pid_type_e::audio == type)         ? timestamp_c{}
132                           : m_apply_dts_timestamp_fix && (m_previous_timestamp == m_timestamp) ? timestamp_c{}
133                           :                                                                      std::max(m_timestamp, f.m_global_timestamp_offset);
134 
135   auto timestamp_to_check = f.m_stream_timestamp.valid() ? f.m_stream_timestamp : timestamp_c::ns(0);
136   auto const &min         = f.m_timestamp_restriction_min;
137   auto const &max         = f.m_timestamp_restriction_max;
138   auto use_packet         = ptzr != -1;
139   auto bytes_to_skip      = std::min<size_t>(pes_payload_read->get_size(), skip_packet_data_bytes);
140 
141   if (   (min.valid() && (timestamp_to_check <  min) && !f.m_timestamp_restriction_min_seen)
142       || (max.valid() && (timestamp_to_check >= max)))
143     use_packet = false;
144 
145   if (use_packet && !f.m_timestamp_restriction_min_seen && min.valid())
146     f.m_timestamp_restriction_min_seen = true;
147 
148   if (timestamp_to_use.valid() && f.m_global_timestamp_offset.valid())
149     timestamp_to_use -= std::min(timestamp_to_use, f.m_global_timestamp_offset);
150 
151   mxdebug_if(m_debug_delivery,
152              fmt::format("send_to_packetizer: PID {0} expected {1} actual {2} timestamp_to_use {3} timestamp_to_check {4} m_timestamp {5} m_previous_timestamp {6} stream_timestamp {7} restriction {8}/{9} min_seen {10} ptzr {11} use? {12}\n",
153                          pid, pes_payload_size_to_read, pes_payload_read->get_size() - bytes_to_skip, timestamp_to_use, timestamp_to_check, m_timestamp, m_previous_timestamp, f.m_stream_timestamp, min, max, f.m_timestamp_restriction_min_seen, ptzr, use_packet));
154 
155   if (use_packet) {
156     process(std::make_shared<packet_t>(memory_c::clone(pes_payload_read->get_buffer() + bytes_to_skip, pes_payload_read->get_size() - bytes_to_skip), timestamp_to_use.to_ns(-1)));
157 
158     f.m_packet_sent_to_packetizer = true;
159   }
160 
161   clear_pes_payload();
162   processed            = false;
163   m_previous_timestamp = m_timestamp;
164   m_timestamp.reset();
165 }
166 
167 bool
is_pes_payload_complete() const168 track_c::is_pes_payload_complete()
169   const {
170   return !is_pes_payload_size_unbounded()
171       && pes_payload_size_to_read
172       && !remaining_payload_size_to_read();
173 }
174 
175 bool
is_pes_payload_size_unbounded() const176 track_c::is_pes_payload_size_unbounded()
177   const {
178   return pes_payload_size_to_read == offsetof(pes_header_t, flags1);
179 }
180 
181 void
add_pes_payload(unsigned char * ts_payload,size_t ts_payload_size)182 track_c::add_pes_payload(unsigned char *ts_payload,
183                          size_t ts_payload_size) {
184   auto to_add = is_pes_payload_size_unbounded() ? ts_payload_size : std::min(ts_payload_size, remaining_payload_size_to_read());
185 
186   if (to_add)
187     pes_payload_read->add(ts_payload, to_add);
188 }
189 
190 void
add_pes_payload_to_probe_data()191 track_c::add_pes_payload_to_probe_data() {
192   if (!m_probe_data)
193     m_probe_data = mtx::bytes::buffer_cptr(new mtx::bytes::buffer_c);
194   m_probe_data->add(pes_payload_read->get_buffer(), pes_payload_read->get_size());
195 }
196 
197 void
clear_pes_payload()198 track_c::clear_pes_payload() {
199   pes_payload_read->clear();
200   pes_payload_size_to_read = 0;
201 }
202 
203 int
new_stream_v_mpeg_1_2(bool end_of_detection)204 track_c::new_stream_v_mpeg_1_2(bool end_of_detection) {
205   if (!m_m2v_parser) {
206     m_m2v_parser = std::shared_ptr<M2VParser>(new M2VParser);
207     m_m2v_parser->SetProbeMode();
208     m_m2v_parser->SetThrowOnError(true);
209   }
210 
211   m_m2v_parser->WriteData(pes_payload_read->get_buffer(), pes_payload_read->get_size());
212   if (end_of_detection)
213     m_m2v_parser->SetEOS();
214 
215   int state = m_m2v_parser->GetState();
216   if (state != MPV_PARSER_STATE_FRAME) {
217     mxdebug_if(m_debug_headers, fmt::format("new_stream_v_mpeg_1_2: no valid frame in {0} bytes\n", pes_payload_read->get_size()));
218     return FILE_STATUS_MOREDATA;
219   }
220 
221   MPEG2SequenceHeader seq_hdr = m_m2v_parser->GetSequenceHeader();
222   std::shared_ptr<MPEGFrame> frame(m_m2v_parser->ReadFrame());
223   if (!frame)
224     return FILE_STATUS_MOREDATA;
225 
226   codec          = codec_c::look_up(codec_c::type_e::V_MPEG12);
227   v_interlaced   = !seq_hdr.progressiveSequence;
228   v_version      = m_m2v_parser->GetMPEGVersion();
229   v_width        = seq_hdr.width;
230   v_height       = seq_hdr.height;
231   v_aspect_ratio = seq_hdr.aspectRatio;
232 
233   m_default_duration = 1'000'000'000 / seq_hdr.frameRate;
234 
235   if ((0 >= v_aspect_ratio) || (1 == v_aspect_ratio))
236     v_dwidth = v_width;
237   else
238     v_dwidth = mtx::to_int_rounded(v_height * v_aspect_ratio);
239   v_dheight  = v_height;
240 
241   mxdebug_if(m_debug_headers, fmt::format("new_stream_v_mpeg_1_2: width: {0}, height: {1}\n", v_width, v_height));
242   if (v_width == 0 || v_height == 0)
243     return FILE_STATUS_MOREDATA;
244 
245   return 0;
246 }
247 
248 int
new_stream_v_avc(bool end_of_detection)249 track_c::new_stream_v_avc(bool end_of_detection) {
250   if (!m_avc_parser)
251     m_avc_parser = std::make_shared<mtx::avc::es_parser_c>();
252 
253   mxdebug_if(m_debug_headers, fmt::format("new_stream_v_avc: packet size: {0}\n", pes_payload_read->get_size()));
254 
255   m_avc_parser->add_bytes(pes_payload_read->get_buffer(), pes_payload_read->get_size());
256   if (end_of_detection)
257     m_avc_parser->flush();
258 
259   if (!m_avc_parser->headers_parsed())
260     return FILE_STATUS_MOREDATA;
261 
262   codec    = codec_c::look_up(codec_c::type_e::V_MPEG4_P10);
263   v_width  = m_avc_parser->get_width();
264   v_height = m_avc_parser->get_height();
265 
266   if (m_avc_parser->has_par_been_found()) {
267     auto dimensions = m_avc_parser->get_display_dimensions();
268     v_dwidth        = dimensions.first;
269     v_dheight       = dimensions.second;
270   }
271 
272   return 0;
273 }
274 
275 int
new_stream_v_hevc(bool end_of_detection)276 track_c::new_stream_v_hevc(bool end_of_detection) {
277   if (!m_hevc_parser)
278     m_hevc_parser = std::make_shared<mtx::hevc::es_parser_c>();
279 
280   m_hevc_parser->add_bytes(pes_payload_read->get_buffer(), pes_payload_read->get_size());
281   if (end_of_detection)
282     m_hevc_parser->flush();
283 
284   if (!m_hevc_parser->headers_parsed())
285     return FILE_STATUS_MOREDATA;
286 
287   codec    = codec_c::look_up(codec_c::type_e::V_MPEGH_P2);
288   v_width  = m_hevc_parser->get_width();
289   v_height = m_hevc_parser->get_height();
290 
291   if (m_hevc_parser->has_par_been_found()) {
292     auto dimensions = m_hevc_parser->get_display_dimensions();
293     v_dwidth        = dimensions.first;
294     v_dheight       = dimensions.second;
295   }
296 
297   return 0;
298 }
299 
300 int
new_stream_v_vc1()301 track_c::new_stream_v_vc1() {
302   if (!m_vc1_parser)
303     m_vc1_parser = std::make_shared<mtx::vc1::es_parser_c>();
304 
305   m_vc1_parser->add_bytes(pes_payload_read->get_buffer(), pes_payload_read->get_size());
306 
307   if (!m_vc1_parser->is_sequence_header_available())
308     return FILE_STATUS_MOREDATA;
309 
310   auto seqhdr = mtx::vc1::sequence_header_t{};
311   m_vc1_parser->get_sequence_header(seqhdr);
312 
313   v_width  = seqhdr.pixel_width;
314   v_height = seqhdr.pixel_height;
315 
316   return 0;
317 }
318 
319 int
new_stream_a_mpeg()320 track_c::new_stream_a_mpeg() {
321   add_pes_payload_to_probe_data();
322 
323   mp3_header_t header;
324 
325   int offset = find_mp3_header(m_probe_data->get_buffer(), m_probe_data->get_size());
326   if (-1 == offset)
327     return FILE_STATUS_MOREDATA;
328 
329   decode_mp3_header(m_probe_data->get_buffer() + offset, &header);
330   a_channels    = header.channels;
331   a_sample_rate = header.sampling_frequency;
332   codec         = header.get_codec();
333 
334   mxdebug_if(m_debug_headers, fmt::format("new_stream_a_mpeg: Channels: {0}, sample rate: {1}\n",a_channels, a_sample_rate));
335   return 0;
336 }
337 
338 int
new_stream_a_aac()339 track_c::new_stream_a_aac() {
340   add_pes_payload_to_probe_data();
341 
342   auto pos = aac::parser_c::find_consecutive_frames(m_probe_data->get_buffer(), m_probe_data->get_size(), 5);
343   if (pos == -1)
344     return FILE_STATUS_MOREDATA;
345 
346   auto parser = aac::parser_c{};
347   parser.add_bytes(m_probe_data->get_buffer() + pos, m_probe_data->get_size() - pos);
348   if (!parser.frames_available() || !parser.headers_parsed())
349     return FILE_STATUS_MOREDATA;
350 
351   m_aac_frame          = parser.get_frame();
352   m_aac_multiplex_type = parser.get_multiplex_type();
353   a_channels           = m_aac_frame.m_header.config.channels;
354   a_sample_rate        = m_aac_frame.m_header.config.sample_rate;
355 
356   mxdebug_if(reader.m_debug_aac,
357              fmt::format("new_stream_a_aac: found headers at {0} multiplex type {1} first header: {2}\n",
358                          pos, aac::parser_c::get_multiplex_type_name(m_aac_multiplex_type), m_aac_frame.to_string()));
359 
360   return 0;
361 }
362 
363 int
new_stream_a_ac3()364 track_c::new_stream_a_ac3() {
365   add_pes_payload_to_probe_data();
366 
367   ac3::parser_c parser;
368   parser.add_bytes(m_probe_data->get_buffer(), m_probe_data->get_size());
369   if (!parser.frame_available())
370     return FILE_STATUS_MOREDATA;
371 
372   ac3::frame_c header = parser.get_frame();
373 
374   mxdebug_if(m_debug_headers,
375              fmt::format("new_stream_a_ac3: first ac3 header bsid {0} channels {1} sample_rate {2} bytes {3} samples {4}\n",
376                          header.m_bs_id, header.m_channels, header.m_sample_rate, header.m_bytes, header.m_samples));
377 
378   a_channels    = header.m_channels;
379   a_sample_rate = header.m_sample_rate;
380   a_bsid        = header.m_bs_id;
381   codec         = header.get_codec();
382 
383   return 0;
384 }
385 
386 int
new_stream_a_dts()387 track_c::new_stream_a_dts() {
388   add_pes_payload_to_probe_data();
389 
390   if (-1 == mtx::dts::find_header(m_probe_data->get_buffer(), m_probe_data->get_size(), a_dts_header))
391     return FILE_STATUS_MOREDATA;
392 
393   m_apply_dts_timestamp_fix = true;
394   a_channels                = a_dts_header.get_total_num_audio_channels();
395   a_sample_rate             = a_dts_header.get_effective_sampling_frequency();
396 
397   codec.set_specialization(a_dts_header.get_codec_specialization());
398 
399   return 0;
400 }
401 
402 int
new_stream_a_pcm()403 track_c::new_stream_a_pcm() {
404   static uint8_t const s_bits_per_samples[4] = { 0, 16, 20, 24 };
405   static uint8_t const s_channels[16]        = { 0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0 };
406 
407   add_pes_payload_to_probe_data();
408 
409   if (4 > m_probe_data->get_size())
410     return FILE_STATUS_MOREDATA;
411 
412   skip_packet_data_bytes = 4;
413   auto buffer            = m_probe_data->get_buffer();
414   a_channels             = s_channels[         buffer[2] >> 4 ];
415   a_bits_per_sample      = s_bits_per_samples[ buffer[3] >> 6 ];
416   auto sample_rate_idx   = buffer[2] & 0x0f;
417   a_sample_rate          = sample_rate_idx == 1 ?  48000
418                          : sample_rate_idx == 4 ?  96000
419                          : sample_rate_idx == 5 ? 192000
420                          :                             0;
421 
422   mxdebug_if(m_debug_headers,
423              fmt::format("new_stream_a_pcm: header: 0x{0:08x} channels: {1}, sample rate: {2}, bits per channel: {3}\n",
424                          get_uint32_be(buffer), a_channels, a_sample_rate, a_bits_per_sample));
425 
426   if ((a_sample_rate == 0) || !mtx::included_in(a_bits_per_sample, 16, 24))
427     return FILE_STATUS_DONE;
428 
429   converter = std::make_shared<bluray_pcm_channel_layout_packet_converter_c>(a_bits_per_sample / 8, a_channels + 1, a_channels);
430 
431   return 0;
432 }
433 
434 int
new_stream_a_truehd()435 track_c::new_stream_a_truehd() {
436   if (!m_truehd_parser)
437     m_truehd_parser.reset(new mtx::truehd::parser_c);
438 
439   m_truehd_parser->add_data(pes_payload_read->get_buffer(), pes_payload_read->get_size());
440   clear_pes_payload();
441 
442   while (m_truehd_parser->frame_available() && (!m_truehd_found_truehd || !m_truehd_found_ac3)) {
443     auto frame = m_truehd_parser->get_next_frame();
444 
445     if (frame->is_ac3()) {
446       if (!m_truehd_found_ac3) {
447         m_truehd_found_ac3 = true;
448         auto &header       = frame->m_ac3_header;
449 
450         mxdebug_if(m_debug_headers,
451                    fmt::format("new_stream_a_truehd: first AC-3 header bsid {0} channels {1} sample_rate {2} bytes {3} samples {4}\n",
452                                header.m_bs_id, header.m_channels, header.m_sample_rate, header.m_bytes, header.m_samples));
453 
454         auto &coupled_track         = *m_coupled_tracks[0];
455         coupled_track.a_channels    = header.m_channels;
456         coupled_track.a_sample_rate = header.m_sample_rate;
457         coupled_track.a_bsid        = header.m_bs_id;
458         coupled_track.probed_ok     = true;
459       }
460 
461       continue;
462 
463     }
464 
465     if (!frame->is_sync())
466       continue;
467 
468     mxdebug_if(m_debug_headers,
469                fmt::format("new_stream_a_truehd: first TrueHD header channels {0} sampling_rate {1} samples_per_frame {2}\n",
470                            frame->m_channels, frame->m_sampling_rate, frame->m_samples_per_frame));
471 
472     codec                 = frame->codec();
473     a_channels            = frame->m_channels;
474     a_sample_rate         = frame->m_sampling_rate;
475     m_truehd_found_truehd = true;
476   }
477 
478   return m_truehd_found_truehd && m_truehd_found_ac3 ? 0 : FILE_STATUS_MOREDATA;
479 }
480 
481 int
new_stream_s_hdmv_textst()482 track_c::new_stream_s_hdmv_textst() {
483   add_pes_payload_to_probe_data();
484 
485   // CodecPrivate for TextST consists solely of the "dialog style segment" element:
486   // segment descriptor:
487   //   1 byte segment type (0x81 == dialog style segment)
488   //   2 bytes segment size (Big Endian)
489   // x bytes dialog style segment data
490 
491   if (!m_probe_data || (m_probe_data->get_size() < 3))
492     return FILE_STATUS_MOREDATA;
493 
494   auto buf = m_probe_data->get_buffer();
495   if (static_cast<mtx::hdmv_textst::segment_type_e>(buf[0]) != mtx::hdmv_textst::dialog_style_segment)
496     return FILE_STATUS_DONE;
497 
498   auto dialog_segment_size = get_uint16_be(&buf[1]);
499   if ((dialog_segment_size + 3u) > m_probe_data->get_size())
500     return FILE_STATUS_MOREDATA;
501 
502   m_codec_private_data = memory_c::clone(buf, dialog_segment_size + 3);
503 
504   return 0;
505 }
506 
507 int
new_stream_s_dvbsub()508 track_c::new_stream_s_dvbsub() {
509   if (!m_codec_private_data || (5 != m_codec_private_data->get_size()))
510       return FILE_STATUS_DONE;
511 
512   return 0;
513 }
514 
515 bool
has_packetizer() const516 track_c::has_packetizer()
517   const {
518   return -1 != ptzr;
519 }
520 
521 void
set_pid(uint16_t new_pid)522 track_c::set_pid(uint16_t new_pid) {
523   pid = new_pid;
524 
525   std::string arg;
526   m_debug_delivery = debugging_c::requested("mpeg_ts")
527                   || (   debugging_c::requested("mpeg_ts_delivery", &arg)
528                       && (arg.empty() || (arg == fmt::to_string(pid))));
529 
530   m_debug_timestamp_wrapping = debugging_c::requested("mpeg_ts")
531                             || (   debugging_c::requested("mpeg_ts_timestamp_wrapping", &arg)
532                                 && (arg.empty() || (arg == fmt::to_string(pid))));
533 }
534 
535 bool
detect_timestamp_wrap(timestamp_c const & timestamp) const536 track_c::detect_timestamp_wrap(timestamp_c const &timestamp)
537   const {
538   static auto const s_wrap_limit = timestamp_c::mpeg(1 << 30);
539 
540   if (   !timestamp.valid()
541       || !m_previous_valid_timestamp.valid()
542       || ((timestamp - m_previous_valid_timestamp).abs() < s_wrap_limit))
543     return false;
544   return true;
545 }
546 
547 void
adjust_timestamp_for_wrap(timestamp_c & timestamp)548 track_c::adjust_timestamp_for_wrap(timestamp_c &timestamp) {
549   static auto const s_wrap_limit = timestamp_c::mpeg(1ll << 30);
550   static auto const s_bad_limit  = timestamp_c::m(5);
551 
552   if (!timestamp.valid())
553     return;
554 
555   if (timestamp < s_wrap_limit)
556     timestamp += m_timestamp_wrap_add;
557 
558   // For subtitle tracks only detect jumps backwards in time, not
559   // forward. Subtitles often have holes larger than five minutes
560   // between the entries.
561   if (   ((timestamp < m_previous_valid_timestamp) || (pid_type_e::subtitles != type))
562       && ((timestamp - m_previous_valid_timestamp).abs() >= s_bad_limit))
563     timestamp = timestamp_c{};
564 }
565 
566 void
handle_timestamp_wrap(timestamp_c & pts,timestamp_c & dts)567 track_c::handle_timestamp_wrap(timestamp_c &pts,
568                                timestamp_c &dts) {
569   static auto const s_wrap_add    = timestamp_c::mpeg(1ll << 33);
570   static auto const s_wrap_limit  = timestamp_c::mpeg(1ll << 30);
571   static auto const s_reset_limit = timestamp_c::h(1);
572 
573   if (!m_timestamps_wrapped) {
574     m_timestamps_wrapped = detect_timestamp_wrap(pts) || detect_timestamp_wrap(dts);
575     if (m_timestamps_wrapped) {
576       m_timestamp_wrap_add += s_wrap_add;
577       mxdebug_if(m_debug_timestamp_wrapping,
578                  fmt::format("handle_timestamp_wrap: Timestamp wrapping detected for PID {0} pts {1} dts {2} previous_valid {3} global_offset {4} new wrap_add {5}\n",
579                              pid, pts, dts, m_previous_valid_timestamp, reader.file().m_global_timestamp_offset, m_timestamp_wrap_add));
580 
581     }
582 
583   } else if (pts.valid() && (pts < s_wrap_limit) && (pts > s_reset_limit)) {
584     m_timestamps_wrapped = false;
585     mxdebug_if(m_debug_timestamp_wrapping,
586                fmt::format("handle_timestamp_wrap: Timestamp wrapping reset for PID {0} pts {1} dts {2} previous_valid {3} global_offset {4} current wrap_add {5}\n",
587                            pid, pts, dts, m_previous_valid_timestamp, reader.file().m_global_timestamp_offset, m_timestamp_wrap_add));
588   }
589 
590   adjust_timestamp_for_wrap(pts);
591   adjust_timestamp_for_wrap(dts);
592 
593   // mxinfo(fmt::format("pid {4} PTS before {0} now {1} wrapped {2} reset prevvalid {3} diff {5}\n", before, pts, m_timestamps_wrapped, m_previous_valid_timestamp, pid, pts - m_previous_valid_timestamp));
594 }
595 
596 drop_decision_e
handle_bogus_subtitle_timestamps(timestamp_c & pts,timestamp_c & dts)597 track_c::handle_bogus_subtitle_timestamps(timestamp_c &pts,
598                                           timestamp_c &dts) {
599   auto &f = reader.file();
600 
601   if (processing_state_e::muxing != f.m_state)
602     return drop_decision_e::keep;
603 
604   // Sometimes the subtitle timestamps aren't valid, they can be off
605   // from the audio/video timestamps by hours. In such a case replace
606   // the subtitle's timestamps with last valid one from audio/video
607   // packets.
608   if (   mtx::included_in(type, pid_type_e::audio, pid_type_e::video)
609       && pts.valid()) {
610     f.m_last_non_subtitle_pts = pts;
611     f.m_last_non_subtitle_dts = dts;
612     return drop_decision_e::keep;
613 
614   }
615 
616   if (pid_type_e::subtitles != type)
617     return drop_decision_e::keep;
618 
619   // PGS subtitles often have their "stop displaying" segments located
620   // right after the "display stuff" segments. In that case their PTS
621   // will differ from the surrounding audio/video PTS
622   // considerably. That's fine, though. No correction must take in
623   // such a case.
624   if (codec.is(codec_c::type_e::S_HDMV_PGS))
625     return drop_decision_e::keep;
626 
627   if (pts.valid())
628     pts += m_subtitle_timestamp_correction;
629   if (dts.valid())
630     dts += m_subtitle_timestamp_correction;
631 
632   if (!f.m_last_non_subtitle_pts.valid())
633     return f.m_has_audio_or_video_track ? drop_decision_e::drop : drop_decision_e::keep;
634 
635   if (   !pts.valid()
636       || ((pts - f.m_last_non_subtitle_pts).abs() >= timestamp_c::s(5))) {
637     auto additional_correction       = f.m_last_non_subtitle_pts - pts;
638     m_subtitle_timestamp_correction += additional_correction;
639     pts                              = f.m_last_non_subtitle_pts;
640     dts                              = f.m_last_non_subtitle_dts;
641 
642     mxdebug_if(m_debug_timestamp_wrapping, fmt::format("additional subtitle correction {0} total {1}\n", additional_correction, m_subtitle_timestamp_correction));
643   }
644 
645   return drop_decision_e::keep;
646 }
647 
648 bool
parse_ac3_pmt_descriptor(pmt_descriptor_t const &,pmt_pid_info_t const & pmt_pid_info)649 track_c::parse_ac3_pmt_descriptor(pmt_descriptor_t const &,
650                                   pmt_pid_info_t const &pmt_pid_info) {
651   if (pmt_pid_info.stream_type != stream_type_e::iso_13818_pes_private)
652     return false;
653 
654   type  = pid_type_e::audio;
655   codec = codec_c::look_up(codec_c::type_e::A_AC3);
656 
657   return true;
658 }
659 
660 bool
parse_dts_pmt_descriptor(pmt_descriptor_t const &,pmt_pid_info_t const & pmt_pid_info)661 track_c::parse_dts_pmt_descriptor(pmt_descriptor_t const &,
662                                   pmt_pid_info_t const &pmt_pid_info) {
663   if (pmt_pid_info.stream_type != stream_type_e::iso_13818_pes_private)
664     return false;
665 
666   type  = pid_type_e::audio;
667   codec = codec_c::look_up(codec_c::type_e::A_DTS);
668 
669   return true;
670 }
671 
672 bool
parse_srt_pmt_descriptor(pmt_descriptor_t const & pmt_descriptor,pmt_pid_info_t const & pmt_pid_info)673 track_c::parse_srt_pmt_descriptor(pmt_descriptor_t const &pmt_descriptor,
674                                   pmt_pid_info_t const &pmt_pid_info) {
675   if (pmt_pid_info.stream_type != stream_type_e::iso_13818_pes_private)
676     return false;
677 
678   auto buffer      = reinterpret_cast<unsigned char const *>(&pmt_descriptor + 1);
679   auto num_entries = static_cast<unsigned int>(pmt_descriptor.length) / 5;
680   mxdebug_if(reader.m_debug_pat_pmt, fmt::format("parse_srt_pmt_descriptor: Teletext PMT descriptor, {0} entries\n", num_entries));
681   for (auto idx = 0u; idx < num_entries; ++idx) {
682     // Bits:
683     //  0–23: ISO 639 language code
684     // 24–28: teletext type
685     // 29-31: teletext magazine number
686     // 32-35: teletext page number (units)
687     // 36-39: teletext page number (tens)
688 
689     // Teletext type is:
690     //   0: ?
691     //   1: teletext
692     //   2: teletext subtitles
693     //   3: teletext additional information
694     //   4: teletext program schedule
695     //   5: teletext subtitles: hearing impaired
696 
697     mtx::bits::reader_c r{buffer, 5};
698 
699     r.skip_bits(24);
700     auto ttx_type     = r.get_bits(5);
701     auto ttx_magazine = r.get_bits(3);
702     auto ttx_page     = r.get_bits(4) * 10 + r.get_bits(4);
703     ttx_page          = (ttx_magazine ? ttx_magazine : 8) * 100 + ttx_page;
704 
705     if (reader.m_debug_pat_pmt) {
706       mxdebug(fmt::format(" {0}: language {1} type {2} magazine {3} page {4}\n",
707                           idx, std::string(reinterpret_cast<char const *>(buffer), 3), ttx_type, ttx_magazine, ttx_page));
708     }
709 
710     if (!mtx::included_in(ttx_type, 2u, 5u)) {
711       buffer += 5;
712       continue;
713     }
714 
715     track_c *to_set_up{};
716 
717     if (!m_ttx_wanted_page) {
718       converter.reset(new teletext_to_srt_packet_converter_c{});
719       to_set_up = this;
720 
721     } else {
722       auto new_track      = std::make_shared<track_c>(reader);
723       new_track->m_master = this;
724       m_coupled_tracks.emplace_back(new_track);
725 
726       to_set_up            = new_track.get();
727       to_set_up->converter = converter;
728       to_set_up->set_pid(pid);
729     }
730 
731     to_set_up->parse_iso639_language_from(buffer);
732     to_set_up->m_ttx_wanted_page = ttx_page;
733 
734     to_set_up->type      = pid_type_e::subtitles;
735     to_set_up->codec     = codec_c::look_up(codec_c::type_e::S_SRT);
736     to_set_up->probed_ok = true;
737 
738     buffer += 5;
739   }
740 
741   return true;
742 }
743 
744 bool
parse_registration_pmt_descriptor(pmt_descriptor_t const & pmt_descriptor,pmt_pid_info_t const & pmt_pid_info)745 track_c::parse_registration_pmt_descriptor(pmt_descriptor_t const &pmt_descriptor,
746                                            pmt_pid_info_t const &pmt_pid_info) {
747   if (pmt_pid_info.stream_type != stream_type_e::iso_13818_pes_private)
748     return false;
749 
750   if (pmt_descriptor.length < 4)
751     return false;
752 
753   auto fourcc = fourcc_c{reinterpret_cast<unsigned char const *>(&pmt_descriptor + 1)};
754   auto reg_codec  = codec_c::look_up(fourcc.str());
755 
756   mxdebug_if(reader.m_debug_pat_pmt, fmt::format("parse_registration_pmt_descriptor: Registration descriptor with FourCC: {0} codec: {1}\n", fourcc.description(), reg_codec));
757 
758   if (!reg_codec.valid())
759     return false;
760 
761   switch (reg_codec.get_track_type()) {
762     case track_audio:    type = pid_type_e::audio; break;
763     case track_video:    type = pid_type_e::video; break;
764     case track_subtitle: type = pid_type_e::subtitles;  break;
765     default:
766       return false;
767   }
768 
769   codec = reg_codec;
770 
771   return true;
772 }
773 
774 bool
parse_subtitling_pmt_descriptor(pmt_descriptor_t const & pmt_descriptor,pmt_pid_info_t const & pmt_pid_info)775 track_c::parse_subtitling_pmt_descriptor(pmt_descriptor_t const &pmt_descriptor,
776                                          pmt_pid_info_t const &pmt_pid_info) {
777   // Bits:
778   // 24: ISO 639 language code
779   //  8: subtitling type
780   // 16: composition page ID
781   // 16: ancillary page ID
782 
783   if (   (pmt_pid_info.stream_type != stream_type_e::iso_13818_pes_private)
784       || (pmt_descriptor.length     < 8))
785     return false;
786 
787   type                 = pid_type_e::subtitles;
788   codec                = codec_c::look_up(codec_c::type_e::S_DVBSUB);
789   m_codec_private_data = memory_c::alloc(5);
790   auto codec_private   = m_codec_private_data->get_buffer();
791   auto descriptor      = reinterpret_cast<unsigned char const *>(&pmt_descriptor + 1);
792 
793   parse_iso639_language_from(descriptor);
794 
795   put_uint16_be(&codec_private[0], get_uint16_be(&descriptor[4])); // composition page ID
796   put_uint16_be(&codec_private[2], get_uint16_be(&descriptor[6])); // ancillary page ID
797   codec_private[4] = descriptor[3];                                // subtitling type
798 
799   return true;
800 }
801 
802 void
parse_iso639_language_from(void const * buffer)803 track_c::parse_iso639_language_from(void const *buffer) {
804   auto value           = std::string{ reinterpret_cast<char const *>(buffer), 3 };
805   auto parsed_language = mtx::bcp47::language_c::parse(value);
806 
807   if (parsed_language.has_valid_iso639_code())
808     language = parsed_language;
809 }
810 
811 std::size_t
remaining_payload_size_to_read() const812 track_c::remaining_payload_size_to_read()
813   const {
814   return pes_payload_size_to_read - std::min(pes_payload_size_to_read, pes_payload_read->get_size());
815 }
816 
817 timestamp_c
derive_pts_from_content()818 track_c::derive_pts_from_content() {
819   if (codec.is(codec_c::type_e::S_HDMV_TEXTST))
820     return derive_hdmv_textst_pts_from_content();
821 
822   return {};
823 }
824 
825 timestamp_c
derive_hdmv_textst_pts_from_content()826 track_c::derive_hdmv_textst_pts_from_content() {
827   if (pes_payload_read->get_size() < 8)
828     return {};
829 
830   auto &file = reader.m_files[m_file_num];
831   auto buf   = pes_payload_read->get_buffer();
832 
833   if (static_cast<mtx::hdmv_textst::segment_type_e>(buf[0]) != mtx::hdmv_textst::dialog_presentation_segment)
834     return file->m_timestamp_mpls_sync;
835 
836   auto stream_timestamp = timestamp_c::mpeg((static_cast<int64_t>(buf[3] & 1) << 32) | get_uint32_be(&buf[4]));
837   auto diff             = file->m_timestamp_mpls_sync.value_or_zero() - reader.m_files[0]->m_timestamp_restriction_min.value_or_zero();
838   auto timestamp        = stream_timestamp + diff;
839 
840   return timestamp;
841 }
842 
843 void
determine_codec_from_stream_type(stream_type_e stream_type)844 track_c::determine_codec_from_stream_type(stream_type_e stream_type) {
845   switch (stream_type) {
846     case stream_type_e::iso_11172_video:
847     case stream_type_e::iso_13818_video:
848       type  = pid_type_e::video;
849       codec = codec_c::look_up(codec_c::type_e::V_MPEG12);
850       break;
851     case stream_type_e::iso_14496_part2_video:
852       type  = pid_type_e::video;
853       codec = codec_c::look_up(codec_c::type_e::V_MPEG4_P2);
854       break;
855     case stream_type_e::iso_14496_part10_video:
856       type  = pid_type_e::video;
857       codec = codec_c::look_up(codec_c::type_e::V_MPEG4_P10);
858       break;
859     case stream_type_e::iso_23008_part2_video:
860       type  = pid_type_e::video;
861       codec = codec_c::look_up(codec_c::type_e::V_MPEGH_P2);
862       break;
863     case stream_type_e::stream_video_vc1:
864       type  = pid_type_e::video;
865       codec = codec_c::look_up(codec_c::type_e::V_VC1);
866       break;
867     case stream_type_e::iso_11172_audio:
868     case stream_type_e::iso_13818_audio:
869       type  = pid_type_e::audio;
870       codec = codec_c::look_up(codec_c::type_e::A_MP3);
871       break;
872     case stream_type_e::iso_13818_part7_audio:
873     case stream_type_e::iso_14496_part3_audio:
874       type  = pid_type_e::audio;
875       codec = codec_c::look_up(codec_c::type_e::A_AAC);
876       break;
877     case stream_type_e::stream_audio_pcm:
878       type  = pid_type_e::audio;
879       codec = codec_c::look_up(codec_c::type_e::A_PCM);
880       break;
881 
882     case stream_type_e::stream_audio_ac3_lossless: {
883       auto ac3_track       = std::make_shared<track_c>(*this);
884       ac3_track->type      = pid_type_e::audio;
885       ac3_track->codec     = codec_c::look_up(codec_c::type_e::A_AC3);
886       ac3_track->converter = std::make_shared<truehd_ac3_splitting_packet_converter_c>();
887       ac3_track->m_master  = this;
888       ac3_track->set_pid(pid);
889 
890       type                 = pid_type_e::audio;
891       codec                = codec_c::look_up(codec_c::type_e::A_TRUEHD);
892       converter            = ac3_track->converter;
893       m_coupled_tracks.push_back(ac3_track);
894 
895       break;
896     }
897 
898     case stream_type_e::stream_audio_ac3:
899     case stream_type_e::stream_audio_eac3:      // E-AC-3
900     case stream_type_e::stream_audio_eac3_2:    // E-AC-3 secondary stream
901     case stream_type_e::stream_audio_eac3_atsc: // E-AC-3 as defined in ATSC A/52:2012 Annex G
902       type      = pid_type_e::audio;
903       codec     = codec_c::look_up(codec_c::type_e::A_AC3);
904       break;
905     case stream_type_e::stream_audio_dts:
906     case stream_type_e::stream_audio_dts_hd:
907     case stream_type_e::stream_audio_dts_hd_ma:
908     case stream_type_e::stream_audio_dts_hd2:
909       type      = pid_type_e::audio;
910       codec     = codec_c::look_up(codec_c::type_e::A_DTS);
911       break;
912     case stream_type_e::stream_subtitles_hdmv_pgs:
913       type      = pid_type_e::subtitles;
914       codec     = codec_c::look_up(codec_c::type_e::S_HDMV_PGS);
915       probed_ok = true;
916       break;
917     case stream_type_e::stream_subtitles_hdmv_textst:
918       type      = pid_type_e::subtitles;
919       codec     = codec_c::look_up(codec_c::type_e::S_HDMV_TEXTST);
920       break;
921     case stream_type_e::iso_13818_pes_private:
922       break;
923     default:
924       mxdebug_if(reader.m_debug_pat_pmt, fmt::format("parse_pmt: Unknown stream type: {0}\n", static_cast<int>(stream_type)));
925       type      = pid_type_e::unknown;
926       break;
927   }
928 }
929 
930 void
reset_processing_state()931 track_c::reset_processing_state() {
932   m_timestamp.reset();
933   m_previous_timestamp.reset();
934   m_previous_valid_timestamp.reset();
935   m_expected_next_continuity_counter.reset();
936 
937   clear_pes_payload();
938   processed            = false;
939   m_timestamps_wrapped = false;
940   m_timestamp_wrap_add = timestamp_c::ns(0);
941 }
942 
943 bool
transport_error_detected(packet_header_t & ts_header) const944 track_c::transport_error_detected(packet_header_t &ts_header)
945   const {
946   if (ts_header.has_transport_error())
947     return true;
948 
949   if (!m_expected_next_continuity_counter)
950     return false;
951 
952   return ts_header.continuity_counter() != m_expected_next_continuity_counter.value();
953 }
954 
955 void
set_packetizer_source_id() const956 track_c::set_packetizer_source_id()
957   const {
958   if (!reader.m_is_reading_mpls || (ptzr < 0))
959     return;
960 
961   reader.m_reader_packetizers[ptzr]->set_source_id(fmt::format("00{0:04x}", pid));
962 }
963 
964 // ------------------------------------------------------------
965 
file_t(mm_io_cptr const & in)966 file_t::file_t(mm_io_cptr const &in)
967   : m_in{in}
968   , m_pat_found{}
969   , m_num_pmts_found{}
970   , m_num_pmts_to_find{}
971   , m_es_to_process{}
972   , m_stream_timestamp{timestamp_c::ns(0)}
973   , m_timestamp_mpls_sync{timestamp_c::ns(0)}
974   , m_state{processing_state_e::probing}
975   , m_probe_range{}
976   , m_file_done{}
977   , m_packet_sent_to_packetizer{}
978   , m_detected_packet_size{}
979   , m_num_pat_crc_errors{}
980   , m_num_pmt_crc_errors{}
981   , m_validate_pat_crc{true}
982   , m_validate_pmt_crc{true}
983   , m_has_audio_or_video_track{}
984 {
985 }
986 
987 int64_t
get_queued_bytes() const988 file_t::get_queued_bytes()
989   const {
990   int64_t bytes{};
991 
992   for (auto ptzr : m_packetizers)
993     bytes += ptzr->get_queued_bytes();
994 
995   return bytes;
996 }
997 
998 void
reset_processing_state(processing_state_e new_state)999 file_t::reset_processing_state(processing_state_e new_state) {
1000   m_state = new_state;
1001   m_last_non_subtitle_pts.reset();
1002   m_last_non_subtitle_dts.reset();
1003 }
1004 
1005 bool
all_pmts_found() const1006 file_t::all_pmts_found()
1007   const {
1008   return (0 != m_num_pmts_to_find) && (m_num_pmts_found >= m_num_pmts_to_find);
1009 }
1010 
1011 uint64_t
get_start_source_packet_position() const1012 file_t::get_start_source_packet_position()
1013   const {
1014   return m_start_source_packet_number * m_detected_packet_size;
1015 }
1016 
1017 // ------------------------------------------------------------
1018 
1019 bool
probe_file()1020 reader_c::probe_file() {
1021   return detect_packet_size(*m_in, m_in->get_size()) > 0;
1022 }
1023 
1024 int
detect_packet_size(mm_io_c & in,uint64_t size)1025 reader_c::detect_packet_size(mm_io_c &in,
1026                              uint64_t size) {
1027   debugging_option_c debug{"mpeg_ts|mpeg_ts_packet_size"};
1028 
1029   try {
1030     size                         = std::min<uint64_t>(1024 * 1024, size);
1031     auto num_startcodes_required = std::max<uint64_t>(size / 3 / TS_MAX_PACKET_SIZE, 32);
1032     auto buffer                  = memory_c::alloc(size);
1033     auto mem                     = buffer->get_buffer();
1034 
1035     mxdebug_if(debug, fmt::format("detect_packet_size: size to probe {0} num required startcodes {1}\n", size, num_startcodes_required));
1036 
1037     in.setFilePointer(0);
1038     size = in.read(mem, size);
1039 
1040     std::vector<int> positions;
1041     for (int i = 0; i < static_cast<int>(size); ++i)
1042       if (0x47 == mem[i])
1043         positions.push_back(i);
1044 
1045     for (int i = 0, num_positions = positions.size(); i < num_positions; ++i) {
1046       for (int k = 0; 0 != potential_packet_sizes[k]; ++k) {
1047         unsigned int pos            = positions[i];
1048         unsigned int packet_size    = potential_packet_sizes[k];
1049         unsigned int num_startcodes = 1;
1050 
1051         while ((num_startcodes_required > num_startcodes) && (pos < size) && (0x47 == mem[pos])) {
1052           pos += packet_size;
1053           ++num_startcodes;
1054         }
1055 
1056         if (num_startcodes_required <= num_startcodes) {
1057           mxdebug_if(debug, fmt::format("detect_packet_size: detected packet size {0} at offset {1}\n", packet_size, positions[i]));
1058           return packet_size;
1059         }
1060       }
1061     }
1062   } catch (...) {
1063   }
1064 
1065   mxdebug_if(debug, "detect_packet_size: packet size could not be determined\n");
1066 
1067   return -1;
1068 }
1069 
1070 void
setup_initial_tracks()1071 reader_c::setup_initial_tracks() {
1072   m_tracks.clear();
1073 
1074   m_tracks.push_back(std::make_shared<track_c>(*this, pid_type_e::pat));
1075   m_tracks.push_back(std::make_shared<track_c>(*this, pid_type_e::sdt));
1076   m_tracks.back()->set_pid(TS_SDT_PID);
1077 
1078   auto &f                      = file();
1079   f.m_ignored_pids[TS_PAT_PID] = true;
1080   f.m_ignored_pids[TS_SDT_PID] = true;
1081 }
1082 
1083 void
read_headers_for_file(std::size_t file_num)1084 reader_c::read_headers_for_file(std::size_t file_num) {
1085   m_current_file = file_num;
1086   auto &f        = file();
1087 
1088   setup_initial_tracks();
1089 
1090   try {
1091     auto file_size           = f.m_in->get_size();
1092     m_bytes_to_process      += file_size;
1093     f.m_probe_range          = calculate_probe_range(file_size, 10 * 1024 * 1024);
1094     auto size_to_probe       = std::min<uint64_t>(file_size,     f.m_probe_range);
1095     auto min_size_to_probe   = std::min<uint64_t>(size_to_probe, 5 * 1024 * 1024);
1096     f.m_detected_packet_size = detect_packet_size(*f.m_in, size_to_probe);
1097 
1098     f.m_in->setFilePointer(0);
1099 
1100     mxdebug_if(m_debug_headers, fmt::format("read_headers: Starting to build PID list. (packet size: {0})\n", f.m_detected_packet_size));
1101 
1102     unsigned char buf[TS_MAX_PACKET_SIZE]; // maximum TS packet size + 1
1103 
1104     while (true) {
1105       if (f.m_in->read(buf, f.m_detected_packet_size) != static_cast<unsigned int>(f.m_detected_packet_size))
1106         break;
1107 
1108       if (buf[0] != 0x47) {
1109         if (resync(f.m_in->getFilePointer() - f.m_detected_packet_size))
1110           continue;
1111         break;
1112       }
1113 
1114       parse_packet(buf);
1115 
1116       if (   f.m_pat_found
1117           && f.all_pmts_found()
1118           && (0 == f.m_es_to_process)
1119           && (f.m_in->getFilePointer() >= min_size_to_probe))
1120         break;
1121 
1122       auto eof = f.m_in->eof() || (f.m_in->getFilePointer() >= size_to_probe);
1123       if (!eof)
1124         continue;
1125 
1126       // Determine if we haven't found a PAT or a PMT but have plenty
1127       // of CRC errors (e.g. for badly mastered discs). In such a case
1128       // we should read from the start again, this time ignoring the
1129       // errors for the specific type.
1130       mxdebug_if(m_debug_headers,
1131                  fmt::format("read_headers: EOF during detection. #tracks {0} #PAT CRC errors {1} #PMT CRC errors {2} PAT found {3} PMT found {4}/{5}\n",
1132                              m_tracks.size(), f.m_num_pat_crc_errors, f.m_num_pmt_crc_errors, f.m_pat_found, f.m_num_pmts_found, f.m_num_pmts_to_find));
1133 
1134       if (!f.m_pat_found && f.m_validate_pat_crc)
1135         f.m_validate_pat_crc = false;
1136 
1137       else if (f.m_pat_found && !f.all_pmts_found() && f.m_validate_pmt_crc) {
1138         f.m_validate_pmt_crc = false;
1139         f.m_num_pmts_to_find = 0;
1140         f.m_pmt_pid_seen.clear();
1141 
1142       } else
1143         break;
1144 
1145       f.m_in->setFilePointer(0);
1146       f.m_in->clear_eof();
1147 
1148       setup_initial_tracks();
1149     }
1150   } catch (...) {
1151     mxdebug_if(m_debug_headers, fmt::format("read_headers: caught exception\n"));
1152   }
1153 
1154   mxdebug_if(m_debug_headers, fmt::format("read_headers: Detection done on {0} bytes\n", f.m_in->getFilePointer()));
1155 
1156   // Run probe_packet_complete() for track-type detection once for
1157   // each track. This way tracks that don't actually need their
1158   // content to be found during probing will be set to OK, too.
1159   for (auto const &track : m_tracks) {
1160     if (track->is_pes_payload_size_unbounded() && (track->pes_payload_read->get_size() >= 6))
1161       parse_pes(*track);
1162 
1163     track->clear_pes_payload();
1164     probe_packet_complete(*track, true);
1165   }
1166 
1167   std::copy(m_tracks.begin(), m_tracks.end(), std::back_inserter(m_all_probed_tracks));
1168 }
1169 
1170 void
determine_start_source_packet_number(file_t & file)1171 reader_c::determine_start_source_packet_number(file_t &file) {
1172   mxdebug_if(m_debug_mpls, fmt::format("MPLS: start SPN: file {0} min timestamp restriction {1}\n", to_utf8(Q(file.m_in->get_file_name()).replace(QRegularExpression{".*[/\\\\]"}, {})), file.m_timestamp_restriction_min));
1173 
1174   if (!file.m_clpi_parser || !file.m_timestamp_restriction_min.valid()) {
1175     mxdebug_if(m_debug_mpls, fmt::format("MPLS: start SPN: clip information not found or no minimum timestamp restriction\n"));
1176     return;
1177   }
1178 
1179   std::vector<uint64_t> source_packet_numbers;
1180 
1181   for (auto const &ep_map : file.m_clpi_parser->m_ep_map) {
1182     std::optional<uint64_t> source_packet_number;
1183 
1184     for (auto const &point : ep_map.points) {
1185       if (point.pts <= file.m_timestamp_restriction_min)
1186         source_packet_number = point.spn;
1187       else
1188         break;
1189     }
1190 
1191     if (source_packet_number) {
1192       mxdebug_if(m_debug_mpls, fmt::format("MPLS: start SPN: candidate SPN for PID {0} is {1}\n", ep_map.pid, *source_packet_number));
1193       source_packet_numbers.push_back(*source_packet_number);
1194     }
1195   }
1196 
1197   if (!source_packet_numbers.empty())
1198     file.m_start_source_packet_number = *std::min_element(source_packet_numbers.begin(), source_packet_numbers.end());
1199 
1200   mxdebug_if(m_debug_mpls, fmt::format("MPLS: start SPN: chosen start SPN is {0}\n", file.m_start_source_packet_number));
1201 }
1202 
1203 void
read_headers()1204 reader_c::read_headers() {
1205   m_files.emplace_back(std::make_shared<file_t>(m_in));
1206 
1207   m_files[0]->m_timestamp_restriction_min = m_restricted_timestamps_min;
1208   m_files[0]->m_timestamp_restriction_max = m_restricted_timestamps_max;
1209 
1210   auto mpls_in = dynamic_cast<mm_mpls_multi_file_io_c *>(get_underlying_input());
1211   if (mpls_in) {
1212     m_is_reading_mpls = true;
1213     m_mpls_chapters   = mpls_in->get_chapters();
1214 
1215     add_external_files_from_mpls(*mpls_in);
1216   }
1217 
1218   for (int idx = 0, num_files = m_files.size(); idx < num_files; ++idx)
1219     read_headers_for_file(idx);
1220 
1221   m_tracks = std::move(m_all_probed_tracks);
1222 
1223   for (int idx = 0, num_files = m_files.size(); idx < num_files; ++idx) {
1224     parse_clip_info_file(idx);
1225     determine_start_source_packet_number(*m_files[idx]);
1226   }
1227 
1228   process_chapter_entries();
1229 
1230   std::vector<track_ptr> identified_tracks;
1231 
1232   auto track_id = uint64_t{};
1233   for (auto &track : m_tracks) {
1234     // For TrueHD tracks detection for embedded AC-3 frames is
1235     // done. However, "probed_ok" is only set on the TrueHD track if
1236     // both types have been found. If only TrueHD is found then
1237     // "probed_ok" must be set to true after detection has exhausted
1238     // the search space; otherwise a TrueHD-only track would never be
1239     // considered OK.
1240     if (track->codec.is(codec_c::type_e::A_TRUEHD) && track->m_truehd_found_truehd)
1241       track->probed_ok = true;
1242 
1243     if (!track->probed_ok || !track->codec)
1244       continue;
1245 
1246     track->clear_pes_payload();
1247     track->processed        = false;
1248     track->m_id             = track_id++;
1249     // track->timestamp_offset = -1;
1250 
1251     for (auto const &coupled_track : track->m_coupled_tracks)
1252       if (!coupled_track->language.is_valid())
1253         coupled_track->language = track->language;
1254 
1255     identified_tracks.push_back(track);
1256   }
1257 
1258   m_tracks = std::move(identified_tracks);
1259 
1260   show_demuxer_info();
1261 }
1262 
1263 void
reset_processing_state(processing_state_e new_state)1264 reader_c::reset_processing_state(processing_state_e new_state) {
1265   for (auto const &file : m_files)
1266     file->reset_processing_state(new_state);
1267 
1268   for (auto const &track : m_tracks)
1269     track->reset_processing_state();
1270 
1271   m_packet_num = 0;
1272 }
1273 
1274 void
determine_global_timestamp_offset()1275 reader_c::determine_global_timestamp_offset() {
1276   reset_processing_state(processing_state_e::determining_timestamp_offset);
1277 
1278   auto &f = file();
1279 
1280   auto probe_start_pos = f.get_start_source_packet_position();
1281   auto probe_end_pos   = probe_start_pos + f.m_probe_range;
1282 
1283   f.m_in->setFilePointer(probe_start_pos);
1284   f.m_in->clear_eof();
1285 
1286   mxdebug_if(m_debug_timestamp_offset, fmt::format("determine_global_timestamp_offset: determining global timestamp offset from the first {0} bytes\n", f.m_probe_range));
1287 
1288   try {
1289     unsigned char buf[TS_MAX_PACKET_SIZE]; // maximum TS packet size + 1
1290 
1291     while (f.m_in->getFilePointer() < probe_end_pos) {
1292       if (f.m_in->read(buf, f.m_detected_packet_size) != static_cast<unsigned int>(f.m_detected_packet_size))
1293         break;
1294 
1295       if (buf[0] != 0x47) {
1296         if (resync(f.m_in->getFilePointer() - f.m_detected_packet_size))
1297           continue;
1298         break;
1299       }
1300 
1301       parse_packet(buf);
1302     }
1303   } catch (...) {
1304     mxdebug_if(m_debug_timestamp_offset, fmt::format("determine_global_timestamp_offset: caught exception\n"));
1305   }
1306 
1307   mxdebug_if(m_debug_timestamp_offset, fmt::format("determine_global_timestamp_offset: detection done; global timestamp offset is {0}\n", f.m_global_timestamp_offset));
1308 
1309   f.m_in->setFilePointer(f.get_start_source_packet_position());
1310   f.m_in->clear_eof();
1311 
1312   reset_processing_state(processing_state_e::muxing);
1313 
1314   if (debugging_c::requested("mpeg_ts_dont_offset_timestamps"))
1315     for (auto const &file : m_files)
1316       file->m_global_timestamp_offset = timestamp_c::ns(0);
1317 }
1318 
1319 void
process_chapter_entries()1320 reader_c::process_chapter_entries() {
1321   if (m_mpls_chapters.empty() || m_ti.m_no_chapters)
1322     return;
1323 
1324   auto language    = m_ti.m_chapter_language.is_valid() ? m_ti.m_chapter_language
1325                    : g_default_language.is_valid()      ? g_default_language
1326                    :                                      mtx::bcp47::language_c::parse("eng");
1327 
1328   m_chapters       = mtx::chapters::convert_mpls_chapters_kax_chapters(m_mpls_chapters, language);
1329 
1330   auto const &sync = mtx::includes(m_ti.m_timestamp_syncs, track_info_c::chapter_track_id) ? m_ti.m_timestamp_syncs[track_info_c::chapter_track_id]
1331                    : mtx::includes(m_ti.m_timestamp_syncs, track_info_c::all_tracks_id)    ? m_ti.m_timestamp_syncs[track_info_c::all_tracks_id]
1332                    :                                                                         timestamp_sync_t{};
1333   mtx::chapters::adjust_timestamps(*m_chapters, sync.displacement, sync.factor);
1334 }
1335 
1336 uint32_t
calculate_crc(void const * buffer,size_t size) const1337 reader_c::calculate_crc(void const *buffer,
1338                         size_t size)
1339   const {
1340   return mtx::bytes::swap_32(mtx::checksum::calculate_as_uint(mtx::checksum::algorithm_e::crc32_ieee, buffer, size, 0xffffffff));
1341 }
1342 
1343 void
add_multiplexed_ids(std::vector<uint64_t> & multiplexed_ids,track_c & track)1344 reader_c::add_multiplexed_ids(std::vector<uint64_t> &multiplexed_ids,
1345                               track_c &track) {
1346   multiplexed_ids.push_back(track.m_id);
1347   for (auto const &coupled_track : track.m_coupled_tracks)
1348     if (coupled_track->probed_ok)
1349       multiplexed_ids.push_back(coupled_track->m_id);
1350 }
1351 
1352 void
add_programs_to_identification_info(mtx::id::info_c & info)1353 reader_c::add_programs_to_identification_info(mtx::id::info_c &info) {
1354   if (m_files[0]->m_programs.empty())
1355     return;
1356 
1357   std::sort(m_files[0]->m_programs.begin(), m_files[0]->m_programs.end());
1358 
1359   auto programs_json = nlohmann::json::array();
1360 
1361   for (auto &program : m_files[0]->m_programs) {
1362     auto program_json = nlohmann::json{
1363       { mtx::id::program_number,   program.program_number },
1364       { mtx::id::service_provider, program.service_provider },
1365       { mtx::id::service_name,     program.service_name },
1366     };
1367 
1368     programs_json.push_back(program_json);
1369   }
1370 
1371   info.add(mtx::id::programs, programs_json);
1372 }
1373 
1374 void
identify()1375 reader_c::identify() {
1376   auto info    = mtx::id::info_c{};
1377   auto mpls_in = dynamic_cast<mm_mpls_multi_file_io_c *>(get_underlying_input());
1378   if (mpls_in)
1379     mpls_in->create_verbose_identification_info(info);
1380 
1381   add_programs_to_identification_info(info);
1382 
1383   id_result_container(info.get());
1384 
1385   for (auto const &track : m_tracks) {
1386     info = mtx::id::info_c{};
1387     info.add(mtx::id::language,  track->language.get_iso639_alpha_3_code());
1388     info.set(mtx::id::stream_id, track->pid);
1389     info.set(mtx::id::number,    track->pid);
1390 
1391     if (track->program_number)
1392       info.set(mtx::id::program_number, track->program_number.value());
1393 
1394     if (pid_type_e::audio == track->type) {
1395       info.add(mtx::id::audio_channels,           track->a_channels);
1396       info.add(mtx::id::audio_sampling_frequency, track->a_sample_rate);
1397       info.add(mtx::id::audio_bits_per_sample,    track->a_bits_per_sample);
1398 
1399     } else if (pid_type_e::video == track->type)
1400       info.add(mtx::id::pixel_dimensions, fmt::format("{0}x{1}", track->v_width, track->v_height));
1401 
1402     else if (pid_type_e::subtitles == track->type) {
1403       info.set(mtx::id::text_subtitles, track->codec.is(codec_c::type_e::S_SRT));
1404       if (track->m_ttx_wanted_page)
1405         info.set(mtx::id::teletext_page, *track->m_ttx_wanted_page);
1406     }
1407 
1408     auto multiplexed_track_ids = std::vector<uint64_t>{};
1409     if (!track->m_coupled_tracks.empty())
1410       add_multiplexed_ids(multiplexed_track_ids, *track);
1411 
1412     else if (track->m_master)
1413       add_multiplexed_ids(multiplexed_track_ids, *track->m_master);
1414 
1415     if (!multiplexed_track_ids.empty()) {
1416       std::sort(multiplexed_track_ids.begin(), multiplexed_track_ids.end());
1417       info.set(mtx::id::multiplexed_tracks, multiplexed_track_ids);
1418     }
1419 
1420     std::string type = pid_type_e::audio == track->type ? ID_RESULT_TRACK_AUDIO
1421                      : pid_type_e::video == track->type ? ID_RESULT_TRACK_VIDEO
1422                      :                                    ID_RESULT_TRACK_SUBTITLES;
1423 
1424     id_result_track(track->m_id, type, track->codec.get_name(), info.get());
1425   }
1426 
1427   if (!m_mpls_chapters.empty())
1428     id_result_chapters(m_mpls_chapters.size());
1429 }
1430 
1431 bool
parse_pat(track_c & track)1432 reader_c::parse_pat(track_c &track) {
1433   if (track.pes_payload_read->get_size() < sizeof(pat_t)) {
1434     mxdebug_if(m_debug_pat_pmt, "Invalid parameters!\n");
1435     return false;
1436   }
1437 
1438   auto pat        = track.pes_payload_read->get_buffer();
1439   auto pat_header = reinterpret_cast<pat_t *>(pat);
1440 
1441   if (pat_header->table_id != 0x00) {
1442     mxdebug_if(m_debug_pat_pmt, "Invalid PAT table_id!\n");
1443     return false;
1444   }
1445 
1446   if (pat_header->get_section_syntax_indicator() != 1 || pat_header->get_current_next_indicator() == 0) {
1447     mxdebug_if(m_debug_pat_pmt, "Invalid PAT section_syntax_indicator/current_next_indicator!\n");
1448     return false;
1449   }
1450 
1451   if (pat_header->section_number != 0 || pat_header->last_section_number != 0) {
1452     mxdebug_if(m_debug_pat_pmt, "Unsupported multiple section PAT!\n");
1453     return false;
1454   }
1455 
1456   auto &f                           = file();
1457   unsigned short pat_section_length = pat_header->get_section_length();
1458   uint32_t elapsed_CRC              = calculate_crc(pat, 3 + pat_section_length - 4/*CRC32*/);
1459   uint32_t read_CRC                 = get_uint32_be(pat + 3 + pat_section_length - 4);
1460 
1461   if (elapsed_CRC != read_CRC) {
1462     mxdebug_if(m_debug_pat_pmt, fmt::format("parse_pat: Wrong PAT CRC !!! Elapsed = 0x{0:08x}, read 0x{1:08x}, validate PAT CRC? {2}\n", elapsed_CRC, read_CRC, f.m_validate_pat_crc));
1463     ++f.m_num_pat_crc_errors;
1464     if (f.m_validate_pat_crc)
1465       return false;
1466   }
1467 
1468   if (pat_section_length < 13 || pat_section_length > 1021) {
1469     mxdebug_if(m_debug_pat_pmt, fmt::format("parse_pat: Wrong PAT section_length (= {0})\n", pat_section_length));
1470     return false;
1471   }
1472 
1473   auto prog_count  = static_cast<unsigned int>(pat_section_length - 5 - 4/*CRC32*/) / 4;
1474   auto pat_section = reinterpret_cast<pat_section_t *>(pat + sizeof(pat_t));
1475 
1476   for (auto i = 0u; i < prog_count; i++, pat_section++) {
1477     unsigned short local_program_number = pat_section->get_program_number();
1478     uint16_t tmp_pid                    = pat_section->get_pid();
1479 
1480     mxdebug_if(m_debug_pat_pmt,
1481                fmt::format("parse_pat: program_number: {0}; {1}_pid: {2}\n",
1482                            local_program_number,
1483                            0 == local_program_number ? "nit" : "pmt",
1484                            tmp_pid));
1485 
1486     if (!local_program_number || f.m_pmt_pid_seen[tmp_pid])
1487       continue;
1488 
1489     auto pmt                  = std::make_shared<track_c>(*this, pid_type_e::pmt);
1490     f.m_es_to_process         = 0;
1491     f.m_ignored_pids[tmp_pid] = true;
1492     f.m_pmt_pid_seen[tmp_pid] = true;
1493     f.m_pat_found             = true;
1494     ++f.m_num_pmts_to_find;
1495 
1496     pmt->set_pid(tmp_pid);
1497 
1498     m_tracks.push_back(pmt);
1499   }
1500 
1501   mxdebug_if(m_debug_pat_pmt, fmt::format("parse_pat: number of PMTs to find: {0}\n", f.m_num_pmts_to_find));
1502 
1503   return true;
1504 }
1505 
1506 memory_cptr
read_pmt_descriptor(mm_io_c & io)1507 reader_c::read_pmt_descriptor(mm_io_c &io) {
1508   auto buffer = io.read(sizeof(pmt_descriptor_t));
1509   auto length = buffer->get_buffer()[1];
1510 
1511   buffer->resize(sizeof(pmt_descriptor_t) + length);
1512   if (io.read(buffer->get_buffer() + sizeof(pmt_descriptor_t), length) != length)
1513     throw mtx::mm_io::end_of_file_x{};
1514 
1515   return buffer;
1516 }
1517 
1518 bool
parse_pmt_pid_info(mm_mem_io_c & mem,uint16_t program_number)1519 reader_c::parse_pmt_pid_info(mm_mem_io_c &mem,
1520                              uint16_t program_number) {
1521   auto &f                  = file();
1522   auto missing_tag         = true;
1523 
1524   auto pmt_pid_info_buffer = mem.read(sizeof(pmt_pid_info_t));
1525   auto pmt_pid_info        = reinterpret_cast<pmt_pid_info_t *>(pmt_pid_info_buffer->get_buffer());
1526   auto es_info_length      = pmt_pid_info->get_es_info_length();
1527 
1528   auto track               = std::make_shared<track_c>(*this);
1529   track->type              = pid_type_e::unknown;
1530   track->program_number    = program_number;
1531 
1532   track->set_pid(pmt_pid_info->get_pid());
1533   track->determine_codec_from_stream_type(pmt_pid_info->stream_type);
1534 
1535   while (es_info_length >= sizeof(pmt_descriptor_t)) {
1536     auto pmt_descriptor_buffer = read_pmt_descriptor(mem);
1537     auto pmt_descriptor        = reinterpret_cast<pmt_descriptor_t *>(pmt_descriptor_buffer->get_buffer());
1538 
1539     mxdebug_if(m_debug_pat_pmt, fmt::format("parse_pmt: PMT descriptor tag 0x{0:02x} length {1}\n", static_cast<unsigned int>(pmt_descriptor->tag), static_cast<unsigned int>(pmt_descriptor->length)));
1540 
1541     if (pmt_descriptor_buffer->get_size() > es_info_length)
1542       break;
1543 
1544     es_info_length -= pmt_descriptor_buffer->get_size();
1545 
1546     if (0x0a != pmt_descriptor->tag)
1547       missing_tag = false;
1548 
1549     switch (pmt_descriptor->tag) {
1550       case 0x05: // registration descriptor
1551         track->parse_registration_pmt_descriptor(*pmt_descriptor, *pmt_pid_info);
1552         break;
1553       case 0x0a: // ISO 639 language descriptor
1554         track->parse_iso639_language_from(pmt_descriptor + 1);
1555         break;
1556       case 0x56: // Teletext descriptor
1557         track->parse_srt_pmt_descriptor(*pmt_descriptor, *pmt_pid_info);
1558         break;
1559       case 0x59: // Subtitles descriptor
1560         track->parse_subtitling_pmt_descriptor(*pmt_descriptor, *pmt_pid_info);
1561         break;
1562       case 0x6A: // AC-3 descriptor
1563       case 0x7A: // E-AC-3 descriptor
1564         track->parse_ac3_pmt_descriptor(*pmt_descriptor, *pmt_pid_info);
1565         break;
1566       case 0x7b: // DTS descriptor
1567         track->parse_dts_pmt_descriptor(*pmt_descriptor, *pmt_pid_info);
1568         break;
1569     }
1570   }
1571 
1572   // Default to AC-3 if it's a PES private stream type that's missing
1573   // a known/more concrete descriptor tag.
1574   if ((pmt_pid_info->stream_type == stream_type_e::iso_13818_pes_private) && missing_tag) {
1575     track->type  = pid_type_e::audio;
1576     track->codec = codec_c::look_up(codec_c::type_e::A_AC3);
1577   }
1578 
1579   if (track->type != pid_type_e::unknown) {
1580     track->processed = false;
1581     m_tracks.push_back(track);
1582     ++f.m_es_to_process;
1583 
1584     std::copy(track->m_coupled_tracks.begin(), track->m_coupled_tracks.end(), std::back_inserter(m_tracks));
1585     f.m_es_to_process += track->m_coupled_tracks.size();
1586   }
1587 
1588   mxdebug_if(m_debug_pat_pmt,
1589              fmt::format("parse_pmt: PID {0} stream type {1:02x} has type: {2}\n",
1590                          track->pid,
1591                          static_cast<unsigned int>(pmt_pid_info->stream_type),
1592                          track->type != pid_type_e::unknown ? track->codec.get_name() : "<unknown>"));
1593 
1594   return true;
1595 }
1596 
1597 bool
parse_pmt(track_c & track)1598 reader_c::parse_pmt(track_c &track) {
1599   auto payload_size = track.pes_payload_read->get_size();
1600   auto pmt_start    = track.pes_payload_read->get_buffer();
1601   auto pmt_end      = pmt_start + payload_size;
1602 
1603   if (payload_size < sizeof(pmt_t)) {
1604     mxdebug_if(m_debug_pat_pmt, fmt::format("Actual PMT size {0} less than PMT structure size {1}!\n", payload_size, sizeof(pmt_t)));
1605     return false;
1606   }
1607 
1608   auto pmt_header     = reinterpret_cast<pmt_t *>(pmt_start);
1609   auto program_number = get_uint16_be(&pmt_header->program_number);
1610 
1611   if (pmt_header->table_id != 0x02) {
1612     mxdebug_if(m_debug_pat_pmt, "Invalid PMT table_id!\n");
1613     return false;
1614   }
1615 
1616   if (pmt_header->get_section_syntax_indicator() != 1 || pmt_header->get_current_next_indicator() == 0) {
1617     mxdebug_if(m_debug_pat_pmt, "Invalid PMT section_syntax_indicator/current_next_indicator!\n");
1618     return false;
1619   }
1620 
1621   if (pmt_header->section_number != 0 || pmt_header->last_section_number != 0) {
1622     mxdebug_if(m_debug_pat_pmt, "Unsupported multiple section PMT!\n");
1623     return false;
1624   }
1625 
1626   auto &f                  = file();
1627   auto pmt_section_length  = pmt_header->get_section_length();
1628   auto pmt_section_start   = pmt_start         + offsetof(pmt_t, program_number);
1629   auto pmt_section_end     = pmt_section_start + pmt_section_length;
1630   auto program_info_length = pmt_header->get_program_info_length();
1631   auto program_info_start  = pmt_start + sizeof(pmt_t);
1632   auto program_info_end    = program_info_start + program_info_length;
1633 
1634   if (program_info_end > pmt_end) {
1635     mxdebug_if(m_debug_pat_pmt, fmt::format("Actual PMT size {0} less than PMT program info size + program info offset {1}!\n", payload_size, pmt_end - pmt_start));
1636     return false;
1637   }
1638 
1639   if (pmt_section_end > pmt_end) {
1640     mxdebug_if(m_debug_pat_pmt, fmt::format("Actual PMT size {0} less than PMT section size + section offset {1}!\n", payload_size, pmt_end - pmt_start));
1641     return false;
1642   }
1643 
1644   if ((pmt_section_length < 13) || (pmt_section_length > 1021)) {
1645     mxdebug_if(m_debug_pat_pmt, fmt::format("parse_pmt: Wrong PMT section_length {0}\n", pmt_section_length));
1646     return false;
1647   }
1648 
1649   uint32_t elapsed_CRC = calculate_crc(pmt_start, 3 + pmt_section_length - 4/*CRC32*/);
1650   uint32_t read_CRC    = get_uint32_be(pmt_section_end - 4);
1651 
1652   if (elapsed_CRC != read_CRC) {
1653     mxdebug_if(m_debug_pat_pmt, fmt::format("parse_pmt: Wrong PMT CRC !!! Elapsed = 0x{0:08x}, read 0x{1:08x}, validate PMT CRC? {2}\n", elapsed_CRC, read_CRC, f.m_validate_pmt_crc));
1654     ++f.m_num_pmt_crc_errors;
1655     if (f.m_validate_pmt_crc)
1656       return false;
1657   }
1658 
1659   mxdebug_if(m_debug_pat_pmt,
1660              fmt::format("parse_pmt: program number: {0} PCR PID: {1} program info length: {2}\n",
1661                          pmt_header->get_program_number(), pmt_header->get_pcr_pid(), program_info_length));
1662 
1663   mm_mem_io_c mem{program_info_end, static_cast<uint64_t>(pmt_section_end - 4 - program_info_end)};
1664 
1665   try {
1666     bool ok = true;
1667     while (ok)
1668       ok = parse_pmt_pid_info(mem, program_number);
1669 
1670   } catch (mtx::mm_io::exception &) {
1671   }
1672 
1673   f.m_ignored_pids[track.pid] = true;
1674 
1675   ++f.m_num_pmts_found;
1676 
1677   mxdebug_if(m_debug_pat_pmt,
1678              fmt::format("parse_pmt: {0} num PMTs found {1} vs. to find {2}\n",
1679                            f.m_num_pmts_found  < f.m_num_pmts_to_find ? "find_ongoing"
1680                          : f.m_num_pmts_found == f.m_num_pmts_to_find ? "find_done"
1681                          :                                              "find_error",
1682                          f.m_num_pmts_found, f.m_num_pmts_to_find));
1683 
1684   return true;
1685 }
1686 
1687 charset_converter_cptr
get_charset_converter_for_coding_type(unsigned int coding)1688 reader_c::get_charset_converter_for_coding_type(unsigned int coding) {
1689   static std::unordered_map<unsigned int, std::string> coding_names;
1690 
1691   if (coding_names.empty()) {
1692     coding_names[0x00]     = "ISO6937";
1693     coding_names[0x01]     = "ISO8859-5";
1694     coding_names[0x02]     = "ISO8859-6";
1695     coding_names[0x03]     = "ISO8859-7";
1696     coding_names[0x04]     = "ISO8859-8";
1697     coding_names[0x05]     = "ISO8859-9";
1698     coding_names[0x06]     = "ISO8859-10";
1699     coding_names[0x07]     = "ISO8859-11";
1700     coding_names[0x09]     = "ISO8859-13";
1701     coding_names[0x0a]     = "ISO8859-14";
1702     coding_names[0x0b]     = "ISO8859-15";
1703     coding_names[0x10]     = "ISO8859";
1704     coding_names[0x13]     = "GB2312";
1705     coding_names[0x14]     = "BIG5";
1706     coding_names[0x100001] = "ISO8859-1";
1707     coding_names[0x100002] = "ISO8859-2";
1708     coding_names[0x100003] = "ISO8859-3";
1709     coding_names[0x100004] = "ISO8859-4";
1710     coding_names[0x100005] = "ISO8859-5";
1711     coding_names[0x100006] = "ISO8859-6";
1712     coding_names[0x100007] = "ISO8859-7";
1713     coding_names[0x100008] = "ISO8859-8";
1714     coding_names[0x100009] = "ISO8859-9";
1715     coding_names[0x10000a] = "ISO8859-10";
1716     coding_names[0x10000b] = "ISO8859-11";
1717     coding_names[0x10000d] = "ISO8859-13";
1718     coding_names[0x10000e] = "ISO8859-14";
1719     coding_names[0x10000f] = "ISO8859-15";
1720   }
1721 
1722   auto coding_name = coding_names[coding];
1723   if (coding_name.empty())
1724     coding_name = "UTF-8";
1725 
1726   auto converter = charset_converter_c::init(coding_name, true);
1727   return converter ? converter : charset_converter_c::init("UTF-8");
1728 }
1729 
1730 std::string
read_descriptor_string(mtx::bits::reader_c & r)1731 reader_c::read_descriptor_string(mtx::bits::reader_c &r) {
1732   auto str_length = r.get_bits(8);
1733   if (!str_length)
1734     return {};
1735 
1736   std::string content(str_length, ' ');
1737 
1738   r.get_bytes(reinterpret_cast<unsigned char *>(&content[0]), str_length);
1739 
1740   auto coding = static_cast<unsigned int>(content[0]);
1741 
1742   if (coding >= 0x20)
1743     coding = 0x00;
1744 
1745   else if (coding == 0x10) {
1746     if (str_length < 4)
1747       return {};
1748 
1749     coding = 0x100000 | get_uint16_be(&content[1]);
1750     content.erase(0, 3);
1751 
1752   } else if (coding == 0x1f) {
1753     if (str_length < 3)
1754       return {};
1755 
1756     coding = 0x1f00 | static_cast<unsigned char>(content[1]);
1757     content.erase(0, 2);
1758 
1759   } else
1760     content.erase(0, 1);
1761 
1762   return get_charset_converter_for_coding_type(coding)->utf8(content);
1763 }
1764 
1765 void
parse_sdt_service_desciptor(mtx::bits::reader_c & r,uint16_t program_number)1766 reader_c::parse_sdt_service_desciptor(mtx::bits::reader_c &r,
1767                                       uint16_t program_number) {
1768   r.skip_bits(8);               // service_type
1769 
1770   auto service_provider = read_descriptor_string(r);
1771   auto service_name     = read_descriptor_string(r);
1772 
1773   mxdebug_if(m_debug_sdt, fmt::format("parse_sdt: program_number {0} service_provider {1} service_name {2}\n", program_number, service_provider, service_name));
1774 
1775   file().m_programs.push_back({ program_number, service_provider, service_name });
1776 }
1777 
1778 bool
parse_sdt(track_c & track)1779 reader_c::parse_sdt(track_c &track) {
1780   if (!track.pes_payload_read->get_size())
1781     return false;
1782 
1783   at_scope_exit_c finally{[&track]() { track.clear_pes_payload(); }};
1784 
1785   try {
1786     mtx::bits::reader_c r{track.pes_payload_read->get_buffer(), track.pes_payload_read->get_size()};
1787 
1788     if (r.get_bits(8) != TS_SDT_TID)
1789       return false;
1790 
1791     r.skip_bits(1 + 1 + 2       // section_syntax_indicator, reserved_for_future_use, reserved
1792                 + 12 + 16       // section_length, transport_stream_id
1793                 + 2 + 5 + 1     // reserved, version_number, current_next_indicator
1794                 + 8 + 8         // section_number, last_section_number
1795                 + 16 + 8);      // original_network_id, reserved_future_use
1796 
1797     while (r.get_remaining_bits() > 32) { // only CRC_32
1798       auto program_number = r.get_bits(16);
1799 
1800       r.skip_bits(6 + 1 + 1     // reserved_future_use, EIT_schedule_flag, EIT_Present_following_flag
1801                   + 3 + 1);     // running_status, free_CA_mode
1802 
1803       auto descriptors_loop_end_bits = r.get_bit_position() + 12 + r.get_bits(12) * 8;
1804 
1805       while ((r.get_bit_position() + 16u) < descriptors_loop_end_bits) {
1806         auto start   = r.get_bit_position();
1807         auto tag     = r.get_bits(8);
1808         auto length  = r.get_bits(8);
1809 
1810         if ((start + 8 * (2 + length)) > descriptors_loop_end_bits)
1811           break;
1812 
1813         if (tag == 0x48)
1814           parse_sdt_service_desciptor(r, program_number);
1815 
1816         r.set_bit_position(start + 8 * (2 + length));
1817       }
1818     }
1819 
1820   } catch (mtx::mm_io::exception &) {
1821     mxdebug_if(m_debug_sdt, fmt::format("parse_sdt: exception during SDT parsing\n"));
1822     return false;
1823   }
1824 
1825   return true;
1826 }
1827 
1828 void
parse_pes(track_c & track)1829 reader_c::parse_pes(track_c &track) {
1830   at_scope_exit_c finally{[&track]() { track.clear_pes_payload(); }};
1831 
1832   auto &f             = file();
1833   auto pes            = track.pes_payload_read->get_buffer();
1834   auto const pes_size = track.pes_payload_read->get_size();
1835   auto pes_header     = reinterpret_cast<pes_header_t *>(pes);
1836 
1837   if (pes_size < 6) {
1838     mxdebug_if(m_debug_packet, fmt::format("parse_pes: error: PES payload ({0}) too small even for the basic PES header (6)\n", pes_size));
1839     return;
1840   }
1841 
1842   timestamp_c pts, dts;
1843   auto has_pts = false;
1844   auto has_dts = false;
1845   auto to_skip = 0u;
1846 
1847   if (mtx::included_in(pes_header->stream_id, mtx::mpeg1_2::PRIVATE_STREAM_2)) {
1848     to_skip = 6;
1849     track.pes_payload_read->remove(to_skip);
1850 
1851     pts = track.derive_pts_from_content();
1852     dts = pts;
1853 
1854   } else {
1855     if (pes_size < sizeof(pes_header_t)) {
1856       mxdebug_if(m_debug_packet, fmt::format("parse_pes: error: PES payload ({0}) too small for PES header structure itself ({1})\n", pes_size, sizeof(pes_header_t)));
1857       return;
1858     }
1859 
1860     has_pts = (pes_header->get_pts_dts_flags() & 0x02) == 0x02; // 10 and 11 mean PTS is present
1861     has_dts = (pes_header->get_pts_dts_flags() & 0x01) == 0x01; // 01 and 11 mean DTS is present
1862     to_skip = offsetof(pes_header_t, pes_header_data_length) + pes_header->pes_header_data_length + 1;
1863 
1864     if (pes_size < to_skip) {
1865       mxdebug_if(m_debug_packet, fmt::format("parse_pes: error: PES payload ({0}) too small for PES header + header data including PTS/DTS ({1})\n", pes_size, to_skip));
1866       return;
1867     }
1868 
1869     if (has_pts) {
1870       pts = read_timestamp(&pes_header->pts_dts);
1871       dts = pts;
1872     }
1873 
1874     if (has_dts)
1875       dts = read_timestamp(&pes_header->pts_dts + (has_pts ? 5 : 0));
1876 
1877     track.pes_payload_read->remove(to_skip);
1878   }
1879 
1880   if (!track.m_use_dts)
1881     dts = pts;
1882 
1883   auto orig_pts = pts;
1884   auto orig_dts = dts;
1885 
1886   auto result = track.handle_bogus_subtitle_timestamps(pts, dts);
1887 
1888   if (drop_decision_e::drop == result)
1889     return;
1890 
1891   track.handle_timestamp_wrap(pts, dts);
1892 
1893   auto set_global_timestamp_offset_from_pts
1894      = pts.valid()
1895     && (mtx::included_in(track.type, pid_type_e::audio, pid_type_e::video))
1896     && (!f.m_global_timestamp_offset.valid()   || (pts <  f.m_global_timestamp_offset))
1897     && (!f.m_timestamp_restriction_min.valid() || (pts >= f.m_timestamp_restriction_min));
1898 
1899   if (set_global_timestamp_offset_from_pts) {
1900     mxdebug_if(m_debug_headers,
1901                fmt::format("determining_timestamp_offset: new global timestamp offset {0} prior {1} file position afterwards {2} min_restriction {3} DTS {4}\n",
1902                            pts, f.m_global_timestamp_offset, f.m_in->getFilePointer(), f.m_timestamp_restriction_min, dts));
1903     f.m_global_timestamp_offset = pts;
1904   }
1905 
1906   if (processing_state_e::determining_timestamp_offset == f.m_state)
1907     return;
1908 
1909   if (f.m_timestamp_restriction_max.valid() && has_pts && (pts >= f.m_timestamp_restriction_max)) {
1910     mxdebug_if(m_debug_mpls, fmt::format("MPLS: stopping processing file as PTS {0} >= max. timestamp restriction {1}\n", pts, f.m_timestamp_restriction_max));
1911     f.m_in->setFilePointer(f.m_in->get_size());
1912     return;
1913   }
1914 
1915   if (m_debug_packet) {
1916     mxdebug(fmt::format("parse_pes: PES info at file position {0} (file num {1}):\n", f.m_position, track.m_file_num));
1917     mxdebug(fmt::format("parse_pes:    stream_id = {0} PID = {1}\n", static_cast<unsigned int>(pes_header->stream_id), track.pid));
1918     mxdebug(fmt::format("parse_pes:    PES_packet_length = {0}, PES_header_data_length = {1}, data starts at {2}\n", pes_size, static_cast<unsigned int>(pes_header->pes_header_data_length), to_skip));
1919     mxdebug(fmt::format("parse_pes:    PTS? {0} ({4} processed {5}) DTS? ({6} processed {7}) {1} ESCR = {2} ES_rate = {3}\n",
1920                         has_pts, has_dts, static_cast<unsigned int>(pes_header->get_escr()), static_cast<unsigned int>(pes_header->get_es_rate()), orig_pts, pts, orig_dts, dts));
1921     mxdebug(fmt::format("parse_pes:    DSM_trick_mode = {0}, add_copy = {1}, CRC = {2}, ext = {3}\n",
1922                         static_cast<unsigned int>(pes_header->get_dsm_trick_mode()), static_cast<unsigned int>(pes_header->get_additional_copy_info()), static_cast<unsigned int>(pes_header->get_pes_crc()),
1923                         static_cast<unsigned int>(pes_header->get_pes_extension())));
1924   }
1925 
1926   if (pts.valid()) {
1927     track.m_previous_valid_timestamp = pts;
1928     f.m_stream_timestamp             = pts;
1929     track.m_timestamp                = dts;
1930 
1931     mxdebug_if(m_debug_packet, fmt::format("parse_pes: PID {0} PTS found: {1} DTS: {2}\n", track.pid, pts, dts));
1932   }
1933 
1934   if (processing_state_e::probing == f.m_state)
1935     probe_packet_complete(track);
1936 
1937   else
1938     track.send_to_packetizer();
1939 }
1940 
1941 timestamp_c
read_timestamp(unsigned char * p)1942 reader_c::read_timestamp(unsigned char *p) {
1943   int64_t mpeg_timestamp  =  static_cast<int64_t>(             ( p[0]   >> 1) & 0x07) << 30;
1944   mpeg_timestamp         |= (static_cast<int64_t>(get_uint16_be(&p[1])) >> 1)         << 15;
1945   mpeg_timestamp         |=  static_cast<int64_t>(get_uint16_be(&p[3]))               >>  1;
1946 
1947   return timestamp_c::mpeg(mpeg_timestamp);
1948 }
1949 
1950 track_ptr
handle_packet_for_pid_not_listed_in_pmt(uint16_t pid)1951 reader_c::handle_packet_for_pid_not_listed_in_pmt(uint16_t pid) {
1952   auto &f = file();
1953 
1954   if (   (f.m_state != processing_state_e::probing)
1955       || f.m_ignored_pids[pid]
1956       || !f.m_pat_found
1957       || !f.all_pmts_found())
1958     return {};
1959 
1960   mxdebug_if(m_debug_pat_pmt, fmt::format("found packet for track PID {0} not listed in PMT, attempting type detection by content\n", pid));
1961 
1962   auto track = std::make_shared<track_c>(*this);
1963   track->set_pid(pid);
1964 
1965   m_tracks.push_back(track);
1966   ++f.m_es_to_process;
1967 
1968   return track;
1969 }
1970 
1971 void
parse_packet(unsigned char * buf)1972 reader_c::parse_packet(unsigned char *buf) {
1973   auto hdr   = reinterpret_cast<packet_header_t *>(buf);
1974   auto track = find_track_for_pid(hdr->get_pid());
1975 
1976   if (!track)
1977     track = handle_packet_for_pid_not_listed_in_pmt(hdr->get_pid());
1978 
1979   if (   !track
1980       || !hdr->has_payload())   // no ts_payload
1981     return;
1982 
1983   if (mtx::included_in(track->type, pid_type_e::video, pid_type_e::audio, pid_type_e::subtitles, pid_type_e::unknown))
1984     handle_transport_errors(*track, *hdr);
1985 
1986   if (   hdr->has_transport_error() // corrupted packet
1987       || track->processed)
1988     return;
1989 
1990   auto payload = determine_ts_payload_start(hdr);
1991 
1992   if (payload.second)
1993     handle_ts_payload(*track, *hdr, payload.first, payload.second);
1994 }
1995 
1996 void
handle_ts_payload(track_c & track,packet_header_t & ts_header,unsigned char * ts_payload,std::size_t ts_payload_size)1997 reader_c::handle_ts_payload(track_c &track,
1998                             packet_header_t &ts_header,
1999                             unsigned char *ts_payload,
2000                             std::size_t ts_payload_size) {
2001   if (mtx::included_in(track.type, pid_type_e::pat, pid_type_e::pmt, pid_type_e::sdt))
2002     handle_pat_pmt_payload(track, ts_header, ts_payload, ts_payload_size);
2003 
2004   else if (mtx::included_in(track.type, pid_type_e::video, pid_type_e::audio, pid_type_e::subtitles, pid_type_e::unknown))
2005     handle_pes_payload(track, ts_header, ts_payload, ts_payload_size);
2006 
2007   else {
2008     mxdebug_if(m_debug_headers, fmt::format("handle_ts_payload: error: unknown track.type {0}\n", static_cast<unsigned int>(track.type)));
2009   }
2010 }
2011 
2012 void
handle_pat_pmt_payload(track_c & track,packet_header_t & ts_header,unsigned char * ts_payload,std::size_t ts_payload_size)2013 reader_c::handle_pat_pmt_payload(track_c &track,
2014                                  packet_header_t &ts_header,
2015                                  unsigned char *ts_payload,
2016                                  std::size_t ts_payload_size) {
2017   auto &f = file();
2018 
2019   if (processing_state_e::probing != f.m_state)
2020     return;
2021 
2022   if (ts_header.is_payload_unit_start()) {
2023     auto to_skip = static_cast<std::size_t>(ts_payload[0]) + 1;
2024 
2025     if (to_skip >= ts_payload_size) {
2026       mxdebug_if(m_debug_headers, fmt::format("handle_pat_pmt_payload: error: TS payload size {0} too small; needed to skip {1}\n", ts_payload_size, to_skip));
2027       track.pes_payload_size_to_read = 0;
2028       return;
2029     }
2030 
2031     track.clear_pes_payload();
2032     auto pat_table                   = reinterpret_cast<pat_t *>(ts_payload + to_skip);
2033     ts_payload_size                 -= to_skip;
2034     ts_payload                      += to_skip;
2035     track.pes_payload_size_to_read  = pat_table->get_section_length() + 3;
2036   }
2037 
2038   track.add_pes_payload(ts_payload, ts_payload_size);
2039 
2040   if (track.is_pes_payload_complete())
2041     probe_packet_complete(track);
2042 }
2043 
2044 drop_decision_e
handle_transport_errors(track_c & track,packet_header_t & ts_header)2045 reader_c::handle_transport_errors(track_c &track,
2046                                   packet_header_t &ts_header) {
2047   auto decision = drop_decision_e::keep;
2048 
2049   if (track.transport_error_detected(ts_header) && !track.m_skip_pes_payload) {
2050     mxdebug_if(m_debug_pes_headers,
2051                fmt::format("handle_transport_errors: error detected for track PID {0} (0x{0:04x}) at {1} packet num {7} ({2}, expected continuity_counter {3} actual {4}); dropping current PES packet (expected size {5} read {6})\n",
2052                            track.pid,
2053                            file().m_position,
2054                            ts_header.has_transport_error() ? "transport_error flag" : "wrong continuity_counter",
2055                            track.m_expected_next_continuity_counter ? fmt::to_string(static_cast<unsigned int>(track.m_expected_next_continuity_counter.value())) : "—"s,
2056                            static_cast<unsigned int>(ts_header.continuity_counter()),
2057                            track.pes_payload_size_to_read,
2058                            track.pes_payload_read->get_size(),
2059                            m_packet_num));
2060 
2061     track.clear_pes_payload();
2062     track.m_skip_pes_payload = true;
2063     decision                 = drop_decision_e::drop;
2064   }
2065 
2066   track.m_expected_next_continuity_counter = (ts_header.continuity_counter() + (ts_header.has_payload() ? 1 : 0)) % 16;
2067 
2068   return decision;
2069 }
2070 
2071 void
handle_pes_payload(track_c & track,packet_header_t & ts_header,unsigned char * ts_payload,std::size_t ts_payload_size)2072 reader_c::handle_pes_payload(track_c &track,
2073                              packet_header_t &ts_header,
2074                              unsigned char *ts_payload,
2075                              std::size_t ts_payload_size) {
2076   if (ts_header.is_payload_unit_start()) {
2077     if (track.is_pes_payload_size_unbounded() && track.pes_payload_read->get_size())
2078       parse_pes(track);
2079 
2080     if (track.pes_payload_size_to_read && track.pes_payload_read->get_size() && m_debug_pes_headers)
2081       mxdebug(fmt::format("handle_pes_payload: error: dropping incomplete PES payload; target size {0} already read {1}\n", track.pes_payload_size_to_read, track.pes_payload_read->get_size()));
2082 
2083     track.clear_pes_payload();
2084 
2085     if (ts_payload_size < sizeof(pes_header_t)) {
2086       mxdebug_if(m_debug_pes_headers, fmt::format("handle_pes_payload: error: TS payload size {0} too small for PES header {1}\n", ts_payload_size, sizeof(pes_header_t)));
2087       track.m_skip_pes_payload = true;
2088       return;
2089     }
2090 
2091     auto const start_code = get_uint24_be(ts_payload);
2092     if (start_code != 0x000001) {
2093       mxdebug_if(m_debug_pes_headers, fmt::format("handle_pes_payload: error: PES header in TS payload does not start with proper start code; actual: {0:06x}\n", start_code));
2094       track.m_skip_pes_payload = true;
2095       return;
2096     }
2097 
2098     auto pes_header                = reinterpret_cast<pes_header_t *>(ts_payload);
2099     track.pes_payload_size_to_read = pes_header->get_pes_packet_length() + offsetof(pes_header_t, flags1);
2100     track.m_skip_pes_payload       = false;
2101   }
2102 
2103   if (track.m_skip_pes_payload)
2104     return;
2105 
2106   track.add_pes_payload(ts_payload, ts_payload_size);
2107 
2108   if (track.is_pes_payload_complete())
2109     parse_pes(track);
2110 }
2111 
2112 void
determine_track_type_by_pes_content(track_c & track)2113 reader_c::determine_track_type_by_pes_content(track_c &track) {
2114   auto buffer = track.pes_payload_read->get_buffer();
2115   auto size   = track.pes_payload_read->get_size();
2116 
2117   if (!size)
2118     return;
2119 
2120   if (m_debug_pat_pmt) {
2121     auto data = mtx::string::to_hex(buffer, std::min<unsigned int>(size, 4));
2122     mxdebug(fmt::format("PID {0}: attempting type detection from content for with size {1}; first four bytes: {2}\n", track.pid, size, data));
2123   }
2124 
2125   if ((size >= 3) && ((get_uint24_be(buffer) & mtx::aac::ADTS_SYNC_WORD_MASK) == mtx::aac::ADTS_SYNC_WORD)) {
2126     track.type  = pid_type_e::audio;
2127     track.codec = codec_c::look_up(codec_c::type_e::A_AAC);
2128 
2129   } else if ((size >= 2) && (get_uint16_be(buffer) == mtx::ac3::SYNC_WORD)) {
2130     track.type  = pid_type_e::audio;
2131     track.codec = codec_c::look_up(codec_c::type_e::A_AC3);
2132   }
2133 
2134   mxdebug_if(m_debug_pat_pmt, fmt::format("Detected type: {0} codec: {1}\n", static_cast<unsigned int>(track.type), track.codec));
2135 }
2136 
2137 int
determine_track_parameters(track_c & track,bool end_of_detection)2138 reader_c::determine_track_parameters(track_c &track,
2139                                      bool end_of_detection) {
2140   if (track.type == pid_type_e::pat)
2141     return parse_pat(track) ? 0 : -1;
2142 
2143   else if (track.type == pid_type_e::pmt)
2144     return parse_pmt(track) ? 0 : -1;
2145 
2146   else if (track.type == pid_type_e::sdt)
2147     return parse_sdt(track) ? 0 : -1;
2148 
2149   else if (track.type == pid_type_e::unknown)
2150     determine_track_type_by_pes_content(track);
2151 
2152   if (track.type == pid_type_e::video) {
2153     if (track.codec.is(codec_c::type_e::V_MPEG12))
2154       return track.new_stream_v_mpeg_1_2(end_of_detection);
2155     else if (track.codec.is(codec_c::type_e::V_MPEG4_P10))
2156       return track.new_stream_v_avc(end_of_detection);
2157     else if (track.codec.is(codec_c::type_e::V_MPEGH_P2))
2158       return track.new_stream_v_hevc(end_of_detection);
2159     else if (track.codec.is(codec_c::type_e::V_VC1))
2160       return track.new_stream_v_vc1();
2161 
2162     track.pes_payload_read->set_chunk_size(512 * 1024);
2163 
2164   } else if (track.type == pid_type_e::subtitles) {
2165     if (track.codec.is(codec_c::type_e::S_HDMV_TEXTST))
2166       return track.new_stream_s_hdmv_textst();
2167 
2168     else if (track.codec.is(codec_c::type_e::S_DVBSUB))
2169       return track.new_stream_s_dvbsub();
2170 
2171   } else if (track.type != pid_type_e::audio)
2172     return -1;
2173 
2174   if (track.codec.is(codec_c::type_e::A_MP3))
2175     return track.new_stream_a_mpeg();
2176   else if (track.codec.is(codec_c::type_e::A_AAC))
2177     return track.new_stream_a_aac();
2178   else if (track.codec.is(codec_c::type_e::A_AC3))
2179     return track.new_stream_a_ac3();
2180   else if (track.codec.is(codec_c::type_e::A_DTS))
2181     return track.new_stream_a_dts();
2182   else if (track.codec.is(codec_c::type_e::A_PCM))
2183     return track.new_stream_a_pcm();
2184   else if (track.codec.is(codec_c::type_e::A_TRUEHD))
2185     return track.new_stream_a_truehd();
2186 
2187   return -1;
2188 }
2189 
2190 void
probe_packet_complete(track_c & track,bool end_of_detection)2191 reader_c::probe_packet_complete(track_c &track,
2192                                 bool end_of_detection) {
2193   if (track.probed_ok) {
2194     track.clear_pes_payload();
2195     return;
2196   }
2197 
2198   int result = -1;
2199 
2200   try {
2201     result = determine_track_parameters(track, end_of_detection);
2202   } catch (...) {
2203   }
2204 
2205   track.clear_pes_payload();
2206 
2207   if (result != 0) {
2208     mxdebug_if(m_debug_headers, (result == FILE_STATUS_MOREDATA) ? "probe_packet_complete: Need more data to probe ES\n" : "probe_packet_complete: Failed to parse packet. Reset and retry\n");
2209     track.processed = false;
2210 
2211     return;
2212   }
2213 
2214   if (mtx::included_in(track.type, pid_type_e::pat, pid_type_e::pmt)) {
2215     auto it = std::find_if(m_tracks.begin(), m_tracks.end(), [&track](track_ptr const &candidate) { return candidate.get() == &track; });
2216     if (m_tracks.end() != it)
2217       m_tracks.erase(it);
2218 
2219   } else {
2220     auto &f         = file();
2221     track.processed = true;
2222     track.probed_ok = true;
2223     --f.m_es_to_process;
2224 
2225     if (mtx::included_in(track.type, pid_type_e::audio, pid_type_e::video))
2226       f.m_has_audio_or_video_track = true;
2227 
2228     mxdebug_if(m_debug_headers, fmt::format("probe_packet_complete: ES to process: {0}\n", f.m_es_to_process));
2229   }
2230 }
2231 
2232 void
create_packetizer(int64_t id)2233 reader_c::create_packetizer(int64_t id) {
2234   if ((0 > id) || (m_tracks.size() <= static_cast<size_t>(id)))
2235     return;
2236 
2237   auto &track = m_tracks[id];
2238   auto type   = track->type == pid_type_e::audio ? 'a'
2239               : track->type == pid_type_e::video ? 'v'
2240               :                                    's';
2241 
2242   if (!track->probed_ok || (0 == track->ptzr) || !demuxing_requested(type, id, track->language))
2243     return;
2244 
2245   m_ti.m_id       = id;
2246   m_ti.m_language = track->language;
2247 
2248   if (pid_type_e::audio == track->type) {
2249     if (track->codec.is(codec_c::type_e::A_MP3))
2250       track->ptzr = add_packetizer(new mp3_packetizer_c(this, m_ti, track->a_sample_rate, track->a_channels, (0 != track->a_sample_rate) && (0 != track->a_channels)));
2251 
2252     else if (track->codec.is(codec_c::type_e::A_AAC))
2253       create_aac_audio_packetizer(track);
2254 
2255     else if (track->codec.is(codec_c::type_e::A_AC3))
2256       create_ac3_audio_packetizer(track);
2257 
2258     else if (track->codec.is(codec_c::type_e::A_DTS))
2259       track->ptzr = add_packetizer(new dts_packetizer_c(this, m_ti, track->a_dts_header));
2260 
2261     else if (track->codec.is(codec_c::type_e::A_PCM))
2262       create_pcm_audio_packetizer(track);
2263 
2264     else if (track->codec.is(codec_c::type_e::A_TRUEHD))
2265       create_truehd_audio_packetizer(track);
2266 
2267   } else if (pid_type_e::video == track->type) {
2268     if (track->codec.is(codec_c::type_e::V_MPEG12))
2269       create_mpeg1_2_video_packetizer(track);
2270 
2271     else if (track->codec.is(codec_c::type_e::V_MPEG4_P10))
2272       create_mpeg4_p10_es_video_packetizer(track);
2273 
2274     else if (track->codec.is(codec_c::type_e::V_MPEGH_P2))
2275       create_mpegh_p2_es_video_packetizer(track);
2276 
2277     else if (track->codec.is(codec_c::type_e::V_VC1))
2278       create_vc1_video_packetizer(track);
2279 
2280   } else if (track->codec.is(codec_c::type_e::S_HDMV_PGS))
2281     create_hdmv_pgs_subtitles_packetizer(track);
2282 
2283   else if (track->codec.is(codec_c::type_e::S_HDMV_TEXTST))
2284     create_hdmv_textst_subtitles_packetizer(track);
2285 
2286   else if (track->codec.is(codec_c::type_e::S_SRT))
2287     create_srt_subtitles_packetizer(track);
2288 
2289   else if (track->codec.is(codec_c::type_e::S_DVBSUB))
2290     create_dvbsub_subtitles_packetizer(track);
2291 
2292   if (-1 != track->ptzr) {
2293     auto &packetizer                 = ptzr(track->ptzr);
2294     m_ptzr_to_track_map[&packetizer] = track;
2295 
2296     m_files[track->m_file_num]->m_packetizers.push_back(&packetizer);
2297 
2298     track->set_packetizer_source_id();
2299 
2300     show_packetizer_info(id, packetizer);
2301   }
2302 }
2303 
2304 void
create_aac_audio_packetizer(track_ptr const & track)2305 reader_c::create_aac_audio_packetizer(track_ptr const &track) {
2306   auto aac_packetizer = new aac_packetizer_c(this, m_ti, track->m_aac_frame.m_header.config, aac_packetizer_c::headerless);
2307   track->ptzr         = add_packetizer(aac_packetizer);
2308   track->converter    = std::make_shared<aac_framing_packet_converter_c>(&ptzr(track->ptzr), track->m_aac_multiplex_type);
2309 
2310   if (mtx::aac::PROFILE_SBR == track->m_aac_frame.m_header.config.profile)
2311     aac_packetizer->set_audio_output_sampling_freq(track->m_aac_frame.m_header.config.sample_rate * 2);
2312 }
2313 
2314 void
create_ac3_audio_packetizer(track_ptr const & track)2315 reader_c::create_ac3_audio_packetizer(track_ptr const &track) {
2316   track->ptzr = add_packetizer(new ac3_packetizer_c(this, m_ti, track->a_sample_rate, track->a_channels, track->a_bsid));
2317 
2318   if (track->converter)
2319     dynamic_cast<truehd_ac3_splitting_packet_converter_c &>(*track->converter).set_ac3_packetizer(&ptzr(track->ptzr));
2320 }
2321 
2322 void
create_pcm_audio_packetizer(track_ptr const & track)2323 reader_c::create_pcm_audio_packetizer(track_ptr const &track) {
2324   track->ptzr = add_packetizer(new pcm_packetizer_c(this, m_ti, track->a_sample_rate, track->a_channels, track->a_bits_per_sample, pcm_packetizer_c::big_endian_integer));
2325 
2326   if (track->converter)
2327     track->converter->set_packetizer(&ptzr(track->ptzr));
2328 }
2329 
2330 void
create_truehd_audio_packetizer(track_ptr const & track)2331 reader_c::create_truehd_audio_packetizer(track_ptr const &track) {
2332   track->ptzr = add_packetizer(new truehd_packetizer_c(this, m_ti, mtx::truehd::frame_t::truehd, track->a_sample_rate, track->a_channels));
2333 
2334   if (track->converter)
2335     dynamic_cast<truehd_ac3_splitting_packet_converter_c &>(*track->converter).set_packetizer(&ptzr(track->ptzr));
2336 }
2337 
2338 void
create_mpeg1_2_video_packetizer(track_ptr & track)2339 reader_c::create_mpeg1_2_video_packetizer(track_ptr &track) {
2340   m_ti.m_private_data = track->m_codec_private_data;
2341   auto m2vpacketizer  = new mpeg1_2_video_packetizer_c(this, m_ti, track->v_version, mtx::to_int(track->m_default_duration), track->v_width, track->v_height, track->v_dwidth, track->v_dheight, false);
2342   track->ptzr         = add_packetizer(m2vpacketizer);
2343 
2344   m2vpacketizer->set_video_interlaced_flag(track->v_interlaced);
2345 }
2346 
2347 void
create_mpeg4_p10_es_video_packetizer(track_ptr & track)2348 reader_c::create_mpeg4_p10_es_video_packetizer(track_ptr &track) {
2349   auto ptzr   = new avc_es_video_packetizer_c(this, m_ti);
2350   track->ptzr = add_packetizer(ptzr);
2351   ptzr->set_video_pixel_dimensions(track->v_width, track->v_height);
2352 }
2353 
2354 void
create_mpegh_p2_es_video_packetizer(track_ptr & track)2355 reader_c::create_mpegh_p2_es_video_packetizer(track_ptr &track) {
2356   auto ptzr   = new hevc_es_video_packetizer_c(this, m_ti);
2357   track->ptzr = add_packetizer(ptzr);
2358   ptzr->set_video_pixel_dimensions(track->v_width, track->v_height);
2359 }
2360 
2361 void
create_vc1_video_packetizer(track_ptr & track)2362 reader_c::create_vc1_video_packetizer(track_ptr &track) {
2363   track->m_use_dts = true;
2364   track->ptzr      = add_packetizer(new vc1_video_packetizer_c(this, m_ti));
2365 }
2366 
2367 void
create_hdmv_pgs_subtitles_packetizer(track_ptr & track)2368 reader_c::create_hdmv_pgs_subtitles_packetizer(track_ptr &track) {
2369   auto ptzr = new hdmv_pgs_packetizer_c(this, m_ti);
2370   ptzr->set_aggregate_packets(true);
2371   track->ptzr = add_packetizer(ptzr);
2372 }
2373 
2374 void
create_hdmv_textst_subtitles_packetizer(track_ptr const & track)2375 reader_c::create_hdmv_textst_subtitles_packetizer(track_ptr const &track) {
2376   track->ptzr = add_packetizer(new hdmv_textst_packetizer_c(this, m_ti, track->m_codec_private_data));
2377 }
2378 
2379 void
create_srt_subtitles_packetizer(track_ptr const & track)2380 reader_c::create_srt_subtitles_packetizer(track_ptr const &track) {
2381   auto recoding_requested = mtx::includes(m_ti.m_sub_charsets, track->m_id) || mtx::includes(m_ti.m_sub_charsets, track->m_id);
2382   track->ptzr             = add_packetizer(new textsubs_packetizer_c(this, m_ti, MKV_S_TEXTUTF8, recoding_requested));
2383 
2384   auto &converter         = dynamic_cast<teletext_to_srt_packet_converter_c &>(*track->converter);
2385 
2386   converter.demux_page(*track->m_ttx_wanted_page, &ptzr(track->ptzr));
2387   converter.override_encoding(*track->m_ttx_wanted_page, track->language.get_iso639_alpha_3_code());
2388 }
2389 
2390 void
create_dvbsub_subtitles_packetizer(track_ptr const & track)2391 reader_c::create_dvbsub_subtitles_packetizer(track_ptr const &track) {
2392   track->ptzr = add_packetizer(new dvbsub_packetizer_c{this, m_ti, track->m_codec_private_data});
2393   track->converter.reset(new dvbsub_pes_framing_removal_packet_converter_c{&ptzr(track->ptzr)});
2394 }
2395 
2396 void
create_packetizers()2397 reader_c::create_packetizers() {
2398   determine_global_timestamp_offset();
2399 
2400   mxdebug_if(m_debug_headers, fmt::format("create_packetizers: create packetizers...\n"));
2401   for (int i = 0, end = m_tracks.size(); i < end; ++i)
2402     create_packetizer(i);
2403 }
2404 
2405 void
add_available_track_ids()2406 reader_c::add_available_track_ids() {
2407   add_available_track_id_range(0, m_tracks.size() - 1);
2408 
2409   if (m_chapters)
2410     add_available_track_id(track_info_c::chapter_track_id);
2411 }
2412 
2413 bool
all_files_done() const2414 reader_c::all_files_done()
2415   const {
2416   for (auto const &file : m_files)
2417     if (!file->m_file_done)
2418       return false;
2419 
2420   return true;
2421 }
2422 
2423 file_status_e
finish()2424 reader_c::finish() {
2425   if (all_files_done()) {
2426     m_bytes_processed = m_bytes_to_process;
2427     return flush_packetizers();
2428   }
2429 
2430   for (auto &track : m_tracks) {
2431     if (track->m_file_num != m_current_file)
2432       continue;
2433 
2434     if ((-1 != track->ptzr) && (0 < track->pes_payload_read->get_size()))
2435       parse_pes(*track);
2436 
2437     if (track->converter)
2438       track->converter->flush();
2439 
2440     if (-1 != track->ptzr)
2441       ptzr(track->ptzr).flush();
2442   }
2443 
2444   file().m_file_done = true;
2445 
2446   return FILE_STATUS_DONE;
2447 }
2448 
2449 file_status_e
read(generic_packetizer_c * requested_ptzr,bool force)2450 reader_c::read(generic_packetizer_c *requested_ptzr,
2451                bool force) {
2452   if (all_files_done())
2453     return flush_packetizers();
2454 
2455   auto &requested_ptzr_track = m_ptzr_to_track_map[requested_ptzr];
2456   if (!requested_ptzr_track)
2457     return flush_packetizers();
2458 
2459   m_current_file        = requested_ptzr_track->m_file_num;
2460   auto &f               = file();
2461   auto num_queued_bytes = f.get_queued_bytes();
2462 
2463   if (!force && (20 * 1024 * 1024 < num_queued_bytes)) {
2464     if (   !requested_ptzr_track
2465         || !mtx::included_in(requested_ptzr_track->type, pid_type_e::audio, pid_type_e::video)
2466         || (512 * 1024 * 1024 < num_queued_bytes))
2467       return FILE_STATUS_HOLDING;
2468   }
2469 
2470   f.m_packet_sent_to_packetizer = false;
2471   auto prior_position           = f.m_in->getFilePointer();
2472 
2473   unsigned char buf[TS_MAX_PACKET_SIZE + 1];
2474 
2475   while (!f.m_packet_sent_to_packetizer) {
2476     f.m_position = f.m_in->getFilePointer();
2477 
2478     if (f.m_in->read(buf, f.m_detected_packet_size) != static_cast<unsigned int>(f.m_detected_packet_size))
2479       return finish();
2480 
2481     if (buf[0] != 0x47) {
2482       if (resync(f.m_position))
2483         continue;
2484       return finish();
2485     }
2486 
2487     ++m_packet_num;
2488 
2489     parse_packet(buf);
2490   }
2491 
2492   m_bytes_processed += f.m_in->getFilePointer() - prior_position;
2493 
2494   return FILE_STATUS_MOREDATA;
2495 }
2496 
2497 void
parse_clip_info_file(std::size_t file_idx)2498 reader_c::parse_clip_info_file(std::size_t file_idx) {
2499   auto &file         = *m_files[file_idx];
2500   auto mpls_multi_in = dynamic_cast<mm_mpls_multi_file_io_c *>(get_underlying_input(file.m_in.get()));
2501   auto source_file   = mpls_multi_in ? mpls_multi_in->get_file_names()[0] : mtx::fs::to_path(file.m_in->get_file_name());
2502 
2503   mxdebug_if(m_debug_clpi, fmt::format("find_clip_info_file: Searching for CLPI corresponding to {0}\n", source_file.u8string()));
2504 
2505   auto clpi_file = mtx::bluray::find_other_file(source_file, mtx::fs::to_path("CLIPINF") / mtx::fs::to_path(fmt::format("{0}.clpi", source_file.stem().u8string())));
2506 
2507   mxdebug_if(m_debug_clpi, fmt::format("reader_c::find_clip_info_file: CLPI file: {0}\n", !clpi_file.empty() ? clpi_file.u8string() : "not found"));
2508 
2509   if (clpi_file.empty())
2510     return;
2511 
2512   file.m_clpi_parser.reset(new mtx::bluray::clpi::parser_c{clpi_file.u8string()});
2513   if (!file.m_clpi_parser->parse()) {
2514     file.m_clpi_parser.reset();
2515     return;
2516   }
2517 
2518   for (auto &track : m_tracks) {
2519     if (track->m_file_num != file_idx)
2520       continue;
2521 
2522     bool found = false;
2523 
2524     for (auto &program : file.m_clpi_parser->m_programs) {
2525       for (auto &stream : program->program_streams) {
2526         if ((stream->pid != track->pid) || !stream->language.is_valid())
2527           continue;
2528 
2529         track->language = stream->language;
2530         found = true;
2531         break;
2532       }
2533 
2534       if (found)
2535         break;
2536     }
2537   }
2538 }
2539 
2540 bool
resync(int64_t start_at)2541 reader_c::resync(int64_t start_at) {
2542   auto &f = file();
2543 
2544   try {
2545     mxdebug_if(m_debug_resync, fmt::format("resync: Start resync for data from {0}\n", start_at));
2546     f.m_in->setFilePointer(start_at);
2547 
2548     unsigned char buf[TS_MAX_PACKET_SIZE + 1];
2549 
2550     while (!f.m_in->eof()) {
2551       auto curr_pos = f.m_in->getFilePointer();
2552       buf[0]        = f.m_in->read_uint8();
2553 
2554       if (0x47 != buf[0])
2555         continue;
2556 
2557       if (f.m_in->read(&buf[1], f.m_detected_packet_size) != static_cast<unsigned int>(f.m_detected_packet_size))
2558         return false;
2559 
2560       if (0x47 != buf[f.m_detected_packet_size]) {
2561         f.m_in->setFilePointer(curr_pos + 1);
2562         continue;
2563       }
2564 
2565       mxdebug_if(m_debug_resync, fmt::format("resync: Re-established at {0}\n", curr_pos));
2566 
2567       f.m_in->setFilePointer(curr_pos);
2568       return true;
2569     }
2570 
2571   } catch (...) {
2572     return false;
2573   }
2574 
2575   return false;
2576 }
2577 
2578 track_ptr
find_track_for_pid(uint16_t pid) const2579 reader_c::find_track_for_pid(uint16_t pid)
2580   const {
2581   auto &f = *m_files[m_current_file];
2582 
2583   for (auto const &track : m_tracks) {
2584     if (   (track->m_file_num != m_current_file)
2585         || (track->pid        != pid))
2586       continue;
2587 
2588     if (track->has_packetizer() || mtx::included_in(f.m_state, processing_state_e::probing, processing_state_e::determining_timestamp_offset))
2589       return track;
2590 
2591     for (auto const &coupled_track : track->m_coupled_tracks)
2592       if (coupled_track->has_packetizer())
2593         return coupled_track;
2594 
2595     return track;
2596   }
2597 
2598   return {};
2599 }
2600 
2601 std::pair<unsigned char *, std::size_t>
determine_ts_payload_start(packet_header_t * hdr) const2602 reader_c::determine_ts_payload_start(packet_header_t *hdr)
2603   const {
2604   auto ts_header_start  = reinterpret_cast<unsigned char *>(hdr);
2605   auto ts_payload_start = ts_header_start + sizeof(packet_header_t);
2606 
2607   if (hdr->has_adaptation_field())
2608     // Adaptation field's first byte is its length - 1.
2609     ts_payload_start += ts_payload_start[0] + 1;
2610 
2611   // Make sure not to overflow the TS packet buffer.
2612   ts_payload_start = std::min(ts_payload_start, ts_header_start + TS_PACKET_SIZE);
2613 
2614   return { ts_payload_start, static_cast<std::size_t>(ts_header_start + TS_PACKET_SIZE - ts_payload_start) };
2615 }
2616 
2617 file_t &
file()2618 reader_c::file() {
2619   return *m_files[m_current_file];
2620 }
2621 
2622 void
add_external_files_from_mpls(mm_mpls_multi_file_io_c & mpls_in)2623 reader_c::add_external_files_from_mpls(mm_mpls_multi_file_io_c &mpls_in) {
2624   auto source_file  = mpls_in.get_file_names()[0];
2625   auto parser       = mpls_in.get_mpls_parser();
2626   auto &playlist    = parser.get_playlist();
2627   auto sub_path_idx = 0u;
2628 
2629   if (!playlist.items.empty()) {
2630     auto &item                        = playlist.items.front();
2631     auto &file                        = m_files.front();
2632 
2633     file->m_timestamp_restriction_min = item.in_time;
2634     file->m_timestamp_restriction_max = item.out_time;
2635 
2636     mxdebug_if(m_debug_mpls, fmt::format("add_external_files_from_mpls: main restrictions for {0} min {1} max {2}\n", mpls_in.get_file_name(), item.in_time, item.out_time));
2637   }
2638 
2639   if (playlist.sub_paths.empty())
2640     return;
2641 
2642   for (auto const &sub_path : playlist.sub_paths) {
2643     ++sub_path_idx;
2644 
2645     if ((mtx::bluray::mpls::sub_path_type_e::text_subtitle_presentation != sub_path.type) || sub_path.items.empty())
2646       continue;
2647 
2648     auto &item = sub_path.items.front();
2649     auto m2ts  = mtx::bluray::find_other_file(mtx::fs::to_path(source_file), mtx::fs::to_path("STREAM") / mtx::fs::to_path(fmt::format("{0}.m2ts", mtx::fs::to_path(item.clpi_file_name).stem().u8string())));
2650 
2651     mxdebug_if(m_debug_mpls, fmt::format("add_external_files_from_mpls: M2TS for sub_path {0}: {1}\n", sub_path_idx - 1, !m2ts.empty() ? m2ts.u8string() : "not found"));
2652 
2653     if (m2ts.empty())
2654       continue;
2655 
2656     try {
2657       auto in                           = std::make_shared<mm_file_io_c>(m2ts.u8string(), MODE_READ);
2658       auto file                         = std::make_shared<file_t>(std::static_pointer_cast<mm_io_c>(in));
2659 
2660       file->m_timestamp_restriction_min = item.in_time;
2661       file->m_timestamp_restriction_max = item.out_time;
2662       file->m_timestamp_mpls_sync       = item.sync_start_pts_of_playitem;
2663 
2664       m_files.push_back(file);
2665 
2666       mxdebug_if(m_debug_mpls, fmt::format("add_external_files_from_mpls: sub_path file num {0} name {1} ts_rec_min {2} ts_rec_max {3} ts_mpls_sync {4}\n",
2667                                            m_files.size() - 1, m2ts.u8string(), file->m_timestamp_restriction_min, file->m_timestamp_restriction_max, file->m_timestamp_mpls_sync));
2668 
2669     } catch (mtx::mm_io::exception &ex) {
2670       mxdebug_if(m_debug_mpls, fmt::format("add_external_files_from_mpls: could not open {0}: {1}\n", m2ts.u8string(), ex.error()));
2671     }
2672   }
2673 }
2674 
2675 int64_t
get_progress()2676 reader_c::get_progress() {
2677   return m_bytes_processed;
2678 }
2679 
2680 int64_t
get_maximum_progress()2681 reader_c::get_maximum_progress() {
2682   return m_bytes_to_process;
2683 }
2684 
2685 }
2686