1 /*
2    mkvmerge -- utility for splicing together matroska files
3    from component media subtypes
4 
5    Distributed under the GPL v2
6    see the file COPYING for details
7    or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8 
9    class definition for the packet structure
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/timestamp.h"
19 
20 namespace libmatroska {
21   class KaxBlock;
22   class KaxBlockBlob;
23   class KaxCluster;
24 }
25 
26 class generic_packetizer_c;
27 class track_statistics_c;
28 
29 class packet_extension_c {
30 public:
31   enum packet_extension_type_e {
32     MULTIPLE_TIMESTAMPS,
33     SUBTITLE_NUMBER,
34     BEFORE_ADDING_TO_CLUSTER_CB,
35   };
36 
37 public:
packet_extension_c()38   packet_extension_c() {
39   }
40 
~packet_extension_c()41   virtual ~packet_extension_c() {
42   }
43 
44   virtual packet_extension_type_e get_type() const = 0;
45 };
46 using packet_extension_cptr = std::shared_ptr<packet_extension_c>;
47 
48 struct packet_t {
49   memory_cptr data;
50   std::vector<memory_cptr> data_adds;
51   memory_cptr codec_state;
52 
53   libmatroska::KaxBlockBlob *group;
54   libmatroska::KaxBlock *block;
55   libmatroska::KaxCluster *cluster;
56   int ref_priority, time_factor;
57   int64_t timestamp, bref, fref, duration, assigned_timestamp;
58   int64_t timestamp_before_factory;
59   int64_t unmodified_assigned_timestamp, unmodified_duration;
60   std::optional<uint64_t> uncompressed_size;
61   timestamp_c discard_padding, output_order_timestamp;
62   bool duration_mandatory, superseeded, gap_following, factory_applied;
63   std::optional<bool> key_flag, discardable_flag;
64   generic_packetizer_c *source;
65 
66   std::vector<packet_extension_cptr> extensions;
67 
packet_tpacket_t68   packet_t()
69     : group{}
70     , block{}
71     , cluster{}
72     , ref_priority{}
73     , time_factor(1)
74     , timestamp(-1)
75     , bref(-1)
76     , fref(-1)
77     , duration(-1)
78     , assigned_timestamp{}
79     , timestamp_before_factory{}
80     , unmodified_assigned_timestamp{}
81     , unmodified_duration{}
82     , discard_padding{}
83     , duration_mandatory{}
84     , superseeded{}
85     , gap_following{}
86     , factory_applied{}
87     , source{}
88   {
89   }
90 
91   packet_t(memory_cptr p_memory,
92            int64_t p_timestamp = -1,
93            int64_t p_duration = -1,
94            int64_t p_bref     = -1,
95            int64_t p_fref     = -1)
datapacket_t96     : data(p_memory)
97     , group{}
98     , block{}
99     , cluster{}
100     , ref_priority{}
101     , time_factor(1)
102     , timestamp(p_timestamp)
103     , bref(p_bref)
104     , fref(p_fref)
105     , duration(p_duration)
106     , assigned_timestamp{}
107     , timestamp_before_factory{}
108     , unmodified_assigned_timestamp{}
109     , unmodified_duration{}
110     , discard_padding{}
111     , duration_mandatory{}
112     , superseeded{}
113     , gap_following{}
114     , factory_applied{}
115     , source{}
116   {
117   }
118 
119   packet_t(memory_c *n_memory,
120            int64_t p_timestamp = -1,
121            int64_t p_duration = -1,
122            int64_t p_bref     = -1,
123            int64_t p_fref     = -1)
datapacket_t124     : data(memory_cptr(n_memory))
125     , group{}
126     , block{}
127     , cluster{}
128     , ref_priority{}
129     , time_factor(1)
130     , timestamp(p_timestamp)
131     , bref(p_bref)
132     , fref(p_fref)
133     , duration(p_duration)
134     , assigned_timestamp{}
135     , timestamp_before_factory{}
136     , unmodified_assigned_timestamp{}
137     , unmodified_duration{}
138     , discard_padding{}
139     , duration_mandatory{}
140     , superseeded{}
141     , gap_following{}
142     , factory_applied{}
143     , source{}
144   {
145   }
146 
~packet_tpacket_t147   ~packet_t() {
148   }
149 
150   bool
has_timestamppacket_t151   has_timestamp()
152     const {
153     return 0 <= timestamp;
154   }
155 
156   bool
has_brefpacket_t157   has_bref()
158     const {
159     return 0 <= bref;
160   }
161 
162   bool
has_frefpacket_t163   has_fref()
164     const {
165     return 0 <= fref;
166   }
167 
168   bool
has_durationpacket_t169   has_duration()
170     const {
171     return 0 <= duration;
172   }
173 
174   bool
has_discard_paddingpacket_t175   has_discard_padding()
176     const {
177     return discard_padding.valid();
178   }
179 
180   int64_t
get_durationpacket_t181   get_duration()
182     const {
183     return has_duration() ? duration : 0;
184   }
185 
186   int64_t
get_unmodified_durationpacket_t187   get_unmodified_duration()
188     const {
189     return has_duration() ? unmodified_duration : 0;
190   }
191 
192   void
force_key_framepacket_t193   force_key_frame() {
194     bref     = -1;
195     fref     = -1;
196     key_flag = true;
197   }
198 
199   bool
is_key_framepacket_t200   is_key_frame()
201     const {
202     return (key_flag && *key_flag) || (!has_bref() && !has_fref());
203   }
204 
205   bool
is_p_framepacket_t206   is_p_frame()
207     const {
208     return (has_bref() || has_fref()) && (has_bref() != has_fref());
209   }
210 
211   bool
is_b_framepacket_t212   is_b_frame()
213     const {
214     return has_bref() && has_fref();
215   }
216 
217   packet_extension_c *
find_extensionpacket_t218   find_extension(packet_extension_c::packet_extension_type_e type)
219     const {
220     for (auto &extension : extensions)
221       if (extension->get_type() == type)
222         return extension.get();
223 
224     return nullptr;
225   }
226 
227   void add_extensions(std::vector<packet_extension_cptr> const &new_extensions);
228 
229   void normalize_timestamps();
230 
231   void account(track_statistics_c &statistics, int64_t timestamp_offset);
232   uint64_t calculate_uncompressed_size();
233 };
234 using packet_cptr = std::shared_ptr<packet_t>;
235