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

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

Issue 1345943009: Reland: 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"
10 11
11 namespace { 12 namespace {
12 13
14 const int kMaxLoopFilterLevel = 63;
15
13 // Helper function for Vp9Parser::ReadTiles. Defined as get_min_log2_tile_cols 16 // Helper function for Vp9Parser::ReadTiles. Defined as get_min_log2_tile_cols
14 // in spec. 17 // in spec.
15 int GetMinLog2TileCols(int sb64_cols) { 18 int GetMinLog2TileCols(int sb64_cols) {
16 const int kMaxTileWidthB64 = 64; 19 const int kMaxTileWidthB64 = 64;
17 int min_log2 = 0; 20 int min_log2 = 0;
18 while ((kMaxTileWidthB64 << min_log2) < sb64_cols) 21 while ((kMaxTileWidthB64 << min_log2) < sb64_cols)
19 min_log2++; 22 min_log2++;
20 return min_log2; 23 return min_log2;
21 } 24 }
22 25
23 // Helper function for Vp9Parser::ReadTiles. Defined as get_max_log2_tile_cols 26 // Helper function for Vp9Parser::ReadTiles. Defined as get_max_log2_tile_cols
24 // in spec. 27 // in spec.
25 int GetMaxLog2TileCols(int sb64_cols) { 28 int GetMaxLog2TileCols(int sb64_cols) {
26 const int kMinTileWidthB64 = 4; 29 const int kMinTileWidthB64 = 4;
27 int max_log2 = 1; 30 int max_log2 = 1;
28 while ((sb64_cols >> max_log2) >= kMinTileWidthB64) 31 while ((sb64_cols >> max_log2) >= kMinTileWidthB64)
29 max_log2++; 32 max_log2++;
30 return max_log2 - 1; 33 return max_log2 - 1;
31 } 34 }
32 35
33 } // namespace 36 } // namespace
34 37
35 namespace media { 38 namespace media {
36 39
37 Vp9Parser::Vp9Parser() : stream_(nullptr), size_(0) { 40 bool Vp9FrameHeader::IsKeyframe() const {
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_));
38 memset(&ref_slots_, 0, sizeof(ref_slots_)); 70 memset(&ref_slots_, 0, sizeof(ref_slots_));
39 } 71 }
40 72
41 uint8_t Vp9Parser::ReadProfile() { 73 uint8_t Vp9Parser::ReadProfile() {
42 uint8_t profile = 0; 74 uint8_t profile = 0;
43 75
44 // LSB first. 76 // LSB first.
45 if (reader_.ReadBool()) 77 if (reader_.ReadBool())
46 profile |= 1; 78 profile |= 1;
47 if (reader_.ReadBool()) 79 if (reader_.ReadBool())
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 fhdr->display_width = reader_.ReadLiteral(16) + 1; 167 fhdr->display_width = reader_.ReadLiteral(16) + 1;
136 fhdr->display_height = reader_.ReadLiteral(16) + 1; 168 fhdr->display_height = reader_.ReadLiteral(16) + 1;
137 } else { 169 } else {
138 fhdr->display_width = fhdr->width; 170 fhdr->display_width = fhdr->width;
139 fhdr->display_height = fhdr->height; 171 fhdr->display_height = fhdr->height;
140 } 172 }
141 } 173 }
142 174
143 Vp9InterpFilter Vp9Parser::ReadInterpFilter() { 175 Vp9InterpFilter Vp9Parser::ReadInterpFilter() {
144 if (reader_.ReadBool()) 176 if (reader_.ReadBool())
145 return Vp9InterpFilter::INTERP_FILTER_SELECT; 177 return Vp9InterpFilter::SWICHABLE;
146 178
147 // The mapping table for next two bits. 179 // The mapping table for next two bits.
148 const Vp9InterpFilter table[] = { 180 const Vp9InterpFilter table[] = {
149 Vp9InterpFilter::EIGHTTAP_SMOOTH, Vp9InterpFilter::EIGHTTAP, 181 Vp9InterpFilter::EIGHTTAP_SMOOTH, Vp9InterpFilter::EIGHTTAP,
150 Vp9InterpFilter::EIGHTTAP_SHARP, Vp9InterpFilter::BILINEAR, 182 Vp9InterpFilter::EIGHTTAP_SHARP, Vp9InterpFilter::BILINEAR,
151 }; 183 };
152 return table[reader_.ReadLiteral(2)]; 184 return table[reader_.ReadLiteral(2)];
153 } 185 }
154 186
155 void Vp9Parser::ReadLoopFilter(Vp9LoopFilter* loop_filter) { 187 void Vp9Parser::ReadLoopFilter() {
156 loop_filter->filter_level = reader_.ReadLiteral(6); 188 loop_filter_.filter_level = reader_.ReadLiteral(6);
157 loop_filter->sharpness_level = reader_.ReadLiteral(3); 189 loop_filter_.sharpness_level = reader_.ReadLiteral(3);
190 loop_filter_.mode_ref_delta_update = false;
158 191
159 loop_filter->mode_ref_delta_enabled = reader_.ReadBool(); 192 loop_filter_.mode_ref_delta_enabled = reader_.ReadBool();
160 if (loop_filter->mode_ref_delta_enabled) { 193 if (loop_filter_.mode_ref_delta_enabled) {
161 loop_filter->mode_ref_delta_update = reader_.ReadBool(); 194 loop_filter_.mode_ref_delta_update = reader_.ReadBool();
162 if (loop_filter->mode_ref_delta_update) { 195 if (loop_filter_.mode_ref_delta_update) {
163 for (size_t i = 0; i < Vp9LoopFilter::kNumRefDeltas; i++) { 196 for (size_t i = 0; i < Vp9LoopFilter::VP9_FRAME_MAX; i++) {
164 loop_filter->update_ref_deltas[i] = reader_.ReadBool(); 197 loop_filter_.update_ref_deltas[i] = reader_.ReadBool();
165 if (loop_filter->update_ref_deltas[i]) 198 if (loop_filter_.update_ref_deltas[i])
166 loop_filter->ref_deltas[i] = reader_.ReadSignedLiteral(6); 199 loop_filter_.ref_deltas[i] = reader_.ReadSignedLiteral(6);
167 } 200 }
168 201
169 for (size_t i = 0; i < Vp9LoopFilter::kNumModeDeltas; i++) { 202 for (size_t i = 0; i < Vp9LoopFilter::kNumModeDeltas; i++) {
170 loop_filter->update_mode_deltas[i] = reader_.ReadBool(); 203 loop_filter_.update_mode_deltas[i] = reader_.ReadBool();
171 if (loop_filter->update_mode_deltas[i]) 204 if (loop_filter_.update_mode_deltas[i])
172 loop_filter->mode_deltas[i] = reader_.ReadLiteral(6); 205 loop_filter_.mode_deltas[i] = reader_.ReadLiteral(6);
173 } 206 }
174 } 207 }
175 } 208 }
176 } 209 }
177 210
178 void Vp9Parser::ReadQuantization(Vp9QuantizationParams* quants) { 211 void Vp9Parser::ReadQuantization(Vp9QuantizationParams* quants) {
179 quants->base_qindex = reader_.ReadLiteral(8); 212 quants->base_qindex = reader_.ReadLiteral(8);
180 213
181 if (reader_.ReadBool()) 214 if (reader_.ReadBool())
182 quants->y_dc_delta = reader_.ReadSignedLiteral(4); 215 quants->y_dc_delta = reader_.ReadSignedLiteral(4);
183 216
184 if (reader_.ReadBool()) 217 if (reader_.ReadBool())
185 quants->uv_ac_delta = reader_.ReadSignedLiteral(4); 218 quants->uv_ac_delta = reader_.ReadSignedLiteral(4);
186 219
187 if (reader_.ReadBool()) 220 if (reader_.ReadBool())
188 quants->uv_dc_delta = reader_.ReadSignedLiteral(4); 221 quants->uv_dc_delta = reader_.ReadSignedLiteral(4);
189 } 222 }
190 223
191 void Vp9Parser::ReadSegmentationMap(Vp9Segmentation* segment) { 224 void Vp9Parser::ReadSegmentationMap() {
192 for (size_t i = 0; i < Vp9Segmentation::kNumTreeProbs; i++) { 225 for (size_t i = 0; i < Vp9Segmentation::kNumTreeProbs; i++) {
193 segment->tree_probs[i] = 226 segmentation_.tree_probs[i] =
194 reader_.ReadBool() ? reader_.ReadLiteral(8) : kVp9MaxProb; 227 reader_.ReadBool() ? reader_.ReadLiteral(8) : kVp9MaxProb;
195 } 228 }
196 229
197 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) 230 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++)
198 segment->pred_probs[i] = kVp9MaxProb; 231 segmentation_.pred_probs[i] = kVp9MaxProb;
199 232
200 segment->temporal_update = reader_.ReadBool(); 233 segmentation_.temporal_update = reader_.ReadBool();
201 if (segment->temporal_update) { 234 if (segmentation_.temporal_update) {
202 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) { 235 for (size_t i = 0; i < Vp9Segmentation::kNumPredictionProbs; i++) {
203 if (reader_.ReadBool()) 236 if (reader_.ReadBool())
204 segment->pred_probs[i] = reader_.ReadLiteral(8); 237 segmentation_.pred_probs[i] = reader_.ReadLiteral(8);
205 } 238 }
206 } 239 }
207 } 240 }
208 241
209 void Vp9Parser::ReadSegmentationData(Vp9Segmentation* segment) { 242 void Vp9Parser::ReadSegmentationData() {
210 segment->abs_delta = reader_.ReadBool(); 243 segmentation_.abs_delta = reader_.ReadBool();
211 244
212 const int kFeatureDataBits[] = {7, 6, 2, 0}; 245 const int kFeatureDataBits[] = {7, 6, 2, 0};
213 const bool kFeatureDataSigned[] = {true, true, false, false}; 246 const bool kFeatureDataSigned[] = {true, true, false, false};
214 247
215 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; i++) { 248 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; i++) {
216 for (size_t j = 0; j < Vp9Segmentation::kNumFeatures; j++) { 249 for (size_t j = 0; j < Vp9Segmentation::SEG_LVL_MAX; j++) {
217 int8_t data = 0; 250 int8_t data = 0;
218 segment->feature_enabled[i][j] = reader_.ReadBool(); 251 segmentation_.feature_enabled[i][j] = reader_.ReadBool();
219 if (segment->feature_enabled[i][j]) { 252 if (segmentation_.feature_enabled[i][j]) {
220 data = reader_.ReadLiteral(kFeatureDataBits[j]); 253 data = reader_.ReadLiteral(kFeatureDataBits[j]);
221 if (kFeatureDataSigned[j]) 254 if (kFeatureDataSigned[j])
222 if (reader_.ReadBool()) 255 if (reader_.ReadBool())
223 data = -data; 256 data = -data;
224 } 257 }
225 segment->feature_data[i][j] = data; 258 segmentation_.feature_data[i][j] = data;
226 } 259 }
227 } 260 }
228 } 261 }
229 262
230 void Vp9Parser::ReadSegmentation(Vp9Segmentation* segment) { 263 void Vp9Parser::ReadSegmentation() {
231 segment->enabled = reader_.ReadBool(); 264 segmentation_.update_map = false;
265 segmentation_.update_data = false;
232 266
233 if (!segment->enabled) { 267 segmentation_.enabled = reader_.ReadBool();
268 if (!segmentation_.enabled)
234 return; 269 return;
235 }
236 270
237 segment->update_map = reader_.ReadBool(); 271 segmentation_.update_map = reader_.ReadBool();
238 if (segment->update_map) 272 if (segmentation_.update_map)
239 ReadSegmentationMap(segment); 273 ReadSegmentationMap();
240 274
241 segment->update_data = reader_.ReadBool(); 275 segmentation_.update_data = reader_.ReadBool();
242 if (segment->update_data) 276 if (segmentation_.update_data)
243 ReadSegmentationData(segment); 277 ReadSegmentationData();
244 } 278 }
245 279
246 void Vp9Parser::ReadTiles(Vp9FrameHeader* fhdr) { 280 void Vp9Parser::ReadTiles(Vp9FrameHeader* fhdr) {
247 int sb64_cols = (fhdr->width + 63) / 64; 281 int sb64_cols = (fhdr->width + 63) / 64;
248 282
249 int min_log2_tile_cols = GetMinLog2TileCols(sb64_cols); 283 int min_log2_tile_cols = GetMinLog2TileCols(sb64_cols);
250 int max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols); 284 int max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols);
251 285
252 int max_ones = max_log2_tile_cols - min_log2_tile_cols; 286 int max_ones = max_log2_tile_cols - min_log2_tile_cols;
253 fhdr->log2_tile_cols = min_log2_tile_cols; 287 fhdr->log2_tile_cols = min_log2_tile_cols;
254 while (max_ones-- && reader_.ReadBool()) 288 while (max_ones-- && reader_.ReadBool())
255 fhdr->log2_tile_cols++; 289 fhdr->log2_tile_cols++;
256 290
257 if (reader_.ReadBool()) 291 if (reader_.ReadBool())
258 fhdr->log2_tile_rows = reader_.ReadLiteral(2) - 1; 292 fhdr->log2_tile_rows = reader_.ReadLiteral(2) - 1;
259 } 293 }
260 294
261 bool Vp9Parser::ParseUncompressedHeader(Vp9FrameHeader* fhdr) { 295 bool Vp9Parser::ParseUncompressedHeader(const uint8_t* stream,
262 reader_.Initialize(stream_, size_); 296 off_t frame_size,
297 Vp9FrameHeader* fhdr) {
298 reader_.Initialize(stream, frame_size);
299
300 fhdr->data = stream;
301 fhdr->frame_size = frame_size;
263 302
264 // frame marker 303 // frame marker
265 if (reader_.ReadLiteral(2) != 0x2) 304 if (reader_.ReadLiteral(2) != 0x2)
266 return false; 305 return false;
267 306
268 fhdr->profile = ReadProfile(); 307 fhdr->profile = ReadProfile();
269 if (fhdr->profile >= kVp9MaxProfile) { 308 if (fhdr->profile >= kVp9MaxProfile) {
270 DVLOG(1) << "Unsupported bitstream profile"; 309 DVLOG(1) << "Unsupported bitstream profile";
271 return false; 310 return false;
272 } 311 }
(...skipping 15 matching lines...) Expand all
288 fhdr->show_frame = reader_.ReadBool(); 327 fhdr->show_frame = reader_.ReadBool();
289 fhdr->error_resilient_mode = reader_.ReadBool(); 328 fhdr->error_resilient_mode = reader_.ReadBool();
290 329
291 if (fhdr->IsKeyframe()) { 330 if (fhdr->IsKeyframe()) {
292 if (!VerifySyncCode()) 331 if (!VerifySyncCode())
293 return false; 332 return false;
294 333
295 if (!ReadBitDepthColorSpaceSampling(fhdr)) 334 if (!ReadBitDepthColorSpaceSampling(fhdr))
296 return false; 335 return false;
297 336
298 for (size_t i = 0; i < kVp9NumRefFrames; i++) 337 fhdr->refresh_flags = 0xff;
299 fhdr->refresh_flag[i] = true;
300 338
301 ReadFrameSize(fhdr); 339 ReadFrameSize(fhdr);
302 ReadDisplayFrameSize(fhdr); 340 ReadDisplayFrameSize(fhdr);
303 } else { 341 } else {
304 if (!fhdr->show_frame) 342 if (!fhdr->show_frame)
305 fhdr->intra_only = reader_.ReadBool(); 343 fhdr->intra_only = reader_.ReadBool();
306 344
307 if (!fhdr->error_resilient_mode) 345 if (!fhdr->error_resilient_mode)
308 fhdr->reset_context = reader_.ReadLiteral(2); 346 fhdr->reset_context = reader_.ReadLiteral(2);
309 347
310 if (fhdr->intra_only) { 348 if (fhdr->intra_only) {
311 if (!VerifySyncCode()) 349 if (!VerifySyncCode())
312 return false; 350 return false;
313 351
314 if (fhdr->profile > 0) { 352 if (fhdr->profile > 0) {
315 if (!ReadBitDepthColorSpaceSampling(fhdr)) 353 if (!ReadBitDepthColorSpaceSampling(fhdr))
316 return false; 354 return false;
317 } else { 355 } else {
318 fhdr->bit_depth = 8; 356 fhdr->bit_depth = 8;
319 fhdr->color_space = Vp9ColorSpace::BT_601; 357 fhdr->color_space = Vp9ColorSpace::BT_601;
320 fhdr->subsampling_x = fhdr->subsampling_y = 1; 358 fhdr->subsampling_x = fhdr->subsampling_y = 1;
321 } 359 }
322 360
323 for (size_t i = 0; i < kVp9NumRefFrames; i++) 361 fhdr->refresh_flags = reader_.ReadLiteral(8);
324 fhdr->refresh_flag[i] = reader_.ReadBool(); 362
325 ReadFrameSize(fhdr); 363 ReadFrameSize(fhdr);
326 ReadDisplayFrameSize(fhdr); 364 ReadDisplayFrameSize(fhdr);
327 } else { 365 } else {
328 for (size_t i = 0; i < kVp9NumRefFrames; i++) 366 fhdr->refresh_flags = reader_.ReadLiteral(8);
329 fhdr->refresh_flag[i] = reader_.ReadBool();
330 367
331 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { 368 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
332 fhdr->frame_refs[i] = reader_.ReadLiteral(kVp9NumRefFramesLog2); 369 fhdr->frame_refs[i] = reader_.ReadLiteral(kVp9NumRefFramesLog2);
333 fhdr->ref_sign_biases[i] = reader_.ReadBool(); 370 fhdr->ref_sign_biases[i] = reader_.ReadBool();
334 } 371 }
335 372
336 if (!ReadFrameSizeFromRefs(fhdr)) 373 if (!ReadFrameSizeFromRefs(fhdr))
337 return false; 374 return false;
338 ReadDisplayFrameSize(fhdr); 375 ReadDisplayFrameSize(fhdr);
339 376
340 fhdr->allow_high_precision_mv = reader_.ReadBool(); 377 fhdr->allow_high_precision_mv = reader_.ReadBool();
341 fhdr->interp_filter = ReadInterpFilter(); 378 fhdr->interp_filter = ReadInterpFilter();
342 } 379 }
343 } 380 }
344 381
345 if (fhdr->error_resilient_mode) { 382 if (fhdr->error_resilient_mode) {
346 fhdr->frame_parallel_decoding_mode = true; 383 fhdr->frame_parallel_decoding_mode = true;
347 } else { 384 } else {
348 fhdr->refresh_frame_context = reader_.ReadBool(); 385 fhdr->refresh_frame_context = reader_.ReadBool();
349 fhdr->frame_parallel_decoding_mode = reader_.ReadBool(); 386 fhdr->frame_parallel_decoding_mode = reader_.ReadBool();
350 } 387 }
351 388
352 fhdr->frame_context_idx = reader_.ReadLiteral(2); 389 fhdr->frame_context_idx = reader_.ReadLiteral(2);
353 390
354 ReadLoopFilter(&fhdr->loop_filter); 391 if (fhdr->IsKeyframe() || fhdr->intra_only)
392 SetupPastIndependence();
393
394 ReadLoopFilter();
355 ReadQuantization(&fhdr->quant_params); 395 ReadQuantization(&fhdr->quant_params);
356 ReadSegmentation(&fhdr->segment); 396 ReadSegmentation();
357 397
358 ReadTiles(fhdr); 398 ReadTiles(fhdr);
359 399
360 fhdr->first_partition_size = reader_.ReadLiteral(16); 400 fhdr->first_partition_size = reader_.ReadLiteral(16);
361 if (fhdr->first_partition_size == 0) { 401 if (fhdr->first_partition_size == 0) {
362 DVLOG(1) << "invalid header size"; 402 DVLOG(1) << "invalid header size";
363 return false; 403 return false;
364 } 404 }
365 405
366 if (!reader_.IsValid()) { 406 if (!reader_.IsValid()) {
367 DVLOG(1) << "parser reads beyond the end of buffer"; 407 DVLOG(1) << "parser reads beyond the end of buffer";
368 return false; 408 return false;
369 } 409 }
370 fhdr->uncompressed_header_size = reader_.GetBytesRead(); 410 fhdr->uncompressed_header_size = reader_.GetBytesRead();
371 411
412 SetupSegmentationDequant(fhdr->quant_params);
413 SetupLoopFilter();
414
415 UpdateSlots(fhdr);
416
372 return true; 417 return true;
373 } 418 }
374 419
375 void Vp9Parser::UpdateSlots(const Vp9FrameHeader* fhdr) { 420 void Vp9Parser::UpdateSlots(const Vp9FrameHeader* fhdr) {
376 for (size_t i = 0; i < kVp9NumRefFrames; i++) { 421 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
377 if (fhdr->refresh_flag[i]) { 422 if (fhdr->RefreshFlag(i)) {
378 ref_slots_[i].width = fhdr->width; 423 ref_slots_[i].width = fhdr->width;
379 ref_slots_[i].height = fhdr->height; 424 ref_slots_[i].height = fhdr->height;
380 } 425 }
381 } 426 }
382 } 427 }
383 428
384 bool Vp9Parser::ParseFrame(const uint8_t* stream, 429 Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) {
385 size_t frame_size, 430 if (frames_.empty()) {
386 Vp9FrameHeader* fhdr) { 431 // No frames to be decoded, if there is no more stream, request more.
387 DCHECK(stream); 432 if (!stream_)
388 stream_ = stream; 433 return kEOStream;
389 size_ = frame_size; 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
390 memset(fhdr, 0, sizeof(*fhdr)); 446 memset(fhdr, 0, sizeof(*fhdr));
391 447 if (!ParseUncompressedHeader(frame_info.ptr, frame_info.size, fhdr))
392 if (!ParseUncompressedHeader(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)
393 return false; 464 return false;
394 465
395 UpdateSlots(fhdr); 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 }
396 513
397 return true; 514 return true;
398 } 515 }
399 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
400 } // namespace media 689 } // 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