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

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

Powered by Google App Engine
This is Rietveld 408576698