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    helper functions for IVF data
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #include "common/common_pch.h"
15 
16 #include "common/bit_reader.h"
17 #include "common/fourcc.h"
18 #include "common/ivf.h"
19 
20 namespace ivf {
21 
file_header_t()22 file_header_t::file_header_t()
23 {
24   memset(this, 0, sizeof(*this));
25 }
26 
27 codec_c
get_codec() const28 file_header_t::get_codec()
29   const {
30   return codec_c::look_up(fourcc_c{fourcc});
31 }
32 
frame_header_t()33 frame_header_t::frame_header_t()
34 {
35   memset(this, 0, sizeof(*this));
36 }
37 
38 static bool
is_keyframe_vp9(memory_c const & buffer)39 is_keyframe_vp9(memory_c const &buffer) {
40   mtx::bits::reader_c bc{buffer.get_buffer(), buffer.get_size()};
41 
42   // frame marker
43   if (bc.get_bits(2) != 0x02)
44     return false;
45 
46   auto profile = bc.get_bit() + (bc.get_bit() * 2);
47   if (3 == profile)
48     bc.get_bit();               // profile += …
49 
50   if (bc.get_bit())             // show_existing_frame
51     return false;
52 
53   return !bc.get_bit();
54 }
55 
56 bool
is_keyframe(memory_cptr const & buffer,codec_c::type_e codec)57 is_keyframe(memory_cptr const &buffer,
58             codec_c::type_e codec) {
59   // Remember: bit numbers start with the least significant bit. Bit 0
60   // == 1, bit 1 == 2 etc.
61 
62   if (!buffer || !buffer->get_size())
63     return false;
64 
65   auto data = buffer->get_buffer();
66 
67   if (codec == codec_c::type_e::V_VP8)
68     return (data[0] & 0x01) == 0x00;
69 
70   try {
71     return is_keyframe_vp9(*buffer);
72   } catch (...) {
73     return false;
74   }
75 }
76 
77 }
78