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    AV1 Open Bistream Unit (OBU) demultiplexer module
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #include "common/common_pch.h"
15 
16 #include "common/av1.h"
17 #include "common/codec.h"
18 #include "common/endian.h"
19 #include "common/mm_io_x.h"
20 #include "common/id_info.h"
21 #include "input/r_obu.h"
22 #include "merge/input_x.h"
23 #include "output/p_av1.h"
24 
25 bool
probe_file()26 obu_reader_c::probe_file() {
27   auto size = std::min<uint64_t>(m_in->get_size(), m_buffer->get_size());
28   if (m_in->read(m_buffer, size) != size)
29     return false;
30 
31   mtx::av1::parser_c parser;
32   parser.parse(*m_buffer);
33 
34   if (!parser.headers_parsed() || !parser.frame_available())
35     return false;
36 
37   auto dimensions = parser.get_pixel_dimensions();
38   m_width         = dimensions.first;
39   m_height        = dimensions.second;
40 
41   return (m_width > 0) && (m_height > 0);
42 }
43 
44 void
read_headers()45 obu_reader_c::read_headers() {
46   show_demuxer_info();
47 }
48 
49 void
create_packetizer(int64_t)50 obu_reader_c::create_packetizer(int64_t) {
51   if (!demuxing_requested('v', 0) || !m_reader_packetizers.empty())
52     return;
53 
54   auto packetizer = new av1_video_packetizer_c{this, m_ti};
55   packetizer->set_is_unframed();
56 
57   add_packetizer(packetizer);
58 
59   show_packetizer_info(0, *packetizer);
60 }
61 
62 file_status_e
read(generic_packetizer_c *,bool)63 obu_reader_c::read(generic_packetizer_c *,
64                    bool) {
65   try {
66     auto to_read = std::min<uint64_t>(m_buffer->get_size(), m_in->get_size() - m_in->getFilePointer());
67     if (to_read == 0)
68       return flush_packetizers();
69 
70     m_in->read(m_buffer, to_read);
71 
72     ptzr(0).process(std::make_shared<packet_t>(memory_c::borrow(m_buffer->get_buffer(), to_read)));
73 
74     if (to_read == m_buffer->get_size())
75       return FILE_STATUS_MOREDATA;
76 
77   } catch (mtx::mm_io::exception &) {
78   } catch (mtx::av1::exception &) {
79   }
80 
81   return flush_packetizers();
82 }
83 
84 void
identify()85 obu_reader_c::identify() {
86   auto info = mtx::id::info_c{};
87   info.add(mtx::id::pixel_dimensions, fmt::format("{0}x{1}", m_width, m_height));
88 
89   id_result_container();
90   id_result_track(0, ID_RESULT_TRACK_VIDEO, codec_c::get_name(codec_c::type_e::V_AV1, {}), info.get());
91 }
92