Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: media/filters/vp9_parser.cc

Issue 2133993002: Parse VP9 compressed header (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: reset curr_frame_info_ when Reset Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/vp9_parser.h ('k') | media/filters/vp9_parser_fuzzertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This file contains an implementation of a VP9 bitstream parser. 5 // This file contains an implementation of a VP9 bitstream parser.
6 //
7 // VERBOSE level:
8 // 1 something wrong in bitstream
9 // 2 parsing steps
10 // 3 parsed values (selected)
6 11
7 #include "media/filters/vp9_parser.h" 12 #include "media/filters/vp9_parser.h"
8 13
9 #include <algorithm> 14 #include <algorithm>
10 15
16 #include "base/bind.h"
11 #include "base/logging.h" 17 #include "base/logging.h"
12 #include "base/macros.h" 18 #include "base/macros.h"
13 #include "base/numerics/safe_conversions.h" 19 #include "base/numerics/safe_conversions.h"
14 20 #include "media/filters/vp9_compressed_header_parser.h"
15 namespace { 21 #include "media/filters/vp9_uncompressed_header_parser.h"
16
17 const int kMaxLoopFilterLevel = 63;
18
19 // Helper function for Vp9Parser::ReadTiles. Defined as get_min_log2_tile_cols
20 // in spec.
21 int GetMinLog2TileCols(int sb64_cols) {
22 const int kMaxTileWidthB64 = 64;
23 int min_log2 = 0;
24 while ((kMaxTileWidthB64 << min_log2) < sb64_cols)
25 min_log2++;
26 return min_log2;
27 }
28
29 // Helper function for Vp9Parser::ReadTiles. Defined as get_max_log2_tile_cols
30 // in spec.
31 int GetMaxLog2TileCols(int sb64_cols) {
32 const int kMinTileWidthB64 = 4;
33 int max_log2 = 1;
34 while ((sb64_cols >> max_log2) >= kMinTileWidthB64)
35 max_log2++;
36 return max_log2 - 1;
37 }
38
39 } // namespace
40 22
41 namespace media { 23 namespace media {
42 24
43 bool Vp9FrameHeader::IsKeyframe() const { 25 bool Vp9FrameHeader::IsKeyframe() const {
44 // When show_existing_frame is true, the frame header does not precede an 26 // When show_existing_frame is true, the frame header does not precede an
45 // actual frame to be decoded, so frame_type does not apply (and is not read 27 // actual frame to be decoded, so frame_type does not apply (and is not read
46 // from the stream). 28 // from the stream).
47 return !show_existing_frame && frame_type == KEYFRAME; 29 return !show_existing_frame && frame_type == KEYFRAME;
48 } 30 }
49 31
32 bool Vp9FrameHeader::IsIntra() const {
33 return !show_existing_frame && (frame_type == KEYFRAME || intra_only);
34 }
35
50 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size) 36 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size)
51 : ptr(ptr), size(size) {} 37 : ptr(ptr), size(size) {}
52 38
53 Vp9Parser::Vp9Parser() { 39 Vp9FrameContextManager::Vp9FrameContextManager() : weak_ptr_factory_(this) {}
40
41 Vp9FrameContextManager::~Vp9FrameContextManager() {}
42
43 bool Vp9FrameContextManager::IsValidFrameContext(
44 const Vp9FrameContext& context) {
45 // probs should be in [1, 255] range.
46 static_assert(sizeof(Vp9Prob) == 1,
47 "following checks assuming Vp9Prob is single byte");
48 if (memchr(context.tx_probs_8x8, 0, sizeof(context.tx_probs_8x8)))
49 return false;
50 if (memchr(context.tx_probs_16x16, 0, sizeof(context.tx_probs_16x16)))
51 return false;
52 if (memchr(context.tx_probs_32x32, 0, sizeof(context.tx_probs_32x32)))
53 return false;
54
55 for (auto& a : context.coef_probs) {
56 for (auto& ai : a) {
57 for (auto& aj : ai) {
58 for (auto& ak : aj) {
59 int max_l = (ak == aj[0]) ? 3 : 6;
60 for (int l = 0; l < max_l; l++) {
61 for (auto& x : ak[l]) {
62 if (x == 0)
63 return false;
64 }
65 }
66 }
67 }
68 }
69 }
70 if (memchr(context.skip_prob, 0, sizeof(context.skip_prob)))
71 return false;
72 if (memchr(context.inter_mode_probs, 0, sizeof(context.inter_mode_probs)))
73 return false;
74 if (memchr(context.interp_filter_probs, 0,
75 sizeof(context.interp_filter_probs)))
76 return false;
77 if (memchr(context.is_inter_prob, 0, sizeof(context.is_inter_prob)))
78 return false;
79 if (memchr(context.comp_mode_prob, 0, sizeof(context.comp_mode_prob)))
80 return false;
81 if (memchr(context.single_ref_prob, 0, sizeof(context.single_ref_prob)))
82 return false;
83 if (memchr(context.comp_ref_prob, 0, sizeof(context.comp_ref_prob)))
84 return false;
85 if (memchr(context.y_mode_probs, 0, sizeof(context.y_mode_probs)))
86 return false;
87 if (memchr(context.uv_mode_probs, 0, sizeof(context.uv_mode_probs)))
88 return false;
89 if (memchr(context.partition_probs, 0, sizeof(context.partition_probs)))
90 return false;
91 if (memchr(context.mv_joint_probs, 0, sizeof(context.mv_joint_probs)))
92 return false;
93 if (memchr(context.mv_sign_prob, 0, sizeof(context.mv_sign_prob)))
94 return false;
95 if (memchr(context.mv_class_probs, 0, sizeof(context.mv_class_probs)))
96 return false;
97 if (memchr(context.mv_class0_bit_prob, 0, sizeof(context.mv_class0_bit_prob)))
98 return false;
99 if (memchr(context.mv_bits_prob, 0, sizeof(context.mv_bits_prob)))
100 return false;
101 if (memchr(context.mv_class0_fr_probs, 0, sizeof(context.mv_class0_fr_probs)))
102 return false;
103 if (memchr(context.mv_fr_probs, 0, sizeof(context.mv_fr_probs)))
104 return false;
105 if (memchr(context.mv_class0_hp_prob, 0, sizeof(context.mv_class0_hp_prob)))
106 return false;
107 if (memchr(context.mv_hp_prob, 0, sizeof(context.mv_hp_prob)))
108 return false;
109
110 return true;
111 }
112
113 const Vp9FrameContext& Vp9FrameContextManager::frame_context() const {
114 DCHECK(initialized_);
115 DCHECK(!needs_client_update_);
116 return frame_context_;
117 }
118
119 void Vp9FrameContextManager::Reset() {
120 initialized_ = false;
121 needs_client_update_ = false;
122 weak_ptr_factory_.InvalidateWeakPtrs();
123 }
124
125 Vp9FrameContextManager::ContextRefreshCallback
126 Vp9FrameContextManager::SetNeedsClientUpdate() {
127 DCHECK(!needs_client_update_);
128 initialized_ = true;
129 needs_client_update_ = true;
130
131 return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
132 weak_ptr_factory_.GetWeakPtr());
133 }
134
135 void Vp9FrameContextManager::Update(const Vp9FrameContext& frame_context) {
136 // DCHECK because we can trust values from our parser.
137 DCHECK(IsValidFrameContext(frame_context));
138 initialized_ = true;
139 frame_context_ = frame_context;
140
141 // For frame context we are updating, it may be still awaiting previous
142 // ContextRefreshCallback. Because we overwrite the value of context here and
143 // previous ContextRefreshCallback no longer matters, invalidate the weak ptr
144 // to prevent previous ContextRefreshCallback run.
145 // With this optimization, we may be able to parse more frames while previous
146 // are still decoding.
147 weak_ptr_factory_.InvalidateWeakPtrs();
148 needs_client_update_ = false;
149 }
150
151 void Vp9FrameContextManager::UpdateFromClient(
152 const Vp9FrameContext& frame_context) {
153 DVLOG(2) << "Got external frame_context update";
154 DCHECK(needs_client_update_);
155 if (!IsValidFrameContext(frame_context)) {
156 DLOG(ERROR) << "Invalid prob value in frame_context";
157 return;
158 }
159 needs_client_update_ = false;
160 initialized_ = true;
161 frame_context_ = frame_context;
162 }
163
164 void Vp9Parser::Context::Reset() {
165 memset(&segmentation, 0, sizeof(segmentation));
166 memset(&loop_filter, 0, sizeof(loop_filter));
167 memset(&ref_slots, 0, sizeof(ref_slots));
168 for (auto& manager : frame_context_managers)
169 manager.Reset();
170 }
171
172 Vp9Parser::Vp9Parser(bool parsing_compressed_header)
173 : parsing_compressed_header_(parsing_compressed_header) {
54 Reset(); 174 Reset();
55 } 175 }
56 176
57 Vp9Parser::~Vp9Parser() {} 177 Vp9Parser::~Vp9Parser() {}
58 178
59 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) { 179 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) {
60 DCHECK(stream); 180 DCHECK(stream);
61 stream_ = stream; 181 stream_ = stream;
62 bytes_left_ = stream_size; 182 bytes_left_ = stream_size;
63 frames_.clear(); 183 frames_.clear();
64 } 184 }
65 185
66 void Vp9Parser::Reset() { 186 void Vp9Parser::Reset() {
67 stream_ = nullptr; 187 stream_ = nullptr;
68 bytes_left_ = 0; 188 bytes_left_ = 0;
69 frames_.clear(); 189 frames_.clear();
70 190 curr_frame_info_.Reset();
71 memset(&segmentation_, 0, sizeof(segmentation_)); 191
72 memset(&loop_filter_, 0, sizeof(loop_filter_)); 192 context_.Reset();
73 memset(&ref_slots_, 0, sizeof(ref_slots_)); 193 }
74 } 194
75 195 Vp9Parser::Result Vp9Parser::ParseNextFrame(
76 uint8_t Vp9Parser::ReadProfile() { 196 Vp9FrameHeader* fhdr,
77 uint8_t profile = 0; 197 Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) {
78 198 DCHECK(fhdr);
79 // LSB first. 199 DCHECK(!parsing_compressed_header_ || context_refresh_cb);
80 if (reader_.ReadBool()) 200 DVLOG(2) << "ParseNextFrame";
81 profile |= 1; 201
82 if (reader_.ReadBool()) 202 // If |curr_frame_info_| is valid, uncompressed header was parsed into
83 profile |= 2; 203 // |curr_frame_header_| and we are awaiting context update to proceed with
84 if (profile > 2 && reader_.ReadBool()) 204 // compressed header parsing.
85 profile += 1; 205 if (!curr_frame_info_.IsValid()) {
86 return profile; 206 if (frames_.empty()) {
87 } 207 // No frames to be decoded, if there is no more stream, request more.
88 208 if (!stream_)
89 bool Vp9Parser::VerifySyncCode() { 209 return kEOStream;
90 const int kSyncCode = 0x498342; 210
91 if (reader_.ReadLiteral(8 * 3) != kSyncCode) { 211 // New stream to be parsed, parse it and fill frames_.
92 DVLOG(1) << "Invalid frame sync code"; 212 frames_ = ParseSuperframe();
93 return false; 213 if (frames_.empty()) {
94 } 214 DVLOG(1) << "Failed parsing superframes";
95 return true; 215 return kInvalidStream;
96 } 216 }
97 217 }
98 bool Vp9Parser::ReadBitDepthColorSpaceSampling(Vp9FrameHeader* fhdr) { 218
99 if (fhdr->profile == 2 || fhdr->profile == 3) { 219 curr_frame_info_ = frames_.front();
100 fhdr->bit_depth = reader_.ReadBool() ? 12 : 10; 220 frames_.pop_front();
101 } else { 221
102 fhdr->bit_depth = 8; 222 memset(&curr_frame_header_, 0, sizeof(curr_frame_header_));
103 } 223
104 224 Vp9UncompressedHeaderParser uncompressed_parser(&context_);
105 fhdr->color_space = static_cast<Vp9ColorSpace>(reader_.ReadLiteral(3)); 225 if (!uncompressed_parser.Parse(curr_frame_info_.ptr, curr_frame_info_.size,
106 if (fhdr->color_space != Vp9ColorSpace::SRGB) { 226 &curr_frame_header_))
107 fhdr->yuv_range = reader_.ReadBool(); 227 return kInvalidStream;
108 if (fhdr->profile == 1 || fhdr->profile == 3) { 228
109 fhdr->subsampling_x = reader_.ReadBool() ? 1 : 0; 229 if (curr_frame_header_.header_size_in_bytes == 0) {
110 fhdr->subsampling_y = reader_.ReadBool() ? 1 : 0; 230 // Verify padding bits are zero.
111 if (fhdr->subsampling_x == 1 && fhdr->subsampling_y == 1) { 231 for (off_t i = curr_frame_header_.uncompressed_header_size;
112 DVLOG(1) << "4:2:0 color not supported in profile 1 or 3"; 232 i < curr_frame_info_.size; i++) {
113 return false; 233 if (curr_frame_info_.ptr[i] != 0) {
114 } 234 DVLOG(1) << "Padding bits are not zeros.";
115 bool reserved = reader_.ReadBool(); 235 return kInvalidStream;
116 if (reserved) { 236 }
117 DVLOG(1) << "reserved bit set"; 237 }
118 return false; 238 *fhdr = curr_frame_header_;
119 } 239 curr_frame_info_.Reset();
120 } else { 240 return kOk;
121 fhdr->subsampling_x = fhdr->subsampling_y = 1; 241 }
122 } 242 if (curr_frame_header_.uncompressed_header_size +
123 } else { 243 curr_frame_header_.header_size_in_bytes >
124 if (fhdr->profile == 1 || fhdr->profile == 3) { 244 base::checked_cast<size_t>(curr_frame_info_.size)) {
125 fhdr->subsampling_x = fhdr->subsampling_y = 0; 245 DVLOG(1) << "header_size_in_bytes="
126 246 << curr_frame_header_.header_size_in_bytes
127 bool reserved = reader_.ReadBool(); 247 << " is larger than bytes left in buffer: "
128 if (reserved) { 248 << curr_frame_info_.size -
129 DVLOG(1) << "reserved bit set"; 249 curr_frame_header_.uncompressed_header_size;
130 return false; 250 return kInvalidStream;
131 } 251 }
132 } else { 252 }
133 DVLOG(1) << "4:4:4 color not supported in profile 0 or 2"; 253
134 return false; 254 if (parsing_compressed_header_) {
135 } 255 Vp9FrameContextManager& context_to_load =
136 } 256 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
137 257 if (!context_to_load.initialized()) {
138 return true; 258 // 8.2 Frame order constraints
139 } 259 // must load an initialized set of probabilities.
140 260 DVLOG(1) << "loading uninitialized frame context, index="
141 void Vp9Parser::ReadFrameSize(Vp9FrameHeader* fhdr) { 261 << curr_frame_header_.frame_context_idx;
142 fhdr->width = reader_.ReadLiteral(16) + 1; 262 return kInvalidStream;
143 fhdr->height = reader_.ReadLiteral(16) + 1; 263 }
144 } 264 if (context_to_load.needs_client_update()) {
145 265 DVLOG(3) << "waiting frame_context_idx="
146 bool Vp9Parser::ReadFrameSizeFromRefs(Vp9FrameHeader* fhdr) { 266 << static_cast<int>(curr_frame_header_.frame_context_idx)
147 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { 267 << " to update";
148 if (reader_.ReadBool()) { 268 return kAwaitingRefresh;
149 fhdr->width = ref_slots_[i].width; 269 }
150 fhdr->height = ref_slots_[i].height; 270 curr_frame_header_.initial_frame_context =
151 271 curr_frame_header_.frame_context = context_to_load.frame_context();
152 const int kMaxDimension = 1 << 16; 272
153 if (fhdr->width == 0 || fhdr->width > kMaxDimension || 273 Vp9CompressedHeaderParser compressed_parser;
154 fhdr->height == 0 || fhdr->height > kMaxDimension) { 274 if (!compressed_parser.Parse(
155 DVLOG(1) << "The size of reference frame is out of range: " 275 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size,
156 << ref_slots_[i].width << "," << ref_slots_[i].height; 276 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) {
157 return false; 277 return kInvalidStream;
158 } 278 }
159 return true; 279
160 } 280 if (curr_frame_header_.refresh_frame_context) {
161 } 281 Vp9FrameContextManager& frame_context_manager =
162 282 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
163 fhdr->width = reader_.ReadLiteral(16) + 1; 283
164 fhdr->height = reader_.ReadLiteral(16) + 1; 284 // In frame parallel mode, we can refresh the context without decoding
165 return true; 285 // tile data.
166 } 286 if (curr_frame_header_.frame_parallel_decoding_mode) {
167 287 frame_context_manager.Update(curr_frame_header_.frame_context);
168 void Vp9Parser::ReadDisplayFrameSize(Vp9FrameHeader* fhdr) {
169 if (reader_.ReadBool()) {
170 fhdr->display_width = reader_.ReadLiteral(16) + 1;
171 fhdr->display_height = reader_.ReadLiteral(16) + 1;
172 } else {
173 fhdr->display_width = fhdr->width;
174 fhdr->display_height = fhdr->height;
175 }
176 }
177
178 Vp9InterpFilter Vp9Parser::ReadInterpFilter() {
179 if (reader_.ReadBool())
180 return Vp9InterpFilter::SWICHABLE;
181
182 // The mapping table for next two bits.
183 const Vp9InterpFilter table[] = {
184 Vp9InterpFilter::EIGHTTAP_SMOOTH, Vp9InterpFilter::EIGHTTAP,
185 Vp9InterpFilter::EIGHTTAP_SHARP, Vp9InterpFilter::BILINEAR,
186 };
187 return table[reader_.ReadLiteral(2)];
188 }
189
190 void Vp9Parser::ReadLoopFilter() {
191 loop_filter_.filter_level = reader_.ReadLiteral(6);
192 loop_filter_.sharpness_level = reader_.ReadLiteral(3);
193 loop_filter_.mode_ref_delta_update = false;
194
195 loop_filter_.mode_ref_delta_enabled = reader_.ReadBool();
196 if (loop_filter_.mode_ref_delta_enabled) {
197 loop_filter_.mode_ref_delta_update = reader_.ReadBool();
198 if (loop_filter_.mode_ref_delta_update) {
199 for (size_t i = 0; i < Vp9LoopFilter::VP9_FRAME_MAX; i++) {
200 loop_filter_.update_ref_deltas[i] = reader_.ReadBool();
201 if (loop_filter_.update_ref_deltas[i])
202 loop_filter_.ref_deltas[i] = reader_.ReadSignedLiteral(6);
203 }
204
205 for (size_t i = 0; i < Vp9LoopFilter::kNumModeDeltas; i++) {
206 loop_filter_.update_mode_deltas[i] = reader_.ReadBool();
207 if (loop_filter_.update_mode_deltas[i])
208 loop_filter_.mode_deltas[i] = reader_.ReadLiteral(6);
209 }
210 }
211 }
212 }
213
214 void Vp9Parser::ReadQuantization(Vp9QuantizationParams* quants) {
215 quants->base_qindex = reader_.ReadLiteral(8);
216
217 if (reader_.ReadBool())
218 quants->y_dc_delta = reader_.ReadSignedLiteral(4);
219
220 if (reader_.ReadBool())
221 quants->uv_dc_delta = reader_.ReadSignedLiteral(4);
222
223 if (reader_.ReadBool())
224 quants->uv_ac_delta = reader_.ReadSignedLiteral(4);
225 }
226
227 void Vp9Parser::ReadSegmentationMap() {
228 for (size_t i = 0; i < Vp9Segmentation::kNumTreeProbs; i++) {
229 segmentation_.tree_probs[i] =
230 reader_.ReadBool() ? reader_.ReadLiteral(8) : kVp9MaxProb;
231 }
232
233 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++)
234 segmentation_.pred_probs[i] = kVp9MaxProb;
235
236 segmentation_.temporal_update = reader_.ReadBool();
237 if (segmentation_.temporal_update) {
238 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) {
239 if (reader_.ReadBool())
240 segmentation_.pred_probs[i] = reader_.ReadLiteral(8);
241 }
242 }
243 }
244
245 void Vp9Parser::ReadSegmentationData() {
246 segmentation_.abs_delta = reader_.ReadBool();
247
248 const int kFeatureDataBits[] = {8, 6, 2, 0};
249 const bool kFeatureDataSigned[] = {true, true, false, false};
250
251 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; i++) {
252 for (size_t j = 0; j < Vp9Segmentation::SEG_LVL_MAX; j++) {
253 int16_t data = 0;
254 segmentation_.feature_enabled[i][j] = reader_.ReadBool();
255 if (segmentation_.feature_enabled[i][j]) {
256 data = reader_.ReadLiteral(kFeatureDataBits[j]);
257 if (kFeatureDataSigned[j])
258 if (reader_.ReadBool())
259 data = -data;
260 }
261 segmentation_.feature_data[i][j] = data;
262 }
263 }
264 }
265
266 void Vp9Parser::ReadSegmentation() {
267 segmentation_.update_map = false;
268 segmentation_.update_data = false;
269
270 segmentation_.enabled = reader_.ReadBool();
271 if (!segmentation_.enabled)
272 return;
273
274 segmentation_.update_map = reader_.ReadBool();
275 if (segmentation_.update_map)
276 ReadSegmentationMap();
277
278 segmentation_.update_data = reader_.ReadBool();
279 if (segmentation_.update_data)
280 ReadSegmentationData();
281 }
282
283 void Vp9Parser::ReadTiles(Vp9FrameHeader* fhdr) {
284 int sb64_cols = (fhdr->width + 63) / 64;
285
286 int min_log2_tile_cols = GetMinLog2TileCols(sb64_cols);
287 int max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols);
288
289 int max_ones = max_log2_tile_cols - min_log2_tile_cols;
290 fhdr->log2_tile_cols = min_log2_tile_cols;
291 while (max_ones-- && reader_.ReadBool())
292 fhdr->log2_tile_cols++;
293
294 fhdr->log2_tile_rows = reader_.ReadBool() ? 1 : 0;
295 if (fhdr->log2_tile_rows > 0 && reader_.ReadBool())
296 fhdr->log2_tile_rows++;
297 }
298
299 bool Vp9Parser::ParseUncompressedHeader(const uint8_t* stream,
300 off_t frame_size,
301 Vp9FrameHeader* fhdr) {
302 reader_.Initialize(stream, frame_size);
303
304 fhdr->data = stream;
305 fhdr->frame_size = frame_size;
306
307 // frame marker
308 if (reader_.ReadLiteral(2) != 0x2)
309 return false;
310
311 fhdr->profile = ReadProfile();
312 if (fhdr->profile >= kVp9MaxProfile) {
313 DVLOG(1) << "Unsupported bitstream profile";
314 return false;
315 }
316
317 fhdr->show_existing_frame = reader_.ReadBool();
318 if (fhdr->show_existing_frame) {
319 fhdr->frame_to_show = reader_.ReadLiteral(3);
320 fhdr->show_frame = true;
321
322 if (!reader_.IsValid()) {
323 DVLOG(1) << "parser reads beyond the end of buffer";
324 return false;
325 }
326 fhdr->uncompressed_header_size = reader_.GetBytesRead();
327 return true;
328 }
329
330 fhdr->frame_type = static_cast<Vp9FrameHeader::FrameType>(reader_.ReadBool());
331 fhdr->show_frame = reader_.ReadBool();
332 fhdr->error_resilient_mode = reader_.ReadBool();
333
334 if (fhdr->IsKeyframe()) {
335 if (!VerifySyncCode())
336 return false;
337
338 if (!ReadBitDepthColorSpaceSampling(fhdr))
339 return false;
340
341 fhdr->refresh_flags = 0xff;
342
343 ReadFrameSize(fhdr);
344 ReadDisplayFrameSize(fhdr);
345 } else {
346 if (!fhdr->show_frame)
347 fhdr->intra_only = reader_.ReadBool();
348
349 if (!fhdr->error_resilient_mode)
350 fhdr->reset_context = reader_.ReadLiteral(2);
351
352 if (fhdr->intra_only) {
353 if (!VerifySyncCode())
354 return false;
355
356 if (fhdr->profile > 0) {
357 if (!ReadBitDepthColorSpaceSampling(fhdr))
358 return false;
359 } else { 288 } else {
360 fhdr->bit_depth = 8; 289 *context_refresh_cb = frame_context_manager.SetNeedsClientUpdate();
361 fhdr->color_space = Vp9ColorSpace::BT_601; 290 }
362 fhdr->subsampling_x = fhdr->subsampling_y = 1; 291 }
363 } 292 }
364 293
365 fhdr->refresh_flags = reader_.ReadLiteral(8); 294 SetupSegmentationDequant();
366
367 ReadFrameSize(fhdr);
368 ReadDisplayFrameSize(fhdr);
369 } else {
370 fhdr->refresh_flags = reader_.ReadLiteral(8);
371
372 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
373 fhdr->frame_refs[i] = reader_.ReadLiteral(kVp9NumRefFramesLog2);
374 fhdr->ref_sign_biases[i] = reader_.ReadBool();
375 }
376
377 if (!ReadFrameSizeFromRefs(fhdr))
378 return false;
379 ReadDisplayFrameSize(fhdr);
380
381 fhdr->allow_high_precision_mv = reader_.ReadBool();
382 fhdr->interp_filter = ReadInterpFilter();
383 }
384 }
385
386 if (fhdr->error_resilient_mode) {
387 fhdr->frame_parallel_decoding_mode = true;
388 } else {
389 fhdr->refresh_frame_context = reader_.ReadBool();
390 fhdr->frame_parallel_decoding_mode = reader_.ReadBool();
391 }
392
393 fhdr->frame_context_idx = reader_.ReadLiteral(2);
394
395 if (fhdr->IsKeyframe() || fhdr->intra_only)
396 SetupPastIndependence();
397
398 ReadLoopFilter();
399 ReadQuantization(&fhdr->quant_params);
400 ReadSegmentation();
401
402 ReadTiles(fhdr);
403
404 fhdr->first_partition_size = reader_.ReadLiteral(16);
405 if (fhdr->first_partition_size == 0) {
406 DVLOG(1) << "invalid header size";
407 return false;
408 }
409
410 if (!reader_.IsValid()) {
411 DVLOG(1) << "parser reads beyond the end of buffer";
412 return false;
413 }
414 fhdr->uncompressed_header_size = reader_.GetBytesRead();
415
416 SetupSegmentationDequant(fhdr->quant_params);
417 SetupLoopFilter(); 295 SetupLoopFilter();
418 296 UpdateSlots();
419 UpdateSlots(fhdr); 297
420 298 *fhdr = curr_frame_header_;
421 return true; 299 curr_frame_info_.Reset();
422 }
423
424 void Vp9Parser::UpdateSlots(const Vp9FrameHeader* fhdr) {
425 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
426 if (fhdr->RefreshFlag(i)) {
427 ref_slots_[i].width = fhdr->width;
428 ref_slots_[i].height = fhdr->height;
429 }
430 }
431 }
432
433 Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) {
434 if (frames_.empty()) {
435 // No frames to be decoded, if there is no more stream, request more.
436 if (!stream_)
437 return kEOStream;
438
439 // New stream to be parsed, parse it and fill frames_.
440 if (!ParseSuperframe()) {
441 DVLOG(1) << "Failed parsing superframes";
442 return kInvalidStream;
443 }
444 }
445
446 DCHECK(!frames_.empty());
447 FrameInfo frame_info = frames_.front();
448 frames_.pop_front();
449
450 memset(fhdr, 0, sizeof(*fhdr));
451 if (!ParseUncompressedHeader(frame_info.ptr, frame_info.size, fhdr))
452 return kInvalidStream;
453
454 return kOk; 300 return kOk;
455 } 301 }
456 302
457 bool Vp9Parser::ParseSuperframe() { 303 // Annex B Superframes
304 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() {
458 const uint8_t* stream = stream_; 305 const uint8_t* stream = stream_;
459 off_t bytes_left = bytes_left_; 306 off_t bytes_left = bytes_left_;
460 307
461 DCHECK(frames_.empty());
462
463 // Make sure we don't parse stream_ more than once. 308 // Make sure we don't parse stream_ more than once.
464 stream_ = nullptr; 309 stream_ = nullptr;
465 bytes_left_ = 0; 310 bytes_left_ = 0;
466 311
467 if (bytes_left < 1) 312 if (bytes_left < 1)
468 return false; 313 return std::deque<FrameInfo>();
469 314
470 // If this is a superframe, the last byte in the stream will contain the 315 // If this is a superframe, the last byte in the stream will contain the
471 // superframe marker. If not, the whole buffer contains a single frame. 316 // superframe marker. If not, the whole buffer contains a single frame.
472 uint8_t marker = *(stream + bytes_left - 1); 317 uint8_t marker = *(stream + bytes_left - 1);
473 if ((marker & 0xe0) != 0xc0) { 318 if ((marker & 0xe0) != 0xc0) {
474 frames_.push_back(FrameInfo(stream, bytes_left)); 319 return {FrameInfo(stream, bytes_left)};
475 return true;
476 } 320 }
477 321
478 DVLOG(1) << "Parsing a superframe"; 322 DVLOG(1) << "Parsing a superframe";
479 323
480 // The bytes immediately before the superframe marker constitute superframe 324 // The bytes immediately before the superframe marker constitute superframe
481 // index, which stores information about sizes of each frame in it. 325 // index, which stores information about sizes of each frame in it.
482 // Calculate its size and set index_ptr to the beginning of it. 326 // Calculate its size and set index_ptr to the beginning of it.
483 size_t num_frames = (marker & 0x7) + 1; 327 size_t num_frames = (marker & 0x7) + 1;
484 size_t mag = ((marker >> 3) & 0x3) + 1; 328 size_t mag = ((marker >> 3) & 0x3) + 1;
485 off_t index_size = 2 + mag * num_frames; 329 off_t index_size = 2 + mag * num_frames;
486 330
487 if (bytes_left < index_size) 331 if (bytes_left < index_size)
488 return false; 332 return std::deque<FrameInfo>();
489 333
490 const uint8_t* index_ptr = stream + bytes_left - index_size; 334 const uint8_t* index_ptr = stream + bytes_left - index_size;
491 if (marker != *index_ptr) 335 if (marker != *index_ptr)
492 return false; 336 return std::deque<FrameInfo>();
493 337
494 ++index_ptr; 338 ++index_ptr;
495 bytes_left -= index_size; 339 bytes_left -= index_size;
496 340
497 // Parse frame information contained in the index and add a pointer to and 341 // Parse frame information contained in the index and add a pointer to and
498 // size of each frame to frames_. 342 // size of each frame to frames.
343 std::deque<FrameInfo> frames;
499 for (size_t i = 0; i < num_frames; ++i) { 344 for (size_t i = 0; i < num_frames; ++i) {
500 uint32_t size = 0; 345 uint32_t size = 0;
501 for (size_t j = 0; j < mag; ++j) { 346 for (size_t j = 0; j < mag; ++j) {
502 size |= *index_ptr << (j * 8); 347 size |= *index_ptr << (j * 8);
503 ++index_ptr; 348 ++index_ptr;
504 } 349 }
505 350
506 if (base::checked_cast<off_t>(size) > bytes_left) { 351 if (base::checked_cast<off_t>(size) > bytes_left) {
507 DVLOG(1) << "Not enough data in the buffer for frame " << i; 352 DVLOG(1) << "Not enough data in the buffer for frame " << i;
508 return false; 353 return std::deque<FrameInfo>();
509 } 354 }
510 355
511 frames_.push_back(FrameInfo(stream, size)); 356 frames.push_back(FrameInfo(stream, size));
512 stream += size; 357 stream += size;
513 bytes_left -= size; 358 bytes_left -= size;
514 359
515 DVLOG(1) << "Frame " << i << ", size: " << size; 360 DVLOG(1) << "Frame " << i << ", size: " << size;
516 } 361 }
517 362
518 return true; 363 return frames;
519 } 364 }
520 365
521 void Vp9Parser::ResetLoopfilter() { 366 // 8.6.1
522 loop_filter_.mode_ref_delta_enabled = true;
523 loop_filter_.mode_ref_delta_update = true;
524
525 const int8_t default_ref_deltas[] = {1, 0, -1, -1};
526 static_assert(
527 arraysize(default_ref_deltas) == arraysize(loop_filter_.ref_deltas),
528 "ref_deltas arrays of incorrect size");
529 for (size_t i = 0; i < arraysize(loop_filter_.ref_deltas); ++i)
530 loop_filter_.ref_deltas[i] = default_ref_deltas[i];
531
532 memset(loop_filter_.mode_deltas, 0, sizeof(loop_filter_.mode_deltas));
533 }
534
535 void Vp9Parser::SetupPastIndependence() {
536 memset(&segmentation_, 0, sizeof(segmentation_));
537 ResetLoopfilter();
538 }
539
540 const size_t QINDEX_RANGE = 256; 367 const size_t QINDEX_RANGE = 256;
541 const int16_t kDcQLookup[QINDEX_RANGE] = { 368 const int16_t kDcQLookup[QINDEX_RANGE] = {
542 4, 8, 8, 9, 10, 11, 12, 12, 369 4, 8, 8, 9, 10, 11, 12, 12,
543 13, 14, 15, 16, 17, 18, 19, 19, 370 13, 14, 15, 16, 17, 18, 19, 19,
544 20, 21, 22, 23, 24, 25, 26, 26, 371 20, 21, 22, 23, 24, 25, 26, 26,
545 27, 28, 29, 30, 31, 32, 32, 33, 372 27, 28, 29, 30, 31, 32, 32, 33,
546 34, 35, 36, 37, 38, 38, 39, 40, 373 34, 35, 36, 37, 38, 38, 39, 40,
547 41, 42, 43, 43, 44, 45, 46, 47, 374 41, 42, 43, 43, 44, 45, 46, 47,
548 48, 48, 49, 50, 51, 52, 53, 53, 375 48, 48, 49, 50, 51, 52, 53, 53,
549 54, 55, 56, 57, 57, 58, 59, 60, 376 54, 55, 56, 57, 57, 58, 59, 60,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 864, 881, 898, 915, 933, 951, 969, 988, 431 864, 881, 898, 915, 933, 951, 969, 988,
605 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, 432 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151,
606 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 433 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
607 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, 434 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567,
608 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, 435 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
609 }; 436 };
610 437
611 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup), 438 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup),
612 "quantizer lookup arrays of incorrect size"); 439 "quantizer lookup arrays of incorrect size");
613 440
614 #define CLAMP_Q(q) \ 441 static size_t ClampQ(size_t q) {
615 std::min(std::max(static_cast<size_t>(0), q), arraysize(kDcQLookup) - 1) 442 return std::min(std::max(static_cast<size_t>(0), q),
443 arraysize(kDcQLookup) - 1);
444 }
616 445
446 // 8.6.1 Dequantization functions
617 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, 447 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
618 size_t segid) const { 448 size_t segid) const {
619 if (segmentation_.FeatureEnabled(segid, Vp9Segmentation::SEG_LVL_ALT_Q)) { 449 const Vp9SegmentationParams& segmentation = context_.segmentation;
450
451 if (segmentation.FeatureEnabled(segid,
452 Vp9SegmentationParams::SEG_LVL_ALT_Q)) {
620 int16_t feature_data = 453 int16_t feature_data =
621 segmentation_.FeatureData(segid, Vp9Segmentation::SEG_LVL_ALT_Q); 454 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q);
622 size_t q_index = segmentation_.abs_delta ? feature_data 455 size_t q_index = segmentation.abs_or_delta_update
623 : quant.base_qindex + feature_data; 456 ? feature_data
624 return CLAMP_Q(q_index); 457 : quant.base_q_idx + feature_data;
458 return ClampQ(q_index);
625 } 459 }
626 460
627 return quant.base_qindex; 461 return quant.base_q_idx;
628 } 462 }
629 463
630 void Vp9Parser::SetupSegmentationDequant(const Vp9QuantizationParams& quant) { 464 // 8.6.1 Dequantization functions
631 if (segmentation_.enabled) { 465 void Vp9Parser::SetupSegmentationDequant() {
632 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) { 466 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params;
467 Vp9SegmentationParams& segmentation = context_.segmentation;
468
469 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8)
470 << "bit_depth > 8 is not supported "
471 "yet, kDcQLookup and kAcQLookup "
472 "need extended";
473 if (segmentation.enabled) {
474 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
633 const size_t q_index = GetQIndex(quant, i); 475 const size_t q_index = GetQIndex(quant, i);
634 segmentation_.y_dequant[i][0] = 476 segmentation.y_dequant[i][0] =
635 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)]; 477 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
636 segmentation_.y_dequant[i][1] = kAcQLookup[CLAMP_Q(q_index)]; 478 segmentation.y_dequant[i][1] = kAcQLookup[ClampQ(q_index)];
637 segmentation_.uv_dequant[i][0] = 479 segmentation.uv_dequant[i][0] =
638 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)]; 480 kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
639 segmentation_.uv_dequant[i][1] = 481 segmentation.uv_dequant[i][1] =
640 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)]; 482 kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
641 } 483 }
642 } else { 484 } else {
643 const size_t q_index = quant.base_qindex; 485 const size_t q_index = quant.base_q_idx;
644 segmentation_.y_dequant[0][0] = 486 segmentation.y_dequant[0][0] =
645 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)]; 487 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
646 segmentation_.y_dequant[0][1] = kAcQLookup[CLAMP_Q(q_index)]; 488 segmentation.y_dequant[0][1] = kAcQLookup[ClampQ(q_index)];
647 segmentation_.uv_dequant[0][0] = 489 segmentation.uv_dequant[0][0] =
648 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)]; 490 kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
649 segmentation_.uv_dequant[0][1] = 491 segmentation.uv_dequant[0][1] =
650 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)]; 492 kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
651 } 493 }
652 } 494 }
653 #undef CLAMP_Q
654 495
655 #define CLAMP_LF(l) std::min(std::max(0, l), kMaxLoopFilterLevel) 496 static int ClampLf(int lf) {
497 const int kMaxLoopFilterLevel = 63;
498 return std::min(std::max(0, lf), kMaxLoopFilterLevel);
499 }
500
501 // 8.8.1 Loop filter frame init process
656 void Vp9Parser::SetupLoopFilter() { 502 void Vp9Parser::SetupLoopFilter() {
657 if (!loop_filter_.filter_level) 503 Vp9LoopFilterParams& loop_filter = context_.loop_filter;
504 if (!loop_filter.level)
658 return; 505 return;
659 506
660 int scale = loop_filter_.filter_level < 32 ? 1 : 2; 507 int scale = loop_filter.level < 32 ? 1 : 2;
661 508
662 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) { 509 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
663 int level = loop_filter_.filter_level; 510 int level = loop_filter.level;
511 Vp9SegmentationParams& segmentation = context_.segmentation;
664 512
665 if (segmentation_.FeatureEnabled(i, Vp9Segmentation::SEG_LVL_ALT_LF)) { 513 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) {
666 int feature_data = 514 int feature_data =
667 segmentation_.FeatureData(i, Vp9Segmentation::SEG_LVL_ALT_LF); 515 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF);
668 level = CLAMP_LF(segmentation_.abs_delta ? feature_data 516 level = ClampLf(segmentation.abs_or_delta_update ? feature_data
669 : level + feature_data); 517 : level + feature_data);
670 } 518 }
671 519
672 if (!loop_filter_.mode_ref_delta_enabled) { 520 if (!loop_filter.delta_enabled) {
673 memset(loop_filter_.lvl[i], level, sizeof(loop_filter_.lvl[i])); 521 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i]));
674 } else { 522 } else {
675 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][0] = CLAMP_LF( 523 loop_filter.lvl[i][Vp9RefType::VP9_FRAME_INTRA][0] = ClampLf(
676 level + 524 level + loop_filter.ref_deltas[Vp9RefType::VP9_FRAME_INTRA] * scale);
677 loop_filter_.ref_deltas[Vp9LoopFilter::VP9_FRAME_INTRA] * scale); 525 loop_filter.lvl[i][Vp9RefType::VP9_FRAME_INTRA][1] = 0;
678 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][1] = 0;
679 526
680 for (size_t type = Vp9LoopFilter::VP9_FRAME_LAST; 527 for (size_t type = Vp9RefType::VP9_FRAME_LAST;
681 type < Vp9LoopFilter::VP9_FRAME_MAX; ++type) { 528 type < Vp9RefType::VP9_FRAME_MAX; ++type) {
682 for (size_t mode = 0; mode < Vp9LoopFilter::kNumModeDeltas; ++mode) { 529 for (size_t mode = 0; mode < Vp9LoopFilterParams::kNumModeDeltas;
683 loop_filter_.lvl[i][type][mode] = 530 ++mode) {
684 CLAMP_LF(level + loop_filter_.ref_deltas[type] * scale + 531 loop_filter.lvl[i][type][mode] =
685 loop_filter_.mode_deltas[mode] * scale); 532 ClampLf(level + loop_filter.ref_deltas[type] * scale +
533 loop_filter.mode_deltas[mode] * scale);
686 } 534 }
687 } 535 }
688 } 536 }
689 } 537 }
690 } 538 }
691 #undef CLAMP_LF 539
540 void Vp9Parser::UpdateSlots() {
541 // 8.10 Reference frame update process
542 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
543 if (curr_frame_header_.RefreshFlag(i)) {
544 ReferenceSlot& ref = context_.ref_slots[i];
545 ref.initialized = true;
546
547 ref.frame_width = curr_frame_header_.frame_width;
548 ref.frame_height = curr_frame_header_.frame_height;
549 ref.subsampling_x = curr_frame_header_.subsampling_x;
550 ref.subsampling_y = curr_frame_header_.subsampling_y;
551 ref.bit_depth = curr_frame_header_.bit_depth;
552
553 ref.profile = curr_frame_header_.profile;
554 ref.color_space = curr_frame_header_.color_space;
555 }
556 }
557 }
692 558
693 } // namespace media 559 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/vp9_parser.h ('k') | media/filters/vp9_parser_fuzzertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698