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 AC-3 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 "common/byte_buffer.h"
19 
20 class codec_c;
21 
22 namespace mtx {
23 
24 namespace bits {
25 class reader_c;
26 }
27 
28 namespace ac3 {
29 
30 constexpr auto SYNC_WORD              = 0x0b77;
31 
32 constexpr auto FRAME_TYPE_INDEPENDENT = 0;
33 constexpr auto FRAME_TYPE_DEPENDENT   = 1;
34 constexpr auto FRAME_TYPE_AC3_CONVERT = 2;
35 constexpr auto FRAME_TYPE_RESERVED    = 3;
36 
37 class frame_c {
38 public:
39   unsigned int m_sample_rate{}, m_bit_rate{}, m_channels{}, m_channel_layout{}, m_flags{}, m_bytes{}, m_bs_id{}, m_samples{}, m_frame_type{}, m_sub_stream_id{};
40   unsigned int m_dialog_normalization_gain{}, m_dialog_normalization_gain_bit_position{};
41   std::optional<unsigned int> m_dialog_normalization_gain2, m_dialog_normalization_gain2_bit_position;
42   uint64_t m_stream_position{}, m_garbage_size{};
43   bool m_valid{}, m_lfeon{}, m_is_surround_ex{};
44   memory_cptr m_data;
45   std::vector<frame_c> m_dependent_frames;
46 
47 public:
48   void init();
49   bool is_eac3() const;
50   codec_c get_codec() const;
51   void add_dependent_frame(frame_c const &frame, unsigned char const *buffer, std::size_t buffer_size);
52   bool decode_header(unsigned char const *buffer, std::size_t buffer_size);
53   bool decode_header_type_eac3(mtx::bits::reader_c &bc);
54   bool decode_header_type_ac3(mtx::bits::reader_c &bc);
55 
56   uint64_t get_effective_channel_layout() const;
57   int get_effective_number_of_channels() const;
58 
59   std::string to_string(bool verbose) const;
60 
61   int find_in(memory_cptr const &buffer);
62   int find_in(unsigned char const *buffer, std::size_t buffer_size);
63 };
64 
65 class parser_c {
66 protected:
67   std::deque<frame_c> m_frames;
68   mtx::bytes::buffer_c m_buffer;
69   uint64_t m_parsed_stream_position, m_total_stream_position;
70   frame_c m_current_frame;
71   std::size_t m_garbage_size;
72 
73 public:
74   parser_c();
75   void add_bytes(memory_cptr const &mem);
76   void add_bytes(unsigned char *const buffer, std::size_t size);
77   void flush();
78   std::size_t frame_available() const;
79   frame_c get_frame();
80   uint64_t get_parsed_stream_position() const;
81   uint64_t get_total_stream_position() const;
82 
83   int find_consecutive_frames(unsigned char const *buffer, std::size_t buffer_size, std::size_t num_required_headers);
84 
85   void parse(bool end_of_stream);
86 };
87 
88 bool verify_checksums(unsigned char const *buf, std::size_t size, bool full_buffer = false);
89 void remove_dialog_normalization_gain(unsigned char *buf, std::size_t size);
90 
91 }}                              // namespace mtx::ac3
92