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

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: fix parse which discard frame while awaiting context update 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;
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.
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
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) {
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; 197 // If |curr_frame_info_| is valid, uncompressed header was parsed into
82 if (reader_.ReadBool()) 198 // |curr_frame_header_| and awaiting context update.
Pawel Osciak 2016/08/05 10:09:39 "and we are awaiting context update to proceed wit
kcwu 2016/08/05 11:38:48 Done.
83 profile |= 2; 199 if (!curr_frame_info_.IsValid()) {
84 if (profile > 2 && reader_.ReadBool()) 200 if (frames_.empty()) {
85 profile += 1; 201 // No frames to be decoded, if there is no more stream, request more.
86 return profile; 202 if (!stream_)
87 } 203 return kEOStream;
88 204
89 bool Vp9Parser::VerifySyncCode() { 205 // New stream to be parsed, parse it and fill frames_.
90 const int kSyncCode = 0x498342; 206 if (!ParseSuperframe()) {
91 if (reader_.ReadLiteral(8 * 3) != kSyncCode) { 207 DVLOG(1) << "Failed parsing superframes";
92 DVLOG(1) << "Invalid frame sync code"; 208 return kInvalidStream;
93 return false; 209 }
94 } 210 }
95 return true; 211
96 } 212 DCHECK(!frames_.empty());
Pawel Osciak 2016/08/05 10:09:39 Perhaps we could use frames_.empty() instead of re
kcwu 2016/08/05 11:38:48 I make ParseSuperFrame() return std::deque.
97 213
98 bool Vp9Parser::ReadBitDepthColorSpaceSampling(Vp9FrameHeader* fhdr) { 214 curr_frame_info_ = frames_.front();
99 if (fhdr->profile == 2 || fhdr->profile == 3) { 215 frames_.pop_front();
100 fhdr->bit_depth = reader_.ReadBool() ? 12 : 10; 216
101 } else { 217 memset(&curr_frame_header_, 0, sizeof(curr_frame_header_));
102 fhdr->bit_depth = 8; 218
103 } 219 Vp9UncompressedHeaderParser uncompressed_parser(&context_);
104 220 if (!uncompressed_parser.Parse(curr_frame_info_.ptr, curr_frame_info_.size,
105 fhdr->color_space = static_cast<Vp9ColorSpace>(reader_.ReadLiteral(3)); 221 &curr_frame_header_))
106 if (fhdr->color_space != Vp9ColorSpace::SRGB) { 222 return kInvalidStream;
107 fhdr->yuv_range = reader_.ReadBool(); 223
108 if (fhdr->profile == 1 || fhdr->profile == 3) { 224 if (curr_frame_header_.header_size_in_bytes == 0) {
109 fhdr->subsampling_x = reader_.ReadBool() ? 1 : 0; 225 // Verify padding bits are zero.
110 fhdr->subsampling_y = reader_.ReadBool() ? 1 : 0; 226 for (int i = curr_frame_header_.uncompressed_header_size;
111 if (fhdr->subsampling_x == 1 && fhdr->subsampling_y == 1) { 227 i < curr_frame_info_.size; i++) {
112 DVLOG(1) << "4:2:0 color not supported in profile 1 or 3"; 228 if (curr_frame_info_.ptr[i] != 0) {
113 return false; 229 DVLOG(1) << "Padding bits are not zeros.";
114 } 230 return kInvalidStream;
115 bool reserved = reader_.ReadBool(); 231 }
116 if (reserved) { 232 }
117 DVLOG(1) << "reserved bit set"; 233 *fhdr = curr_frame_header_;
118 return false; 234 curr_frame_info_.Reset();
119 } 235 return kOk;
120 } else { 236 }
121 fhdr->subsampling_x = fhdr->subsampling_y = 1; 237 if (curr_frame_header_.uncompressed_header_size +
122 } 238 curr_frame_header_.header_size_in_bytes >
123 } else { 239 static_cast<size_t>(curr_frame_info_.size)) {
Pawel Osciak 2016/08/05 10:09:39 Perhaps checked cast?
kcwu 2016/08/05 11:38:48 Done.
124 if (fhdr->profile == 1 || fhdr->profile == 3) { 240 DVLOG(1) << "header_size_in_bytes="
125 fhdr->subsampling_x = fhdr->subsampling_y = 0; 241 << curr_frame_header_.header_size_in_bytes
126 242 << " is larger than bytes left in buffer: "
127 bool reserved = reader_.ReadBool(); 243 << curr_frame_info_.size -
128 if (reserved) { 244 curr_frame_header_.uncompressed_header_size;
129 DVLOG(1) << "reserved bit set"; 245 return kInvalidStream;
130 return false; 246 }
131 } 247 }
132 } else { 248
133 DVLOG(1) << "4:4:4 color not supported in profile 0 or 2"; 249 if (parsing_compressed_header_) {
134 return false; 250 Vp9FrameContextManager& context_to_load =
135 } 251 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
136 } 252 if (!context_to_load.initialized()) {
137 253 // 8.2 Frame order constraints
138 return true; 254 // must load an initialized set of probabilities.
139 } 255 DVLOG(1) << "loading uninitialized frame context, index="
140 256 << curr_frame_header_.frame_context_idx;
141 void Vp9Parser::ReadFrameSize(Vp9FrameHeader* fhdr) { 257 return kInvalidStream;
142 fhdr->width = reader_.ReadLiteral(16) + 1; 258 }
143 fhdr->height = reader_.ReadLiteral(16) + 1; 259 if (context_to_load.need_update()) {
144 } 260 DVLOG(3) << "waiting frame_context_idx="
145 261 << static_cast<int>(curr_frame_header_.frame_context_idx)
146 bool Vp9Parser::ReadFrameSizeFromRefs(Vp9FrameHeader* fhdr) { 262 << " to update";
147 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { 263 return kAwaitingRefresh;
148 if (reader_.ReadBool()) { 264 }
149 fhdr->width = ref_slots_[i].width; 265 curr_frame_header_.initial_frame_context =
150 fhdr->height = ref_slots_[i].height; 266 curr_frame_header_.frame_context = context_to_load.frame_context();
151 267
152 const int kMaxDimension = 1 << 16; 268 Vp9CompressedHeaderParser compressed_parser;
153 if (fhdr->width == 0 || fhdr->width > kMaxDimension || 269 if (!compressed_parser.Parse(
154 fhdr->height == 0 || fhdr->height > kMaxDimension) { 270 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size,
155 DVLOG(1) << "The size of reference frame is out of range: " 271 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) {
156 << ref_slots_[i].width << "," << ref_slots_[i].height; 272 return kInvalidStream;
157 return false; 273 }
158 } 274
159 return true; 275 if (curr_frame_header_.refresh_frame_context) {
160 } 276 Vp9FrameContextManager& frame_context_manager =
161 } 277 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
162 278
163 fhdr->width = reader_.ReadLiteral(16) + 1; 279 // In frame parallel mode, we can refresh the context without decoding
164 fhdr->height = reader_.ReadLiteral(16) + 1; 280 // tile data.
165 return true; 281 if (curr_frame_header_.frame_parallel_decoding_mode) {
166 } 282 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 { 283 } else {
360 fhdr->bit_depth = 8; 284 *context_refresh_cb = frame_context_manager.SetNeedUpdate();
361 fhdr->color_space = Vp9ColorSpace::BT_601; 285 }
362 fhdr->subsampling_x = fhdr->subsampling_y = 1; 286 }
363 } 287 }
364 288
365 fhdr->refresh_flags = reader_.ReadLiteral(8); 289 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(); 290 SetupLoopFilter();
418 291 UpdateSlots();
419 UpdateSlots(fhdr); 292
420 293 *fhdr = curr_frame_header_;
421 return true; 294 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; 295 return kOk;
455 } 296 }
456 297
298 // Annex B Superframes
457 bool Vp9Parser::ParseSuperframe() { 299 bool Vp9Parser::ParseSuperframe() {
458 const uint8_t* stream = stream_; 300 const uint8_t* stream = stream_;
459 off_t bytes_left = bytes_left_; 301 off_t bytes_left = bytes_left_;
460 302
461 DCHECK(frames_.empty()); 303 DCHECK(frames_.empty());
462 304
463 // Make sure we don't parse stream_ more than once. 305 // Make sure we don't parse stream_ more than once.
464 stream_ = nullptr; 306 stream_ = nullptr;
465 bytes_left_ = 0; 307 bytes_left_ = 0;
466 308
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 frames_.push_back(FrameInfo(stream, size)); 353 frames_.push_back(FrameInfo(stream, size));
512 stream += size; 354 stream += size;
513 bytes_left -= size; 355 bytes_left -= size;
514 356
515 DVLOG(1) << "Frame " << i << ", size: " << size; 357 DVLOG(1) << "Frame " << i << ", size: " << size;
516 } 358 }
517 359
518 return true; 360 return true;
519 } 361 }
520 362
521 void Vp9Parser::ResetLoopfilter() { 363 // 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; 364 const size_t QINDEX_RANGE = 256;
541 const int16_t kDcQLookup[QINDEX_RANGE] = { 365 const int16_t kDcQLookup[QINDEX_RANGE] = {
542 4, 8, 8, 9, 10, 11, 12, 12, 366 4, 8, 8, 9, 10, 11, 12, 12,
543 13, 14, 15, 16, 17, 18, 19, 19, 367 13, 14, 15, 16, 17, 18, 19, 19,
544 20, 21, 22, 23, 24, 25, 26, 26, 368 20, 21, 22, 23, 24, 25, 26, 26,
545 27, 28, 29, 30, 31, 32, 32, 33, 369 27, 28, 29, 30, 31, 32, 32, 33,
546 34, 35, 36, 37, 38, 38, 39, 40, 370 34, 35, 36, 37, 38, 38, 39, 40,
547 41, 42, 43, 43, 44, 45, 46, 47, 371 41, 42, 43, 43, 44, 45, 46, 47,
548 48, 48, 49, 50, 51, 52, 53, 53, 372 48, 48, 49, 50, 51, 52, 53, 53,
549 54, 55, 56, 57, 57, 58, 59, 60, 373 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, 428 864, 881, 898, 915, 933, 951, 969, 988,
605 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, 429 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151,
606 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 430 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
607 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, 431 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567,
608 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, 432 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
609 }; 433 };
610 434
611 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup), 435 static_assert(arraysize(kDcQLookup) == arraysize(kAcQLookup),
612 "quantizer lookup arrays of incorrect size"); 436 "quantizer lookup arrays of incorrect size");
613 437
614 #define CLAMP_Q(q) \ 438 static size_t ClampQ(size_t q) {
615 std::min(std::max(static_cast<size_t>(0), q), arraysize(kDcQLookup) - 1) 439 return std::min(std::max(static_cast<size_t>(0), q),
440 arraysize(kDcQLookup) - 1);
441 }
616 442
443 // 8.6.1 Dequantization functions
617 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, 444 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
618 size_t segid) const { 445 size_t segid) const {
619 if (segmentation_.FeatureEnabled(segid, Vp9Segmentation::SEG_LVL_ALT_Q)) { 446 const Vp9SegmentationParams& segmentation = context_.segmentation;
447
448 if (segmentation.FeatureEnabled(segid,
449 Vp9SegmentationParams::SEG_LVL_ALT_Q)) {
620 int16_t feature_data = 450 int16_t feature_data =
621 segmentation_.FeatureData(segid, Vp9Segmentation::SEG_LVL_ALT_Q); 451 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q);
622 size_t q_index = segmentation_.abs_delta ? feature_data 452 size_t q_index = segmentation.abs_or_delta_update
623 : quant.base_qindex + feature_data; 453 ? feature_data
624 return CLAMP_Q(q_index); 454 : quant.base_q_idx + feature_data;
455 return ClampQ(q_index);
625 } 456 }
626 457
627 return quant.base_qindex; 458 return quant.base_q_idx;
628 } 459 }
629 460
630 void Vp9Parser::SetupSegmentationDequant(const Vp9QuantizationParams& quant) { 461 // 8.6.1 Dequantization functions
631 if (segmentation_.enabled) { 462 void Vp9Parser::SetupSegmentationDequant() {
632 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) { 463 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params;
464 Vp9SegmentationParams& segmentation = context_.segmentation;
465
466 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8)
467 << "bit_depth > 8 is not supported "
468 "yet, kDcQLookup and kAcQLookup "
469 "need extended";
470 if (segmentation.enabled) {
471 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
633 const size_t q_index = GetQIndex(quant, i); 472 const size_t q_index = GetQIndex(quant, i);
634 segmentation_.y_dequant[i][0] = 473 segmentation.y_dequant[i][0] =
635 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)]; 474 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
636 segmentation_.y_dequant[i][1] = kAcQLookup[CLAMP_Q(q_index)]; 475 segmentation.y_dequant[i][1] = kAcQLookup[ClampQ(q_index)];
637 segmentation_.uv_dequant[i][0] = 476 segmentation.uv_dequant[i][0] =
638 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)]; 477 kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
639 segmentation_.uv_dequant[i][1] = 478 segmentation.uv_dequant[i][1] =
640 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)]; 479 kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
641 } 480 }
642 } else { 481 } else {
643 const size_t q_index = quant.base_qindex; 482 const size_t q_index = quant.base_q_idx;
644 segmentation_.y_dequant[0][0] = 483 segmentation.y_dequant[0][0] =
645 kDcQLookup[CLAMP_Q(q_index + quant.y_dc_delta)]; 484 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)];
646 segmentation_.y_dequant[0][1] = kAcQLookup[CLAMP_Q(q_index)]; 485 segmentation.y_dequant[0][1] = kAcQLookup[ClampQ(q_index)];
647 segmentation_.uv_dequant[0][0] = 486 segmentation.uv_dequant[0][0] =
648 kDcQLookup[CLAMP_Q(q_index + quant.uv_dc_delta)]; 487 kDcQLookup[ClampQ(q_index + quant.delta_q_uv_dc)];
649 segmentation_.uv_dequant[0][1] = 488 segmentation.uv_dequant[0][1] =
650 kAcQLookup[CLAMP_Q(q_index + quant.uv_ac_delta)]; 489 kAcQLookup[ClampQ(q_index + quant.delta_q_uv_ac)];
651 } 490 }
652 } 491 }
653 #undef CLAMP_Q
654 492
655 #define CLAMP_LF(l) std::min(std::max(0, l), kMaxLoopFilterLevel) 493 static int ClampLf(int lf) {
494 const int kMaxLoopFilterLevel = 63;
495 return std::min(std::max(0, lf), kMaxLoopFilterLevel);
496 }
497
498 // 8.8.1 Loop filter frame init process
656 void Vp9Parser::SetupLoopFilter() { 499 void Vp9Parser::SetupLoopFilter() {
657 if (!loop_filter_.filter_level) 500 Vp9LoopFilterParams& loop_filter = context_.loop_filter;
501 Vp9SegmentationParams& segmentation = context_.segmentation;
502 if (!loop_filter.level)
658 return; 503 return;
659 504
660 int scale = loop_filter_.filter_level < 32 ? 1 : 2; 505 int scale = loop_filter.level < 32 ? 1 : 2;
661 506
662 for (size_t i = 0; i < Vp9Segmentation::kNumSegments; ++i) { 507 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
663 int level = loop_filter_.filter_level; 508 int level = loop_filter.level;
664 509
665 if (segmentation_.FeatureEnabled(i, Vp9Segmentation::SEG_LVL_ALT_LF)) { 510 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) {
666 int feature_data = 511 int feature_data =
667 segmentation_.FeatureData(i, Vp9Segmentation::SEG_LVL_ALT_LF); 512 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF);
668 level = CLAMP_LF(segmentation_.abs_delta ? feature_data 513 level = ClampLf(segmentation.abs_or_delta_update ? feature_data
669 : level + feature_data); 514 : level + feature_data);
670 } 515 }
671 516
672 if (!loop_filter_.mode_ref_delta_enabled) { 517 if (!loop_filter.delta_enabled) {
673 memset(loop_filter_.lvl[i], level, sizeof(loop_filter_.lvl[i])); 518 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i]));
674 } else { 519 } else {
675 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][0] = CLAMP_LF( 520 loop_filter.lvl[i][Vp9FrameType::VP9_FRAME_INTRA][0] = ClampLf(
676 level + 521 level +
677 loop_filter_.ref_deltas[Vp9LoopFilter::VP9_FRAME_INTRA] * scale); 522 loop_filter.ref_deltas[Vp9FrameType::VP9_FRAME_INTRA] * scale);
678 loop_filter_.lvl[i][Vp9LoopFilter::VP9_FRAME_INTRA][1] = 0; 523 loop_filter.lvl[i][Vp9FrameType::VP9_FRAME_INTRA][1] = 0;
679 524
680 for (size_t type = Vp9LoopFilter::VP9_FRAME_LAST; 525 for (size_t type = Vp9FrameType::VP9_FRAME_LAST;
681 type < Vp9LoopFilter::VP9_FRAME_MAX; ++type) { 526 type < Vp9FrameType::VP9_FRAME_MAX; ++type) {
682 for (size_t mode = 0; mode < Vp9LoopFilter::kNumModeDeltas; ++mode) { 527 for (size_t mode = 0; mode < Vp9LoopFilterParams::kNumModeDeltas;
683 loop_filter_.lvl[i][type][mode] = 528 ++mode) {
684 CLAMP_LF(level + loop_filter_.ref_deltas[type] * scale + 529 loop_filter.lvl[i][type][mode] =
685 loop_filter_.mode_deltas[mode] * scale); 530 ClampLf(level + loop_filter.ref_deltas[type] * scale +
531 loop_filter.mode_deltas[mode] * scale);
686 } 532 }
687 } 533 }
688 } 534 }
689 } 535 }
690 } 536 }
691 #undef CLAMP_LF 537
538 void Vp9Parser::UpdateSlots() {
539 // 8.10 Reference frame update process
540 for (size_t i = 0; i < kVp9NumRefFrames; i++) {
541 if (curr_frame_header_.RefreshFlag(i)) {
542 ReferenceSlot& ref = context_.ref_slots[i];
543 ref.initialized = true;
544
545 ref.frame_width = curr_frame_header_.frame_width;
546 ref.frame_height = curr_frame_header_.frame_height;
547 ref.subsampling_x = curr_frame_header_.subsampling_x;
548 ref.subsampling_y = curr_frame_header_.subsampling_y;
549 ref.bit_depth = curr_frame_header_.bit_depth;
550
551 ref.profile = curr_frame_header_.profile;
552 ref.color_space = curr_frame_header_.color_space;
553 }
554 }
555 }
692 556
693 } // namespace media 557 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698