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

Side by Side Diff: media/gpu/v4l2_slice_video_decode_accelerator.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 #include "media/gpu/v4l2_slice_video_decode_accelerator.h" 5 #include "media/gpu/v4l2_slice_video_decode_accelerator.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <linux/videodev2.h> 9 #include <linux/videodev2.h>
10 #include <poll.h> 10 #include <poll.h>
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 #define IOCTL_OR_LOG_ERROR(type, arg) \ 59 #define IOCTL_OR_LOG_ERROR(type, arg) \
60 do { \ 60 do { \
61 if (device_->Ioctl(type, arg) != 0) \ 61 if (device_->Ioctl(type, arg) != 0) \
62 PLOGF(ERROR) << "ioctl() failed: " << #type; \ 62 PLOGF(ERROR) << "ioctl() failed: " << #type; \
63 } while (0) 63 } while (0)
64 64
65 namespace media { 65 namespace media {
66 66
67 // static 67 // static
68 const uint32_t V4L2SliceVideoDecodeAccelerator::supported_input_fourccs_[] = { 68 const uint32_t V4L2SliceVideoDecodeAccelerator::supported_input_fourccs_[] = {
69 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, 69 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME,
70 }; 70 };
71 71
72 class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface 72 class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface
73 : public base::RefCounted<V4L2DecodeSurface> { 73 : public base::RefCounted<V4L2DecodeSurface> {
74 public: 74 public:
75 using ReleaseCB = base::Callback<void(int)>; 75 using ReleaseCB = base::Callback<void(int)>;
76 76
77 V4L2DecodeSurface(int32_t bitstream_id, 77 V4L2DecodeSurface(int32_t bitstream_id,
78 int input_record, 78 int input_record,
79 int output_record, 79 int output_record,
80 const ReleaseCB& release_cb); 80 const ReleaseCB& release_cb);
81 81
82 // Mark the surface as decoded. This will also release all references, as 82 // Mark the surface as decoded. This will also release all references, as
83 // they are not needed anymore. 83 // they are not needed anymore and execute the done callback, if not null.
84 void SetDecoded(); 84 void SetDecoded();
85 bool decoded() const { return decoded_; } 85 bool decoded() const { return decoded_; }
86 86
87 int32_t bitstream_id() const { return bitstream_id_; } 87 int32_t bitstream_id() const { return bitstream_id_; }
88 int input_record() const { return input_record_; } 88 int input_record() const { return input_record_; }
89 int output_record() const { return output_record_; } 89 int output_record() const { return output_record_; }
90 uint32_t config_store() const { return config_store_; } 90 uint32_t config_store() const { return config_store_; }
91 91
92 // Take references to each reference surface and keep them until the 92 // Take references to each reference surface and keep them until the
93 // target surface is decoded. 93 // target surface is decoded.
94 void SetReferenceSurfaces( 94 void SetReferenceSurfaces(
95 const std::vector<scoped_refptr<V4L2DecodeSurface>>& ref_surfaces); 95 const std::vector<scoped_refptr<V4L2DecodeSurface>>& ref_surfaces);
96 96
97 // If provided via this method, |done_cb| callback will be executed after
98 // decoding into this surface is finished. The callback is reset afterwards,
99 // so it needs to be set again before each decode operation.
100 void SetDecodeDoneCallback(const base::Closure& done_cb) {
101 DCHECK(done_cb_.is_null());
102 done_cb_ = done_cb;
103 }
104
97 std::string ToString() const; 105 std::string ToString() const;
98 106
99 private: 107 private:
100 friend class base::RefCounted<V4L2DecodeSurface>; 108 friend class base::RefCounted<V4L2DecodeSurface>;
101 ~V4L2DecodeSurface(); 109 ~V4L2DecodeSurface();
102 110
103 int32_t bitstream_id_; 111 int32_t bitstream_id_;
104 int input_record_; 112 int input_record_;
105 int output_record_; 113 int output_record_;
106 uint32_t config_store_; 114 uint32_t config_store_;
107 115
108 bool decoded_; 116 bool decoded_;
109 ReleaseCB release_cb_; 117 ReleaseCB release_cb_;
118 base::Closure done_cb_;
110 119
111 std::vector<scoped_refptr<V4L2DecodeSurface>> reference_surfaces_; 120 std::vector<scoped_refptr<V4L2DecodeSurface>> reference_surfaces_;
112 121
113 DISALLOW_COPY_AND_ASSIGN(V4L2DecodeSurface); 122 DISALLOW_COPY_AND_ASSIGN(V4L2DecodeSurface);
114 }; 123 };
115 124
116 V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::V4L2DecodeSurface( 125 V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::V4L2DecodeSurface(
117 int32_t bitstream_id, 126 int32_t bitstream_id,
118 int input_record, 127 int input_record,
119 int output_record, 128 int output_record,
(...skipping 16 matching lines...) Expand all
136 reference_surfaces_ = ref_surfaces; 145 reference_surfaces_ = ref_surfaces;
137 } 146 }
138 147
139 void V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::SetDecoded() { 148 void V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::SetDecoded() {
140 DCHECK(!decoded_); 149 DCHECK(!decoded_);
141 decoded_ = true; 150 decoded_ = true;
142 151
143 // We can now drop references to all reference surfaces for this surface 152 // We can now drop references to all reference surfaces for this surface
144 // as we are done with decoding. 153 // as we are done with decoding.
145 reference_surfaces_.clear(); 154 reference_surfaces_.clear();
155
156 // And finally execute and drop the decode done callback, if set.
157 if (!done_cb_.is_null())
158 base::ResetAndReturn(&done_cb_).Run();
146 } 159 }
147 160
148 std::string V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::ToString() 161 std::string V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::ToString()
149 const { 162 const {
150 std::string out; 163 std::string out;
151 base::StringAppendF(&out, "Buffer %d -> %d. ", input_record_, output_record_); 164 base::StringAppendF(&out, "Buffer %d -> %d. ", input_record_, output_record_);
152 base::StringAppendF(&out, "Reference surfaces:"); 165 base::StringAppendF(&out, "Reference surfaces:");
153 for (const auto& ref : reference_surfaces_) { 166 for (const auto& ref : reference_surfaces_) {
154 DCHECK_NE(ref->output_record(), output_record_); 167 DCHECK_NE(ref->output_record(), output_record_);
155 base::StringAppendF(&out, " %d", ref->output_record()); 168 base::StringAppendF(&out, " %d", ref->output_record());
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 V4L2SliceVideoDecodeAccelerator::PictureRecord::PictureRecord( 251 V4L2SliceVideoDecodeAccelerator::PictureRecord::PictureRecord(
239 bool cleared, 252 bool cleared,
240 const Picture& picture) 253 const Picture& picture)
241 : cleared(cleared), picture(picture) {} 254 : cleared(cleared), picture(picture) {}
242 255
243 V4L2SliceVideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 256 V4L2SliceVideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
244 257
245 class V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator 258 class V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator
246 : public H264Decoder::H264Accelerator { 259 : public H264Decoder::H264Accelerator {
247 public: 260 public:
248 V4L2H264Accelerator(V4L2SliceVideoDecodeAccelerator* v4l2_dec); 261 explicit V4L2H264Accelerator(V4L2SliceVideoDecodeAccelerator* v4l2_dec);
249 ~V4L2H264Accelerator() override; 262 ~V4L2H264Accelerator() override;
250 263
251 // H264Decoder::H264Accelerator implementation. 264 // H264Decoder::H264Accelerator implementation.
252 scoped_refptr<H264Picture> CreateH264Picture() override; 265 scoped_refptr<H264Picture> CreateH264Picture() override;
253 266
254 bool SubmitFrameMetadata(const H264SPS* sps, 267 bool SubmitFrameMetadata(const H264SPS* sps,
255 const H264PPS* pps, 268 const H264PPS* pps,
256 const H264DPB& dpb, 269 const H264DPB& dpb,
257 const H264Picture::Vector& ref_pic_listp0, 270 const H264Picture::Vector& ref_pic_listp0,
258 const H264Picture::Vector& ref_pic_listb0, 271 const H264Picture::Vector& ref_pic_listb0,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 static const size_t kMaxSlices = 16; 305 static const size_t kMaxSlices = 16;
293 struct v4l2_ctrl_h264_slice_param v4l2_slice_params_[kMaxSlices]; 306 struct v4l2_ctrl_h264_slice_param v4l2_slice_params_[kMaxSlices];
294 struct v4l2_ctrl_h264_decode_param v4l2_decode_param_; 307 struct v4l2_ctrl_h264_decode_param v4l2_decode_param_;
295 308
296 DISALLOW_COPY_AND_ASSIGN(V4L2H264Accelerator); 309 DISALLOW_COPY_AND_ASSIGN(V4L2H264Accelerator);
297 }; 310 };
298 311
299 class V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator 312 class V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator
300 : public VP8Decoder::VP8Accelerator { 313 : public VP8Decoder::VP8Accelerator {
301 public: 314 public:
302 V4L2VP8Accelerator(V4L2SliceVideoDecodeAccelerator* v4l2_dec); 315 explicit V4L2VP8Accelerator(V4L2SliceVideoDecodeAccelerator* v4l2_dec);
303 ~V4L2VP8Accelerator() override; 316 ~V4L2VP8Accelerator() override;
304 317
305 // VP8Decoder::VP8Accelerator implementation. 318 // VP8Decoder::VP8Accelerator implementation.
306 scoped_refptr<VP8Picture> CreateVP8Picture() override; 319 scoped_refptr<VP8Picture> CreateVP8Picture() override;
307 320
308 bool SubmitDecode(const scoped_refptr<VP8Picture>& pic, 321 bool SubmitDecode(const scoped_refptr<VP8Picture>& pic,
309 const Vp8FrameHeader* frame_hdr, 322 const Vp8FrameHeader* frame_hdr,
310 const scoped_refptr<VP8Picture>& last_frame, 323 const scoped_refptr<VP8Picture>& last_frame,
311 const scoped_refptr<VP8Picture>& golden_frame, 324 const scoped_refptr<VP8Picture>& golden_frame,
312 const scoped_refptr<VP8Picture>& alt_frame) override; 325 const scoped_refptr<VP8Picture>& alt_frame) override;
313 326
314 bool OutputPicture(const scoped_refptr<VP8Picture>& pic) override; 327 bool OutputPicture(const scoped_refptr<VP8Picture>& pic) override;
315 328
316 private: 329 private:
317 scoped_refptr<V4L2DecodeSurface> VP8PictureToV4L2DecodeSurface( 330 scoped_refptr<V4L2DecodeSurface> VP8PictureToV4L2DecodeSurface(
318 const scoped_refptr<VP8Picture>& pic); 331 const scoped_refptr<VP8Picture>& pic);
319 332
320 V4L2SliceVideoDecodeAccelerator* v4l2_dec_; 333 V4L2SliceVideoDecodeAccelerator* v4l2_dec_;
321 334
322 DISALLOW_COPY_AND_ASSIGN(V4L2VP8Accelerator); 335 DISALLOW_COPY_AND_ASSIGN(V4L2VP8Accelerator);
323 }; 336 };
324 337
338 class V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator
339 : public VP9Decoder::VP9Accelerator {
340 public:
341 explicit V4L2VP9Accelerator(V4L2SliceVideoDecodeAccelerator* v4l2_dec);
342 ~V4L2VP9Accelerator() override;
343
344 // VP9Decoder::VP9Accelerator implementation.
345 scoped_refptr<VP9Picture> CreateVP9Picture() override;
346
347 bool SubmitDecode(const scoped_refptr<VP9Picture>& pic,
348 const Vp9SegmentationParams& segm_params,
349 const Vp9LoopFilterParams& lf_params,
350 const std::vector<scoped_refptr<VP9Picture>>& ref_pictures,
351 const base::Closure& done_cb) override;
352
353 bool OutputPicture(const scoped_refptr<VP9Picture>& pic) override;
354
355 bool GetFrameContext(const scoped_refptr<VP9Picture>& pic,
356 Vp9FrameContext* frame_ctx) override;
357
358 bool RequiresFrameContext() const override {
359 return device_needs_frame_context_;
360 }
361
362 private:
363 scoped_refptr<V4L2DecodeSurface> VP9PictureToV4L2DecodeSurface(
364 const scoped_refptr<VP9Picture>& pic);
365
366 bool device_needs_frame_context_;
367
368 V4L2SliceVideoDecodeAccelerator* v4l2_dec_;
369
370 DISALLOW_COPY_AND_ASSIGN(V4L2VP9Accelerator);
371 };
372
373
325 // Codec-specific subclasses of software decoder picture classes. 374 // Codec-specific subclasses of software decoder picture classes.
326 // This allows us to keep decoders oblivious of our implementation details. 375 // This allows us to keep decoders oblivious of our implementation details.
327 class V4L2H264Picture : public H264Picture { 376 class V4L2H264Picture : public H264Picture {
328 public: 377 public:
329 V4L2H264Picture( 378 explicit V4L2H264Picture(
330 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& 379 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
331 dec_surface); 380 dec_surface);
332 381
333 V4L2H264Picture* AsV4L2H264Picture() override { return this; } 382 V4L2H264Picture* AsV4L2H264Picture() override { return this; }
334 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> 383 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
335 dec_surface() { 384 dec_surface() {
336 return dec_surface_; 385 return dec_surface_;
337 } 386 }
338 387
339 private: 388 private:
340 ~V4L2H264Picture() override; 389 ~V4L2H264Picture() override;
341 390
342 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> 391 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
343 dec_surface_; 392 dec_surface_;
344 393
345 DISALLOW_COPY_AND_ASSIGN(V4L2H264Picture); 394 DISALLOW_COPY_AND_ASSIGN(V4L2H264Picture);
346 }; 395 };
347 396
348 V4L2H264Picture::V4L2H264Picture( 397 V4L2H264Picture::V4L2H264Picture(
349 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& 398 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
350 dec_surface) 399 dec_surface)
351 : dec_surface_(dec_surface) {} 400 : dec_surface_(dec_surface) {}
352 401
353 V4L2H264Picture::~V4L2H264Picture() {} 402 V4L2H264Picture::~V4L2H264Picture() {}
354 403
355 class V4L2VP8Picture : public VP8Picture { 404 class V4L2VP8Picture : public VP8Picture {
356 public: 405 public:
357 V4L2VP8Picture( 406 explicit V4L2VP8Picture(
358 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& 407 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
359 dec_surface); 408 dec_surface);
360 409
361 V4L2VP8Picture* AsV4L2VP8Picture() override { return this; } 410 V4L2VP8Picture* AsV4L2VP8Picture() override { return this; }
362 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> 411 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
363 dec_surface() { 412 dec_surface() {
364 return dec_surface_; 413 return dec_surface_;
365 } 414 }
366 415
367 private: 416 private:
368 ~V4L2VP8Picture() override; 417 ~V4L2VP8Picture() override;
369 418
370 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> 419 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
371 dec_surface_; 420 dec_surface_;
372 421
373 DISALLOW_COPY_AND_ASSIGN(V4L2VP8Picture); 422 DISALLOW_COPY_AND_ASSIGN(V4L2VP8Picture);
374 }; 423 };
375 424
376 V4L2VP8Picture::V4L2VP8Picture( 425 V4L2VP8Picture::V4L2VP8Picture(
377 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& 426 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
378 dec_surface) 427 dec_surface)
379 : dec_surface_(dec_surface) {} 428 : dec_surface_(dec_surface) {}
380 429
381 V4L2VP8Picture::~V4L2VP8Picture() {} 430 V4L2VP8Picture::~V4L2VP8Picture() {}
382 431
432 class V4L2VP9Picture : public VP9Picture {
433 public:
434 explicit V4L2VP9Picture(
435 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
436 dec_surface);
437
438 V4L2VP9Picture* AsV4L2VP9Picture() override { return this; }
439 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
440 dec_surface() {
441 return dec_surface_;
442 }
443
444 private:
445 ~V4L2VP9Picture() override;
446
447 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
448 dec_surface_;
449
450 DISALLOW_COPY_AND_ASSIGN(V4L2VP9Picture);
451 };
452
453 V4L2VP9Picture::V4L2VP9Picture(
454 const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
455 dec_surface)
456 : dec_surface_(dec_surface) {}
457
458 V4L2VP9Picture::~V4L2VP9Picture() {}
459
383 V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator( 460 V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator(
384 const scoped_refptr<V4L2Device>& device, 461 const scoped_refptr<V4L2Device>& device,
385 EGLDisplay egl_display, 462 EGLDisplay egl_display,
386 const GetGLContextCallback& get_gl_context_cb, 463 const GetGLContextCallback& get_gl_context_cb,
387 const MakeGLContextCurrentCallback& make_context_current_cb) 464 const MakeGLContextCurrentCallback& make_context_current_cb)
388 : input_planes_count_(0), 465 : input_planes_count_(0),
389 output_planes_count_(0), 466 output_planes_count_(0),
390 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), 467 child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
391 device_(device), 468 device_(device),
392 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"), 469 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 550
474 video_profile_ = config.profile; 551 video_profile_ = config.profile;
475 552
476 if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) { 553 if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) {
477 h264_accelerator_.reset(new V4L2H264Accelerator(this)); 554 h264_accelerator_.reset(new V4L2H264Accelerator(this));
478 decoder_.reset(new H264Decoder(h264_accelerator_.get())); 555 decoder_.reset(new H264Decoder(h264_accelerator_.get()));
479 } else if (video_profile_ >= VP8PROFILE_MIN && 556 } else if (video_profile_ >= VP8PROFILE_MIN &&
480 video_profile_ <= VP8PROFILE_MAX) { 557 video_profile_ <= VP8PROFILE_MAX) {
481 vp8_accelerator_.reset(new V4L2VP8Accelerator(this)); 558 vp8_accelerator_.reset(new V4L2VP8Accelerator(this));
482 decoder_.reset(new VP8Decoder(vp8_accelerator_.get())); 559 decoder_.reset(new VP8Decoder(vp8_accelerator_.get()));
560 } else if (video_profile_ >= VP9PROFILE_MIN &&
561 video_profile_ <= VP9PROFILE_MAX) {
562 vp9_accelerator_.reset(new V4L2VP9Accelerator(this));
563 decoder_.reset(new VP9Decoder(vp9_accelerator_.get()));
483 } else { 564 } else {
484 NOTREACHED() << "Unsupported profile " << video_profile_; 565 NOTREACHED() << "Unsupported profile " << video_profile_;
485 return false; 566 return false;
486 } 567 }
487 568
488 // TODO(posciak): This needs to be queried once supported. 569 // TODO(posciak): This needs to be queried once supported.
489 input_planes_count_ = 1; 570 input_planes_count_ = 1;
490 output_planes_count_ = 1; 571 output_planes_count_ = 1;
491 572
492 if (egl_display_ == EGL_NO_DISPLAY) { 573 if (egl_display_ == EGL_NO_DISPLAY) {
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 } 1057 }
977 1058
978 it->second->SetDecoded(); 1059 it->second->SetDecoded();
979 surfaces_at_device_.erase(it); 1060 surfaces_at_device_.erase(it);
980 } 1061 }
981 1062
982 // A frame was decoded, see if we can output it. 1063 // A frame was decoded, see if we can output it.
983 TryOutputSurfaces(); 1064 TryOutputSurfaces();
984 1065
985 ProcessPendingEventsIfNeeded(); 1066 ProcessPendingEventsIfNeeded();
1067 ScheduleDecodeBufferTaskIfNeeded();
986 } 1068 }
987 1069
988 void V4L2SliceVideoDecodeAccelerator::NewEventPending() { 1070 void V4L2SliceVideoDecodeAccelerator::NewEventPending() {
989 // Switch to event processing mode if we are decoding. Otherwise we are either 1071 // Switch to event processing mode if we are decoding. Otherwise we are either
990 // already in it, or we will potentially switch to it later, after finishing 1072 // already in it, or we will potentially switch to it later, after finishing
991 // other tasks. 1073 // other tasks.
992 if (state_ == kDecoding) 1074 if (state_ == kDecoding)
993 state_ = kIdle; 1075 state_ = kIdle;
994 1076
995 ProcessPendingEventsIfNeeded(); 1077 ProcessPendingEventsIfNeeded();
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 if (!TrySetNewBistreamBuffer()) 1429 if (!TrySetNewBistreamBuffer())
1348 return; 1430 return;
1349 1431
1350 break; 1432 break;
1351 1433
1352 case AcceleratedVideoDecoder::kRanOutOfSurfaces: 1434 case AcceleratedVideoDecoder::kRanOutOfSurfaces:
1353 // No more surfaces for the decoder, we'll come back once we have more. 1435 // No more surfaces for the decoder, we'll come back once we have more.
1354 DVLOGF(4) << "Ran out of surfaces"; 1436 DVLOGF(4) << "Ran out of surfaces";
1355 return; 1437 return;
1356 1438
1439 case AcceleratedVideoDecoder::kNeedContextUpdate:
1440 DVLOGF(4) << "Awaiting context update";
1441 return;
1442
1357 case AcceleratedVideoDecoder::kDecodeError: 1443 case AcceleratedVideoDecoder::kDecodeError:
1358 DVLOGF(1) << "Error decoding stream"; 1444 DVLOGF(1) << "Error decoding stream";
1359 NOTIFY_ERROR(PLATFORM_FAILURE); 1445 NOTIFY_ERROR(PLATFORM_FAILURE);
1360 return; 1446 return;
1361 } 1447 }
1362 } 1448 }
1363 } 1449 }
1364 1450
1365 void V4L2SliceVideoDecodeAccelerator::InitiateSurfaceSetChange() { 1451 void V4L2SliceVideoDecodeAccelerator::InitiateSurfaceSetChange() {
1366 DVLOGF(2); 1452 DVLOGF(2);
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS); 2194 V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
2109 SET_V4L2_SPS_FLAG_IF(delta_pic_order_always_zero_flag, 2195 SET_V4L2_SPS_FLAG_IF(delta_pic_order_always_zero_flag,
2110 V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO); 2196 V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
2111 SET_V4L2_SPS_FLAG_IF(gaps_in_frame_num_value_allowed_flag, 2197 SET_V4L2_SPS_FLAG_IF(gaps_in_frame_num_value_allowed_flag,
2112 V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED); 2198 V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED);
2113 SET_V4L2_SPS_FLAG_IF(frame_mbs_only_flag, V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY); 2199 SET_V4L2_SPS_FLAG_IF(frame_mbs_only_flag, V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
2114 SET_V4L2_SPS_FLAG_IF(mb_adaptive_frame_field_flag, 2200 SET_V4L2_SPS_FLAG_IF(mb_adaptive_frame_field_flag,
2115 V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD); 2201 V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
2116 SET_V4L2_SPS_FLAG_IF(direct_8x8_inference_flag, 2202 SET_V4L2_SPS_FLAG_IF(direct_8x8_inference_flag,
2117 V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE); 2203 V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
2118 #undef SET_FLAG 2204 #undef SET_V4L2_SPS_FLAG_IF
2119 memset(&ctrl, 0, sizeof(ctrl)); 2205 memset(&ctrl, 0, sizeof(ctrl));
2120 ctrl.id = V4L2_CID_MPEG_VIDEO_H264_SPS; 2206 ctrl.id = V4L2_CID_MPEG_VIDEO_H264_SPS;
2121 ctrl.size = sizeof(v4l2_sps); 2207 ctrl.size = sizeof(v4l2_sps);
2122 ctrl.p_h264_sps = &v4l2_sps; 2208 ctrl.p_h264_sps = &v4l2_sps;
2123 ctrls.push_back(ctrl); 2209 ctrls.push_back(ctrl);
2124 2210
2125 struct v4l2_ctrl_h264_pps v4l2_pps; 2211 struct v4l2_ctrl_h264_pps v4l2_pps;
2126 memset(&v4l2_pps, 0, sizeof(v4l2_pps)); 2212 memset(&v4l2_pps, 0, sizeof(v4l2_pps));
2127 #define PPS_TO_V4L2PPS(a) v4l2_pps.a = pps->a 2213 #define PPS_TO_V4L2PPS(a) v4l2_pps.a = pps->a
2128 PPS_TO_V4L2PPS(pic_parameter_set_id); 2214 PPS_TO_V4L2PPS(pic_parameter_set_id);
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 2436
2351 memcpy(static_cast<uint8_t*>(input_record.address) + input_record.bytes_used, 2437 memcpy(static_cast<uint8_t*>(input_record.address) + input_record.bytes_used,
2352 data, size); 2438 data, size);
2353 input_record.bytes_used += size; 2439 input_record.bytes_used += size;
2354 2440
2355 return true; 2441 return true;
2356 } 2442 }
2357 2443
2358 bool V4L2SliceVideoDecodeAccelerator::SubmitExtControls( 2444 bool V4L2SliceVideoDecodeAccelerator::SubmitExtControls(
2359 struct v4l2_ext_controls* ext_ctrls) { 2445 struct v4l2_ext_controls* ext_ctrls) {
2446 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2360 DCHECK_GT(ext_ctrls->config_store, 0u); 2447 DCHECK_GT(ext_ctrls->config_store, 0u);
2361 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_EXT_CTRLS, ext_ctrls); 2448 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_EXT_CTRLS, ext_ctrls);
2362 return true; 2449 return true;
2363 } 2450 }
2364 2451
2452 bool V4L2SliceVideoDecodeAccelerator::GetExtControls(
2453 struct v4l2_ext_controls* ext_ctrls) {
2454 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2455 DCHECK_GT(ext_ctrls->config_store, 0u);
2456 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_EXT_CTRLS, ext_ctrls);
2457 return true;
2458 }
2459
2460 bool V4L2SliceVideoDecodeAccelerator::IsCtrlExposed(uint32_t ctrl_id) {
2461 struct v4l2_queryctrl query_ctrl;
2462 memset(&query_ctrl, 0, sizeof(query_ctrl));
2463 query_ctrl.id = ctrl_id;
2464
2465 return (device_->Ioctl(VIDIOC_QUERYCTRL, &query_ctrl) == 0);
2466 }
2467
2365 bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::SubmitDecode( 2468 bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::SubmitDecode(
2366 const scoped_refptr<H264Picture>& pic) { 2469 const scoped_refptr<H264Picture>& pic) {
2367 scoped_refptr<V4L2DecodeSurface> dec_surface = 2470 scoped_refptr<V4L2DecodeSurface> dec_surface =
2368 H264PictureToV4L2DecodeSurface(pic); 2471 H264PictureToV4L2DecodeSurface(pic);
2369 2472
2370 v4l2_decode_param_.num_slices = num_slices_; 2473 v4l2_decode_param_.num_slices = num_slices_;
2371 v4l2_decode_param_.idr_pic_flag = pic->idr; 2474 v4l2_decode_param_.idr_pic_flag = pic->idr;
2372 v4l2_decode_param_.top_field_order_cnt = pic->top_field_order_cnt; 2475 v4l2_decode_param_.top_field_order_cnt = pic->top_field_order_cnt;
2373 v4l2_decode_param_.bottom_field_order_cnt = pic->bottom_field_order_cnt; 2476 v4l2_decode_param_.bottom_field_order_cnt = pic->bottom_field_order_cnt;
2374 2477
(...skipping 10 matching lines...) Expand all
2385 ctrl.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM; 2488 ctrl.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM;
2386 ctrl.size = sizeof(v4l2_decode_param_); 2489 ctrl.size = sizeof(v4l2_decode_param_);
2387 ctrl.p_h264_decode_param = &v4l2_decode_param_; 2490 ctrl.p_h264_decode_param = &v4l2_decode_param_;
2388 ctrls.push_back(ctrl); 2491 ctrls.push_back(ctrl);
2389 2492
2390 struct v4l2_ext_controls ext_ctrls; 2493 struct v4l2_ext_controls ext_ctrls;
2391 memset(&ext_ctrls, 0, sizeof(ext_ctrls)); 2494 memset(&ext_ctrls, 0, sizeof(ext_ctrls));
2392 ext_ctrls.count = ctrls.size(); 2495 ext_ctrls.count = ctrls.size();
2393 ext_ctrls.controls = &ctrls[0]; 2496 ext_ctrls.controls = &ctrls[0];
2394 ext_ctrls.config_store = dec_surface->config_store(); 2497 ext_ctrls.config_store = dec_surface->config_store();
2395 v4l2_dec_->SubmitExtControls(&ext_ctrls); 2498 if (!v4l2_dec_->SubmitExtControls(&ext_ctrls))
2499 return false;
2396 2500
2397 Reset(); 2501 Reset();
2398 2502
2399 v4l2_dec_->DecodeSurface(dec_surface); 2503 v4l2_dec_->DecodeSurface(dec_surface);
2400 return true; 2504 return true;
2401 } 2505 }
2402 2506
2403 bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::OutputPicture( 2507 bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::OutputPicture(
2404 const scoped_refptr<H264Picture>& pic) { 2508 const scoped_refptr<H264Picture>& pic) {
2405 scoped_refptr<V4L2DecodeSurface> dec_surface = 2509 scoped_refptr<V4L2DecodeSurface> dec_surface =
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2494 const Vp8QuantizationHeader& vp8_quant_hdr, 2598 const Vp8QuantizationHeader& vp8_quant_hdr,
2495 struct v4l2_vp8_quantization_hdr* v4l2_quant_hdr) { 2599 struct v4l2_vp8_quantization_hdr* v4l2_quant_hdr) {
2496 v4l2_quant_hdr->y_ac_qi = vp8_quant_hdr.y_ac_qi; 2600 v4l2_quant_hdr->y_ac_qi = vp8_quant_hdr.y_ac_qi;
2497 v4l2_quant_hdr->y_dc_delta = vp8_quant_hdr.y_dc_delta; 2601 v4l2_quant_hdr->y_dc_delta = vp8_quant_hdr.y_dc_delta;
2498 v4l2_quant_hdr->y2_dc_delta = vp8_quant_hdr.y2_dc_delta; 2602 v4l2_quant_hdr->y2_dc_delta = vp8_quant_hdr.y2_dc_delta;
2499 v4l2_quant_hdr->y2_ac_delta = vp8_quant_hdr.y2_ac_delta; 2603 v4l2_quant_hdr->y2_ac_delta = vp8_quant_hdr.y2_ac_delta;
2500 v4l2_quant_hdr->uv_dc_delta = vp8_quant_hdr.uv_dc_delta; 2604 v4l2_quant_hdr->uv_dc_delta = vp8_quant_hdr.uv_dc_delta;
2501 v4l2_quant_hdr->uv_ac_delta = vp8_quant_hdr.uv_ac_delta; 2605 v4l2_quant_hdr->uv_ac_delta = vp8_quant_hdr.uv_ac_delta;
2502 } 2606 }
2503 2607
2504 static void FillV4L2EntropyHeader( 2608 static void FillV4L2Vp8EntropyHeader(
2505 const Vp8EntropyHeader& vp8_entropy_hdr, 2609 const Vp8EntropyHeader& vp8_entropy_hdr,
2506 struct v4l2_vp8_entropy_hdr* v4l2_entropy_hdr) { 2610 struct v4l2_vp8_entropy_hdr* v4l2_entropy_hdr) {
2507 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->coeff_probs, 2611 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->coeff_probs,
2508 vp8_entropy_hdr.coeff_probs); 2612 vp8_entropy_hdr.coeff_probs);
2509 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->y_mode_probs, 2613 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->y_mode_probs,
2510 vp8_entropy_hdr.y_mode_probs); 2614 vp8_entropy_hdr.y_mode_probs);
2511 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->uv_mode_probs, 2615 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->uv_mode_probs,
2512 vp8_entropy_hdr.uv_mode_probs); 2616 vp8_entropy_hdr.uv_mode_probs);
2513 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->mv_probs, vp8_entropy_hdr.mv_probs); 2617 ARRAY_MEMCPY_CHECKED(v4l2_entropy_hdr->mv_probs, vp8_entropy_hdr.mv_probs);
2514 } 2618 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 #undef SET_V4L2_FRM_HDR_FLAG_IF 2654 #undef SET_V4L2_FRM_HDR_FLAG_IF
2551 2655
2552 FillV4L2SegmentationHeader(frame_hdr->segmentation_hdr, 2656 FillV4L2SegmentationHeader(frame_hdr->segmentation_hdr,
2553 &v4l2_frame_hdr.sgmnt_hdr); 2657 &v4l2_frame_hdr.sgmnt_hdr);
2554 2658
2555 FillV4L2LoopfilterHeader(frame_hdr->loopfilter_hdr, &v4l2_frame_hdr.lf_hdr); 2659 FillV4L2LoopfilterHeader(frame_hdr->loopfilter_hdr, &v4l2_frame_hdr.lf_hdr);
2556 2660
2557 FillV4L2QuantizationHeader(frame_hdr->quantization_hdr, 2661 FillV4L2QuantizationHeader(frame_hdr->quantization_hdr,
2558 &v4l2_frame_hdr.quant_hdr); 2662 &v4l2_frame_hdr.quant_hdr);
2559 2663
2560 FillV4L2EntropyHeader(frame_hdr->entropy_hdr, &v4l2_frame_hdr.entropy_hdr); 2664 FillV4L2Vp8EntropyHeader(frame_hdr->entropy_hdr, &v4l2_frame_hdr.entropy_hdr);
2561 2665
2562 v4l2_frame_hdr.first_part_size = 2666 v4l2_frame_hdr.first_part_size =
2563 base::checked_cast<__u32>(frame_hdr->first_part_size); 2667 base::checked_cast<__u32>(frame_hdr->first_part_size);
2564 v4l2_frame_hdr.first_part_offset = 2668 v4l2_frame_hdr.first_part_offset =
2565 base::checked_cast<__u32>(frame_hdr->first_part_offset); 2669 base::checked_cast<__u32>(frame_hdr->first_part_offset);
2566 v4l2_frame_hdr.macroblock_bit_offset = 2670 v4l2_frame_hdr.macroblock_bit_offset =
2567 base::checked_cast<__u32>(frame_hdr->macroblock_bit_offset); 2671 base::checked_cast<__u32>(frame_hdr->macroblock_bit_offset);
2568 v4l2_frame_hdr.num_dct_parts = frame_hdr->num_of_dct_partitions; 2672 v4l2_frame_hdr.num_dct_parts = frame_hdr->num_of_dct_partitions;
2569 2673
2570 static_assert(arraysize(v4l2_frame_hdr.dct_part_sizes) == 2674 static_assert(arraysize(v4l2_frame_hdr.dct_part_sizes) ==
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2641 } 2745 }
2642 2746
2643 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> 2747 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
2644 V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator:: 2748 V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator::
2645 VP8PictureToV4L2DecodeSurface(const scoped_refptr<VP8Picture>& pic) { 2749 VP8PictureToV4L2DecodeSurface(const scoped_refptr<VP8Picture>& pic) {
2646 V4L2VP8Picture* v4l2_pic = pic->AsV4L2VP8Picture(); 2750 V4L2VP8Picture* v4l2_pic = pic->AsV4L2VP8Picture();
2647 CHECK(v4l2_pic); 2751 CHECK(v4l2_pic);
2648 return v4l2_pic->dec_surface(); 2752 return v4l2_pic->dec_surface();
2649 } 2753 }
2650 2754
2755 V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::V4L2VP9Accelerator(
2756 V4L2SliceVideoDecodeAccelerator* v4l2_dec)
2757 : v4l2_dec_(v4l2_dec) {
2758 DCHECK(v4l2_dec_);
2759
2760 device_needs_frame_context_ =
2761 v4l2_dec_->IsCtrlExposed(V4L2_CID_MPEG_VIDEO_VP9_ENTROPY);
kcwu 2016/08/10 09:59:19 Is "exposed" enough to indicate? Don't you need to
Pawel Osciak 2016/08/13 01:51:30 Yes, V4L2 drivers expose only supported controls.
2762 DVLOG_IF(1, device_needs_frame_context_)
2763 << "Device requires frame context parsing";
2764 }
2765
2766 V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::~V4L2VP9Accelerator() {}
2767
2768 scoped_refptr<VP9Picture>
2769 V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::CreateVP9Picture() {
2770 scoped_refptr<V4L2DecodeSurface> dec_surface = v4l2_dec_->CreateSurface();
2771 if (!dec_surface)
2772 return nullptr;
2773
2774 return new V4L2VP9Picture(dec_surface);
2775 }
2776
2777 static void FillV4L2VP9LoopFilterParams(
2778 const Vp9LoopFilterParams& vp9_lf_params,
2779 struct v4l2_vp9_loop_filter_params* v4l2_lf_params) {
2780 #define SET_LF_PARAMS_FLAG_IF(cond, flag) \
kcwu 2016/08/10 09:59:18 I feel naive if-statement is easier to understand
Pawel Osciak 2016/08/13 01:51:30 You might be right now that I look at it, but I'd
2781 v4l2_lf_params->flags |= ((vp9_lf_params.cond) ? (flag) : 0)
2782 SET_LF_PARAMS_FLAG_IF(delta_enabled, V4L2_VP9_LOOP_FLTR_FLAG_DELTA_ENABLED);
2783 SET_LF_PARAMS_FLAG_IF(delta_update, V4L2_VP9_LOOP_FLTR_FLAG_DELTA_UPDATE);
2784 #undef SET_LF_PARAMS_FLAG_IF
2785
2786 v4l2_lf_params->level = vp9_lf_params.level;
2787 v4l2_lf_params->sharpness = vp9_lf_params.sharpness;
2788
2789 ARRAY_MEMCPY_CHECKED(v4l2_lf_params->deltas, vp9_lf_params.ref_deltas);
2790 ARRAY_MEMCPY_CHECKED(v4l2_lf_params->mode_deltas, vp9_lf_params.mode_deltas);
2791 ARRAY_MEMCPY_CHECKED(v4l2_lf_params->lvl_lookup, vp9_lf_params.lvl);
2792 }
2793
2794 static void FillV4L2VP9QuantizationParams(
2795 const Vp9QuantizationParams& vp9_quant_params,
2796 struct v4l2_vp9_quantization_params* v4l2_q_params) {
2797 #define SET_Q_PARAMS_FLAG_IF(cond, flag) \
2798 v4l2_q_params->flags |= ((vp9_quant_params.cond) ? (flag) : 0)
2799 SET_Q_PARAMS_FLAG_IF(IsLossless(), V4L2_VP9_QUANT_PARAMS_FLAG_LOSSLESS);
2800 #undef SET_Q_PARAMS_FLAG_IF
2801
2802 #define Q_PARAMS_TO_V4L2_Q_PARAMS(a) v4l2_q_params->a = vp9_quant_params.a
2803 Q_PARAMS_TO_V4L2_Q_PARAMS(base_q_idx);
2804 Q_PARAMS_TO_V4L2_Q_PARAMS(delta_q_y_dc);
2805 Q_PARAMS_TO_V4L2_Q_PARAMS(delta_q_uv_dc);
2806 Q_PARAMS_TO_V4L2_Q_PARAMS(delta_q_uv_ac);
2807 #undef Q_PARAMS_TO_V4L2_Q_PARAMS
2808 }
2809
2810 static void FillV4L2VP9SegmentationParams(
2811 const Vp9SegmentationParams& vp9_segm_params,
2812 struct v4l2_vp9_segmentation_params* v4l2_segm_params) {
2813 #define SET_SEG_PARAMS_FLAG_IF(cond, flag) \
2814 v4l2_segm_params->flags |= ((vp9_segm_params.cond) ? (flag) : 0)
2815 SET_SEG_PARAMS_FLAG_IF(enabled, V4L2_VP9_SGMNT_PARAM_FLAG_ENABLED);
2816 SET_SEG_PARAMS_FLAG_IF(update_map, V4L2_VP9_SGMNT_PARAM_FLAG_UPDATE_MAP);
2817 SET_SEG_PARAMS_FLAG_IF(temporal_update,
2818 V4L2_VP9_SGMNT_PARAM_FLAG_TEMPORAL_UPDATE);
2819 SET_SEG_PARAMS_FLAG_IF(update_data, V4L2_VP9_SGMNT_PARAM_FLAG_UPDATE_DATA);
2820 SET_SEG_PARAMS_FLAG_IF(abs_or_delta_update,
2821 V4L2_VP9_SGMNT_PARAM_FLAG_ABS_OR_DELTA_UPDATE);
2822 #undef SET_SEG_PARAMS_FLAG_IF
2823
2824 ARRAY_MEMCPY_CHECKED(v4l2_segm_params->tree_probs,
2825 vp9_segm_params.tree_probs);
2826 ARRAY_MEMCPY_CHECKED(v4l2_segm_params->pred_probs,
2827 vp9_segm_params.pred_probs);
2828 ARRAY_MEMCPY_CHECKED(v4l2_segm_params->feature_data,
2829 vp9_segm_params.feature_data);
2830
2831 static_assert(arraysize(v4l2_segm_params->feature_enabled) ==
2832 arraysize(vp9_segm_params.feature_enabled) &&
2833 arraysize(v4l2_segm_params->feature_enabled[0]) ==
2834 arraysize(vp9_segm_params.feature_enabled[0]),
2835 "feature_enabled arrays must be of same size");
2836 for (size_t i = 0; i < arraysize(v4l2_segm_params->feature_enabled); ++i) {
2837 for (size_t j = 0; j < arraysize(v4l2_segm_params->feature_enabled[i]);
2838 ++j) {
2839 v4l2_segm_params->feature_enabled[i][j] =
2840 vp9_segm_params.feature_enabled[i][j];
2841 }
2842 }
2843 }
2844
2845 static void FillV4L2Vp9EntropyContext(
2846 const Vp9CompressedHeader& vp9_compressed_hdr,
2847 const Vp9FrameContext& vp9_frame_ctx,
2848 struct v4l2_vp9_entropy_ctx* v4l2_entropy_ctx) {
2849 #define ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(a) \
2850 ARRAY_MEMCPY_CHECKED(v4l2_entropy_ctx->a, vp9_frame_ctx.a)
2851 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(tx_probs_8x8);
2852 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(tx_probs_16x16);
2853 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(tx_probs_32x32);
2854
2855 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(coef_probs);
2856 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(skip_prob);
2857 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(inter_mode_probs);
2858 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(interp_filter_probs);
2859 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(is_inter_prob);
2860
2861 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(comp_mode_prob);
2862 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(single_ref_prob);
2863 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(comp_ref_prob);
2864
2865 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(y_mode_probs);
2866 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(uv_mode_probs);
2867
2868 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(partition_probs);
2869
2870 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_joint_probs);
2871 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_sign_prob);
2872 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_class_probs);
2873 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_class0_bit_prob);
2874 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_bits_prob);
2875 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_class0_fr_probs);
2876 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_fr_probs);
2877 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_class0_hp_prob);
2878 ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR(mv_hp_prob);
2879 #undef ARRAY_MEMCPY_CHECKED_FRM_CTX_TO_V4L2_ENTR
2880
2881 v4l2_entropy_ctx->tx_mode = vp9_compressed_hdr.tx_mode;
kcwu 2016/08/10 09:59:19 tx_mode and reference_mode are still inside v4l2_v
Pawel Osciak 2016/08/13 01:51:30 Moved to v4l2_ctrl_vp9_entropy.
2882 v4l2_entropy_ctx->reference_mode = vp9_compressed_hdr.reference_mode;
2883 }
2884
2885 bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::SubmitDecode(
2886 const scoped_refptr<VP9Picture>& pic,
2887 const Vp9SegmentationParams& segm_params,
2888 const Vp9LoopFilterParams& lf_params,
2889 const std::vector<scoped_refptr<VP9Picture>>& ref_pictures,
2890 const base::Closure& done_cb) {
2891 const Vp9FrameHeader* frame_hdr = pic->frame_hdr.get();
2892 DCHECK(frame_hdr);
2893
2894 struct v4l2_ctrl_vp9_frame_hdr v4l2_frame_hdr;
2895 memset(&v4l2_frame_hdr, 0, sizeof(v4l2_frame_hdr));
2896
2897 #define FHDR_TO_V4L2_FHDR(a) v4l2_frame_hdr.a = frame_hdr->a
2898 FHDR_TO_V4L2_FHDR(profile);
2899 FHDR_TO_V4L2_FHDR(frame_type);
2900
2901 FHDR_TO_V4L2_FHDR(bit_depth);
2902 FHDR_TO_V4L2_FHDR(color_range);
2903 FHDR_TO_V4L2_FHDR(subsampling_x);
2904 FHDR_TO_V4L2_FHDR(subsampling_y);
2905
2906 FHDR_TO_V4L2_FHDR(frame_width);
2907 FHDR_TO_V4L2_FHDR(frame_height);
2908 FHDR_TO_V4L2_FHDR(render_width);
2909 FHDR_TO_V4L2_FHDR(render_height);
2910
2911 FHDR_TO_V4L2_FHDR(reset_frame_context);
2912
2913 FHDR_TO_V4L2_FHDR(interpolation_filter);
2914 FHDR_TO_V4L2_FHDR(frame_context_idx);
2915
2916 FHDR_TO_V4L2_FHDR(tile_cols_log2);
2917 FHDR_TO_V4L2_FHDR(tile_rows_log2);
2918
2919 FHDR_TO_V4L2_FHDR(header_size_in_bytes);
2920 #undef FHDR_TO_V4L2_FHDR
2921 v4l2_frame_hdr.color_space = static_cast<uint8_t>(frame_hdr->color_space);
2922
2923 FillV4L2VP9QuantizationParams(frame_hdr->quant_params,
2924 &v4l2_frame_hdr.quant_params);
2925
2926 #define SET_V4L2_FRM_HDR_FLAG_IF(cond, flag) \
2927 v4l2_frame_hdr.flags |= ((frame_hdr->cond) ? (flag) : 0)
2928 SET_V4L2_FRM_HDR_FLAG_IF(show_frame, V4L2_VP9_FRAME_HDR_FLAG_SHOW_FRAME);
2929 SET_V4L2_FRM_HDR_FLAG_IF(error_resilient_mode,
2930 V4L2_VP9_FRAME_HDR_FLAG_ERR_RES);
2931 SET_V4L2_FRM_HDR_FLAG_IF(intra_only, V4L2_VP9_FRAME_HDR_FLAG_FRAME_INTRA);
2932 SET_V4L2_FRM_HDR_FLAG_IF(allow_high_precision_mv,
2933 V4L2_VP9_FRAME_HDR_ALLOW_HIGH_PREC_MV);
2934 SET_V4L2_FRM_HDR_FLAG_IF(refresh_frame_context,
2935 V4L2_VP9_FRAME_HDR_REFRESH_FRAME_CTX);
2936 SET_V4L2_FRM_HDR_FLAG_IF(frame_parallel_decoding_mode,
2937 V4L2_VP9_FRAME_HDR_PARALLEL_DEC_MODE);
2938 #undef SET_V4L2_FRM_HDR_FLAG_IF
2939
2940 FillV4L2VP9LoopFilterParams(lf_params, &v4l2_frame_hdr.lf_params);
2941 FillV4L2VP9SegmentationParams(segm_params, &v4l2_frame_hdr.sgmnt_params);
2942
2943 std::vector<struct v4l2_ext_control> ctrls;
2944
2945 struct v4l2_ext_control ctrl;
2946 memset(&ctrl, 0, sizeof(ctrl));
2947 ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_HDR;
2948 ctrl.size = sizeof(v4l2_frame_hdr);
2949 ctrl.p_vp9_frame_hdr = &v4l2_frame_hdr;
2950 ctrls.push_back(ctrl);
2951
2952 struct v4l2_ctrl_vp9_decode_param v4l2_decode_param;
2953 memset(&v4l2_decode_param, 0, sizeof(v4l2_decode_param));
2954 if (ref_pictures.size() != arraysize(v4l2_decode_param.ref_frames))
kcwu 2016/08/10 09:59:18 How about DCHECK?
Pawel Osciak 2016/08/13 01:51:30 Done.
2955 return false;
2956
2957 std::vector<scoped_refptr<V4L2DecodeSurface>> ref_surfaces;
2958 for (size_t i = 0; i < ref_pictures.size(); ++i) {
2959 if (ref_pictures[i]) {
2960 scoped_refptr<V4L2DecodeSurface> ref_surface =
2961 VP9PictureToV4L2DecodeSurface(ref_pictures[i]);
2962
2963 v4l2_decode_param.ref_frames[i] = ref_surface->output_record();
2964 ref_surfaces.push_back(ref_surface);
2965 } else {
2966 v4l2_decode_param.ref_frames[i] = VIDEO_MAX_FRAME;
2967 }
2968 }
2969
2970 static_assert(arraysize(v4l2_decode_param.active_ref_frames) ==
2971 arraysize(frame_hdr->ref_frame_idx),
2972 "active reference frame array sizes mismatch");
2973
2974 for (size_t i = 0; i < arraysize(frame_hdr->ref_frame_idx); ++i) {
2975 uint8_t idx = frame_hdr->ref_frame_idx[i];
2976 if (idx >= ref_pictures.size())
2977 return false;
2978
2979 struct v4l2_vp9_reference_frame* v4l2_ref_frame =
2980 &v4l2_decode_param.active_ref_frames[i];
2981
2982 scoped_refptr<VP9Picture> ref_pic = ref_pictures[idx];
2983 if (ref_pic) {
2984 scoped_refptr<V4L2DecodeSurface> ref_surface =
2985 VP9PictureToV4L2DecodeSurface(ref_pic);
2986 v4l2_ref_frame->buf_index = ref_surface->output_record();
2987 #define REF_TO_V4L2_REF(a) v4l2_ref_frame->a = ref_pic->frame_hdr->a
2988 REF_TO_V4L2_REF(frame_width);
2989 REF_TO_V4L2_REF(frame_height);
2990 REF_TO_V4L2_REF(bit_depth);
2991 REF_TO_V4L2_REF(subsampling_x);
2992 REF_TO_V4L2_REF(subsampling_y);
2993 #undef REF_TO_V4L2_REF
2994 } else {
2995 v4l2_ref_frame->buf_index = VIDEO_MAX_FRAME;
2996 }
2997 }
2998
2999 memset(&ctrl, 0, sizeof(ctrl));
3000 ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_DECODE_PARAM;
3001 ctrl.size = sizeof(v4l2_decode_param);
3002 ctrl.p_vp9_decode_param = &v4l2_decode_param;
3003 ctrls.push_back(ctrl);
3004
3005 struct v4l2_ctrl_vp9_entropy v4l2_entropy;
kcwu 2016/08/10 09:59:18 How about add comment why this is outside the if-b
Pawel Osciak 2016/08/13 01:51:30 Good idea. Done.
3006 if (device_needs_frame_context_) {
3007 memset(&v4l2_entropy, 0, sizeof(v4l2_entropy));
3008 FillV4L2Vp9EntropyContext(frame_hdr->compressed_header,
3009 frame_hdr->initial_frame_context,
3010 &v4l2_entropy.initial_entropy_ctx);
3011 FillV4L2Vp9EntropyContext(frame_hdr->compressed_header,
3012 frame_hdr->frame_context,
3013 &v4l2_entropy.current_entropy_ctx);
3014 memset(&ctrl, 0, sizeof(ctrl));
3015 ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_ENTROPY;
3016 ctrl.size = sizeof(v4l2_entropy);
3017 ctrl.p_vp9_entropy = &v4l2_entropy;
3018 ctrls.push_back(ctrl);
3019 }
3020
3021 scoped_refptr<V4L2DecodeSurface> dec_surface =
3022 VP9PictureToV4L2DecodeSurface(pic);
3023
3024 struct v4l2_ext_controls ext_ctrls;
3025 memset(&ext_ctrls, 0, sizeof(ext_ctrls));
3026 ext_ctrls.count = ctrls.size();
3027 ext_ctrls.controls = &ctrls[0];
3028 ext_ctrls.config_store = dec_surface->config_store();
3029 if (!v4l2_dec_->SubmitExtControls(&ext_ctrls))
3030 return false;
3031
3032 dec_surface->SetReferenceSurfaces(ref_surfaces);
3033 dec_surface->SetDecodeDoneCallback(done_cb);
3034
3035 if (!v4l2_dec_->SubmitSlice(dec_surface->input_record(), frame_hdr->data,
3036 frame_hdr->frame_size))
3037 return false;
3038
3039 v4l2_dec_->DecodeSurface(dec_surface);
3040 return true;
3041 }
3042
3043 bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::OutputPicture(
3044 const scoped_refptr<VP9Picture>& pic) {
3045 scoped_refptr<V4L2DecodeSurface> dec_surface =
3046 VP9PictureToV4L2DecodeSurface(pic);
3047
3048 v4l2_dec_->SurfaceReady(dec_surface);
3049 return true;
3050 }
3051
3052 static void FillVp9FrameContext(struct v4l2_vp9_entropy_ctx& v4l2_entropy_ctx,
3053 Vp9FrameContext* vp9_frame_ctx) {
3054 #define ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(a) \
3055 ARRAY_MEMCPY_CHECKED(vp9_frame_ctx->a, v4l2_entropy_ctx.a)
3056 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(tx_probs_8x8);
3057 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(tx_probs_16x16);
3058 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(tx_probs_32x32);
3059
3060 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(coef_probs);
3061 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(skip_prob);
3062 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(inter_mode_probs);
3063 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(interp_filter_probs);
3064 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(is_inter_prob);
3065
3066 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(comp_mode_prob);
3067 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(single_ref_prob);
3068 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(comp_ref_prob);
3069
3070 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(y_mode_probs);
3071 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(uv_mode_probs);
3072
3073 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(partition_probs);
3074
3075 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_joint_probs);
3076 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_sign_prob);
3077 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_class_probs);
3078 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_class0_bit_prob);
3079 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_bits_prob);
3080 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_class0_fr_probs);
3081 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_fr_probs);
3082 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_class0_hp_prob);
3083 ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX(mv_hp_prob);
3084 #undef ARRAY_MEMCPY_CHECKED_V4L2_ENTR_TO_FRM_CTX
3085 }
3086
3087 bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::GetFrameContext(
3088 const scoped_refptr<VP9Picture>& pic,
3089 Vp9FrameContext* frame_ctx) {
3090 struct v4l2_ctrl_vp9_entropy v4l2_entropy;
3091 memset(&v4l2_entropy, 0, sizeof(v4l2_entropy));
3092
3093 struct v4l2_ext_control ctrl;
3094 memset(&ctrl, 0, sizeof(ctrl));
3095 ctrl.id = V4L2_CID_MPEG_VIDEO_VP9_ENTROPY;
3096 ctrl.size = sizeof(v4l2_entropy);
3097 ctrl.p_vp9_entropy = &v4l2_entropy;
3098
3099 scoped_refptr<V4L2DecodeSurface> dec_surface =
3100 VP9PictureToV4L2DecodeSurface(pic);
3101
3102 struct v4l2_ext_controls ext_ctrls;
3103 memset(&ext_ctrls, 0, sizeof(ext_ctrls));
3104 ext_ctrls.count = 1;
3105 ext_ctrls.controls = &ctrl;
3106 ext_ctrls.config_store = dec_surface->config_store();
3107
3108 if (!v4l2_dec_->GetExtControls(&ext_ctrls))
3109 return false;
3110
3111 FillVp9FrameContext(v4l2_entropy.current_entropy_ctx, frame_ctx);
3112 return true;
3113 }
3114
3115 scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>
3116 V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::
3117 VP9PictureToV4L2DecodeSurface(const scoped_refptr<VP9Picture>& pic) {
3118 V4L2VP9Picture* v4l2_pic = pic->AsV4L2VP9Picture();
3119 CHECK(v4l2_pic);
3120 return v4l2_pic->dec_surface();
3121 }
3122
2651 void V4L2SliceVideoDecodeAccelerator::DecodeSurface( 3123 void V4L2SliceVideoDecodeAccelerator::DecodeSurface(
2652 const scoped_refptr<V4L2DecodeSurface>& dec_surface) { 3124 const scoped_refptr<V4L2DecodeSurface>& dec_surface) {
2653 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 3125 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2654 3126
2655 DVLOGF(3) << "Submitting decode for surface: " << dec_surface->ToString(); 3127 DVLOGF(3) << "Submitting decode for surface: " << dec_surface->ToString();
2656 Enqueue(dec_surface); 3128 Enqueue(dec_surface);
2657 } 3129 }
2658 3130
2659 void V4L2SliceVideoDecodeAccelerator::SurfaceReady( 3131 void V4L2SliceVideoDecodeAccelerator::SurfaceReady(
2660 const scoped_refptr<V4L2DecodeSurface>& dec_surface) { 3132 const scoped_refptr<V4L2DecodeSurface>& dec_surface) {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { 3275 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() {
2804 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); 3276 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
2805 if (!device) 3277 if (!device)
2806 return SupportedProfiles(); 3278 return SupportedProfiles();
2807 3279
2808 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), 3280 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_),
2809 supported_input_fourccs_); 3281 supported_input_fourccs_);
2810 } 3282 }
2811 3283
2812 } // namespace media 3284 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698