OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |