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

Side by Side Diff: media/gpu/vaapi_video_decode_accelerator.cc

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix several more bot-identified build issues Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/common/gpu/media/vaapi_video_decode_accelerator.h" 5 #include "media/gpu/vaapi_video_decode_accelerator.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
16 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
17 #include "content/common/gpu/media/accelerated_video_decoder.h"
18 #include "content/common/gpu/media/h264_decoder.h"
19 #include "content/common/gpu/media/vaapi_picture.h"
20 #include "content/common/gpu/media/vp8_decoder.h"
21 #include "content/common/gpu/media/vp9_decoder.h"
22 #include "gpu/ipc/service/gpu_channel.h" 17 #include "gpu/ipc/service/gpu_channel.h"
23 #include "media/base/bind_to_current_loop.h" 18 #include "media/base/bind_to_current_loop.h"
19 #include "media/gpu/accelerated_video_decoder.h"
20 #include "media/gpu/h264_decoder.h"
21 #include "media/gpu/vaapi_picture.h"
22 #include "media/gpu/vp8_decoder.h"
23 #include "media/gpu/vp9_decoder.h"
24 #include "media/video/picture.h" 24 #include "media/video/picture.h"
25 #include "third_party/libva/va/va_dec_vp8.h" 25 #include "third_party/libva/va/va_dec_vp8.h"
26 #include "ui/gl/gl_bindings.h" 26 #include "ui/gl/gl_bindings.h"
27 #include "ui/gl/gl_image.h" 27 #include "ui/gl/gl_image.h"
28 28
29 namespace content { 29 namespace media {
30 30
31 namespace { 31 namespace {
32 // UMA errors that the VaapiVideoDecodeAccelerator class reports. 32 // UMA errors that the VaapiVideoDecodeAccelerator class reports.
33 enum VAVDADecoderFailure { 33 enum VAVDADecoderFailure {
34 VAAPI_ERROR = 0, 34 VAAPI_ERROR = 0,
35 // UMA requires that max must be greater than 1. 35 VAVDA_DECODER_FAILURES_MAX,
36 VAVDA_DECODER_FAILURES_MAX = 2,
37 }; 36 };
38 } 37 }
39 38
40 static void ReportToUMA(VAVDADecoderFailure failure) { 39 static void ReportToUMA(VAVDADecoderFailure failure) {
41 UMA_HISTOGRAM_ENUMERATION("Media.VAVDA.DecoderFailure", failure, 40 UMA_HISTOGRAM_ENUMERATION("Media.VAVDA.DecoderFailure", failure,
42 VAVDA_DECODER_FAILURES_MAX); 41 VAVDA_DECODER_FAILURES_MAX + 1);
43 } 42 }
44 43
45 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \ 44 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \
46 do { \ 45 do { \
47 if (!(result)) { \ 46 if (!(result)) { \
48 LOG(ERROR) << log; \ 47 LOG(ERROR) << log; \
49 NotifyError(error_code); \ 48 NotifyError(error_code); \
50 return ret; \ 49 return ret; \
51 } \ 50 } \
52 } while (0) 51 } while (0)
53 52
54 class VaapiVideoDecodeAccelerator::VaapiDecodeSurface 53 class VaapiVideoDecodeAccelerator::VaapiDecodeSurface
55 : public base::RefCountedThreadSafe<VaapiDecodeSurface> { 54 : public base::RefCountedThreadSafe<VaapiDecodeSurface> {
56 public: 55 public:
57 VaapiDecodeSurface(int32_t bitstream_id, 56 VaapiDecodeSurface(int32_t bitstream_id,
58 const scoped_refptr<VASurface>& va_surface); 57 const scoped_refptr<VASurface>& va_surface);
59 58
60 int32_t bitstream_id() const { return bitstream_id_; } 59 int32_t bitstream_id() const { return bitstream_id_; }
61 scoped_refptr<VASurface> va_surface() { return va_surface_; } 60 scoped_refptr<VASurface> va_surface() { return va_surface_; }
62 61
63 private: 62 private:
64 friend class base::RefCountedThreadSafe<VaapiDecodeSurface>; 63 friend class base::RefCountedThreadSafe<VaapiDecodeSurface>;
65 ~VaapiDecodeSurface(); 64 ~VaapiDecodeSurface();
66 65
67 int32_t bitstream_id_; 66 int32_t bitstream_id_;
68 scoped_refptr<VASurface> va_surface_; 67 scoped_refptr<VASurface> va_surface_;
69 }; 68 };
70 69
71 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::VaapiDecodeSurface( 70 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::VaapiDecodeSurface(
72 int32_t bitstream_id, 71 int32_t bitstream_id,
73 const scoped_refptr<VASurface>& va_surface) 72 const scoped_refptr<VASurface>& va_surface)
74 : bitstream_id_(bitstream_id), va_surface_(va_surface) {} 73 : bitstream_id_(bitstream_id), va_surface_(va_surface) {}
75 74
76 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::~VaapiDecodeSurface() { 75 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::~VaapiDecodeSurface() {}
77 }
78 76
79 class VaapiH264Picture : public H264Picture { 77 class VaapiH264Picture : public H264Picture {
80 public: 78 public:
81 VaapiH264Picture(const scoped_refptr< 79 VaapiH264Picture(
82 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface); 80 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
81 dec_surface);
83 82
84 VaapiH264Picture* AsVaapiH264Picture() override { return this; } 83 VaapiH264Picture* AsVaapiH264Picture() override { return this; }
85 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() { 84 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() {
86 return dec_surface_; 85 return dec_surface_;
87 } 86 }
88 87
89 private: 88 private:
90 ~VaapiH264Picture() override; 89 ~VaapiH264Picture() override;
91 90
92 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_; 91 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_;
93 92
94 DISALLOW_COPY_AND_ASSIGN(VaapiH264Picture); 93 DISALLOW_COPY_AND_ASSIGN(VaapiH264Picture);
95 }; 94 };
96 95
97 VaapiH264Picture::VaapiH264Picture(const scoped_refptr< 96 VaapiH264Picture::VaapiH264Picture(
98 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface) 97 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
99 : dec_surface_(dec_surface) { 98 dec_surface)
100 } 99 : dec_surface_(dec_surface) {}
101 100
102 VaapiH264Picture::~VaapiH264Picture() { 101 VaapiH264Picture::~VaapiH264Picture() {}
103 }
104 102
105 class VaapiVideoDecodeAccelerator::VaapiH264Accelerator 103 class VaapiVideoDecodeAccelerator::VaapiH264Accelerator
106 : public H264Decoder::H264Accelerator { 104 : public H264Decoder::H264Accelerator {
107 public: 105 public:
108 VaapiH264Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec, 106 VaapiH264Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec,
109 VaapiWrapper* vaapi_wrapper); 107 VaapiWrapper* vaapi_wrapper);
110 ~VaapiH264Accelerator() override; 108 ~VaapiH264Accelerator() override;
111 109
112 // H264Decoder::H264Accelerator implementation. 110 // H264Decoder::H264Accelerator implementation.
113 scoped_refptr<H264Picture> CreateH264Picture() override; 111 scoped_refptr<H264Picture> CreateH264Picture() override;
(...skipping 29 matching lines...) Expand all
143 int num_pics); 141 int num_pics);
144 142
145 VaapiWrapper* vaapi_wrapper_; 143 VaapiWrapper* vaapi_wrapper_;
146 VaapiVideoDecodeAccelerator* vaapi_dec_; 144 VaapiVideoDecodeAccelerator* vaapi_dec_;
147 145
148 DISALLOW_COPY_AND_ASSIGN(VaapiH264Accelerator); 146 DISALLOW_COPY_AND_ASSIGN(VaapiH264Accelerator);
149 }; 147 };
150 148
151 class VaapiVP8Picture : public VP8Picture { 149 class VaapiVP8Picture : public VP8Picture {
152 public: 150 public:
153 VaapiVP8Picture(const scoped_refptr< 151 VaapiVP8Picture(
154 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface); 152 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
153 dec_surface);
155 154
156 VaapiVP8Picture* AsVaapiVP8Picture() override { return this; } 155 VaapiVP8Picture* AsVaapiVP8Picture() override { return this; }
157 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() { 156 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() {
158 return dec_surface_; 157 return dec_surface_;
159 } 158 }
160 159
161 private: 160 private:
162 ~VaapiVP8Picture() override; 161 ~VaapiVP8Picture() override;
163 162
164 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_; 163 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_;
165 164
166 DISALLOW_COPY_AND_ASSIGN(VaapiVP8Picture); 165 DISALLOW_COPY_AND_ASSIGN(VaapiVP8Picture);
167 }; 166 };
168 167
169 VaapiVP8Picture::VaapiVP8Picture(const scoped_refptr< 168 VaapiVP8Picture::VaapiVP8Picture(
170 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface) 169 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
171 : dec_surface_(dec_surface) { 170 dec_surface)
172 } 171 : dec_surface_(dec_surface) {}
173 172
174 VaapiVP8Picture::~VaapiVP8Picture() { 173 VaapiVP8Picture::~VaapiVP8Picture() {}
175 }
176 174
177 class VaapiVideoDecodeAccelerator::VaapiVP8Accelerator 175 class VaapiVideoDecodeAccelerator::VaapiVP8Accelerator
178 : public VP8Decoder::VP8Accelerator { 176 : public VP8Decoder::VP8Accelerator {
179 public: 177 public:
180 VaapiVP8Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec, 178 VaapiVP8Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec,
181 VaapiWrapper* vaapi_wrapper); 179 VaapiWrapper* vaapi_wrapper);
182 ~VaapiVP8Accelerator() override; 180 ~VaapiVP8Accelerator() override;
183 181
184 // VP8Decoder::VP8Accelerator implementation. 182 // VP8Decoder::VP8Accelerator implementation.
185 scoped_refptr<VP8Picture> CreateVP8Picture() override; 183 scoped_refptr<VP8Picture> CreateVP8Picture() override;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 const scoped_refptr<VP9Picture>& pic); 249 const scoped_refptr<VP9Picture>& pic);
252 250
253 VaapiWrapper* vaapi_wrapper_; 251 VaapiWrapper* vaapi_wrapper_;
254 VaapiVideoDecodeAccelerator* vaapi_dec_; 252 VaapiVideoDecodeAccelerator* vaapi_dec_;
255 253
256 DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator); 254 DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator);
257 }; 255 };
258 256
259 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0) {} 257 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0) {}
260 258
261 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { 259 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() {}
262 }
263 260
264 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { 261 void VaapiVideoDecodeAccelerator::NotifyError(Error error) {
265 if (message_loop_ != base::MessageLoop::current()) { 262 if (message_loop_ != base::MessageLoop::current()) {
266 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 263 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
267 message_loop_->PostTask(FROM_HERE, base::Bind( 264 message_loop_->PostTask(
268 &VaapiVideoDecodeAccelerator::NotifyError, weak_this_, error)); 265 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::NotifyError,
266 weak_this_, error));
269 return; 267 return;
270 } 268 }
271 269
272 // Post Cleanup() as a task so we don't recursively acquire lock_. 270 // Post Cleanup() as a task so we don't recursively acquire lock_.
273 message_loop_->PostTask(FROM_HERE, base::Bind( 271 message_loop_->PostTask(
274 &VaapiVideoDecodeAccelerator::Cleanup, weak_this_)); 272 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::Cleanup, weak_this_));
275 273
276 LOG(ERROR) << "Notifying of error " << error; 274 LOG(ERROR) << "Notifying of error " << error;
277 if (client_) { 275 if (client_) {
278 client_->NotifyError(error); 276 client_->NotifyError(error);
279 client_ptr_factory_.reset(); 277 client_ptr_factory_.reset();
280 } 278 }
281 } 279 }
282 280
283 VaapiPicture* VaapiVideoDecodeAccelerator::PictureById( 281 VaapiPicture* VaapiVideoDecodeAccelerator::PictureById(
284 int32_t picture_buffer_id) { 282 int32_t picture_buffer_id) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 384 }
387 385
388 void VaapiVideoDecodeAccelerator::OutputPicture( 386 void VaapiVideoDecodeAccelerator::OutputPicture(
389 const scoped_refptr<VASurface>& va_surface, 387 const scoped_refptr<VASurface>& va_surface,
390 int32_t input_id, 388 int32_t input_id,
391 VaapiPicture* picture) { 389 VaapiPicture* picture) {
392 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 390 DCHECK_EQ(message_loop_, base::MessageLoop::current());
393 391
394 int32_t output_id = picture->picture_buffer_id(); 392 int32_t output_id = picture->picture_buffer_id();
395 393
396 TRACE_EVENT2("Video Decoder", "VAVDA::OutputSurface", 394 TRACE_EVENT2("Video Decoder", "VAVDA::OutputSurface", "input_id", input_id,
397 "input_id", input_id,
398 "output_id", output_id); 395 "output_id", output_id);
399 396
400 DVLOG(3) << "Outputting VASurface " << va_surface->id() 397 DVLOG(3) << "Outputting VASurface " << va_surface->id()
401 << " into pixmap bound to picture buffer id " << output_id; 398 << " into pixmap bound to picture buffer id " << output_id;
402 399
403 RETURN_AND_NOTIFY_ON_FAILURE(picture->DownloadFromSurface(va_surface), 400 RETURN_AND_NOTIFY_ON_FAILURE(picture->DownloadFromSurface(va_surface),
404 "Failed putting surface into pixmap", 401 "Failed putting surface into pixmap",
405 PLATFORM_FAILURE, ); 402 PLATFORM_FAILURE, );
406 403
407 // Notify the client a picture is ready to be displayed. 404 // Notify the client a picture is ready to be displayed.
408 ++num_frames_at_client_; 405 ++num_frames_at_client_;
409 TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_); 406 TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_);
410 DVLOG(4) << "Notifying output picture id " << output_id 407 DVLOG(4) << "Notifying output picture id " << output_id << " for input "
411 << " for input "<< input_id << " is ready"; 408 << input_id << " is ready";
412 // TODO(posciak): Use visible size from decoder here instead 409 // TODO(posciak): Use visible size from decoder here instead
413 // (crbug.com/402760). Passing (0, 0) results in the client using the 410 // (crbug.com/402760). Passing (0, 0) results in the client using the
414 // visible size extracted from the container instead. 411 // visible size extracted from the container instead.
415 if (client_) 412 if (client_)
416 client_->PictureReady(media::Picture(output_id, input_id, 413 client_->PictureReady(media::Picture(output_id, input_id, gfx::Rect(0, 0),
417 gfx::Rect(0, 0),
418 picture->AllowOverlay())); 414 picture->AllowOverlay()));
419 } 415 }
420 416
421 void VaapiVideoDecodeAccelerator::TryOutputSurface() { 417 void VaapiVideoDecodeAccelerator::TryOutputSurface() {
422 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 418 DCHECK_EQ(message_loop_, base::MessageLoop::current());
423 419
424 // Handle Destroy() arriving while pictures are queued for output. 420 // Handle Destroy() arriving while pictures are queued for output.
425 if (!client_) 421 if (!client_)
426 return; 422 return;
427 423
(...skipping 10 matching lines...) Expand all
438 output_cb.Run(picture); 434 output_cb.Run(picture);
439 435
440 if (finish_flush_pending_ && pending_output_cbs_.empty()) 436 if (finish_flush_pending_ && pending_output_cbs_.empty())
441 FinishFlush(); 437 FinishFlush();
442 } 438 }
443 439
444 void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer( 440 void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer(
445 const media::BitstreamBuffer& bitstream_buffer) { 441 const media::BitstreamBuffer& bitstream_buffer) {
446 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 442 DCHECK_EQ(message_loop_, base::MessageLoop::current());
447 TRACE_EVENT1("Video Decoder", "MapAndQueueNewInputBuffer", "input_id", 443 TRACE_EVENT1("Video Decoder", "MapAndQueueNewInputBuffer", "input_id",
448 bitstream_buffer.id()); 444 bitstream_buffer.id());
449 445
450 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() 446 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id()
451 << " size: " << (int)bitstream_buffer.size(); 447 << " size: " << (int)bitstream_buffer.size();
452 448
453 std::unique_ptr<SharedMemoryRegion> shm( 449 std::unique_ptr<SharedMemoryRegion> shm(
454 new SharedMemoryRegion(bitstream_buffer, true)); 450 new SharedMemoryRegion(bitstream_buffer, true));
455 RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(), "Failed to map input buffer", 451 RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(), "Failed to map input buffer",
456 UNREADABLE_INPUT, ); 452 UNREADABLE_INPUT, );
457 453
458 base::AutoLock auto_lock(lock_); 454 base::AutoLock auto_lock(lock_);
(...skipping 25 matching lines...) Expand all
484 } 480 }
485 481
486 // We could have got woken up in a different state or never got to sleep 482 // We could have got woken up in a different state or never got to sleep
487 // due to current state; check for that. 483 // due to current state; check for that.
488 switch (state_) { 484 switch (state_) {
489 case kFlushing: 485 case kFlushing:
490 // Here we are only interested in finishing up decoding buffers that are 486 // Here we are only interested in finishing up decoding buffers that are
491 // already queued up. Otherwise will stop decoding. 487 // already queued up. Otherwise will stop decoding.
492 if (input_buffers_.empty()) 488 if (input_buffers_.empty())
493 return false; 489 return false;
494 // else fallthrough 490 // else fallthrough
Pawel Osciak 2016/04/19 09:22:55 Please keep the original indent.
Mark Dittmer 2016/05/02 03:51:24 Done.
495 case kDecoding: 491 case kDecoding:
496 case kIdle: 492 case kIdle:
497 DCHECK(!input_buffers_.empty()); 493 DCHECK(!input_buffers_.empty());
498 494
499 curr_input_buffer_ = input_buffers_.front(); 495 curr_input_buffer_ = input_buffers_.front();
500 input_buffers_.pop(); 496 input_buffers_.pop();
501 497
502 DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id 498 DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id
503 << " size: " << curr_input_buffer_->shm->size(); 499 << " size: " << curr_input_buffer_->shm->size();
504 500
(...skipping 10 matching lines...) Expand all
515 } 511 }
516 512
517 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer_Locked() { 513 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer_Locked() {
518 lock_.AssertAcquired(); 514 lock_.AssertAcquired();
519 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 515 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
520 DCHECK(curr_input_buffer_.get()); 516 DCHECK(curr_input_buffer_.get());
521 517
522 int32_t id = curr_input_buffer_->id; 518 int32_t id = curr_input_buffer_->id;
523 curr_input_buffer_.reset(); 519 curr_input_buffer_.reset();
524 DVLOG(4) << "End of input buffer " << id; 520 DVLOG(4) << "End of input buffer " << id;
525 message_loop_->PostTask(FROM_HERE, base::Bind( 521 message_loop_->PostTask(
526 &Client::NotifyEndOfBitstreamBuffer, client_, id)); 522 FROM_HERE, base::Bind(&Client::NotifyEndOfBitstreamBuffer, client_, id));
527 523
528 --num_stream_bufs_at_decoder_; 524 --num_stream_bufs_at_decoder_;
529 TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder", 525 TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder",
530 num_stream_bufs_at_decoder_); 526 num_stream_bufs_at_decoder_);
531 } 527 }
532 528
533 // TODO(posciak): refactor the whole class to remove sleeping in wait for 529 // TODO(posciak): refactor the whole class to remove sleeping in wait for
534 // surfaces, and reschedule DecodeTask instead. 530 // surfaces, and reschedule DecodeTask instead.
535 bool VaapiVideoDecodeAccelerator::WaitForSurfaces_Locked() { 531 bool VaapiVideoDecodeAccelerator::WaitForSurfaces_Locked() {
536 lock_.AssertAcquired(); 532 lock_.AssertAcquired();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 // This is the main decode function of the decoder and while keeping 566 // This is the main decode function of the decoder and while keeping
571 // the lock for its duration would be fine, it would defeat the purpose 567 // the lock for its duration would be fine, it would defeat the purpose
572 // of having a separate decoder thread. 568 // of having a separate decoder thread.
573 base::AutoUnlock auto_unlock(lock_); 569 base::AutoUnlock auto_unlock(lock_);
574 res = decoder_->Decode(); 570 res = decoder_->Decode();
575 } 571 }
576 572
577 switch (res) { 573 switch (res) {
578 case AcceleratedVideoDecoder::kAllocateNewSurfaces: 574 case AcceleratedVideoDecoder::kAllocateNewSurfaces:
579 DVLOG(1) << "Decoder requesting a new set of surfaces"; 575 DVLOG(1) << "Decoder requesting a new set of surfaces";
580 message_loop_->PostTask(FROM_HERE, base::Bind( 576 message_loop_->PostTask(
581 &VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange, weak_this_, 577 FROM_HERE,
582 decoder_->GetRequiredNumOfPictures(), 578 base::Bind(&VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange,
583 decoder_->GetPicSize())); 579 weak_this_, decoder_->GetRequiredNumOfPictures(),
580 decoder_->GetPicSize()));
584 // We'll get rescheduled once ProvidePictureBuffers() finishes. 581 // We'll get rescheduled once ProvidePictureBuffers() finishes.
585 return; 582 return;
586 583
587 case AcceleratedVideoDecoder::kRanOutOfStreamData: 584 case AcceleratedVideoDecoder::kRanOutOfStreamData:
588 ReturnCurrInputBuffer_Locked(); 585 ReturnCurrInputBuffer_Locked();
589 break; 586 break;
590 587
591 case AcceleratedVideoDecoder::kRanOutOfSurfaces: 588 case AcceleratedVideoDecoder::kRanOutOfSurfaces:
592 // No more output buffers in the decoder, try getting more or go to 589 // No more output buffers in the decoder, try getting more or go to
593 // sleep waiting for them. 590 // sleep waiting for them.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 629
633 if (!pending_output_cbs_.empty() || 630 if (!pending_output_cbs_.empty() ||
634 pictures_.size() != available_va_surfaces_.size()) { 631 pictures_.size() != available_va_surfaces_.size()) {
635 // Either: 632 // Either:
636 // 1. Not all pending pending output callbacks have been executed yet. 633 // 1. Not all pending pending output callbacks have been executed yet.
637 // Wait for the client to return enough pictures and retry later. 634 // Wait for the client to return enough pictures and retry later.
638 // 2. The above happened and all surface release callbacks have been posted 635 // 2. The above happened and all surface release callbacks have been posted
639 // as the result, but not all have executed yet. Post ourselves after them 636 // as the result, but not all have executed yet. Post ourselves after them
640 // to let them release surfaces. 637 // to let them release surfaces.
641 DVLOG(2) << "Awaiting pending output/surface release callbacks to finish"; 638 DVLOG(2) << "Awaiting pending output/surface release callbacks to finish";
642 message_loop_->PostTask(FROM_HERE, base::Bind( 639 message_loop_->PostTask(
643 &VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange, weak_this_)); 640 FROM_HERE,
641 base::Bind(&VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange,
642 weak_this_));
644 return; 643 return;
645 } 644 }
646 645
647 // All surfaces released, destroy them and dismiss all PictureBuffers. 646 // All surfaces released, destroy them and dismiss all PictureBuffers.
648 awaiting_va_surfaces_recycle_ = false; 647 awaiting_va_surfaces_recycle_ = false;
649 available_va_surfaces_.clear(); 648 available_va_surfaces_.clear();
650 vaapi_wrapper_->DestroySurfaces(); 649 vaapi_wrapper_->DestroySurfaces();
651 650
652 for (Pictures::iterator iter = pictures_.begin(); iter != pictures_.end(); 651 for (Pictures::iterator iter = pictures_.begin(); iter != pictures_.end();
653 ++iter) { 652 ++iter) {
654 DVLOG(2) << "Dismissing picture id: " << iter->first; 653 DVLOG(2) << "Dismissing picture id: " << iter->first;
655 if (client_) 654 if (client_)
656 client_->DismissPictureBuffer(iter->first); 655 client_->DismissPictureBuffer(iter->first);
657 } 656 }
658 pictures_.clear(); 657 pictures_.clear();
659 658
660 // And ask for a new set as requested. 659 // And ask for a new set as requested.
661 DVLOG(1) << "Requesting " << requested_num_pics_ << " pictures of size: " 660 DVLOG(1) << "Requesting " << requested_num_pics_
662 << requested_pic_size_.ToString(); 661 << " pictures of size: " << requested_pic_size_.ToString();
663 662
664 message_loop_->PostTask( 663 message_loop_->PostTask(
665 FROM_HERE, 664 FROM_HERE,
666 base::Bind(&Client::ProvidePictureBuffers, client_, requested_num_pics_, 665 base::Bind(&Client::ProvidePictureBuffers, client_, requested_num_pics_,
667 1, requested_pic_size_, VaapiPicture::GetGLTextureTarget())); 666 1, requested_pic_size_, VaapiPicture::GetGLTextureTarget()));
668 } 667 }
669 668
670 void VaapiVideoDecodeAccelerator::Decode( 669 void VaapiVideoDecodeAccelerator::Decode(
671 const media::BitstreamBuffer& bitstream_buffer) { 670 const media::BitstreamBuffer& bitstream_buffer) {
672 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 671 DCHECK_EQ(message_loop_, base::MessageLoop::current());
(...skipping 13 matching lines...) Expand all
686 base::AutoLock auto_lock(lock_); 685 base::AutoLock auto_lock(lock_);
687 switch (state_) { 686 switch (state_) {
688 case kIdle: 687 case kIdle:
689 state_ = kDecoding; 688 state_ = kDecoding;
690 decoder_thread_task_runner_->PostTask( 689 decoder_thread_task_runner_->PostTask(
691 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask, 690 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask,
692 base::Unretained(this))); 691 base::Unretained(this)));
693 break; 692 break;
694 693
695 case kDecoding: 694 case kDecoding:
696 // Decoder already running, fallthrough. 695 // Decoder already running, fallthrough.
697 case kResetting: 696 case kResetting:
698 // When resetting, allow accumulating bitstream buffers, so that 697 // When resetting, allow accumulating bitstream buffers, so that
699 // the client can queue after-seek-buffers while we are finishing with 698 // the client can queue after-seek-buffers while we are finishing with
700 // the before-seek one. 699 // the before-seek one.
701 break; 700 break;
702 701
703 default: 702 default:
704 RETURN_AND_NOTIFY_ON_FAILURE(false, 703 RETURN_AND_NOTIFY_ON_FAILURE(
705 "Decode request from client in invalid state: " << state_, 704 false, "Decode request from client in invalid state: " << state_,
706 PLATFORM_FAILURE, ); 705 PLATFORM_FAILURE, );
707 break; 706 break;
708 } 707 }
709 } 708 }
710 709
711 void VaapiVideoDecodeAccelerator::RecycleVASurfaceID( 710 void VaapiVideoDecodeAccelerator::RecycleVASurfaceID(
712 VASurfaceID va_surface_id) { 711 VASurfaceID va_surface_id) {
713 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 712 DCHECK_EQ(message_loop_, base::MessageLoop::current());
714 base::AutoLock auto_lock(lock_); 713 base::AutoLock auto_lock(lock_);
715 714
716 available_va_surfaces_.push_back(va_surface_id); 715 available_va_surfaces_.push_back(va_surface_id);
717 surfaces_available_.Signal(); 716 surfaces_available_.Signal();
718 } 717 }
719 718
720 void VaapiVideoDecodeAccelerator::AssignPictureBuffers( 719 void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
721 const std::vector<media::PictureBuffer>& buffers) { 720 const std::vector<media::PictureBuffer>& buffers) {
722 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 721 DCHECK_EQ(message_loop_, base::MessageLoop::current());
723 722
724 base::AutoLock auto_lock(lock_); 723 base::AutoLock auto_lock(lock_);
725 DCHECK(pictures_.empty()); 724 DCHECK(pictures_.empty());
726 725
727 while (!output_buffers_.empty()) 726 while (!output_buffers_.empty())
728 output_buffers_.pop(); 727 output_buffers_.pop();
729 728
730 RETURN_AND_NOTIFY_ON_FAILURE( 729 RETURN_AND_NOTIFY_ON_FAILURE(buffers.size() >= requested_num_pics_,
731 buffers.size() >= requested_num_pics_, 730 "Got an invalid number of picture buffers. (Got "
732 "Got an invalid number of picture buffers. (Got " << buffers.size() 731 << buffers.size() << ", requested "
733 << ", requested " << requested_num_pics_ << ")", INVALID_ARGUMENT, ); 732 << requested_num_pics_ << ")",
733 INVALID_ARGUMENT, );
734 DCHECK(requested_pic_size_ == buffers[0].size()); 734 DCHECK(requested_pic_size_ == buffers[0].size());
735 735
736 std::vector<VASurfaceID> va_surface_ids; 736 std::vector<VASurfaceID> va_surface_ids;
737 RETURN_AND_NOTIFY_ON_FAILURE( 737 RETURN_AND_NOTIFY_ON_FAILURE(
738 vaapi_wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420, requested_pic_size_, 738 vaapi_wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420, requested_pic_size_,
739 buffers.size(), &va_surface_ids), 739 buffers.size(), &va_surface_ids),
740 "Failed creating VA Surfaces", PLATFORM_FAILURE, ); 740 "Failed creating VA Surfaces", PLATFORM_FAILURE, );
741 DCHECK_EQ(va_surface_ids.size(), buffers.size()); 741 DCHECK_EQ(va_surface_ids.size(), buffers.size());
742 742
743 for (size_t i = 0; i < buffers.size(); ++i) { 743 for (size_t i = 0; i < buffers.size(); ++i) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 797
798 // First flush all the pictures that haven't been outputted, notifying the 798 // First flush all the pictures that haven't been outputted, notifying the
799 // client to output them. 799 // client to output them.
800 bool res = decoder_->Flush(); 800 bool res = decoder_->Flush();
801 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.", 801 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.",
802 PLATFORM_FAILURE, ); 802 PLATFORM_FAILURE, );
803 803
804 // Put the decoder in idle state, ready to resume. 804 // Put the decoder in idle state, ready to resume.
805 decoder_->Reset(); 805 decoder_->Reset();
806 806
807 message_loop_->PostTask(FROM_HERE, base::Bind( 807 message_loop_->PostTask(
808 &VaapiVideoDecodeAccelerator::FinishFlush, weak_this_)); 808 FROM_HERE,
809 base::Bind(&VaapiVideoDecodeAccelerator::FinishFlush, weak_this_));
809 } 810 }
810 811
811 void VaapiVideoDecodeAccelerator::Flush() { 812 void VaapiVideoDecodeAccelerator::Flush() {
812 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 813 DCHECK_EQ(message_loop_, base::MessageLoop::current());
813 DVLOG(1) << "Got flush request"; 814 DVLOG(1) << "Got flush request";
814 815
815 base::AutoLock auto_lock(lock_); 816 base::AutoLock auto_lock(lock_);
816 state_ = kFlushing; 817 state_ = kFlushing;
817 // Queue a flush task after all existing decoding tasks to clean up. 818 // Queue a flush task after all existing decoding tasks to clean up.
818 decoder_thread_task_runner_->PostTask( 819 decoder_thread_task_runner_->PostTask(
(...skipping 17 matching lines...) Expand all
836 837
837 // Still waiting for textures from client to finish outputting all pending 838 // Still waiting for textures from client to finish outputting all pending
838 // frames. Try again later. 839 // frames. Try again later.
839 if (!pending_output_cbs_.empty()) { 840 if (!pending_output_cbs_.empty()) {
840 finish_flush_pending_ = true; 841 finish_flush_pending_ = true;
841 return; 842 return;
842 } 843 }
843 844
844 state_ = kIdle; 845 state_ = kIdle;
845 846
846 message_loop_->PostTask(FROM_HERE, base::Bind( 847 message_loop_->PostTask(FROM_HERE,
847 &Client::NotifyFlushDone, client_)); 848 base::Bind(&Client::NotifyFlushDone, client_));
848 849
849 DVLOG(1) << "Flush finished"; 850 DVLOG(1) << "Flush finished";
850 } 851 }
851 852
852 void VaapiVideoDecodeAccelerator::ResetTask() { 853 void VaapiVideoDecodeAccelerator::ResetTask() {
853 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 854 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
854 DVLOG(1) << "ResetTask"; 855 DVLOG(1) << "ResetTask";
855 856
856 // All the decoding tasks from before the reset request from client are done 857 // All the decoding tasks from before the reset request from client are done
857 // by now, as this task was scheduled after them and client is expected not 858 // by now, as this task was scheduled after them and client is expected not
858 // to call Decode() after Reset() and before NotifyResetDone. 859 // to call Decode() after Reset() and before NotifyResetDone.
859 decoder_->Reset(); 860 decoder_->Reset();
860 861
861 base::AutoLock auto_lock(lock_); 862 base::AutoLock auto_lock(lock_);
862 863
863 // Return current input buffer, if present. 864 // Return current input buffer, if present.
864 if (curr_input_buffer_.get()) 865 if (curr_input_buffer_.get())
865 ReturnCurrInputBuffer_Locked(); 866 ReturnCurrInputBuffer_Locked();
866 867
867 // And let client know that we are done with reset. 868 // And let client know that we are done with reset.
868 message_loop_->PostTask(FROM_HERE, base::Bind( 869 message_loop_->PostTask(
869 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); 870 FROM_HERE,
871 base::Bind(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
870 } 872 }
871 873
872 void VaapiVideoDecodeAccelerator::Reset() { 874 void VaapiVideoDecodeAccelerator::Reset() {
873 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 875 DCHECK_EQ(message_loop_, base::MessageLoop::current());
874 DVLOG(1) << "Got reset request"; 876 DVLOG(1) << "Got reset request";
875 877
876 // This will make any new decode tasks exit early. 878 // This will make any new decode tasks exit early.
877 base::AutoLock auto_lock(lock_); 879 base::AutoLock auto_lock(lock_);
878 state_ = kResetting; 880 state_ = kResetting;
879 finish_flush_pending_ = false; 881 finish_flush_pending_ = false;
880 882
881 // Drop all remaining input buffers, if present. 883 // Drop all remaining input buffers, if present.
882 while (!input_buffers_.empty()) { 884 while (!input_buffers_.empty()) {
883 message_loop_->PostTask(FROM_HERE, base::Bind( 885 message_loop_->PostTask(
884 &Client::NotifyEndOfBitstreamBuffer, client_, 886 FROM_HERE, base::Bind(&Client::NotifyEndOfBitstreamBuffer, client_,
885 input_buffers_.front()->id)); 887 input_buffers_.front()->id));
886 input_buffers_.pop(); 888 input_buffers_.pop();
887 } 889 }
888 890
889 decoder_thread_task_runner_->PostTask( 891 decoder_thread_task_runner_->PostTask(
890 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::ResetTask, 892 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::ResetTask,
891 base::Unretained(this))); 893 base::Unretained(this)));
892 894
893 input_ready_.Signal(); 895 input_ready_.Signal();
894 surfaces_available_.Signal(); 896 surfaces_available_.Signal();
895 } 897 }
896 898
897 void VaapiVideoDecodeAccelerator::FinishReset() { 899 void VaapiVideoDecodeAccelerator::FinishReset() {
898 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 900 DCHECK_EQ(message_loop_, base::MessageLoop::current());
899 DVLOG(1) << "FinishReset"; 901 DVLOG(1) << "FinishReset";
900 base::AutoLock auto_lock(lock_); 902 base::AutoLock auto_lock(lock_);
901 903
902 if (state_ != kResetting) { 904 if (state_ != kResetting) {
903 DCHECK(state_ == kDestroying || state_ == kUninitialized) << state_; 905 DCHECK(state_ == kDestroying || state_ == kUninitialized) << state_;
904 return; // We could've gotten destroyed already. 906 return; // We could've gotten destroyed already.
905 } 907 }
906 908
907 // Drop pending outputs. 909 // Drop pending outputs.
908 while (!pending_output_cbs_.empty()) 910 while (!pending_output_cbs_.empty())
909 pending_output_cbs_.pop(); 911 pending_output_cbs_.pop();
910 912
911 if (awaiting_va_surfaces_recycle_) { 913 if (awaiting_va_surfaces_recycle_) {
912 // Decoder requested a new surface set while we were waiting for it to 914 // Decoder requested a new surface set while we were waiting for it to
913 // finish the last DecodeTask, running at the time of Reset(). 915 // finish the last DecodeTask, running at the time of Reset().
914 // Let the surface set change finish first before resetting. 916 // Let the surface set change finish first before resetting.
915 message_loop_->PostTask(FROM_HERE, base::Bind( 917 message_loop_->PostTask(
916 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); 918 FROM_HERE,
919 base::Bind(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
917 return; 920 return;
918 } 921 }
919 922
920 num_stream_bufs_at_decoder_ = 0; 923 num_stream_bufs_at_decoder_ = 0;
921 state_ = kIdle; 924 state_ = kIdle;
922 925
923 message_loop_->PostTask(FROM_HERE, base::Bind( 926 message_loop_->PostTask(FROM_HERE,
924 &Client::NotifyResetDone, client_)); 927 base::Bind(&Client::NotifyResetDone, client_));
925 928
926 // The client might have given us new buffers via Decode() while we were 929 // The client might have given us new buffers via Decode() while we were
927 // resetting and might be waiting for our move, and not call Decode() anymore 930 // resetting and might be waiting for our move, and not call Decode() anymore
928 // until we return something. Post a DecodeTask() so that we won't 931 // until we return something. Post a DecodeTask() so that we won't
929 // sleep forever waiting for Decode() in that case. Having two of them 932 // sleep forever waiting for Decode() in that case. Having two of them
930 // in the pipe is harmless, the additional one will return as soon as it sees 933 // in the pipe is harmless, the additional one will return as soon as it sees
931 // that we are back in kDecoding state. 934 // that we are back in kDecoding state.
932 if (!input_buffers_.empty()) { 935 if (!input_buffers_.empty()) {
933 state_ = kDecoding; 936 state_ = kDecoding;
934 decoder_thread_task_runner_->PostTask( 937 decoder_thread_task_runner_->PostTask(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 } 1037 }
1035 1038
1036 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::VaapiH264Accelerator( 1039 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::VaapiH264Accelerator(
1037 VaapiVideoDecodeAccelerator* vaapi_dec, 1040 VaapiVideoDecodeAccelerator* vaapi_dec,
1038 VaapiWrapper* vaapi_wrapper) 1041 VaapiWrapper* vaapi_wrapper)
1039 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) { 1042 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) {
1040 DCHECK(vaapi_wrapper_); 1043 DCHECK(vaapi_wrapper_);
1041 DCHECK(vaapi_dec_); 1044 DCHECK(vaapi_dec_);
1042 } 1045 }
1043 1046
1044 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::~VaapiH264Accelerator() { 1047 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::~VaapiH264Accelerator() {}
1045 }
1046 1048
1047 scoped_refptr<H264Picture> 1049 scoped_refptr<H264Picture>
1048 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::CreateH264Picture() { 1050 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::CreateH264Picture() {
1049 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface(); 1051 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface();
1050 if (!va_surface) 1052 if (!va_surface)
1051 return nullptr; 1053 return nullptr;
1052 1054
1053 return new VaapiH264Picture(va_surface); 1055 return new VaapiH264Picture(va_surface);
1054 } 1056 }
1055 1057
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 for (int i = 0; i < 16; ++i) 1136 for (int i = 0; i < 16; ++i)
1135 InitVAPicture(&pic_param.ReferenceFrames[i]); 1137 InitVAPicture(&pic_param.ReferenceFrames[i]);
1136 1138
1137 // And fill it with picture info from DPB. 1139 // And fill it with picture info from DPB.
1138 FillVARefFramesFromDPB(dpb, pic_param.ReferenceFrames, 1140 FillVARefFramesFromDPB(dpb, pic_param.ReferenceFrames,
1139 arraysize(pic_param.ReferenceFrames)); 1141 arraysize(pic_param.ReferenceFrames));
1140 1142
1141 pic_param.num_ref_frames = sps->max_num_ref_frames; 1143 pic_param.num_ref_frames = sps->max_num_ref_frames;
1142 1144
1143 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, 1145 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType,
1144 sizeof(pic_param), 1146 sizeof(pic_param), &pic_param))
1145 &pic_param))
1146 return false; 1147 return false;
1147 1148
1148 VAIQMatrixBufferH264 iq_matrix_buf; 1149 VAIQMatrixBufferH264 iq_matrix_buf;
1149 memset(&iq_matrix_buf, 0, sizeof(iq_matrix_buf)); 1150 memset(&iq_matrix_buf, 0, sizeof(iq_matrix_buf));
1150 1151
1151 if (pps->pic_scaling_matrix_present_flag) { 1152 if (pps->pic_scaling_matrix_present_flag) {
1152 for (int i = 0; i < 6; ++i) { 1153 for (int i = 0; i < 6; ++i) {
1153 for (int j = 0; j < 16; ++j) 1154 for (int j = 0; j < 16; ++j)
1154 iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j]; 1155 iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j];
1155 } 1156 }
1156 1157
1157 for (int i = 0; i < 2; ++i) { 1158 for (int i = 0; i < 2; ++i) {
1158 for (int j = 0; j < 64; ++j) 1159 for (int j = 0; j < 64; ++j)
1159 iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j]; 1160 iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j];
1160 } 1161 }
1161 } else { 1162 } else {
1162 for (int i = 0; i < 6; ++i) { 1163 for (int i = 0; i < 6; ++i) {
1163 for (int j = 0; j < 16; ++j) 1164 for (int j = 0; j < 16; ++j)
1164 iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j]; 1165 iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j];
1165 } 1166 }
1166 1167
1167 for (int i = 0; i < 2; ++i) { 1168 for (int i = 0; i < 2; ++i) {
1168 for (int j = 0; j < 64; ++j) 1169 for (int j = 0; j < 64; ++j)
1169 iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j]; 1170 iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j];
1170 } 1171 }
1171 } 1172 }
1172 1173
1173 return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, 1174 return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType,
1174 sizeof(iq_matrix_buf), 1175 sizeof(iq_matrix_buf), &iq_matrix_buf);
1175 &iq_matrix_buf);
1176 } 1176 }
1177 1177
1178 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitSlice( 1178 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitSlice(
1179 const media::H264PPS* pps, 1179 const media::H264PPS* pps,
1180 const media::H264SliceHeader* slice_hdr, 1180 const media::H264SliceHeader* slice_hdr,
1181 const H264Picture::Vector& ref_pic_list0, 1181 const H264Picture::Vector& ref_pic_list0,
1182 const H264Picture::Vector& ref_pic_list1, 1182 const H264Picture::Vector& ref_pic_list1,
1183 const scoped_refptr<H264Picture>& pic, 1183 const scoped_refptr<H264Picture>& pic,
1184 const uint8_t* data, 1184 const uint8_t* data,
1185 size_t size) { 1185 size_t size) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 FillVAPicture(&slice_param.RefPicList0[i], ref_pic_list0[i]); 1265 FillVAPicture(&slice_param.RefPicList0[i], ref_pic_list0[i]);
1266 } 1266 }
1267 for (size_t i = 0; 1267 for (size_t i = 0;
1268 i < ref_pic_list1.size() && i < arraysize(slice_param.RefPicList1); 1268 i < ref_pic_list1.size() && i < arraysize(slice_param.RefPicList1);
1269 ++i) { 1269 ++i) {
1270 if (ref_pic_list1[i]) 1270 if (ref_pic_list1[i])
1271 FillVAPicture(&slice_param.RefPicList1[i], ref_pic_list1[i]); 1271 FillVAPicture(&slice_param.RefPicList1[i], ref_pic_list1[i]);
1272 } 1272 }
1273 1273
1274 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, 1274 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType,
1275 sizeof(slice_param), 1275 sizeof(slice_param), &slice_param))
1276 &slice_param))
1277 return false; 1276 return false;
1278 1277
1279 // Can't help it, blame libva... 1278 // Can't help it, blame libva...
1280 void* non_const_ptr = const_cast<uint8_t*>(data); 1279 void* non_const_ptr = const_cast<uint8_t*>(data);
1281 return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size, 1280 return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size,
1282 non_const_ptr); 1281 non_const_ptr);
1283 } 1282 }
1284 1283
1285 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitDecode( 1284 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitDecode(
1286 const scoped_refptr<H264Picture>& pic) { 1285 const scoped_refptr<H264Picture>& pic) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 } 1366 }
1368 1367
1369 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::VaapiVP8Accelerator( 1368 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::VaapiVP8Accelerator(
1370 VaapiVideoDecodeAccelerator* vaapi_dec, 1369 VaapiVideoDecodeAccelerator* vaapi_dec,
1371 VaapiWrapper* vaapi_wrapper) 1370 VaapiWrapper* vaapi_wrapper)
1372 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) { 1371 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) {
1373 DCHECK(vaapi_wrapper_); 1372 DCHECK(vaapi_wrapper_);
1374 DCHECK(vaapi_dec_); 1373 DCHECK(vaapi_dec_);
1375 } 1374 }
1376 1375
1377 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::~VaapiVP8Accelerator() { 1376 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::~VaapiVP8Accelerator() {}
1378 }
1379 1377
1380 scoped_refptr<VP8Picture> 1378 scoped_refptr<VP8Picture>
1381 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::CreateVP8Picture() { 1379 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::CreateVP8Picture() {
1382 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface(); 1380 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface();
1383 if (!va_surface) 1381 if (!va_surface)
1384 return nullptr; 1382 return nullptr;
1385 1383
1386 return new VaapiVP8Picture(va_surface); 1384 return new VaapiVP8Picture(va_surface);
1387 } 1385 }
1388 1386
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 "incorrect quantization matrix size"); 1421 "incorrect quantization matrix size");
1424 iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q); 1422 iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q);
1425 iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta); 1423 iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta);
1426 iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta); 1424 iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta);
1427 iq_matrix_buf.quantization_index[i][3] = CLAMP_Q(q + quant_hdr.y2_ac_delta); 1425 iq_matrix_buf.quantization_index[i][3] = CLAMP_Q(q + quant_hdr.y2_ac_delta);
1428 iq_matrix_buf.quantization_index[i][4] = CLAMP_Q(q + quant_hdr.uv_dc_delta); 1426 iq_matrix_buf.quantization_index[i][4] = CLAMP_Q(q + quant_hdr.uv_dc_delta);
1429 iq_matrix_buf.quantization_index[i][5] = CLAMP_Q(q + quant_hdr.uv_ac_delta); 1427 iq_matrix_buf.quantization_index[i][5] = CLAMP_Q(q + quant_hdr.uv_ac_delta);
1430 #undef CLAMP_Q 1428 #undef CLAMP_Q
1431 } 1429 }
1432 1430
1433 if (!vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, 1431 if (!vaapi_wrapper_->SubmitBuffer(
1434 sizeof(VAIQMatrixBufferVP8), 1432 VAIQMatrixBufferType, sizeof(VAIQMatrixBufferVP8), &iq_matrix_buf))
1435 &iq_matrix_buf))
1436 return false; 1433 return false;
1437 1434
1438 VAProbabilityDataBufferVP8 prob_buf; 1435 VAProbabilityDataBufferVP8 prob_buf;
1439 memset(&prob_buf, 0, sizeof(VAProbabilityDataBufferVP8)); 1436 memset(&prob_buf, 0, sizeof(VAProbabilityDataBufferVP8));
1440 1437
1441 const media::Vp8EntropyHeader& entr_hdr = frame_hdr->entropy_hdr; 1438 const media::Vp8EntropyHeader& entr_hdr = frame_hdr->entropy_hdr;
1442 ARRAY_MEMCPY_CHECKED(prob_buf.dct_coeff_probs, entr_hdr.coeff_probs); 1439 ARRAY_MEMCPY_CHECKED(prob_buf.dct_coeff_probs, entr_hdr.coeff_probs);
1443 1440
1444 if (!vaapi_wrapper_->SubmitBuffer(VAProbabilityBufferType, 1441 if (!vaapi_wrapper_->SubmitBuffer(VAProbabilityBufferType,
1445 sizeof(VAProbabilityDataBufferVP8), 1442 sizeof(VAProbabilityDataBufferVP8),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 lf_level = sgmnt_hdr.lf_update_value[i]; 1507 lf_level = sgmnt_hdr.lf_update_value[i];
1511 else 1508 else
1512 lf_level += sgmnt_hdr.lf_update_value[i]; 1509 lf_level += sgmnt_hdr.lf_update_value[i];
1513 } 1510 }
1514 1511
1515 // Clamp to [0..63] range. 1512 // Clamp to [0..63] range.
1516 lf_level = std::min(std::max(lf_level, 0), 63); 1513 lf_level = std::min(std::max(lf_level, 0), 63);
1517 pic_param.loop_filter_level[i] = lf_level; 1514 pic_param.loop_filter_level[i] = lf_level;
1518 } 1515 }
1519 1516
1520 static_assert(arraysize(lf_hdr.ref_frame_delta) == 1517 static_assert(
1521 arraysize(pic_param.loop_filter_deltas_ref_frame) && 1518 arraysize(lf_hdr.ref_frame_delta) ==
1522 arraysize(lf_hdr.mb_mode_delta) == 1519 arraysize(pic_param.loop_filter_deltas_ref_frame) &&
1523 arraysize(pic_param.loop_filter_deltas_mode) && 1520 arraysize(lf_hdr.mb_mode_delta) ==
1524 arraysize(lf_hdr.ref_frame_delta) == 1521 arraysize(pic_param.loop_filter_deltas_mode) &&
1525 arraysize(lf_hdr.mb_mode_delta), 1522 arraysize(lf_hdr.ref_frame_delta) == arraysize(lf_hdr.mb_mode_delta),
1526 "loop filter deltas arrays size mismatch"); 1523 "loop filter deltas arrays size mismatch");
1527 for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) { 1524 for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) {
1528 pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i]; 1525 pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i];
1529 pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i]; 1526 pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i];
1530 } 1527 }
1531 1528
1532 #define FHDR_TO_PP(a) pic_param.a = frame_hdr->a 1529 #define FHDR_TO_PP(a) pic_param.a = frame_hdr->a
1533 FHDR_TO_PP(prob_skip_false); 1530 FHDR_TO_PP(prob_skip_false);
1534 FHDR_TO_PP(prob_intra); 1531 FHDR_TO_PP(prob_intra);
1535 FHDR_TO_PP(prob_last); 1532 FHDR_TO_PP(prob_last);
1536 FHDR_TO_PP(prob_gf); 1533 FHDR_TO_PP(prob_gf);
(...skipping 28 matching lines...) Expand all
1565 for (size_t i = 0; i < frame_hdr->num_of_dct_partitions; ++i) 1562 for (size_t i = 0; i < frame_hdr->num_of_dct_partitions; ++i)
1566 slice_param.partition_size[i + 1] = frame_hdr->dct_partition_sizes[i]; 1563 slice_param.partition_size[i + 1] = frame_hdr->dct_partition_sizes[i];
1567 1564
1568 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, 1565 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType,
1569 sizeof(VASliceParameterBufferVP8), 1566 sizeof(VASliceParameterBufferVP8),
1570 &slice_param)) 1567 &slice_param))
1571 return false; 1568 return false;
1572 1569
1573 void* non_const_ptr = const_cast<uint8_t*>(frame_hdr->data); 1570 void* non_const_ptr = const_cast<uint8_t*>(frame_hdr->data);
1574 if (!vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, 1571 if (!vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType,
1575 frame_hdr->frame_size, 1572 frame_hdr->frame_size, non_const_ptr))
1576 non_const_ptr))
1577 return false; 1573 return false;
1578 1574
1579 scoped_refptr<VaapiDecodeSurface> dec_surface = 1575 scoped_refptr<VaapiDecodeSurface> dec_surface =
1580 VP8PictureToVaapiDecodeSurface(pic); 1576 VP8PictureToVaapiDecodeSurface(pic);
1581 1577
1582 return vaapi_dec_->DecodeSurface(dec_surface); 1578 return vaapi_dec_->DecodeSurface(dec_surface);
1583 } 1579 }
1584 1580
1585 bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::OutputPicture( 1581 bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::OutputPicture(
1586 const scoped_refptr<VP8Picture>& pic) { 1582 const scoped_refptr<VP8Picture>& pic) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 CHECK(vaapi_pic); 1750 CHECK(vaapi_pic);
1755 return vaapi_pic->dec_surface(); 1751 return vaapi_pic->dec_surface();
1756 } 1752 }
1757 1753
1758 // static 1754 // static
1759 media::VideoDecodeAccelerator::SupportedProfiles 1755 media::VideoDecodeAccelerator::SupportedProfiles
1760 VaapiVideoDecodeAccelerator::GetSupportedProfiles() { 1756 VaapiVideoDecodeAccelerator::GetSupportedProfiles() {
1761 return VaapiWrapper::GetSupportedDecodeProfiles(); 1757 return VaapiWrapper::GetSupportedDecodeProfiles();
1762 } 1758 }
1763 1759
1764 } // namespace content 1760 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698