Chromium Code Reviews| 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 |