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