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 definitions and helper functions for AAC data 10 11 Written by Moritz Bunkus <moritz@bunkus.org>. 12 */ 13 14 #pragma once 15 16 #include "common/common_pch.h" 17 18 #include <ostream> 19 20 #include "common/byte_buffer.h" 21 #include "common/timestamp.h" 22 23 namespace mtx::bits { 24 class reader_c; 25 class writer_c; 26 } 27 28 namespace mtx::aac { 29 30 constexpr auto ID_MPEG4 = 0; 31 constexpr auto ID_MPEG2 = 1; 32 33 constexpr auto PROFILE_MAIN = 0; 34 constexpr auto PROFILE_LC = 1; 35 constexpr auto PROFILE_SSR = 2; 36 constexpr auto PROFILE_LTP = 3; 37 constexpr auto PROFILE_SBR = 4; 38 39 constexpr auto SYNC_EXTENSION_TYPE = 0x02b7; 40 41 constexpr auto MAX_PRIVATE_DATA_SIZE = 5; 42 43 constexpr auto ADTS_SYNC_WORD = 0xfff000; 44 constexpr auto ADTS_SYNC_WORD_MASK = 0xfff000; // first 12 of 24 bits 45 46 constexpr auto LOAS_SYNC_WORD = 0x56e000; // 0x2b7 47 constexpr auto LOAS_SYNC_WORD_MASK = 0xffe000; // first 11 of 24 bits 48 constexpr auto LOAS_FRAME_SIZE_MASK = 0x001fff; // last 13 of 24 bits 49 50 constexpr auto ID_PCE = 0x05; // Table 4.71 "Syntactic elements" 51 52 struct audio_config_t { 53 unsigned int profile{}, sample_rate{}, output_sample_rate{}, channels{}, samples_per_frame{1024}; 54 bool sbr{}; 55 memory_cptr ga_specific_config; 56 unsigned int ga_specific_config_bit_size{}; 57 bool ga_specific_config_contains_program_config_element{}; 58 }; 59 60 unsigned int get_sampling_freq_idx(unsigned int sampling_freq); 61 bool parse_codec_id(const std::string &codec_id, int &id, int &profile); 62 std::optional<audio_config_t> parse_audio_specific_config(unsigned char const *data, std::size_t size); 63 void copy_program_config_element(mtx::bits::reader_c &r, mtx::bits::writer_c &w); 64 memory_cptr create_audio_specific_config(audio_config_t const &audio_config); 65 66 class header_c { 67 public: 68 audio_config_t config{}; 69 70 unsigned int object_type{}, extension_object_type{}, bit_rate{}, bytes{}; 71 unsigned int id{}; // 0 = MPEG-4, 1 = MPEG-2 72 size_t header_bit_size{}, header_byte_size{}, data_byte_size{}; 73 74 bool is_valid{}; 75 76 protected: 77 mtx::bits::reader_c *m_bc{}; 78 79 public: 80 std::string to_string() const; 81 82 public: 83 static header_c from_audio_specific_config(const unsigned char *data, size_t size); 84 85 void parse_audio_specific_config(const unsigned char *data, size_t size, bool look_for_sync_extension = true); 86 void parse_audio_specific_config(mtx::bits::reader_c &bc, bool look_for_sync_extension = true); 87 void parse_program_config_element(mtx::bits::reader_c &bc); 88 89 protected: 90 int read_object_type(); 91 int read_sample_rate(); 92 void read_eld_specific_config(); 93 void read_er_celp_specific_config(); 94 void read_ga_specific_config(); 95 void read_program_config_element(); 96 void read_error_protection_specific_config(); 97 }; 98 99 bool operator ==(const header_c &h1, const header_c &h2); 100 101 inline std::ostream & 102 operator <<(std::ostream &out, 103 header_c const &header) { 104 out << header.to_string(); 105 return out; 106 } 107 108 class latm_parser_c { 109 protected: 110 int m_audio_mux_version, m_audio_mux_version_a; 111 size_t m_fixed_frame_length, m_frame_length_type, m_frame_bit_offset, m_frame_length; 112 header_c m_header; 113 mtx::bits::reader_c *m_bc; 114 bool m_config_parsed; 115 memory_cptr m_audio_specific_config; 116 debugging_option_c m_debug; 117 118 public: 119 latm_parser_c(); 120 121 bool config_parsed() const; 122 memory_cptr get_audio_specific_config() const; 123 header_c const &get_header() const; 124 size_t get_frame_bit_offset() const; 125 size_t get_frame_length() const; 126 127 void parse(mtx::bits::reader_c &bc); 128 129 protected: 130 unsigned int get_value(); 131 void parse_audio_specific_config(size_t asc_length); 132 void parse_stream_mux_config(); 133 void parse_payload_mux(size_t length); 134 void parse_audio_mux_element(); 135 size_t parse_payload_length_info(); 136 }; 137 138 class frame_c { 139 public: 140 header_c m_header; 141 uint64_t m_stream_position; 142 size_t m_garbage_size; 143 timestamp_c m_timestamp; 144 memory_cptr m_data; 145 146 public: 147 frame_c(); 148 void init(); 149 150 std::string to_string(bool verbose = false) const; 151 }; 152 153 class parser_c { 154 public: 155 enum multiplex_type_e { 156 unknown_multiplex = 0 157 , adts_multiplex 158 , adif_multiplex 159 , loas_latm_multiplex 160 }; 161 162 protected: 163 enum parse_result_e { 164 failure 165 , success 166 , need_more_data 167 }; 168 169 protected: 170 std::deque<frame_c> m_frames; 171 std::deque<timestamp_c> m_provided_timestamps; 172 mtx::bytes::buffer_c m_buffer; 173 unsigned char const *m_fixed_buffer; 174 size_t m_fixed_buffer_size; 175 uint64_t m_parsed_stream_position, m_total_stream_position; 176 size_t m_garbage_size, m_num_frames_found, m_abort_after_num_frames; 177 bool m_require_frame_at_first_byte, m_copy_data; 178 multiplex_type_e m_multiplex_type; 179 header_c m_header; 180 latm_parser_c m_latm_parser; 181 debugging_option_c m_debug; 182 183 public: 184 parser_c(); 185 void add_timestamp(timestamp_c const ×tamp); 186 187 void add_bytes(memory_cptr const &mem); 188 void add_bytes(unsigned char const *buffer, size_t size); 189 190 void parse_fixed_buffer(unsigned char const *fixed_buffer, size_t fixed_buffer_size); 191 void parse_fixed_buffer(memory_cptr const &fixed_buffer); 192 193 void flush(); 194 195 multiplex_type_e get_multiplex_type() const; 196 void set_multiplex_type(multiplex_type_e multiplex_type); 197 198 size_t frames_available() const; 199 bool headers_parsed() const; 200 201 frame_c get_frame(); 202 uint64_t get_parsed_stream_position() const; 203 uint64_t get_total_stream_position() const; 204 memory_cptr get_audio_specific_config() const; 205 206 void abort_after_num_frames(size_t num_frames); 207 void require_frame_at_first_byte(bool require); 208 void copy_data(bool copy); 209 210 public: // static functions 211 static int find_consecutive_frames(unsigned char const *buffer, size_t buffer_size, size_t num_required_frames); 212 static std::string get_multiplex_type_name(multiplex_type_e multiplex_type); 213 214 protected: 215 void parse(); 216 std::pair<parse_result_e, size_t> decode_header(unsigned char const *buffer, size_t buffer_size); 217 std::pair<parse_result_e, size_t> decode_adts_header(unsigned char const *buffer, size_t buffer_size); 218 std::pair<parse_result_e, size_t> decode_loas_latm_header(unsigned char const *buffer, size_t buffer_size); 219 void push_frame(frame_c &frame); 220 }; 221 using parser_cptr = std::shared_ptr<parser_c>; 222 223 } // namespace mtx::aac 224