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

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

Issue 1357513002: Revert of Add accelerated VP9 decode infrastructure and an implementation for VA-API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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_unittest.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 6
7 #include "media/filters/vp9_parser.h" 7 #include "media/filters/vp9_parser.h"
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h"
11 10
12 namespace { 11 namespace {
13 12
14 const int kMaxLoopFilterLevel = 63;
15
16 // Helper function for Vp9Parser::ReadTiles. Defined as get_min_log2_tile_cols 13 // Helper function for Vp9Parser::ReadTiles. Defined as get_min_log2_tile_cols
17 // in spec. 14 // in spec.
18 int GetMinLog2TileCols(int sb64_cols) { 15 int GetMinLog2TileCols(int sb64_cols) {
19 const int kMaxTileWidthB64 = 64; 16 const int kMaxTileWidthB64 = 64;
20 int min_log2 = 0; 17 int min_log2 = 0;
21 while ((kMaxTileWidthB64 << min_log2) < sb64_cols) 18 while ((kMaxTileWidthB64 << min_log2) < sb64_cols)
22 min_log2++; 19 min_log2++;
23 return min_log2; 20 return min_log2;
24 } 21 }
25 22
26 // Helper function for Vp9Parser::ReadTiles. Defined as get_max_log2_tile_cols 23 // Helper function for Vp9Parser::ReadTiles. Defined as get_max_log2_tile_cols
27 // in spec. 24 // in spec.
28 int GetMaxLog2TileCols(int sb64_cols) { 25 int GetMaxLog2TileCols(int sb64_cols) {
29 const int kMinTileWidthB64 = 4; 26 const int kMinTileWidthB64 = 4;
30 int max_log2 = 1; 27 int max_log2 = 1;
31 while ((sb64_cols >> max_log2) >= kMinTileWidthB64) 28 while ((sb64_cols >> max_log2) >= kMinTileWidthB64)
32 max_log2++; 29 max_log2++;
33 return max_log2 - 1; 30 return max_log2 - 1;
34 } 31 }
35 32
36 } // namespace 33 } // namespace
37 34
38 namespace media { 35 namespace media {
39 36
40 bool Vp9FrameHeader::IsKeyframe() const { 37 Vp9Parser::Vp9Parser() : stream_(nullptr), size_(0) {
41 // When show_existing_frame is true, the frame header does not precede an
42 // actual frame to be decoded, so frame_type does not apply (and is not read
43 // from the stream).
44 return !show_existing_frame && frame_type == KEYFRAME;
45 }
46
47 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size)
48 : ptr(ptr), size(size) {}
49
50 Vp9Parser::Vp9Parser() {
51 Reset();
52 }
53
54 Vp9Parser::~Vp9Parser() {}
55
56 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) {
57 DCHECK(stream);
58 stream_ = stream;
59 bytes_left_ = stream_size;
60 frames_.clear();
61 }
62
63 void Vp9Parser::Reset() {
64 stream_ = nullptr;
65 bytes_left_ = 0;
66 frames_.clear();
67
68 memset(&segmentation_, 0, sizeof(segmentation_));
69 memset(&loop_filter_, 0, sizeof(loop_filter_));
70 memset(&ref_slots_, 0, sizeof(ref_slots_)); 38 memset(&ref_slots_, 0, sizeof(ref_slots_));
71 } 39 }
72 40
73 uint8_t Vp9Parser::ReadProfile() { 41 uint8_t Vp9Parser::ReadProfile() {
74 uint8_t profile = 0; 42 uint8_t profile = 0;
75 43
76 // LSB first. 44 // LSB first.
77 if (reader_.ReadBool()) 45 if (reader_.ReadBool())
78 profile |= 1; 46 profile |= 1;
79 if (reader_.ReadBool()) 47 if (reader_.ReadBool())
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 fhdr->display_width = reader_.ReadLiteral(16) + 1; 135 fhdr->display_width = reader_.ReadLiteral(16) + 1;
168 fhdr->display_height = reader_.ReadLiteral(16) + 1; 136 fhdr->display_height = reader_.ReadLiteral(16) + 1;
169 } else { 137 } else {
170 fhdr->display_width = fhdr->width; 138 fhdr->display_width = fhdr->width;
171 fhdr->display_height = fhdr->height; 139 fhdr->display_height = fhdr->height;
172 } 140 }
173 } 141 }
174 142
175 Vp9InterpFilter Vp9Parser::ReadInterpFilter() { 143 Vp9InterpFilter Vp9Parser::ReadInterpFilter() {
176 if (reader_.ReadBool()) 144 if (reader_.ReadBool())
177 return Vp9InterpFilter::SWICHABLE; 145 return Vp9InterpFilter::INTERP_FILTER_SELECT;
178 146
179 // The mapping table for next two bits. 147 // The mapping table for next two bits.
180 const Vp9InterpFilter table[] = { 148 const Vp9InterpFilter table[] = {
181 Vp9InterpFilter::EIGHTTAP_SMOOTH, Vp9InterpFilter::EIGHTTAP, 149 Vp9InterpFilter::EIGHTTAP_SMOOTH, Vp9InterpFilter::EIGHTTAP,
182 Vp9InterpFilter::EIGHTTAP_SHARP, Vp9InterpFilter::BILINEAR, 150 Vp9InterpFilter::EIGHTTAP_SHARP, Vp9InterpFilter::BILINEAR,
183 }; 151 };
184 return table[reader_.ReadLiteral(2)]; 152 return table[reader_.ReadLiteral(2)];
185 } 153 }
186 154
187 void Vp9Parser::ReadLoopFilter() { 155 void Vp9Parser::ReadLoopFilter(Vp9LoopFilter* loop_filter) {
188 loop_filter_.filter_level = reader_.ReadLiteral(6); 156 loop_filter->filter_level = reader_.ReadLiteral(6);
189 loop_filter_.sharpness_level = reader_.ReadLiteral(3); 157 loop_filter->sharpness_level = reader_.ReadLiteral(3);
190 loop_filter_.mode_ref_delta_update = false;
191 158
192 loop_filter_.mode_ref_delta_enabled = reader_.ReadBool(); 159 loop_filter->mode_ref_delta_enabled = reader_.ReadBool();
193 if (loop_filter_.mode_ref_delta_enabled) { 160 if (loop_filter->mode_ref_delta_enabled) {
194 loop_filter_.mode_ref_delta_update = reader_.ReadBool(); 161 loop_filter->mode_ref_delta_update = reader_.ReadBool();
195 if (loop_filter_.mode_ref_delta_update) { 162 if (loop_filter->mode_ref_delta_update) {
196 for (size_t i = 0; i < Vp9LoopFilter::VP9_FRAME_MAX; i++) { 163 for (size_t i = 0; i < Vp9LoopFilter::kNumRefDeltas; i++) {
197 loop_filter_.update_ref_deltas[i] = reader_.ReadBool(); 164 loop_filter->update_ref_deltas[i] = reader_.ReadBool();
198 if (loop_filter_.update_ref_deltas[i]) 165 if (loop_filter->update_ref_deltas[i])
199 loop_filter_.ref_deltas[i] = reader_.ReadSignedLiteral(6); 166 loop_filter->ref_deltas[i] = reader_.ReadSignedLiteral(6);
200 } 167 }
201 168
202 for (size_t i = 0; i < Vp9LoopFilter::kNumModeDeltas; i++) { 169 for (size_t i = 0; i < Vp9LoopFilter::kNumModeDeltas; i++) {
203 loop_filter_.update_mode_deltas[i] = reader_.ReadBool(); 170 loop_filter->update_mode_deltas[i] = reader_.ReadBool();
204 if (loop_filter_.update_mode_deltas[i]) 171 if (loop_filter->update_mode_deltas[i])
205 loop_filter_.mode_deltas[i] = reader_.ReadLiteral(6); 172 loop_filter->mode_deltas[i] = reader_.ReadLiteral(6);
206 } 173 }
207 } 174 }
208 } 175 }
209 } 176 }
210 177
211 void Vp9Parser::ReadQuantization(Vp9QuantizationParams* quants) { 178 void Vp9Parser::ReadQuantization(Vp9QuantizationParams* quants) {
212 quants->base_qindex = reader_.ReadLiteral(8); 179 quants->base_qindex = reader_.ReadLiteral(8);
213 180
214 if (reader_.ReadBool()) 181 if (reader_.ReadBool())
215 quants->y_dc_delta = reader_.ReadSignedLiteral(4); 182 quants->y_dc_delta = reader_.ReadSignedLiteral(4);
216 183
217 if (reader_.ReadBool()) 184 if (reader_.ReadBool())
218 quants->uv_ac_delta = reader_.ReadSignedLiteral(4); 185 quants->uv_ac_delta = reader_.ReadSignedLiteral(4);
219 186
220 if (reader_.ReadBool()) 187 if (reader_.ReadBool())
221 quants->uv_dc_delta = reader_.ReadSignedLiteral(4); 188 quants->uv_dc_delta = reader_.ReadSignedLiteral(4);
222 } 189 }
223 190
224 void Vp9Parser::ReadSegmentationMap() { 191 void Vp9Parser::ReadSegmentationMap(Vp9Segmentation* segment) {
225 for (size_t i = 0; i < Vp9Segmentation::kNumTreeProbs; i++) { 192 for (size_t i = 0; i < Vp9Segmentation::kNumTreeProbs; i++) {
226 segmentation_.tree_probs[i] = 193 segment->tree_probs[i] =
227 reader_.ReadBool() ? reader_.ReadLiteral(8) : kVp9MaxProb; 194 reader_.ReadBool() ? reader_.ReadLiteral(8) : kVp9MaxProb;
228 } 195 }
229 196
230 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) 197 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++)
231 segmentation_.pred_probs[i] = kVp9MaxProb; 198 segment->pred_probs[i] = kVp9MaxProb;
232 199
233 segmentation_.temporal_update = reader_.ReadBool(); 200 segment->temporal_update = reader_.ReadBool();
234 if (segmentation_.temporal_update) { 201 if (segment->temporal_update) {
235 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) { 202 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) {
236 if (reader_.ReadBool()) 203 if (reader_.ReadBool())
237 segmentation_.pred_probs[i] = reader_.ReadLiteral(8); 204 segment->pred_probs[i] = reader_.ReadLiteral(8);
238 } 205 }
239 } 206 }
240 } 207 }
241 208
242 void Vp9Parser::ReadSegmentationData() { 209 void Vp9Parser::ReadSegmentationData(Vp9Segmentation* segment) {
243 segmentation_.abs_delta = reader_.ReadBool(); 210 segment->abs_delta = reader_.ReadBool();
244 211
245 const int kFeatureDataBits[] = {7, 6, 2, 0}; 212 const int kFeatureDataBits[] = {7, 6, 2, 0};
246 const bool kFeatureDataSigned[] = {true, true, false, false}; 213 const bool kFeatureDataSigned[] = {true, true, false, false};
247 214
248 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; i++) { 215 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; i++) {
249 for (size_t j = 0; j < Vp9Segmentation::SEG_LVL_MAX; j++) { 216 for (size_t j = 0; j < Vp9Segmentation::kNumFeatures; j++) {
250 int8_t data = 0; 217 int8_t data = 0;
251 segmentation_.feature_enabled[i][j] = reader_.ReadBool(); 218 segment->feature_enabled[i][j] = reader_.ReadBool();
252 if (segmentation_.feature_enabled[i][j]) { 219 if (segment->feature_enabled[i][j]) {
253 data = reader_.ReadLiteral(kFeatureDataBits[j]); 220 data = reader_.ReadLiteral(kFeatureDataBits[j]);
254 if (kFeatureDataSigned[j]) 221 if (kFeatureDataSigned[j])
255 if (reader_.ReadBool()) 222 if (reader_.ReadBool())
256 data = -data; 223 data = -data;
257 } 224 }
258 segmentation_.feature_data[i][j] = data; 225 segment->feature_data[i][j] = data;
259 } 226 }
260 } 227 }
261 } 228 }
262 229
263 void Vp9Parser::ReadSegmentation() { 230 void Vp9Parser::ReadSegmentation(Vp9Segmentation* segment) {
264 segmentation_.update_map = false; 231 segment->enabled = reader_.ReadBool();
265 segmentation_.update_data = false;
266 232
267 segmentation_.enabled = reader_.ReadBool(); 233 if (!segment->enabled) {
268 if (!segmentation_.enabled)
269 return; 234 return;
235 }
270 236
271 segmentation_.update_map = reader_.ReadBool(); 237 segment->update_map = reader_.ReadBool();
272 if (segmentation_.update_map) 238 if (segment->update_map)
273 ReadSegmentationMap(); 239 ReadSegmentationMap(segment);
274 240
275 segmentation_.update_data = reader_.ReadBool(); 241 segment->update_data = reader_.ReadBool();
276 if (segmentation_.update_data) 242 if (segment->update_data)
277 ReadSegmentationData(); 243 ReadSegmentationData(segment);
278 } 244 }
279 245
280 void Vp9Parser::ReadTiles(Vp9FrameHeader* fhdr) { 246 void Vp9Parser::ReadTiles(Vp9FrameHeader* fhdr) {
281 int sb64_cols = (fhdr->width + 63) / 64; 247 int sb64_cols = (fhdr->width + 63) / 64;
282 248
283 int min_log2_tile_cols = GetMinLog2TileCols(sb64_cols); 249 int min_log2_tile_cols = GetMinLog2TileCols(sb64_cols);
284 int max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols); 250 int max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols);
285 251
286 int max_ones = max_log2_tile_cols - min_log2_tile_cols; 252 int max_ones = max_log2_tile_cols - min_log2_tile_cols;
287 fhdr->log2_tile_cols = min_log2_tile_cols; 253 fhdr->log2_tile_cols = min_log2_tile_cols;
288 while (max_ones-- && reader_.ReadBool()) 254 while (max_ones-- && reader_.ReadBool())
289 fhdr->log2_tile_cols++; 255 fhdr->log2_tile_cols++;
290 256
291 if (reader_.ReadBool()) 257 if (reader_.ReadBool())
292 fhdr->log2_tile_rows = reader_.ReadLiteral(2) - 1; 258 fhdr->log2_tile_rows = reader_.ReadLiteral(2) - 1;
293 } 259 }
294 260
295 bool Vp9Parser::ParseUncompressedHeader(const uint8_t* stream, 261 bool Vp9Parser::ParseUncompressedHeader(Vp9FrameHeader* fhdr) {
296 off_t frame_size, 262 reader_.Initialize(stream_, size_);
297 Vp9FrameHeader* fhdr) {
298 reader_.Initialize(stream, frame_size);
299
300 fhdr->data = stream;
301 fhdr->frame_size = frame_size;
302 263
303 // frame marker 264 // frame marker
304 if (reader_.ReadLiteral(2) != 0x2) 265 if (reader_.ReadLiteral(2) != 0x2)
305 return false; 266 return false;
306 267
307 fhdr->profile = ReadProfile(); 268 fhdr->profile = ReadProfile();
308 if (fhdr->profile >= kVp9MaxProfile) { 269 if (fhdr->profile >= kVp9MaxProfile) {
309 DVLOG(1) << "Unsupported bitstream profile"; 270 DVLOG(1) << "Unsupported bitstream profile";
310 return false; 271 return false;
311 } 272 }
(...skipping 15 matching lines...) Expand all
327 fhdr->show_frame = reader_.ReadBool(); 288 fhdr->show_frame = reader_.ReadBool();
328 fhdr->error_resilient_mode = reader_.ReadBool(); 289 fhdr->error_resilient_mode = reader_.ReadBool();
329 290
330 if (fhdr->IsKeyframe()) { 291 if (fhdr->IsKeyframe()) {
331 if (!VerifySyncCode()) 292 if (!VerifySyncCode())
332 return false; 293 return false;
333 294
334 if (!ReadBitDepthColorSpaceSampling(fhdr)) 295 if (!ReadBitDepthColorSpaceSampling(fhdr))
335 return false; 296 return false;
336 297
337 fhdr->refresh_flags = 0xff; 298 for (size_t i = 0; i < kVp9NumRefFrames; i++)
299 fhdr->refresh_flag[i] = true;
338 300
339 ReadFrameSize(fhdr); 301 ReadFrameSize(fhdr);
340 ReadDisplayFrameSize(fhdr); 302 ReadDisplayFrameSize(fhdr);
341 } else { 303 } else {
342 if (!fhdr->show_frame) 304 if (!fhdr->show_frame)
343 fhdr->intra_only = reader_.ReadBool(); 305 fhdr->intra_only = reader_.ReadBool();
344 306
345 if (!fhdr->error_resilient_mode) 307 if (!fhdr->error_resilient_mode)
346 fhdr->reset_context = reader_.ReadLiteral(2); 308 fhdr->reset_context = reader_.ReadLiteral(2);
347 309
348 if (fhdr->intra_only) { 310 if (fhdr->intra_only) {
349 if (!VerifySyncCode()) 311 if (!VerifySyncCode())
350 return false; 312 return false;
351 313
352 if (fhdr->profile > 0) { 314 if (fhdr->profile > 0) {
353 if (!ReadBitDepthColorSpaceSampling(fhdr)) 315 if (!ReadBitDepthColorSpaceSampling(fhdr))
354 return false; 316 return false;
355 } else { 317 } else {
356 fhdr->bit_depth = 8; 318 fhdr->bit_depth = 8;
357 fhdr->color_space = Vp9ColorSpace::BT_601; 319 fhdr->color_space = Vp9ColorSpace::BT_601;
358 fhdr->subsampling_x = fhdr->subsampling_y = 1; 320 fhdr->subsampling_x = fhdr->subsampling_y = 1;
359 } 321 }
360 322
361 fhdr->refresh_flags = reader_.ReadLiteral(8); 323 for (size_t i = 0; i < kVp9NumRefFrames; i++)
362 324 fhdr->refresh_flag[i] = reader_.ReadBool();
363 ReadFrameSize(fhdr); 325 ReadFrameSize(fhdr);
364 ReadDisplayFrameSize(fhdr); 326 ReadDisplayFrameSize(fhdr);
365 } else { 327 } else {
366 fhdr->refresh_flags = reader_.ReadLiteral(8); 328 for (size_t i = 0; i < kVp9NumRefFrames; i++)
329 fhdr->refresh_flag[i] = reader_.ReadBool();
367 330
368 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { 331 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
369 fhdr->frame_refs[i] = reader_.ReadLiteral(kVp9NumRefFramesLog2); 332 fhdr->frame_refs[i] = reader_.ReadLiteral(kVp9NumRefFramesLog2);
370 fhdr->ref_sign_biases[i] = reader_.ReadBool(); 333 fhdr->ref_sign_biases[i] = reader_.ReadBool();
371 } 334 }
372 335
373 if (!ReadFrameSizeFromRefs(fhdr)) 336 if (!ReadFrameSizeFromRefs(fhdr))
374 return false; 337 return false;
375 ReadDisplayFrameSize(fhdr); 338 ReadDisplayFrameSize(fhdr);
376 339
377 fhdr->allow_high_precision_mv = reader_.ReadBool(); 340 fhdr->allow_high_precision_mv = reader_.ReadBool();
378 fhdr->interp_filter = ReadInterpFilter(); 341 fhdr->interp_filter = ReadInterpFilter();
379 } 342 }
380 } 343 }
381 344
382 if (fhdr->error_resilient_mode) { 345 if (fhdr->error_resilient_mode) {
383 fhdr->frame_parallel_decoding_mode = true; 346 fhdr->frame_parallel_decoding_mode = true;
384 } else { 347 } else {
385 fhdr->refresh_frame_context = reader_.ReadBool(); 348 fhdr->refresh_frame_context = reader_.ReadBool();
386 fhdr->frame_parallel_decoding_mode = reader_.ReadBool(); 349 fhdr->frame_parallel_decoding_mode = reader_.ReadBool();
387 } 350 }
388 351
389 fhdr->frame_context_idx = reader_.ReadLiteral(2); 352 fhdr->frame_context_idx = reader_.ReadLiteral(2);
390 353
391 if (fhdr->IsKeyframe() || fhdr->intra_only) 354 ReadLoopFilter(&fhdr->loop_filter);
392 SetupPastIndependence();
393
394 ReadLoopFilter();
395 ReadQuantization(&fhdr->quant_params); 355 ReadQuantization(&fhdr->quant_params);
396 ReadSegmentation(); 356 ReadSegmentation(&fhdr->segment);
397 357
398 ReadTiles(fhdr); 358 ReadTiles(fhdr);
399 359
400 fhdr->first_partition_size = reader_.ReadLiteral(16); 360 fhdr->first_partition_size = reader_.ReadLiteral(16);
401 if (fhdr->first_partition_size == 0) { 361 if (fhdr->first_partition_size == 0) {
402 DVLOG(1) << "invalid header size"; 362 DVLOG(1) << "invalid header size";
403 return false; 363 return false;
404 } 364 }
405 365
406 if (!reader_.IsValid()) { 366 if (!reader_.IsValid()) {
407 DVLOG(1) << "parser reads beyond the end of buffer"; 367 DVLOG(1) << "parser reads beyond the end of buffer";
408 return false; 368 return false;
409 } 369 }
410 fhdr->uncompressed_header_size = reader_.GetBytesRead(); 370 fhdr->uncompressed_header_size = reader_.GetBytesRead();
411 371
412 SetupSegmentationDequant(fhdr->quant_params); 372 return true;
413 SetupLoopFilter(); 373 }
374
375 void Vp9Parser::UpdateSlots(const Vp9FrameHeader* fhdr) {
376 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
377 if (fhdr->refresh_flag[i]) {
378 ref_slots_[i].width = fhdr->width;
379 ref_slots_[i].height = fhdr->height;
380 }
381 }
382 }
383
384 bool Vp9Parser::ParseFrame(const uint8_t* stream,
385 size_t frame_size,
386 Vp9FrameHeader* fhdr) {
387 DCHECK(stream);
388 stream_ = stream;
389 size_ = frame_size;
390 memset(fhdr, 0, sizeof(*fhdr));
391
392 if (!ParseUncompressedHeader(fhdr))
393 return false;
414 394
415 UpdateSlots(fhdr); 395 UpdateSlots(fhdr);
416 396
417 return true; 397 return true;
418 } 398 }
419 399
420 void Vp9Parser::UpdateSlots(const Vp9FrameHeader* fhdr) {
421 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
422 if (fhdr->RefreshFlag(i)) {
423 ref_slots_[i].width = fhdr->width;
424 ref_slots_[i].height = fhdr->height;
425 }
426 }
427 }
428
429 Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) {
430 if (frames_.empty()) {
431 // No frames to be decoded, if there is no more stream, request more.
432 if (!stream_)
433 return kEOStream;
434
435 // New stream to be parsed, parse it and fill frames_.
436 if (!ParseSuperframe()) {
437 DVLOG(1) << "Failed parsing superframes";
438 return kInvalidStream;
439 }
440 }
441
442 DCHECK(!frames_.empty());
443 FrameInfo frame_info = frames_.front();
444 frames_.pop_front();
445
446 memset(fhdr, 0, sizeof(*fhdr));
447 if (!ParseUncompressedHeader(frame_info.ptr, frame_info.size, fhdr))
448 return kInvalidStream;
449
450 return kOk;
451 }
452
453 bool Vp9Parser::ParseSuperframe() {
454 const uint8_t* stream = stream_;
455 off_t bytes_left = bytes_left_;
456
457 DCHECK(frames_.empty());
458
459 // Make sure we don't parse stream_ more than once.
460 stream_ = nullptr;
461 bytes_left_ = 0;
462
463 if (bytes_left < 1)
464 return false;
465
466 // If this is a superframe, the last byte in the stream will contain the
467 // superframe marker. If not, the whole buffer contains a single frame.
468 uint8_t marker = *(stream + bytes_left - 1);
469 if ((marker & 0xe0) != 0xc0) {
470 frames_.push_back(FrameInfo(stream, bytes_left));
471 return true;
472 }
473
474 DVLOG(1) << "Parsing a superframe";
475
476 // The bytes immediately before the superframe marker constitute superframe
477 // index, which stores information about sizes of each frame in it.
478 // Calculate its size and set index_ptr to the beginning of it.
479 size_t num_frames = (marker & 0x7) + 1;
480 size_t mag = ((marker >> 3) & 0x3) + 1;
481 off_t index_size = 2 + mag * num_frames;
482
483 if (bytes_left < index_size)
484 return false;
485
486 const uint8_t* index_ptr = stream + bytes_left - index_size;
487 if (marker != *index_ptr)
488 return false;
489
490 ++index_ptr;
491 bytes_left -= index_size;
492
493 // Parse frame information contained in the index and add a pointer to and
494 // size of each frame to frames_.
495 for (size_t i = 0; i < num_frames; ++i) {
496 uint32_t size = 0;
497 for (size_t j = 0; j < mag; ++j) {
498 size |= *index_ptr << (j * 8);
499 ++index_ptr;
500 }
501
502 if (base::checked_cast<off_t>(size) > bytes_left) {
503 DVLOG(1) << "Not enough data in the buffer for frame " << i;
504 return false;
505 }
506
507 frames_.push_back(FrameInfo(stream, size));
508 stream += size;
509 bytes_left -= size;
510
511 DVLOG(1) << "Frame " << i << ", size: " << size;
512 }
513
514 return true;
515 }
516
517 void Vp9Parser::ResetLoopfilter() {
518 loop_filter_.mode_ref_delta_enabled = true;
519 loop_filter_.mode_ref_delta_update = true;
520
521 const int8_t default_ref_deltas[] = {1, 0, -1, -1};
522 static_assert(
523 arraysize(default_ref_deltas) == arraysize(loop_filter_.ref_deltas),
524 "ref_deltas arrays of incorrect size");
525 for (size_t i = 0; i < arraysize(loop_filter_.ref_deltas); ++i)
526 loop_filter_.ref_deltas[i] = default_ref_deltas[i];
527
528 memset(loop_filter_.mode_deltas, 0, sizeof(loop_filter_.mode_deltas));
529 }
530
531 void Vp9Parser::SetupPastIndependence() {
532 memset(&segmentation_, 0, sizeof(segmentation_));
533 ResetLoopfilter();
534 }
535
536 const size_t QINDEX_RANGE = 256;
537 const int16_t kDcQLookup[QINDEX_RANGE] = {
538 4, 8, 8, 9, 10, 11, 12, 12,
539 13, 14, 15, 16, 17, 18, 19, 19,
540 20, 21, 22, 23, 24, 25, 26, 26,
541 27, 28, 29, 30, 31, 32, 32, 33,
542 34, 35, 36, 37, 38, 38, 39, 40,
543 41, 42, 43, 43, 44, 45, 46, 47,
544 48, 48, 49, 50, 51, 52, 53, 53,
545 54, 55, 56, 57, 57, 58, 59, 60,
546 61, 62, 62, 63, 64, 65, 66, 66,
547 67, 68, 69, 70, 70, 71, 72, 73,
548 74, 74, 75, 76, 77, 78, 78, 79,
549 80, 81, 81, 82, 83, 84, 85, 85,
550 87, 88, 90, 92, 93, 95, 96, 98,
551 99, 101, 102, 104, 105, 107, 108, 110,
552 111, 113, 114, 116, 117, 118, 120, 121,
553 123, 125, 127, 129, 131, 134, 136, 138,
554 140, 142, 144, 146, 148, 150, 152, 154,
555 156, 158, 161, 164, 166, 169, 172, 174,
556 177, 180, 182, 185, 187, 190, 192, 195,
557 199, 202, 205, 208, 211, 214, 217, 220,
558 223, 226, 230, 233, 237, 240, 243, 247,
559 250, 253, 257, 261, 265, 269, 272, 276,
560 280, 284, 288, 292, 296, 300, 304, 309,
561 313, 317, 322, 326, 330, 335, 340, 344,
562 349, 354, 359, 364, 369, 374, 379, 384,
563 389, 395, 400, 406, 411, 417, 423, 429,
564 435, 441, 447, 454, 461, 467, 475, 482,
565 489, 497, 505, 513, 522, 530, 539, 549,
566 559, 569, 579, 590, 602, 614, 626, 640,
567 654, 668, 684, 700, 717, 736, 755, 775,
568 796, 819, 843, 869, 896, 925, 955, 988,
569 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336,
570 };
571
572 const int16_t kAcQLookup[QINDEX_RANGE] = {
573 4, 8, 9, 10, 11, 12, 13, 14,
574 15, 16, 17, 18, 19, 20, 21, 22,
575 23, 24, 25, 26, 27, 28, 29, 30,
576 31, 32, 33, 34, 35, 36, 37, 38,
577 39, 40, 41, 42, 43, 44, 45, 46,
578 47, 48, 49, 50, 51, 52, 53, 54,
579 55, 56, 57, 58, 59, 60, 61, 62,
580 63, 64, 65, 66, 67, 68, 69, 70,
581 71, 72, 73, 74, 75, 76, 77, 78,
582 79, 80, 81, 82, 83, 84, 85, 86,
583 87, 88, 89, 90, 91, 92, 93, 94,
584 95, 96, 97, 98, 99, 100, 101, 102,
585 104, 106, 108, 110, 112, 114, 116, 118,
586 120, 122, 124, 126, 128, 130, 132, 134,
587 136, 138, 140, 142, 144, 146, 148, 150,
588 152, 155, 158, 161, 164, 167, 170, 173,
589 176, 179, 182, 185, 188, 191, 194, 197,
590 200, 203, 207, 211, 215, 219, 223, 227,
591 231, 235, 239, 243, 247, 251, 255, 260,
592 265, 270, 275, 280, 285, 290, 295, 300,
593 305, 311, 317, 323, 329, 335, 341, 347,
594 353, 359, 366, 373, 380, 387, 394, 401,
595 408, 416, 424, 432, 440, 448, 456, 465,
596 474, 483, 492, 501, 510, 520, 530, 540,
597 550, 560, 571, 582, 593, 604, 615, 627,
598 639, 651, 663, 676, 689, 702, 715, 729,
599 743, 757, 771, 786, 801, 816, 832, 848,
600 864, 881, 898, 915, 933, 951, 969, 988,
601 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151,
602 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
603 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567,
604 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
605 };
606
607 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup),
608 "quantizer lookup arrays of incorrect size");
609
610 #define CLAMP_Q(q) \
611 std::min(std::max(static_cast<size_t>(0), q), arraysize(kDcQLookup) - 1)
612
613 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
614 size_t segid) const {
615 if (segmentation_.FeatureEnabled(segid, Vp9Segmentation::SEG_LVL_ALT_Q)) {
616 int8_t feature_data =
617 segmentation_.FeatureData(segid, Vp9Segmentation::SEG_LVL_ALT_Q);
618 size_t q_index = segmentation_.abs_delta ? feature_data
619 : quant.base_qindex + feature_data;
620 return CLAMP_Q(q_index);
621 }
622
623 return quant.base_qindex;
624 }
625
626 void Vp9Parser::SetupSegmentationDequant(const Vp9QuantizationParams& quant) {
627 if (segmentation_.enabled) {
628 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) {
629 const size_t q_index = GetQIndex(quant, i);
630 segmentation_.y_dequant[i][0] =
631 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)];
632 segmentation_.y_dequant[i][1] = kAcQLookup[CLAMP_Q(q_index)];
633 segmentation_.uv_dequant[i][0] =
634 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)];
635 segmentation_.uv_dequant[i][1] =
636 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)];
637 }
638 } else {
639 const size_t q_index = quant.base_qindex;
640 segmentation_.y_dequant[0][0] =
641 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)];
642 segmentation_.y_dequant[0][1] = kAcQLookup[CLAMP_Q(q_index)];
643 segmentation_.uv_dequant[0][0] =
644 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)];
645 segmentation_.uv_dequant[0][1] =
646 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)];
647 }
648 }
649 #undef CLAMP_Q
650
651 #define CLAMP_LF(l) std::min(std::max(0, l), kMaxLoopFilterLevel)
652 void Vp9Parser::SetupLoopFilter() {
653 if (!loop_filter_.filter_level)
654 return;
655
656 int scale = loop_filter_.filter_level < 32 ? 1 : 2;
657
658 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) {
659 int level = loop_filter_.filter_level;
660
661 if (segmentation_.FeatureEnabled(i, Vp9Segmentation::SEG_LVL_ALT_LF)) {
662 int feature_data =
663 segmentation_.FeatureData(i, Vp9Segmentation::SEG_LVL_ALT_LF);
664 level = CLAMP_LF(segmentation_.abs_delta ? feature_data
665 : level + feature_data);
666 }
667
668 if (!loop_filter_.mode_ref_delta_enabled) {
669 memset(loop_filter_.lvl[i], level, sizeof(loop_filter_.lvl[i]));
670 } else {
671 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][0] = CLAMP_LF(
672 level +
673 loop_filter_.ref_deltas[Vp9LoopFilter::VP9_FRAME_INTRA] * scale);
674 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][1] = 0;
675
676 for (size_t type = Vp9LoopFilter::VP9_FRAME_LAST;
677 type < Vp9LoopFilter::VP9_FRAME_MAX; ++type) {
678 for (size_t mode = 0; mode < Vp9LoopFilter::kNumModeDeltas; ++mode) {
679 loop_filter_.lvl[i][type][mode] =
680 CLAMP_LF(level + loop_filter_.ref_deltas[type] * scale +
681 loop_filter_.mode_deltas[mode] * scale);
682 }
683 }
684 }
685 }
686 }
687 #undef CLAMP_LF
688
689 } // namespace media 400 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/vp9_parser.h ('k') | media/filters/vp9_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698