Shaka Packager SDK
Loading...
Searching...
No Matches
vp8_parser.cc
1// Copyright 2015 Google LLC. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file or at
5// https://developers.google.com/open-source/licenses/bsd
6
7#include <packager/media/codecs/vp8_parser.h>
8
9#include <absl/log/check.h>
10#include <absl/log/log.h>
11
12#include <packager/macros/logging.h>
13#include <packager/media/base/bit_reader.h>
14#include <packager/media/base/rcheck.h>
15
16namespace shaka {
17namespace media {
18namespace {
19
20const uint32_t MB_FEATURE_TREE_PROBS = 3;
21const uint32_t MAX_MB_SEGMENTS = 4;
22const uint32_t MAX_REF_LF_DELTAS = 4;
23const uint32_t MAX_MODE_LF_DELTAS = 4;
24const uint32_t MB_LVL_MAX = 2;
25const uint32_t MB_FEATURE_DATA_BITS[MB_LVL_MAX] = {7, 6};
26
27bool VerifySyncCode(const uint8_t* data) {
28 return data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a;
29}
30
31bool ReadSegmentation(BitReader* reader) {
32 bool enabled;
33 RCHECK(reader->ReadBits(1, &enabled));
34 if (!enabled)
35 return true;
36
37 bool update_map;
38 RCHECK(reader->ReadBits(1, &update_map));
39 bool update_data;
40 RCHECK(reader->ReadBits(1, &update_data));
41
42 if (update_data) {
43 RCHECK(reader->SkipBits(1)); // abs_delta
44 for (uint32_t i = 0; i < MAX_MB_SEGMENTS; ++i)
45 for (uint32_t j = 0; j < MB_LVL_MAX; ++j) {
46 RCHECK(reader->SkipBitsConditional(true, MB_FEATURE_DATA_BITS[j] + 1));
47 }
48 }
49 if (update_map) {
50 for (uint32_t i = 0; i < MB_FEATURE_TREE_PROBS; ++i)
51 RCHECK(reader->SkipBitsConditional(true, 8));
52 }
53 return true;
54}
55
56bool ReadLoopFilter(BitReader* reader) {
57 RCHECK(reader->SkipBits(10)); // filter_type, filter_evel, sharness_level
58
59 bool mode_ref_delta_enabled;
60 RCHECK(reader->ReadBits(1, &mode_ref_delta_enabled));
61 if (!mode_ref_delta_enabled)
62 return true;
63 bool mode_ref_delta_update;
64 RCHECK(reader->ReadBits(1, &mode_ref_delta_update));
65 if (!mode_ref_delta_update)
66 return true;
67
68 for (uint32_t i = 0; i < MAX_REF_LF_DELTAS + MAX_MODE_LF_DELTAS; ++i)
69 RCHECK(reader->SkipBitsConditional(true, 6 + 1));
70 return true;
71}
72
73bool ReadQuantization(BitReader* reader) {
74 uint32_t yac_index;
75 RCHECK(reader->ReadBits(7, &yac_index));
76 VLOG(4) << "yac_index: " << yac_index;
77 RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y dc delta
78 RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y2 dc delta
79 RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y2 ac delta
80 RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // chroma dc delta
81 RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // chroma ac delta
82 return true;
83}
84
85bool ReadRefreshFrame(BitReader* reader) {
86 bool refresh_golden_frame;
87 RCHECK(reader->ReadBits(1, &refresh_golden_frame));
88 bool refresh_altref_frame;
89 RCHECK(reader->ReadBits(1, &refresh_altref_frame));
90 if (!refresh_golden_frame)
91 RCHECK(reader->SkipBits(2)); // buffer copy flag
92 if (!refresh_altref_frame)
93 RCHECK(reader->SkipBits(2)); // buffer copy flag
94 RCHECK(reader->SkipBits(2)); // sign bias flags
95 return true;
96}
97
98} // namespace
99
100VP8Parser::VP8Parser() : width_(0), height_(0) {}
101VP8Parser::~VP8Parser() {}
102
103bool VP8Parser::Parse(const uint8_t* data,
104 size_t data_size,
105 std::vector<VPxFrameInfo>* vpx_frames) {
106 DCHECK(data);
107 DCHECK(vpx_frames);
108
109 BitReader reader(data, data_size);
110 // The following 3 bytes are read directly from |data|.
111 RCHECK(reader.SkipBytes(3));
112
113 // One bit for frame type.
114 bool is_interframe = data[0] & 1;
115 // 3-bit version number with 2 bits for profile and the other bit reserved for
116 // future variants.
117 uint8_t profile = (data[0] >> 1) & 3;
118 // One bit for show frame flag.
119 // Then 19 bits (the remaining 3 bits in the first byte + next two bytes) for
120 // header size.
121 uint32_t header_size = (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
122 RCHECK(header_size <= data_size);
123
124 if (!is_interframe) {
125 // The following 7 bytes are read directly from |data|.
126 RCHECK(reader.SkipBytes(7));
127
128 RCHECK(VerifySyncCode(&data[3]));
129
130 // Bits 0b11000000 for data[7] and data[9] are scaling.
131 width_ = data[6] | ((data[7] & 0x3f) << 8);
132 height_ = data[8] | ((data[9] & 0x3f) << 8);
133
134 RCHECK(reader.SkipBits(2)); // colorspace and pixel value clamping.
135 }
136
137 RCHECK(ReadSegmentation(&reader));
138 RCHECK(ReadLoopFilter(&reader));
139 RCHECK(reader.SkipBits(2)); // partitions bits
140 RCHECK(ReadQuantization(&reader));
141
142 if (is_interframe) {
143 RCHECK(ReadRefreshFrame(&reader));
144 RCHECK(reader.SkipBits(1)); // refresh_entropy_probs
145 RCHECK(reader.SkipBits(1)); // refresh last frame flag
146 } else {
147 RCHECK(reader.SkipBits(1)); // refresh_entropy_probs
148 }
149
150 // The next field is entropy header (coef probability tree), which is encoded
151 // using bool entropy encoder, i.e. compressed. We don't consider it as part
152 // of uncompressed header.
153
154 writable_codec_config()->set_profile(profile);
155 // VP8 uses an 8-bit YUV 4:2:0 format.
156 // http://tools.ietf.org/html/rfc6386 Section 2.
157 writable_codec_config()->set_bit_depth(8);
158 writable_codec_config()->SetChromaSubsampling(
159 VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA);
160
161 VPxFrameInfo vpx_frame;
162 vpx_frame.frame_size = data_size;
163 vpx_frame.uncompressed_header_size =
164 vpx_frame.frame_size - reader.bits_available() / 8;
165 vpx_frame.is_keyframe = !is_interframe;
166 vpx_frame.width = width_;
167 vpx_frame.height = height_;
168
169 vpx_frames->clear();
170 vpx_frames->push_back(vpx_frame);
171
172 VLOG(3) << "\n frame_size: " << vpx_frame.frame_size
173 << "\n uncompressed_header_size: "
174 << vpx_frame.uncompressed_header_size
175 << "\n bits read: " << reader.bit_position()
176 << "\n header_size: " << header_size
177 << "\n width: " << vpx_frame.width
178 << "\n height: " << vpx_frame.height;
179 return true;
180}
181
182bool VP8Parser::IsKeyframe(const uint8_t* data, size_t data_size) {
183 // Make sure the block is big enough for the minimal keyframe header size.
184 if (data_size < 10)
185 return false;
186
187 // The LSb of the first byte must be a 0 for a keyframe.
188 if ((data[0] & 0x01) != 0)
189 return false;
190 return VerifySyncCode(&data[3]);
191}
192
193} // namespace media
194} // namespace shaka
A class to read bit streams.
Definition bit_reader.h:20
size_t bit_position() const
Definition bit_reader.h:97
bool SkipBits(size_t num_bits)
Definition bit_reader.cc:26
bool SkipBytes(size_t num_bytes)
Definition bit_reader.cc:65
size_t bits_available() const
Definition bit_reader.h:92
All the methods that are virtual are virtual for mocking.