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    WAV AC-3 (ACM mode) demuxer module
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #include "common/common_pch.h"
15 
16 #include "avilib.h"
17 #include "common/ac3.h"
18 #include "common/bswap.h"
19 #include "input/r_wav.h"
20 #include "input/wav_ac3acm_demuxer.h"
21 #include "output/p_ac3.h"
22 
wav_ac3acm_demuxer_c(wav_reader_c * reader,wave_header * wheader)23 wav_ac3acm_demuxer_c::wav_ac3acm_demuxer_c(wav_reader_c *reader,
24                                            wave_header  *wheader)
25   : wav_demuxer_c{reader, wheader}
26   , m_buf{memory_c::alloc(AC3ACM_READ_SIZE), memory_c::alloc(AC3ACM_READ_SIZE)}
27   , m_cur_buf{}
28   , m_swap_bytes{}
29 {
30   m_codec  = codec_c::look_up(codec_c::type_e::A_AC3);
31 }
32 
~wav_ac3acm_demuxer_c()33 wav_ac3acm_demuxer_c::~wav_ac3acm_demuxer_c() {
34 }
35 
36 bool
probe(mm_io_cptr & io)37 wav_ac3acm_demuxer_c::probe(mm_io_cptr &io) {
38   io->save_pos();
39   int len = io->read(m_buf[m_cur_buf]->get_buffer(), AC3ACM_READ_SIZE);
40   io->restore_pos();
41 
42   mtx::ac3::parser_c parser;
43   int pos = parser.find_consecutive_frames(m_buf[m_cur_buf]->get_buffer(), len, 4);
44 
45   if (-1 == pos) {
46     m_swap_bytes = true;
47     decode_buffer(len);
48     pos = parser.find_consecutive_frames(m_buf[m_cur_buf]->get_buffer(), len, 4);
49   }
50 
51   if (-1 == pos)
52     return false;
53 
54   if (!m_ac3header.decode_header(m_buf[m_cur_buf]->get_buffer() + pos, len - pos))
55     return false;
56 
57   m_codec = m_ac3header.get_codec();
58 
59   return true;
60 }
61 
62 int
decode_buffer(int len)63 wav_ac3acm_demuxer_c::decode_buffer(int len) {
64   if ((2 < len) && m_swap_bytes) {
65     mtx::bytes::swap_buffer(m_buf[m_cur_buf]->get_buffer(), m_buf[m_cur_buf ^ 1]->get_buffer(), len, 2);
66     m_cur_buf ^= 1;
67   }
68 
69   return 0;
70 }
71 
72 generic_packetizer_c *
create_packetizer()73 wav_ac3acm_demuxer_c::create_packetizer() {
74   m_ptzr = new ac3_packetizer_c(m_reader, m_ti, m_ac3header.m_sample_rate, m_ac3header.m_channels, m_ac3header.m_bs_id);
75 
76   m_reader->show_packetizer_info(0, *m_ptzr);
77 
78   return m_ptzr;
79 }
80 
81 void
process(int64_t size)82 wav_ac3acm_demuxer_c::process(int64_t size) {
83   if (0 >= size)
84     return;
85 
86   decode_buffer(size);
87   m_ptzr->process(std::make_shared<packet_t>(memory_c::borrow(m_buf[m_cur_buf]->get_buffer(), size)));
88 }
89 
90 unsigned int
get_channels() const91 wav_ac3acm_demuxer_c::get_channels()
92   const {
93   return m_ac3header.m_channels;
94 }
95 
96 unsigned int
get_sampling_frequency() const97 wav_ac3acm_demuxer_c::get_sampling_frequency()
98   const {
99   return m_ac3header.m_sample_rate;
100 }
101 
102 unsigned int
get_bits_per_sample() const103 wav_ac3acm_demuxer_c::get_bits_per_sample()
104   const {
105   return 0;
106 }
107