1 /*
2    mkvmerge -- utility for splicing together matroska files
3    from component media subtypes
4 
5    Distributed under the GPL v2
6    see the file COPYING for details
7    or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8 
9    class definitions for the MPEG PS demultiplexer module
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #pragma once
15 
16 #include "common/common_pch.h"
17 
18 #include "common/bit_reader.h"
19 #include "common/codec.h"
20 #include "common/debugging.h"
21 #include "common/dts.h"
22 #include "common/mm_multi_file_io.h"
23 #include "common/mpeg1_2.h"
24 #include "merge/packet_extensions.h"
25 #include "merge/generic_reader.h"
26 
27 struct mpeg_ps_id_t {
28   int id;
29   int sub_id;
30 
31   mpeg_ps_id_t(int n_id = 0, int n_sub_id = 0)
idmpeg_ps_id_t32     : id(n_id)
33     , sub_id(n_sub_id) {
34   }
35 
idxmpeg_ps_id_t36   inline unsigned int idx() const {
37     return ((id & 0xff) << 8) | (sub_id & 0xff);
38   }
39 };
40 
41 inline std::ostream &
42 operator <<(std::ostream &out,
43             mpeg_ps_id_t const &id) {
44   out << fmt::format("{0:02x}.{1:02x}", id.id, id.sub_id);
45 
46   return out;
47 }
48 
49 class mpeg_ps_packet_c {
50 public:
51   mpeg_ps_id_t m_id;
52   int64_t m_pts, m_dts;
53   unsigned int m_length, m_full_length;
54   bool m_valid;
55   memory_cptr m_buffer;
56 
57 public:
58   mpeg_ps_packet_c(mpeg_ps_id_t id = mpeg_ps_id_t{})
59     : m_id{id}
60     , m_pts{-1}
61     , m_dts{-1}
62     , m_length{0}
63     , m_full_length{0}
64     , m_valid{false}
65   {
66   }
67 
has_pts()68   bool has_pts() const {
69     return -1 != m_pts;
70   }
71 
has_dts()72   bool has_dts() const {
73     return -1 != m_dts;
74   }
75 
pts()76   int64_t pts() const {
77     return has_pts() ? m_pts : std::numeric_limits<int64_t>::max();
78   }
79 
dts()80   int64_t dts() const {
81     return has_dts() ? m_dts : pts();
82   }
83 
84   operator bool() const {
85     return m_valid;
86   }
87 
has_been_read()88   bool has_been_read() const {
89     return m_valid && m_buffer;
90   }
91 };
92 
93 inline std::ostream &
94 operator <<(std::ostream &out,
95             mpeg_ps_packet_c const &p) {
96   out << fmt::format("[ID {0} PTS {1} DTS {2} length {3} full_length {4} valid? {5} read? {6}]",
97                      p.m_id,
98                      p.has_pts() ? mtx::string::format_timestamp(p.pts()) : "none"s,
99                      p.has_dts() ? mtx::string::format_timestamp(p.dts()) : "none"s,
100                      p.m_length, p.m_full_length, p.m_valid,
101                      p.has_been_read() ? "yes, fully" : p.m_buffer ? "only partially" : "no");
102 
103   return out;
104 }
105 
106 struct mpeg_ps_track_t {
107   int ptzr;
108 
109   char type;                    // 'v' for video, 'a' for audio, 's' for subs
110   mpeg_ps_id_t id;
111   int sort_key;
112   codec_c codec;
113 
114   bool provide_timestamps;
115   int64_t timestamp_offset, timestamp_b_frame_offset;
116 
117   bool v_interlaced;
118   int v_version, v_width, v_height, v_dwidth, v_dheight;
119   mtx_mp_rational_t v_field_duration, v_aspect_ratio;
120 
121   int a_channels, a_sample_rate, a_bits_per_sample, a_bsid;
122   mtx::dts::header_t dts_header;
123 
124   unsigned char *buffer;
125   unsigned int buffer_usage, buffer_size;
126 
127   multiple_timestamps_packet_extension_c *multiple_timestamps_packet_extension;
128 
129   unsigned int skip_packet_data_bytes;
130 
mpeg_ps_track_tmpeg_ps_track_t131   mpeg_ps_track_t():
132     ptzr(-1),
133     type(0),
134     sort_key(0),
135     provide_timestamps(false),
136     timestamp_offset(std::numeric_limits<int64_t>::max()),
137     timestamp_b_frame_offset{0},
138     v_interlaced(false),
139     v_version(0),
140     v_width(0),
141     v_height(0),
142     v_dwidth(0),
143     v_dheight(0),
144     a_channels(0),
145     a_sample_rate(0),
146     a_bits_per_sample(0),
147     a_bsid(0),
148     buffer(nullptr),
149     buffer_usage(0),
150     buffer_size(0),
151     multiple_timestamps_packet_extension(new multiple_timestamps_packet_extension_c)
152     , skip_packet_data_bytes{}
153   {
154   };
155 
use_buffermpeg_ps_track_t156   void use_buffer(size_t size) {
157     safefree(buffer);
158     buffer       = (unsigned char *)safemalloc(size);
159     buffer_size  = size;
160     buffer_usage = 0;
161   }
162 
assert_buffer_sizempeg_ps_track_t163   void assert_buffer_size(size_t size) {
164     if (!buffer)
165       use_buffer(size);
166     else if (size > buffer_size) {
167       buffer      = (unsigned char *)saferealloc(buffer, size);
168       buffer_size = size;
169     }
170   }
171 
~mpeg_ps_track_tmpeg_ps_track_t172   ~mpeg_ps_track_t() {
173     safefree(buffer);
174     delete multiple_timestamps_packet_extension;
175   }
176 };
177 using mpeg_ps_track_ptr = std::shared_ptr<mpeg_ps_track_t>;
178 
179 inline bool
180 operator <(mpeg_ps_track_ptr const &a,
181            mpeg_ps_track_ptr const &b) {
182   return a->sort_key < b->sort_key;
183 }
184 
185 class mpeg_ps_reader_c: public generic_reader_c {
186 private:
187   int64_t global_timestamp_offset;
188 
189   std::map<int, int> id2idx;
190   std::map<int, bool> m_blocked_ids;
191 
192   std::map<int, int> es_map;
193   int version{};
194   bool file_done{};
195 
196   std::vector<mpeg_ps_track_ptr> tracks;
197   std::map<generic_packetizer_c *, mpeg_ps_track_ptr> m_ptzr_to_track_map;
198 
199   uint64_t m_probe_range{};
200 
201   debugging_option_c
202       m_debug_timestamps{"mpeg_ps|mpeg_ps_timestamps"}
203     , m_debug_headers{   "mpeg_ps|mpeg_ps_headers"}
204     , m_debug_packets{   "mpeg_ps|mpeg_ps_packets"}
205     , m_debug_resync{    "mpeg_ps|mpeg_ps_resync"};
206 
207 public:
get_format_type()208   virtual mtx::file_type_e get_format_type() const {
209     return mtx::file_type_e::mpeg_ps;
210   }
211 
212   virtual void read_headers();
213   virtual void identify();
214   virtual void create_packetizer(int64_t id);
215   virtual void create_packetizers();
216   virtual void add_available_track_ids();
217 
218   virtual void found_new_stream(mpeg_ps_id_t id);
219 
220   virtual bool read_timestamp(mtx::bits::reader_c &bc, int64_t &timestamp);
221   virtual bool read_timestamp(int c, int64_t &timestamp);
222   virtual mpeg_ps_packet_c parse_packet(mpeg_ps_id_t id, bool read_data = true);
223   virtual bool find_next_packet(mpeg_ps_id_t &id, int64_t max_file_pos = -1);
224   virtual bool find_next_packet_for_id(mpeg_ps_id_t id, int64_t max_file_pos = -1);
225 
226   virtual void parse_program_stream_map();
227 
228   virtual bool probe_file() override;
229 
230 private:
231   virtual file_status_e read(generic_packetizer_c *packetizer, bool force = false) override;
232 
233   virtual void new_stream_v_avc_or_mpeg_1_2(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
234   virtual void new_stream_v_mpeg_1_2(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
235   virtual void new_stream_v_avc(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
236   virtual void new_stream_v_vc1(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
237   virtual void new_stream_a_mpeg(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
238   virtual void new_stream_a_ac3(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
239   virtual void new_stream_a_dts(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
240   virtual void new_stream_a_pcm(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
241   virtual void new_stream_a_truehd(mpeg_ps_id_t id, unsigned char *buf, unsigned int length, mpeg_ps_track_ptr &track);
242   virtual bool resync_stream(uint32_t &header);
243   virtual file_status_e finish();
244   void sort_tracks();
245   void calculate_global_timestamp_offset();
246 };
247