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

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

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

Powered by Google App Engine
This is Rietveld 408576698