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

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

Issue 2229353002: V4L2SVDA: Add a VP9Accelerator implementation utilizing the V4L2 VP9 frame API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 // 6 //
7 // VERBOSE level: 7 // VERBOSE level:
8 // 1 something wrong in bitstream 8 // 1 something wrong in bitstream
9 // 2 parsing steps 9 // 2 parsing steps
10 // 3 parsed values (selected) 10 // 3 parsed values (selected)
(...skipping 18 matching lines...) Expand all
29 return !show_existing_frame && frame_type == KEYFRAME; 29 return !show_existing_frame && frame_type == KEYFRAME;
30 } 30 }
31 31
32 bool Vp9FrameHeader::IsIntra() const { 32 bool Vp9FrameHeader::IsIntra() const {
33 return !show_existing_frame && (frame_type == KEYFRAME || intra_only); 33 return !show_existing_frame && (frame_type == KEYFRAME || intra_only);
34 } 34 }
35 35
36 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size) 36 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size)
37 : ptr(ptr), size(size) {} 37 : ptr(ptr), size(size) {}
38 38
39 Vp9FrameContextManager::Vp9FrameContextManager() : weak_ptr_factory_(this) {} 39 // static
40 40 bool Vp9FrameContext::IsValid(const Vp9FrameContext& context) {
41 Vp9FrameContextManager::~Vp9FrameContextManager() {}
42
43 bool Vp9FrameContextManager::IsValidFrameContext(
44 const Vp9FrameContext& context) {
45 // probs should be in [1, 255] range. 41 // probs should be in [1, 255] range.
46 static_assert(sizeof(Vp9Prob) == 1, 42 static_assert(sizeof(Vp9Prob) == 1,
47 "following checks assuming Vp9Prob is single byte"); 43 "following checks assuming Vp9Prob is single byte");
48 if (memchr(context.tx_probs_8x8, 0, sizeof(context.tx_probs_8x8))) 44 if (memchr(context.tx_probs_8x8, 0, sizeof(context.tx_probs_8x8)))
49 return false; 45 return false;
50 if (memchr(context.tx_probs_16x16, 0, sizeof(context.tx_probs_16x16))) 46 if (memchr(context.tx_probs_16x16, 0, sizeof(context.tx_probs_16x16)))
51 return false; 47 return false;
52 if (memchr(context.tx_probs_32x32, 0, sizeof(context.tx_probs_32x32))) 48 if (memchr(context.tx_probs_32x32, 0, sizeof(context.tx_probs_32x32)))
53 return false; 49 return false;
54 50
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 if (memchr(context.mv_fr_probs, 0, sizeof(context.mv_fr_probs))) 99 if (memchr(context.mv_fr_probs, 0, sizeof(context.mv_fr_probs)))
104 return false; 100 return false;
105 if (memchr(context.mv_class0_hp_prob, 0, sizeof(context.mv_class0_hp_prob))) 101 if (memchr(context.mv_class0_hp_prob, 0, sizeof(context.mv_class0_hp_prob)))
106 return false; 102 return false;
107 if (memchr(context.mv_hp_prob, 0, sizeof(context.mv_hp_prob))) 103 if (memchr(context.mv_hp_prob, 0, sizeof(context.mv_hp_prob)))
108 return false; 104 return false;
109 105
110 return true; 106 return true;
111 } 107 }
112 108
113 const Vp9FrameContext& Vp9FrameContextManager::frame_context() const { 109 Vp9Parser::Context::Vp9FrameContextManager::Vp9FrameContextManager()
110 : weak_ptr_factory_(this) {}
111
112 Vp9Parser::Context::Vp9FrameContextManager::~Vp9FrameContextManager() {}
113
114 const Vp9FrameContext&
115 Vp9Parser::Context::Vp9FrameContextManager::frame_context() const {
114 DCHECK(initialized_); 116 DCHECK(initialized_);
115 DCHECK(!needs_client_update_); 117 DCHECK(!needs_client_update_);
116 return frame_context_; 118 return frame_context_;
117 } 119 }
118 120
119 void Vp9FrameContextManager::Reset() { 121 void Vp9Parser::Context::Vp9FrameContextManager::Reset() {
120 initialized_ = false; 122 initialized_ = false;
121 needs_client_update_ = false; 123 needs_client_update_ = false;
122 weak_ptr_factory_.InvalidateWeakPtrs(); 124 weak_ptr_factory_.InvalidateWeakPtrs();
123 } 125 }
124 126
125 Vp9FrameContextManager::ContextRefreshCallback 127 void Vp9Parser::Context::Vp9FrameContextManager::SetNeedsClientUpdate() {
126 Vp9FrameContextManager::SetNeedsClientUpdate() {
127 DCHECK(!needs_client_update_); 128 DCHECK(!needs_client_update_);
128 initialized_ = true; 129 initialized_ = true;
129 needs_client_update_ = true; 130 needs_client_update_ = true;
130
131 return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
132 weak_ptr_factory_.GetWeakPtr());
133 } 131 }
134 132
135 void Vp9FrameContextManager::Update(const Vp9FrameContext& frame_context) { 133 Vp9Parser::ContextRefreshCallback
134 Vp9Parser::Context::Vp9FrameContextManager::GetUpdateCb() {
135 if (needs_client_update_)
136 return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
137 weak_ptr_factory_.GetWeakPtr());
138 else
139 return Vp9Parser::ContextRefreshCallback();
140 }
141
142 void Vp9Parser::Context::Vp9FrameContextManager::Update(
143 const Vp9FrameContext& frame_context) {
136 // DCHECK because we can trust values from our parser. 144 // DCHECK because we can trust values from our parser.
137 DCHECK(IsValidFrameContext(frame_context)); 145 DCHECK(Vp9FrameContext::IsValid(frame_context));
138 initialized_ = true; 146 initialized_ = true;
139 frame_context_ = frame_context; 147 frame_context_ = frame_context;
140 148
141 // For frame context we are updating, it may be still awaiting previous 149 // For frame context we are updating, it may be still awaiting previous
142 // ContextRefreshCallback. Because we overwrite the value of context here and 150 // ContextRefreshCallback. Because we overwrite the value of context here and
143 // previous ContextRefreshCallback no longer matters, invalidate the weak ptr 151 // previous ContextRefreshCallback no longer matters, invalidate the weak ptr
144 // to prevent previous ContextRefreshCallback run. 152 // to prevent previous ContextRefreshCallback run.
145 // With this optimization, we may be able to parse more frames while previous 153 // With this optimization, we may be able to parse more frames while previous
146 // are still decoding. 154 // are still decoding.
147 weak_ptr_factory_.InvalidateWeakPtrs(); 155 weak_ptr_factory_.InvalidateWeakPtrs();
148 needs_client_update_ = false; 156 needs_client_update_ = false;
149 } 157 }
150 158
151 void Vp9FrameContextManager::UpdateFromClient( 159 void Vp9Parser::Context::Vp9FrameContextManager::UpdateFromClient(
152 const Vp9FrameContext& frame_context) { 160 const Vp9FrameContext& frame_context) {
153 DVLOG(2) << "Got external frame_context update"; 161 DVLOG(2) << "Got external frame_context update";
154 DCHECK(needs_client_update_); 162 DCHECK(needs_client_update_);
155 if (!IsValidFrameContext(frame_context)) { 163 if (!Vp9FrameContext::IsValid(frame_context)) {
156 DLOG(ERROR) << "Invalid prob value in frame_context"; 164 DLOG(ERROR) << "Invalid prob value in frame_context";
157 return; 165 return;
158 } 166 }
159 needs_client_update_ = false; 167 needs_client_update_ = false;
160 initialized_ = true; 168 initialized_ = true;
161 frame_context_ = frame_context; 169 frame_context_ = frame_context;
162 } 170 }
163 171
164 void Vp9Parser::Context::Reset() { 172 void Vp9Parser::Context::Reset() {
165 memset(&segmentation, 0, sizeof(segmentation)); 173 memset(&segmentation, 0, sizeof(segmentation));
166 memset(&loop_filter, 0, sizeof(loop_filter)); 174 memset(&loop_filter, 0, sizeof(loop_filter));
167 memset(&ref_slots, 0, sizeof(ref_slots)); 175 memset(&ref_slots, 0, sizeof(ref_slots));
168 for (auto& manager : frame_context_managers) 176 for (auto& manager : frame_context_managers)
169 manager.Reset(); 177 manager.Reset();
170 } 178 }
171 179
180 void Vp9Parser::Context::MarkFrameContextForUpdate(size_t frame_context_idx) {
181 DCHECK_LT(frame_context_idx, arraysize(frame_context_managers));
182 frame_context_managers[frame_context_idx].SetNeedsClientUpdate();
183 }
184
185 void Vp9Parser::Context::UpdateFrameContext(
186 size_t frame_context_idx,
187 const Vp9FrameContext& frame_context) {
188 DCHECK_LT(frame_context_idx, arraysize(frame_context_managers));
189 frame_context_managers[frame_context_idx].Update(frame_context);
190 }
191
172 Vp9Parser::Vp9Parser(bool parsing_compressed_header) 192 Vp9Parser::Vp9Parser(bool parsing_compressed_header)
173 : parsing_compressed_header_(parsing_compressed_header) { 193 : parsing_compressed_header_(parsing_compressed_header) {
174 Reset(); 194 Reset();
175 } 195 }
176 196
177 Vp9Parser::~Vp9Parser() {} 197 Vp9Parser::~Vp9Parser() {}
178 198
179 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) { 199 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) {
180 DCHECK(stream); 200 DCHECK(stream);
181 stream_ = stream; 201 stream_ = stream;
182 bytes_left_ = stream_size; 202 bytes_left_ = stream_size;
183 frames_.clear(); 203 frames_.clear();
184 } 204 }
185 205
186 void Vp9Parser::Reset() { 206 void Vp9Parser::Reset() {
187 stream_ = nullptr; 207 stream_ = nullptr;
188 bytes_left_ = 0; 208 bytes_left_ = 0;
189 frames_.clear(); 209 frames_.clear();
190 210
191 context_.Reset(); 211 context_.Reset();
192 } 212 }
193 213
194 Vp9Parser::Result Vp9Parser::ParseNextFrame( 214 Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) {
195 Vp9FrameHeader* fhdr,
196 Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) {
197 DCHECK(fhdr); 215 DCHECK(fhdr);
198 DCHECK(!parsing_compressed_header_ || context_refresh_cb);
199 DVLOG(2) << "ParseNextFrame"; 216 DVLOG(2) << "ParseNextFrame";
200 217
201 // If |curr_frame_info_| is valid, uncompressed header was parsed into 218 // If |curr_frame_info_| is valid, uncompressed header was parsed into
202 // |curr_frame_header_| and we are awaiting context update to proceed with 219 // |curr_frame_header_| and we are awaiting context update to proceed with
203 // compressed header parsing. 220 // compressed header parsing.
204 if (!curr_frame_info_.IsValid()) { 221 if (!curr_frame_info_.IsValid()) {
205 if (frames_.empty()) { 222 if (frames_.empty()) {
206 // No frames to be decoded, if there is no more stream, request more. 223 // No frames to be decoded, if there is no more stream, request more.
207 if (!stream_) 224 if (!stream_)
208 return kEOStream; 225 return kEOStream;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 DVLOG(1) << "header_size_in_bytes=" 261 DVLOG(1) << "header_size_in_bytes="
245 << curr_frame_header_.header_size_in_bytes 262 << curr_frame_header_.header_size_in_bytes
246 << " is larger than bytes left in buffer: " 263 << " is larger than bytes left in buffer: "
247 << curr_frame_info_.size - 264 << curr_frame_info_.size -
248 curr_frame_header_.uncompressed_header_size; 265 curr_frame_header_.uncompressed_header_size;
249 return kInvalidStream; 266 return kInvalidStream;
250 } 267 }
251 } 268 }
252 269
253 if (parsing_compressed_header_) { 270 if (parsing_compressed_header_) {
254 Vp9FrameContextManager& context_to_load = 271 size_t frame_context_idx = curr_frame_header_.frame_context_idx;
255 context_.frame_context_managers[curr_frame_header_.frame_context_idx]; 272 const Context::Vp9FrameContextManager& context_to_load =
273 context_.frame_context_managers[frame_context_idx];
256 if (!context_to_load.initialized()) { 274 if (!context_to_load.initialized()) {
257 // 8.2 Frame order constraints 275 // 8.2 Frame order constraints
258 // must load an initialized set of probabilities. 276 // must load an initialized set of probabilities.
259 DVLOG(1) << "loading uninitialized frame context, index=" 277 DVLOG(1) << "loading uninitialized frame context, index="
260 << curr_frame_header_.frame_context_idx; 278 << frame_context_idx;
261 return kInvalidStream; 279 return kInvalidStream;
262 } 280 }
263 if (context_to_load.needs_client_update()) { 281 if (context_to_load.needs_client_update()) {
264 DVLOG(3) << "waiting frame_context_idx=" 282 DVLOG(3) << "waiting frame_context_idx="
265 << static_cast<int>(curr_frame_header_.frame_context_idx) 283 << static_cast<int>(frame_context_idx) << " to update";
kcwu 2016/08/10 09:59:18 no longer needed to cast for size_t.
Pawel Osciak 2016/08/13 01:51:30 Done.
266 << " to update";
267 return kAwaitingRefresh; 284 return kAwaitingRefresh;
268 } 285 }
269 curr_frame_header_.initial_frame_context = 286 curr_frame_header_.initial_frame_context =
270 curr_frame_header_.frame_context = context_to_load.frame_context(); 287 curr_frame_header_.frame_context = context_to_load.frame_context();
271 288
272 Vp9CompressedHeaderParser compressed_parser; 289 Vp9CompressedHeaderParser compressed_parser;
273 if (!compressed_parser.Parse( 290 if (!compressed_parser.Parse(
274 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size, 291 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size,
275 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) { 292 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) {
276 return kInvalidStream; 293 return kInvalidStream;
277 } 294 }
278 295
279 if (curr_frame_header_.refresh_frame_context) { 296 if (curr_frame_header_.refresh_frame_context) {
280 Vp9FrameContextManager& frame_context_manager =
281 context_.frame_context_managers[curr_frame_header_.frame_context_idx];
282
283 // In frame parallel mode, we can refresh the context without decoding 297 // In frame parallel mode, we can refresh the context without decoding
284 // tile data. 298 // tile data.
285 if (curr_frame_header_.frame_parallel_decoding_mode) { 299 if (curr_frame_header_.frame_parallel_decoding_mode) {
286 frame_context_manager.Update(curr_frame_header_.frame_context); 300 context_.UpdateFrameContext(frame_context_idx,
301 curr_frame_header_.frame_context);
287 } else { 302 } else {
288 *context_refresh_cb = frame_context_manager.SetNeedsClientUpdate(); 303 context_.MarkFrameContextForUpdate(frame_context_idx);
289 } 304 }
290 } 305 }
291 } 306 }
292 307
293 SetupSegmentationDequant(); 308 SetupSegmentationDequant();
294 SetupLoopFilter(); 309 SetupLoopFilter();
295 UpdateSlots(); 310 UpdateSlots();
296 311
297 *fhdr = curr_frame_header_; 312 *fhdr = curr_frame_header_;
298 curr_frame_info_.Reset(); 313 curr_frame_info_.Reset();
299 return kOk; 314 return kOk;
300 } 315 }
301 316
317 Vp9Parser::ContextRefreshCallback Vp9Parser::GetContextRefreshCb(
318 const std::unique_ptr<Vp9FrameHeader>& frame_hdr) {
319 auto& frame_context_manager =
320 context_.frame_context_managers[frame_hdr->frame_context_idx];
321
322 return frame_context_manager.GetUpdateCb();
323 }
324
302 // Annex B Superframes 325 // Annex B Superframes
303 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() { 326 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() {
304 const uint8_t* stream = stream_; 327 const uint8_t* stream = stream_;
305 off_t bytes_left = bytes_left_; 328 off_t bytes_left = bytes_left_;
306 329
307 // Make sure we don't parse stream_ more than once. 330 // Make sure we don't parse stream_ more than once.
308 stream_ = nullptr; 331 stream_ = nullptr;
309 bytes_left_ = 0; 332 bytes_left_ = 0;
310 333
311 if (bytes_left < 1) 334 if (bytes_left < 1)
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 ref.subsampling_y = curr_frame_header_.subsampling_y; 572 ref.subsampling_y = curr_frame_header_.subsampling_y;
550 ref.bit_depth = curr_frame_header_.bit_depth; 573 ref.bit_depth = curr_frame_header_.bit_depth;
551 574
552 ref.profile = curr_frame_header_.profile; 575 ref.profile = curr_frame_header_.profile;
553 ref.color_space = curr_frame_header_.color_space; 576 ref.color_space = curr_frame_header_.color_space;
554 } 577 }
555 } 578 }
556 } 579 }
557 580
558 } // namespace media 581 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698