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

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: address Pawel's comments 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),
Pawel Osciak 2016/08/08 08:13:37 Perhaps we could initialize in class body?
kcwu 2016/08/09 04:29:43 Done.
41 needs_client_update_(false),
42 weak_ptr_factory_(this) {}
43
44 Vp9FrameContextManager::~Vp9FrameContextManager() {}
45
46 bool Vp9FrameContextManager::IsValidFrameContext(
47 const Vp9FrameContext& context) {
48 // probs should be in [1, 255] range.
49 static_assert(sizeof(Vp9Prob) == 1,
50 "following checks assuming Vp9Prob is single byte");
51 if (memchr(context.tx_probs_8x8, 0, sizeof(context.tx_probs_8x8)))
52 return false;
53 if (memchr(context.tx_probs_16x16, 0, sizeof(context.tx_probs_16x16)))
54 return false;
55 if (memchr(context.tx_probs_32x32, 0, sizeof(context.tx_probs_32x32)))
56 return false;
57
58 for (auto& a : context.coef_probs) {
59 for (auto& ai : a) {
60 for (auto& aj : ai) {
61 for (auto& ak : aj) {
62 int max_l = (ak == aj[0]) ? 3 : 6;
63 for (int l = 0; l < max_l; l++) {
64 for (auto& x : ak[l]) {
65 if (x == 0)
66 return false;
67 }
68 }
69 }
70 }
71 }
72 }
73 if (memchr(context.skip_prob, 0, sizeof(context.skip_prob)))
74 return false;
75 if (memchr(context.inter_mode_probs, 0, sizeof(context.inter_mode_probs)))
76 return false;
77 if (memchr(context.interp_filter_probs, 0,
78 sizeof(context.interp_filter_probs)))
79 return false;
80 if (memchr(context.is_inter_prob, 0, sizeof(context.is_inter_prob)))
81 return false;
82 if (memchr(context.comp_mode_prob, 0, sizeof(context.comp_mode_prob)))
83 return false;
84 if (memchr(context.single_ref_prob, 0, sizeof(context.single_ref_prob)))
85 return false;
86 if (memchr(context.comp_ref_prob, 0, sizeof(context.comp_ref_prob)))
87 return false;
88 if (memchr(context.y_mode_probs, 0, sizeof(context.y_mode_probs)))
89 return false;
90 if (memchr(context.uv_mode_probs, 0, sizeof(context.uv_mode_probs)))
91 return false;
92 if (memchr(context.partition_probs, 0, sizeof(context.partition_probs)))
93 return false;
94 if (memchr(context.mv_joint_probs, 0, sizeof(context.mv_joint_probs)))
95 return false;
96 if (memchr(context.mv_sign_prob, 0, sizeof(context.mv_sign_prob)))
97 return false;
98 if (memchr(context.mv_class_probs, 0, sizeof(context.mv_class_probs)))
99 return false;
100 if (memchr(context.mv_class0_bit_prob, 0, sizeof(context.mv_class0_bit_prob)))
101 return false;
102 if (memchr(context.mv_bits_prob, 0, sizeof(context.mv_bits_prob)))
103 return false;
104 if (memchr(context.mv_class0_fr_probs, 0, sizeof(context.mv_class0_fr_probs)))
105 return false;
106 if (memchr(context.mv_fr_probs, 0, sizeof(context.mv_fr_probs)))
107 return false;
108 if (memchr(context.mv_class0_hp_prob, 0, sizeof(context.mv_class0_hp_prob)))
109 return false;
110 if (memchr(context.mv_hp_prob, 0, sizeof(context.mv_hp_prob)))
111 return false;
112
113 return true;
114 }
115
116 const Vp9FrameContext& Vp9FrameContextManager::frame_context() const {
117 DCHECK(initialized_);
118 DCHECK(!needs_client_update_);
119 return frame_context_;
120 }
121
122 void Vp9FrameContextManager::Reset() {
123 initialized_ = false;
124 needs_client_update_ = false;
125 weak_ptr_factory_.InvalidateWeakPtrs();
126 }
127
128 Vp9FrameContextManager::ContextRefreshCallback
129 Vp9FrameContextManager::SetNeedsClientUpdate() {
130 DCHECK(!needs_client_update_);
131 initialized_ = true;
132 needs_client_update_ = true;
133
134 return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
135 weak_ptr_factory_.GetWeakPtr());
136 }
137
138 void Vp9FrameContextManager::Update(const Vp9FrameContext& frame_context) {
139 // DCHECK because we can trust values from our parser.
140 DCHECK(IsValidFrameContext(frame_context));
141 initialized_ = true;
142 frame_context_ = frame_context;
143
144 // For frame context we are updating, it may be still awaiting previous
145 // ContextRefreshCallback. Because we overwrite the value of context here and
146 // previous ContextRefreshCallback no longer matters, invalidate the weak ptr
147 // to prevent previous ContextRefreshCallback run.
148 // With this optimization, we may be able to parse more frames while previous
149 // are still decoding.
150 weak_ptr_factory_.InvalidateWeakPtrs();
151 needs_client_update_ = false;
152 }
153
154 void Vp9FrameContextManager::UpdateFromClient(
155 const Vp9FrameContext& frame_context) {
156 DVLOG(2) << "Got external frame_context update";
157 DCHECK(needs_client_update_);
158 if (!IsValidFrameContext(frame_context)) {
159 DLOG(ERROR) << "Invalid prob value in frame_context";
160 return;
161 }
162 needs_client_update_ = false;
163 initialized_ = true;
164 frame_context_ = frame_context;
165 }
166
167 void Vp9Parser::Context::Reset() {
168 memset(&segmentation, 0, sizeof(segmentation));
169 memset(&loop_filter, 0, sizeof(loop_filter));
170 memset(&ref_slots, 0, sizeof(ref_slots));
171 for (auto& manager : frame_context_managers)
172 manager.Reset();
173 }
174
175 Vp9Parser::Vp9Parser(bool parsing_compressed_header)
176 : parsing_compressed_header_(parsing_compressed_header) {
54 Reset(); 177 Reset();
55 } 178 }
56 179
57 Vp9Parser::~Vp9Parser() {} 180 Vp9Parser::~Vp9Parser() {}
58 181
59 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) { 182 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) {
60 DCHECK(stream); 183 DCHECK(stream);
61 stream_ = stream; 184 stream_ = stream;
62 bytes_left_ = stream_size; 185 bytes_left_ = stream_size;
63 frames_.clear(); 186 frames_.clear();
64 } 187 }
65 188
66 void Vp9Parser::Reset() { 189 void Vp9Parser::Reset() {
67 stream_ = nullptr; 190 stream_ = nullptr;
68 bytes_left_ = 0; 191 bytes_left_ = 0;
69 frames_.clear(); 192 frames_.clear();
70 193
71 memset(&segmentation_, 0, sizeof(segmentation_)); 194 context_.Reset();
72 memset(&loop_filter_, 0, sizeof(loop_filter_)); 195 }
73 memset(&ref_slots_, 0, sizeof(ref_slots_)); 196
74 } 197 Vp9Parser::Result Vp9Parser::ParseNextFrame(
75 198 Vp9FrameHeader* fhdr,
76 uint8_t Vp9Parser::ReadProfile() { 199 Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) {
77 uint8_t profile = 0; 200 DCHECK(fhdr);
78 201 DCHECK(!parsing_compressed_header_ || context_refresh_cb);
79 // LSB first. 202 DVLOG(2) << "ParseNextFrame";
80 if (reader_.ReadBool()) 203
81 profile |= 1; 204 // If |curr_frame_info_| is valid, uncompressed header was parsed into
82 if (reader_.ReadBool()) 205 // |curr_frame_header_| and we are awaiting context update to proceed with
83 profile |= 2; 206 // compressed header parsing.
84 if (profile > 2 && reader_.ReadBool()) 207 if (!curr_frame_info_.IsValid()) {
85 profile += 1; 208 if (frames_.empty()) {
86 return profile; 209 // No frames to be decoded, if there is no more stream, request more.
87 } 210 if (!stream_)
88 211 return kEOStream;
89 bool Vp9Parser::VerifySyncCode() { 212
90 const int kSyncCode = 0x498342; 213 // New stream to be parsed, parse it and fill frames_.
91 if (reader_.ReadLiteral(8 * 3) != kSyncCode) { 214 frames_ = ParseSuperframe();
92 DVLOG(1) << "Invalid frame sync code"; 215 if (frames_.empty()) {
93 return false; 216 DVLOG(1) << "Failed parsing superframes";
94 } 217 return kInvalidStream;
95 return true; 218 }
96 } 219 }
97 220
98 bool Vp9Parser::ReadBitDepthColorSpaceSampling(Vp9FrameHeader* fhdr) { 221 curr_frame_info_ = frames_.front();
99 if (fhdr->profile == 2 || fhdr->profile == 3) { 222 frames_.pop_front();
100 fhdr->bit_depth = reader_.ReadBool() ? 12 : 10; 223
101 } else { 224 memset(&curr_frame_header_, 0, sizeof(curr_frame_header_));
102 fhdr->bit_depth = 8; 225
103 } 226 Vp9UncompressedHeaderParser uncompressed_parser(&context_);
104 227 if (!uncompressed_parser.Parse(curr_frame_info_.ptr, curr_frame_info_.size,
105 fhdr->color_space = static_cast<Vp9ColorSpace>(reader_.ReadLiteral(3)); 228 &curr_frame_header_))
106 if (fhdr->color_space != Vp9ColorSpace::SRGB) { 229 return kInvalidStream;
107 fhdr->yuv_range = reader_.ReadBool(); 230
108 if (fhdr->profile == 1 || fhdr->profile == 3) { 231 if (curr_frame_header_.header_size_in_bytes == 0) {
109 fhdr->subsampling_x = reader_.ReadBool() ? 1 : 0; 232 // Verify padding bits are zero.
110 fhdr->subsampling_y = reader_.ReadBool() ? 1 : 0; 233 for (off_t i = curr_frame_header_.uncompressed_header_size;
111 if (fhdr->subsampling_x == 1 && fhdr->subsampling_y == 1) { 234 i < curr_frame_info_.size; i++) {
112 DVLOG(1) << "4:2:0 color not supported in profile 1 or 3"; 235 if (curr_frame_info_.ptr[i] != 0) {
113 return false; 236 DVLOG(1) << "Padding bits are not zeros.";
114 } 237 return kInvalidStream;
115 bool reserved = reader_.ReadBool(); 238 }
116 if (reserved) { 239 }
117 DVLOG(1) << "reserved bit set"; 240 *fhdr = curr_frame_header_;
118 return false; 241 curr_frame_info_.Reset();
119 } 242 return kOk;
120 } else { 243 }
121 fhdr->subsampling_x = fhdr->subsampling_y = 1; 244 if (curr_frame_header_.uncompressed_header_size +
122 } 245 curr_frame_header_.header_size_in_bytes >
123 } else { 246 base::checked_cast<size_t>(curr_frame_info_.size)) {
124 if (fhdr->profile == 1 || fhdr->profile == 3) { 247 DVLOG(1) << "header_size_in_bytes="
125 fhdr->subsampling_x = fhdr->subsampling_y = 0; 248 << curr_frame_header_.header_size_in_bytes
126 249 << " is larger than bytes left in buffer: "
127 bool reserved = reader_.ReadBool(); 250 << curr_frame_info_.size -
128 if (reserved) { 251 curr_frame_header_.uncompressed_header_size;
129 DVLOG(1) << "reserved bit set"; 252 return kInvalidStream;
130 return false; 253 }
131 } 254 }
132 } else { 255
133 DVLOG(1) << "4:4:4 color not supported in profile 0 or 2"; 256 if (parsing_compressed_header_) {
134 return false; 257 Vp9FrameContextManager& context_to_load =
135 } 258 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
136 } 259 if (!context_to_load.initialized()) {
137 260 // 8.2 Frame order constraints
138 return true; 261 // must load an initialized set of probabilities.
139 } 262 DVLOG(1) << "loading uninitialized frame context, index="
140 263 << curr_frame_header_.frame_context_idx;
141 void Vp9Parser::ReadFrameSize(Vp9FrameHeader* fhdr) { 264 return kInvalidStream;
142 fhdr->width = reader_.ReadLiteral(16) + 1; 265 }
143 fhdr->height = reader_.ReadLiteral(16) + 1; 266 if (context_to_load.needs_client_update()) {
144 } 267 DVLOG(3) << "waiting frame_context_idx="
145 268 << static_cast<int>(curr_frame_header_.frame_context_idx)
146 bool Vp9Parser::ReadFrameSizeFromRefs(Vp9FrameHeader* fhdr) { 269 << " to update";
147 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { 270 return kAwaitingRefresh;
148 if (reader_.ReadBool()) { 271 }
149 fhdr->width = ref_slots_[i].width; 272 curr_frame_header_.initial_frame_context =
150 fhdr->height = ref_slots_[i].height; 273 curr_frame_header_.frame_context = context_to_load.frame_context();
151 274
152 const int kMaxDimension = 1 << 16; 275 Vp9CompressedHeaderParser compressed_parser;
153 if (fhdr->width == 0 || fhdr->width > kMaxDimension || 276 if (!compressed_parser.Parse(
154 fhdr->height == 0 || fhdr->height > kMaxDimension) { 277 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size,
155 DVLOG(1) << "The size of reference frame is out of range: " 278 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) {
156 << ref_slots_[i].width << "," << ref_slots_[i].height; 279 return kInvalidStream;
157 return false; 280 }
158 } 281
159 return true; 282 if (curr_frame_header_.refresh_frame_context) {
160 } 283 Vp9FrameContextManager& frame_context_manager =
161 } 284 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
162 285
163 fhdr->width = reader_.ReadLiteral(16) + 1; 286 // In frame parallel mode, we can refresh the context without decoding
164 fhdr->height = reader_.ReadLiteral(16) + 1; 287 // tile data.
165 return true; 288 if (curr_frame_header_.frame_parallel_decoding_mode) {
166 } 289 frame_context_manager.Update(curr_frame_header_.frame_context);
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 { 290 } else {
360 fhdr->bit_depth = 8; 291 *context_refresh_cb = frame_context_manager.SetNeedsClientUpdate();
361 fhdr->color_space = Vp9ColorSpace::BT_601; 292 }
362 fhdr->subsampling_x = fhdr->subsampling_y = 1; 293 }
363 } 294 }
364 295
365 fhdr->refresh_flags = reader_.ReadLiteral(8); 296 SetupSegmentationDequant();
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(); 297 SetupLoopFilter();
418 298 UpdateSlots();
419 UpdateSlots(fhdr); 299
420 300 *fhdr = curr_frame_header_;
421 return true; 301 curr_frame_info_.Reset();
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()) {
435 // No frames to be decoded, if there is no more stream, request more.
436 if (!stream_)
437 return kEOStream;
438
439 // New stream to be parsed, parse it and fill frames_.
440 if (!ParseSuperframe()) {
441 DVLOG(1) << "Failed parsing superframes";
442 return kInvalidStream;
443 }
444 }
445
446 DCHECK(!frames_.empty());
447 FrameInfo frame_info = frames_.front();
448 frames_.pop_front();
449
450 memset(fhdr, 0, sizeof(*fhdr));
451 if (!ParseUncompressedHeader(frame_info.ptr, frame_info.size, fhdr))
452 return kInvalidStream;
453
454 return kOk; 302 return kOk;
455 } 303 }
456 304
457 bool Vp9Parser::ParseSuperframe() { 305 // Annex B Superframes
306 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() {
458 const uint8_t* stream = stream_; 307 const uint8_t* stream = stream_;
459 off_t bytes_left = bytes_left_; 308 off_t bytes_left = bytes_left_;
460 309
461 DCHECK(frames_.empty());
462
463 // Make sure we don't parse stream_ more than once. 310 // Make sure we don't parse stream_ more than once.
464 stream_ = nullptr; 311 stream_ = nullptr;
465 bytes_left_ = 0; 312 bytes_left_ = 0;
466 313
467 if (bytes_left < 1) 314 if (bytes_left < 1)
468 return false; 315 return std::deque<FrameInfo>();
469 316
470 // If this is a superframe, the last byte in the stream will contain the 317 // If this is a superframe, the last byte in the stream will contain the
471 // superframe marker. If not, the whole buffer contains a single frame. 318 // superframe marker. If not, the whole buffer contains a single frame.
472 uint8_t marker = *(stream + bytes_left - 1); 319 uint8_t marker = *(stream + bytes_left - 1);
473 if ((marker & 0xe0) != 0xc0) { 320 if ((marker & 0xe0) != 0xc0) {
474 frames_.push_back(FrameInfo(stream, bytes_left)); 321 return {FrameInfo(stream, bytes_left)};
475 return true;
476 } 322 }
477 323
478 DVLOG(1) << "Parsing a superframe"; 324 DVLOG(1) << "Parsing a superframe";
479 325
480 // The bytes immediately before the superframe marker constitute superframe 326 // The bytes immediately before the superframe marker constitute superframe
481 // index, which stores information about sizes of each frame in it. 327 // index, which stores information about sizes of each frame in it.
482 // Calculate its size and set index_ptr to the beginning of it. 328 // Calculate its size and set index_ptr to the beginning of it.
483 size_t num_frames = (marker & 0x7) + 1; 329 size_t num_frames = (marker & 0x7) + 1;
484 size_t mag = ((marker >> 3) & 0x3) + 1; 330 size_t mag = ((marker >> 3) & 0x3) + 1;
485 off_t index_size = 2 + mag * num_frames; 331 off_t index_size = 2 + mag * num_frames;
486 332
487 if (bytes_left < index_size) 333 if (bytes_left < index_size)
488 return false; 334 return std::deque<FrameInfo>();
489 335
490 const uint8_t* index_ptr = stream + bytes_left - index_size; 336 const uint8_t* index_ptr = stream + bytes_left - index_size;
491 if (marker != *index_ptr) 337 if (marker != *index_ptr)
492 return false; 338 return std::deque<FrameInfo>();
493 339
494 ++index_ptr; 340 ++index_ptr;
495 bytes_left -= index_size; 341 bytes_left -= index_size;
496 342
497 // Parse frame information contained in the index and add a pointer to and 343 // Parse frame information contained in the index and add a pointer to and
498 // size of each frame to frames_. 344 // size of each frame to frames.
345 std::deque<FrameInfo> frames;
499 for (size_t i = 0; i < num_frames; ++i) { 346 for (size_t i = 0; i < num_frames; ++i) {
500 uint32_t size = 0; 347 uint32_t size = 0;
501 for (size_t j = 0; j < mag; ++j) { 348 for (size_t j = 0; j < mag; ++j) {
502 size |= *index_ptr << (j * 8); 349 size |= *index_ptr << (j * 8);
503 ++index_ptr; 350 ++index_ptr;
504 } 351 }
505 352
506 if (base::checked_cast<off_t>(size) > bytes_left) { 353 if (base::checked_cast<off_t>(size) > bytes_left) {
507 DVLOG(1) << "Not enough data in the buffer for frame " << i; 354 DVLOG(1) << "Not enough data in the buffer for frame " << i;
508 return false; 355 return std::deque<FrameInfo>();
509 } 356 }
510 357
511 frames_.push_back(FrameInfo(stream, size)); 358 frames.push_back(FrameInfo(stream, size));
512 stream += size; 359 stream += size;
513 bytes_left -= size; 360 bytes_left -= size;
514 361
515 DVLOG(1) << "Frame " << i << ", size: " << size; 362 DVLOG(1) << "Frame " << i << ", size: " << size;
516 } 363 }
517 364
518 return true; 365 return frames;
519 } 366 }
520 367
521 void Vp9Parser::ResetLoopfilter() { 368 // 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; 369 const size_t QINDEX_RANGE = 256;
541 const int16_t kDcQLookup[QINDEX_RANGE] = { 370 const int16_t kDcQLookup[QINDEX_RANGE] = {
542 4, 8, 8, 9, 10, 11, 12, 12, 371 4, 8, 8, 9, 10, 11, 12, 12,
543 13, 14, 15, 16, 17, 18, 19, 19, 372 13, 14, 15, 16, 17, 18, 19, 19,
544 20, 21, 22, 23, 24, 25, 26, 26, 373 20, 21, 22, 23, 24, 25, 26, 26,
545 27, 28, 29, 30, 31, 32, 32, 33, 374 27, 28, 29, 30, 31, 32, 32, 33,
546 34, 35, 36, 37, 38, 38, 39, 40, 375 34, 35, 36, 37, 38, 38, 39, 40,
547 41, 42, 43, 43, 44, 45, 46, 47, 376 41, 42, 43, 43, 44, 45, 46, 47,
548 48, 48, 49, 50, 51, 52, 53, 53, 377 48, 48, 49, 50, 51, 52, 53, 53,
549 54, 55, 56, 57, 57, 58, 59, 60, 378 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, 433 864, 881, 898, 915, 933, 951, 969, 988,
605 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, 434 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151,
606 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 435 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
607 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, 436 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567,
608 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, 437 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
609 }; 438 };
610 439
611 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup), 440 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup),
612 "quantizer lookup arrays of incorrect size"); 441 "quantizer lookup arrays of incorrect size");
613 442
614 #define CLAMP_Q(q) \ 443 static size_t ClampQ(size_t q) {
615 std::min(std::max(static_cast<size_t>(0), q), arraysize(kDcQLookup) - 1) 444 return std::min(std::max(static_cast<size_t>(0), q),
445 arraysize(kDcQLookup) - 1);
446 }
616 447
448 // 8.6.1 Dequantization functions
617 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, 449 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
618 size_t segid) const { 450 size_t segid) const {
619 if (segmentation_.FeatureEnabled(segid, Vp9Segmentation::SEG_LVL_ALT_Q)) { 451 const Vp9SegmentationParams& segmentation = context_.segmentation;
452
453 if (segmentation.FeatureEnabled(segid,
454 Vp9SegmentationParams::SEG_LVL_ALT_Q)) {
620 int16_t feature_data = 455 int16_t feature_data =
621 segmentation_.FeatureData(segid, Vp9Segmentation::SEG_LVL_ALT_Q); 456 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q);
622 size_t q_index = segmentation_.abs_delta ? feature_data 457 size_t q_index = segmentation.abs_or_delta_update
623 : quant.base_qindex + feature_data; 458 ? feature_data
624 return CLAMP_Q(q_index); 459 : quant.base_q_idx + feature_data;
460 return ClampQ(q_index);
625 } 461 }
626 462
627 return quant.base_qindex; 463 return quant.base_q_idx;
628 } 464 }
629 465
630 void Vp9Parser::SetupSegmentationDequant(const Vp9QuantizationParams& quant) { 466 // 8.6.1 Dequantization functions
631 if (segmentation_.enabled) { 467 void Vp9Parser::SetupSegmentationDequant() {
632 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) { 468 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params;
469 Vp9SegmentationParams& segmentation = context_.segmentation;
470
471 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8)
472 << "bit_depth > 8 is not supported "
473 "yet, kDcQLookup and kAcQLookup "
474 "need extended";
475 if (segmentation.enabled) {
476 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
633 const size_t q_index = GetQIndex(quant, i); 477 const size_t q_index = GetQIndex(quant, i);
634 segmentation_.y_dequant[i][0] = 478 segmentation.y_dequant[i][0] =
635 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)]; 479 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
636 segmentation_.y_dequant[i][1] = kAcQLookup[CLAMP_Q(q_index)]; 480 segmentation.y_dequant[i][1] = kAcQLookup[ClampQ(q_index)];
637 segmentation_.uv_dequant[i][0] = 481 segmentation.uv_dequant[i][0] =
638 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)]; 482 kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
639 segmentation_.uv_dequant[i][1] = 483 segmentation.uv_dequant[i][1] =
640 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)]; 484 kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
641 } 485 }
642 } else { 486 } else {
643 const size_t q_index = quant.base_qindex; 487 const size_t q_index = quant.base_q_idx;
644 segmentation_.y_dequant[0][0] = 488 segmentation.y_dequant[0][0] =
645 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)]; 489 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
646 segmentation_.y_dequant[0][1] = kAcQLookup[CLAMP_Q(q_index)]; 490 segmentation.y_dequant[0][1] = kAcQLookup[ClampQ(q_index)];
647 segmentation_.uv_dequant[0][0] = 491 segmentation.uv_dequant[0][0] =
648 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)]; 492 kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
649 segmentation_.uv_dequant[0][1] = 493 segmentation.uv_dequant[0][1] =
650 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)]; 494 kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
651 } 495 }
652 } 496 }
653 #undef CLAMP_Q
654 497
655 #define CLAMP_LF(l) std::min(std::max(0, l), kMaxLoopFilterLevel) 498 static int ClampLf(int lf) {
499 const int kMaxLoopFilterLevel = 63;
500 return std::min(std::max(0, lf), kMaxLoopFilterLevel);
501 }
502
503 // 8.8.1 Loop filter frame init process
656 void Vp9Parser::SetupLoopFilter() { 504 void Vp9Parser::SetupLoopFilter() {
657 if (!loop_filter_.filter_level) 505 Vp9LoopFilterParams& loop_filter = context_.loop_filter;
506 if (!loop_filter.level)
658 return; 507 return;
659 508
660 int scale = loop_filter_.filter_level < 32 ? 1 : 2; 509 int scale = loop_filter.level < 32 ? 1 : 2;
661 510
662 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) { 511 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
663 int level = loop_filter_.filter_level; 512 int level = loop_filter.level;
513 Vp9SegmentationParams& segmentation = context_.segmentation;
664 514
665 if (segmentation_.FeatureEnabled(i, Vp9Segmentation::SEG_LVL_ALT_LF)) { 515 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) {
666 int feature_data = 516 int feature_data =
667 segmentation_.FeatureData(i, Vp9Segmentation::SEG_LVL_ALT_LF); 517 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF);
668 level = CLAMP_LF(segmentation_.abs_delta ? feature_data 518 level = ClampLf(segmentation.abs_or_delta_update ? feature_data
669 : level + feature_data); 519 : level + feature_data);
670 } 520 }
671 521
672 if (!loop_filter_.mode_ref_delta_enabled) { 522 if (!loop_filter.delta_enabled) {
673 memset(loop_filter_.lvl[i], level, sizeof(loop_filter_.lvl[i])); 523 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i]));
674 } else { 524 } else {
675 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][0] = CLAMP_LF( 525 loop_filter.lvl[i][Vp9RefType::VP9_FRAME_INTRA][0] = ClampLf(
676 level + 526 level + loop_filter.ref_deltas[Vp9RefType::VP9_FRAME_INTRA] * scale);
677 loop_filter_.ref_deltas[Vp9LoopFilter::VP9_FRAME_INTRA] * scale); 527 loop_filter.lvl[i][Vp9RefType::VP9_FRAME_INTRA][1] = 0;
678 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][1] = 0;
679 528
680 for (size_t type = Vp9LoopFilter::VP9_FRAME_LAST; 529 for (size_t type = Vp9RefType::VP9_FRAME_LAST;
681 type < Vp9LoopFilter::VP9_FRAME_MAX; ++type) { 530 type < Vp9RefType::VP9_FRAME_MAX; ++type) {
682 for (size_t mode = 0; mode < Vp9LoopFilter::kNumModeDeltas; ++mode) { 531 for (size_t mode = 0; mode < Vp9LoopFilterParams::kNumModeDeltas;
683 loop_filter_.lvl[i][type][mode] = 532 ++mode) {
684 CLAMP_LF(level + loop_filter_.ref_deltas[type] * scale + 533 loop_filter.lvl[i][type][mode] =
685 loop_filter_.mode_deltas[mode] * scale); 534 ClampLf(level + loop_filter.ref_deltas[type] * scale +
535 loop_filter.mode_deltas[mode] * scale);
686 } 536 }
687 } 537 }
688 } 538 }
689 } 539 }
690 } 540 }
691 #undef CLAMP_LF 541
542 void Vp9Parser::UpdateSlots() {
543 // 8.10 Reference frame update process
544 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
545 if (curr_frame_header_.RefreshFlag(i)) {
546 ReferenceSlot& ref = context_.ref_slots[i];
547 ref.initialized = true;
548
549 ref.frame_width = curr_frame_header_.frame_width;
550 ref.frame_height = curr_frame_header_.frame_height;
551 ref.subsampling_x = curr_frame_header_.subsampling_x;
552 ref.subsampling_y = curr_frame_header_.subsampling_y;
553 ref.bit_depth = curr_frame_header_.bit_depth;
554
555 ref.profile = curr_frame_header_.profile;
556 ref.color_space = curr_frame_header_.color_space;
557 }
558 }
559 }
692 560
693 } // namespace media 561 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698