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

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

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

Powered by Google App Engine
This is Rietveld 408576698