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