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

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

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « media/gpu/vaapi_video_decode_accelerator.h ('k') | media/gpu/vaapi_video_encode_accelerator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <memory> 9 #include <memory>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/synchronization/waitable_event.h" 17 #include "base/synchronization/waitable_event.h"
18 #include "base/trace_event/trace_event.h" 18 #include "base/trace_event/trace_event.h"
19 #include "content/common/gpu/media/accelerated_video_decoder.h"
20 #include "content/common/gpu/media/h264_decoder.h"
21 #include "content/common/gpu/media/vaapi_picture.h"
22 #include "content/common/gpu/media/vp8_decoder.h"
23 #include "content/common/gpu/media/vp9_decoder.h"
24 #include "gpu/ipc/service/gpu_channel.h" 19 #include "gpu/ipc/service/gpu_channel.h"
25 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
21 #include "media/gpu/accelerated_video_decoder.h"
22 #include "media/gpu/h264_decoder.h"
23 #include "media/gpu/vaapi_picture.h"
24 #include "media/gpu/vp8_decoder.h"
25 #include "media/gpu/vp9_decoder.h"
26 #include "media/video/picture.h" 26 #include "media/video/picture.h"
27 #include "third_party/libva/va/va_dec_vp8.h" 27 #include "third_party/libva/va/va_dec_vp8.h"
28 #include "ui/gl/gl_bindings.h" 28 #include "ui/gl/gl_bindings.h"
29 #include "ui/gl/gl_image.h" 29 #include "ui/gl/gl_image.h"
30 30
31 namespace content { 31 namespace media {
32 32
33 namespace { 33 namespace {
34 // UMA errors that the VaapiVideoDecodeAccelerator class reports. 34 // UMA errors that the VaapiVideoDecodeAccelerator class reports.
35 enum VAVDADecoderFailure { 35 enum VAVDADecoderFailure {
36 VAAPI_ERROR = 0, 36 VAAPI_ERROR = 0,
37 // UMA requires that max must be greater than 1. 37 VAVDA_DECODER_FAILURES_MAX,
38 VAVDA_DECODER_FAILURES_MAX = 2,
39 }; 38 };
40 } 39 }
41 40
42 static void ReportToUMA(VAVDADecoderFailure failure) { 41 static void ReportToUMA(VAVDADecoderFailure failure) {
43 UMA_HISTOGRAM_ENUMERATION("Media.VAVDA.DecoderFailure", failure, 42 UMA_HISTOGRAM_ENUMERATION("Media.VAVDA.DecoderFailure", failure,
44 VAVDA_DECODER_FAILURES_MAX); 43 VAVDA_DECODER_FAILURES_MAX + 1);
45 } 44 }
46 45
47 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \ 46 #define RETURN_AND_NOTIFY_ON_FAILURE(result, log, error_code, ret) \
48 do { \ 47 do { \
49 if (!(result)) { \ 48 if (!(result)) { \
50 LOG(ERROR) << log; \ 49 LOG(ERROR) << log; \
51 NotifyError(error_code); \ 50 NotifyError(error_code); \
52 return ret; \ 51 return ret; \
53 } \ 52 } \
54 } while (0) 53 } while (0)
55 54
56 class VaapiVideoDecodeAccelerator::VaapiDecodeSurface 55 class VaapiVideoDecodeAccelerator::VaapiDecodeSurface
57 : public base::RefCountedThreadSafe<VaapiDecodeSurface> { 56 : public base::RefCountedThreadSafe<VaapiDecodeSurface> {
58 public: 57 public:
59 VaapiDecodeSurface(int32_t bitstream_id, 58 VaapiDecodeSurface(int32_t bitstream_id,
60 const scoped_refptr<VASurface>& va_surface); 59 const scoped_refptr<VASurface>& va_surface);
61 60
62 int32_t bitstream_id() const { return bitstream_id_; } 61 int32_t bitstream_id() const { return bitstream_id_; }
63 scoped_refptr<VASurface> va_surface() { return va_surface_; } 62 scoped_refptr<VASurface> va_surface() { return va_surface_; }
64 63
65 private: 64 private:
66 friend class base::RefCountedThreadSafe<VaapiDecodeSurface>; 65 friend class base::RefCountedThreadSafe<VaapiDecodeSurface>;
67 ~VaapiDecodeSurface(); 66 ~VaapiDecodeSurface();
68 67
69 int32_t bitstream_id_; 68 int32_t bitstream_id_;
70 scoped_refptr<VASurface> va_surface_; 69 scoped_refptr<VASurface> va_surface_;
71 }; 70 };
72 71
73 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::VaapiDecodeSurface( 72 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::VaapiDecodeSurface(
74 int32_t bitstream_id, 73 int32_t bitstream_id,
75 const scoped_refptr<VASurface>& va_surface) 74 const scoped_refptr<VASurface>& va_surface)
76 : bitstream_id_(bitstream_id), va_surface_(va_surface) {} 75 : bitstream_id_(bitstream_id), va_surface_(va_surface) {}
77 76
78 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::~VaapiDecodeSurface() { 77 VaapiVideoDecodeAccelerator::VaapiDecodeSurface::~VaapiDecodeSurface() {}
79 }
80 78
81 class VaapiH264Picture : public H264Picture { 79 class VaapiH264Picture : public H264Picture {
82 public: 80 public:
83 VaapiH264Picture(const scoped_refptr< 81 VaapiH264Picture(
84 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface); 82 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
83 dec_surface);
85 84
86 VaapiH264Picture* AsVaapiH264Picture() override { return this; } 85 VaapiH264Picture* AsVaapiH264Picture() override { return this; }
87 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() { 86 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() {
88 return dec_surface_; 87 return dec_surface_;
89 } 88 }
90 89
91 private: 90 private:
92 ~VaapiH264Picture() override; 91 ~VaapiH264Picture() override;
93 92
94 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_; 93 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_;
95 94
96 DISALLOW_COPY_AND_ASSIGN(VaapiH264Picture); 95 DISALLOW_COPY_AND_ASSIGN(VaapiH264Picture);
97 }; 96 };
98 97
99 VaapiH264Picture::VaapiH264Picture(const scoped_refptr< 98 VaapiH264Picture::VaapiH264Picture(
100 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface) 99 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
101 : dec_surface_(dec_surface) { 100 dec_surface)
102 } 101 : dec_surface_(dec_surface) {}
103 102
104 VaapiH264Picture::~VaapiH264Picture() { 103 VaapiH264Picture::~VaapiH264Picture() {}
105 }
106 104
107 class VaapiVideoDecodeAccelerator::VaapiH264Accelerator 105 class VaapiVideoDecodeAccelerator::VaapiH264Accelerator
108 : public H264Decoder::H264Accelerator { 106 : public H264Decoder::H264Accelerator {
109 public: 107 public:
110 VaapiH264Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec, 108 VaapiH264Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec,
111 VaapiWrapper* vaapi_wrapper); 109 VaapiWrapper* vaapi_wrapper);
112 ~VaapiH264Accelerator() override; 110 ~VaapiH264Accelerator() override;
113 111
114 // H264Decoder::H264Accelerator implementation. 112 // H264Decoder::H264Accelerator implementation.
115 scoped_refptr<H264Picture> CreateH264Picture() override; 113 scoped_refptr<H264Picture> CreateH264Picture() override;
(...skipping 29 matching lines...) Expand all
145 int num_pics); 143 int num_pics);
146 144
147 VaapiWrapper* vaapi_wrapper_; 145 VaapiWrapper* vaapi_wrapper_;
148 VaapiVideoDecodeAccelerator* vaapi_dec_; 146 VaapiVideoDecodeAccelerator* vaapi_dec_;
149 147
150 DISALLOW_COPY_AND_ASSIGN(VaapiH264Accelerator); 148 DISALLOW_COPY_AND_ASSIGN(VaapiH264Accelerator);
151 }; 149 };
152 150
153 class VaapiVP8Picture : public VP8Picture { 151 class VaapiVP8Picture : public VP8Picture {
154 public: 152 public:
155 VaapiVP8Picture(const scoped_refptr< 153 VaapiVP8Picture(
156 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface); 154 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
155 dec_surface);
157 156
158 VaapiVP8Picture* AsVaapiVP8Picture() override { return this; } 157 VaapiVP8Picture* AsVaapiVP8Picture() override { return this; }
159 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() { 158 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() {
160 return dec_surface_; 159 return dec_surface_;
161 } 160 }
162 161
163 private: 162 private:
164 ~VaapiVP8Picture() override; 163 ~VaapiVP8Picture() override;
165 164
166 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_; 165 scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_;
167 166
168 DISALLOW_COPY_AND_ASSIGN(VaapiVP8Picture); 167 DISALLOW_COPY_AND_ASSIGN(VaapiVP8Picture);
169 }; 168 };
170 169
171 VaapiVP8Picture::VaapiVP8Picture(const scoped_refptr< 170 VaapiVP8Picture::VaapiVP8Picture(
172 VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface) 171 const scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface>&
173 : dec_surface_(dec_surface) { 172 dec_surface)
174 } 173 : dec_surface_(dec_surface) {}
175 174
176 VaapiVP8Picture::~VaapiVP8Picture() { 175 VaapiVP8Picture::~VaapiVP8Picture() {}
177 }
178 176
179 class VaapiVideoDecodeAccelerator::VaapiVP8Accelerator 177 class VaapiVideoDecodeAccelerator::VaapiVP8Accelerator
180 : public VP8Decoder::VP8Accelerator { 178 : public VP8Decoder::VP8Accelerator {
181 public: 179 public:
182 VaapiVP8Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec, 180 VaapiVP8Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec,
183 VaapiWrapper* vaapi_wrapper); 181 VaapiWrapper* vaapi_wrapper);
184 ~VaapiVP8Accelerator() override; 182 ~VaapiVP8Accelerator() override;
185 183
186 // VP8Decoder::VP8Accelerator implementation. 184 // VP8Decoder::VP8Accelerator implementation.
187 scoped_refptr<VP8Picture> CreateVP8Picture() override; 185 scoped_refptr<VP8Picture> CreateVP8Picture() override;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 const scoped_refptr<VP9Picture>& pic); 251 const scoped_refptr<VP9Picture>& pic);
254 252
255 VaapiWrapper* vaapi_wrapper_; 253 VaapiWrapper* vaapi_wrapper_;
256 VaapiVideoDecodeAccelerator* vaapi_dec_; 254 VaapiVideoDecodeAccelerator* vaapi_dec_;
257 255
258 DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator); 256 DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator);
259 }; 257 };
260 258
261 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0) {} 259 VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0) {}
262 260
263 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() { 261 VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() {}
264 }
265 262
266 void VaapiVideoDecodeAccelerator::NotifyError(Error error) { 263 void VaapiVideoDecodeAccelerator::NotifyError(Error error) {
267 if (message_loop_ != base::MessageLoop::current()) { 264 if (message_loop_ != base::MessageLoop::current()) {
268 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 265 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
269 message_loop_->PostTask(FROM_HERE, base::Bind( 266 message_loop_->PostTask(
270 &VaapiVideoDecodeAccelerator::NotifyError, weak_this_, error)); 267 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::NotifyError,
268 weak_this_, error));
271 return; 269 return;
272 } 270 }
273 271
274 // Post Cleanup() as a task so we don't recursively acquire lock_. 272 // Post Cleanup() as a task so we don't recursively acquire lock_.
275 message_loop_->PostTask(FROM_HERE, base::Bind( 273 message_loop_->PostTask(
276 &VaapiVideoDecodeAccelerator::Cleanup, weak_this_)); 274 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::Cleanup, weak_this_));
277 275
278 LOG(ERROR) << "Notifying of error " << error; 276 LOG(ERROR) << "Notifying of error " << error;
279 if (client_) { 277 if (client_) {
280 client_->NotifyError(error); 278 client_->NotifyError(error);
281 client_ptr_factory_.reset(); 279 client_ptr_factory_.reset();
282 } 280 }
283 } 281 }
284 282
285 VaapiPicture* VaapiVideoDecodeAccelerator::PictureById( 283 VaapiPicture* VaapiVideoDecodeAccelerator::PictureById(
286 int32_t picture_buffer_id) { 284 int32_t picture_buffer_id) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 391 }
394 392
395 void VaapiVideoDecodeAccelerator::OutputPicture( 393 void VaapiVideoDecodeAccelerator::OutputPicture(
396 const scoped_refptr<VASurface>& va_surface, 394 const scoped_refptr<VASurface>& va_surface,
397 int32_t input_id, 395 int32_t input_id,
398 VaapiPicture* picture) { 396 VaapiPicture* picture) {
399 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 397 DCHECK_EQ(message_loop_, base::MessageLoop::current());
400 398
401 int32_t output_id = picture->picture_buffer_id(); 399 int32_t output_id = picture->picture_buffer_id();
402 400
403 TRACE_EVENT2("Video Decoder", "VAVDA::OutputSurface", 401 TRACE_EVENT2("Video Decoder", "VAVDA::OutputSurface", "input_id", input_id,
404 "input_id", input_id,
405 "output_id", output_id); 402 "output_id", output_id);
406 403
407 DVLOG(3) << "Outputting VASurface " << va_surface->id() 404 DVLOG(3) << "Outputting VASurface " << va_surface->id()
408 << " into pixmap bound to picture buffer id " << output_id; 405 << " into pixmap bound to picture buffer id " << output_id;
409 406
410 RETURN_AND_NOTIFY_ON_FAILURE(picture->DownloadFromSurface(va_surface), 407 RETURN_AND_NOTIFY_ON_FAILURE(picture->DownloadFromSurface(va_surface),
411 "Failed putting surface into pixmap", 408 "Failed putting surface into pixmap",
412 PLATFORM_FAILURE, ); 409 PLATFORM_FAILURE, );
413 410
414 // Notify the client a picture is ready to be displayed. 411 // Notify the client a picture is ready to be displayed.
415 ++num_frames_at_client_; 412 ++num_frames_at_client_;
416 TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_); 413 TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_);
417 DVLOG(4) << "Notifying output picture id " << output_id 414 DVLOG(4) << "Notifying output picture id " << output_id << " for input "
418 << " for input "<< input_id << " is ready"; 415 << input_id << " is ready";
419 // TODO(posciak): Use visible size from decoder here instead 416 // TODO(posciak): Use visible size from decoder here instead
420 // (crbug.com/402760). Passing (0, 0) results in the client using the 417 // (crbug.com/402760). Passing (0, 0) results in the client using the
421 // visible size extracted from the container instead. 418 // visible size extracted from the container instead.
422 if (client_) 419 if (client_)
423 client_->PictureReady(media::Picture(output_id, input_id, 420 client_->PictureReady(media::Picture(output_id, input_id, gfx::Rect(0, 0),
424 gfx::Rect(0, 0),
425 picture->AllowOverlay())); 421 picture->AllowOverlay()));
426 } 422 }
427 423
428 void VaapiVideoDecodeAccelerator::TryOutputSurface() { 424 void VaapiVideoDecodeAccelerator::TryOutputSurface() {
429 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 425 DCHECK_EQ(message_loop_, base::MessageLoop::current());
430 426
431 // Handle Destroy() arriving while pictures are queued for output. 427 // Handle Destroy() arriving while pictures are queued for output.
432 if (!client_) 428 if (!client_)
433 return; 429 return;
434 430
(...skipping 10 matching lines...) Expand all
445 output_cb.Run(picture); 441 output_cb.Run(picture);
446 442
447 if (finish_flush_pending_ && pending_output_cbs_.empty()) 443 if (finish_flush_pending_ && pending_output_cbs_.empty())
448 FinishFlush(); 444 FinishFlush();
449 } 445 }
450 446
451 void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer( 447 void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer(
452 const media::BitstreamBuffer& bitstream_buffer) { 448 const media::BitstreamBuffer& bitstream_buffer) {
453 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 449 DCHECK_EQ(message_loop_, base::MessageLoop::current());
454 TRACE_EVENT1("Video Decoder", "MapAndQueueNewInputBuffer", "input_id", 450 TRACE_EVENT1("Video Decoder", "MapAndQueueNewInputBuffer", "input_id",
455 bitstream_buffer.id()); 451 bitstream_buffer.id());
456 452
457 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() 453 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id()
458 << " size: " << (int)bitstream_buffer.size(); 454 << " size: " << (int)bitstream_buffer.size();
459 455
460 std::unique_ptr<SharedMemoryRegion> shm( 456 std::unique_ptr<SharedMemoryRegion> shm(
461 new SharedMemoryRegion(bitstream_buffer, true)); 457 new SharedMemoryRegion(bitstream_buffer, true));
462 458
463 // Skip empty buffers. 459 // Skip empty buffers.
464 if (bitstream_buffer.size() == 0) { 460 if (bitstream_buffer.size() == 0) {
465 if (client_) 461 if (client_)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 495 }
500 496
501 // We could have got woken up in a different state or never got to sleep 497 // We could have got woken up in a different state or never got to sleep
502 // due to current state; check for that. 498 // due to current state; check for that.
503 switch (state_) { 499 switch (state_) {
504 case kFlushing: 500 case kFlushing:
505 // Here we are only interested in finishing up decoding buffers that are 501 // Here we are only interested in finishing up decoding buffers that are
506 // already queued up. Otherwise will stop decoding. 502 // already queued up. Otherwise will stop decoding.
507 if (input_buffers_.empty()) 503 if (input_buffers_.empty())
508 return false; 504 return false;
509 // else fallthrough 505 // else fallthrough
510 case kDecoding: 506 case kDecoding:
511 case kIdle: 507 case kIdle:
512 DCHECK(!input_buffers_.empty()); 508 DCHECK(!input_buffers_.empty());
513 509
514 curr_input_buffer_ = input_buffers_.front(); 510 curr_input_buffer_ = input_buffers_.front();
515 input_buffers_.pop(); 511 input_buffers_.pop();
516 512
517 DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id 513 DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id
518 << " size: " << curr_input_buffer_->shm->size(); 514 << " size: " << curr_input_buffer_->shm->size();
519 515
(...skipping 10 matching lines...) Expand all
530 } 526 }
531 527
532 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer_Locked() { 528 void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer_Locked() {
533 lock_.AssertAcquired(); 529 lock_.AssertAcquired();
534 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 530 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
535 DCHECK(curr_input_buffer_.get()); 531 DCHECK(curr_input_buffer_.get());
536 532
537 int32_t id = curr_input_buffer_->id; 533 int32_t id = curr_input_buffer_->id;
538 curr_input_buffer_.reset(); 534 curr_input_buffer_.reset();
539 DVLOG(4) << "End of input buffer " << id; 535 DVLOG(4) << "End of input buffer " << id;
540 message_loop_->PostTask(FROM_HERE, base::Bind( 536 message_loop_->PostTask(
541 &Client::NotifyEndOfBitstreamBuffer, client_, id)); 537 FROM_HERE, base::Bind(&Client::NotifyEndOfBitstreamBuffer, client_, id));
542 538
543 --num_stream_bufs_at_decoder_; 539 --num_stream_bufs_at_decoder_;
544 TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder", 540 TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder",
545 num_stream_bufs_at_decoder_); 541 num_stream_bufs_at_decoder_);
546 } 542 }
547 543
548 // TODO(posciak): refactor the whole class to remove sleeping in wait for 544 // TODO(posciak): refactor the whole class to remove sleeping in wait for
549 // surfaces, and reschedule DecodeTask instead. 545 // surfaces, and reschedule DecodeTask instead.
550 bool VaapiVideoDecodeAccelerator::WaitForSurfaces_Locked() { 546 bool VaapiVideoDecodeAccelerator::WaitForSurfaces_Locked() {
551 lock_.AssertAcquired(); 547 lock_.AssertAcquired();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 // This is the main decode function of the decoder and while keeping 581 // This is the main decode function of the decoder and while keeping
586 // the lock for its duration would be fine, it would defeat the purpose 582 // the lock for its duration would be fine, it would defeat the purpose
587 // of having a separate decoder thread. 583 // of having a separate decoder thread.
588 base::AutoUnlock auto_unlock(lock_); 584 base::AutoUnlock auto_unlock(lock_);
589 res = decoder_->Decode(); 585 res = decoder_->Decode();
590 } 586 }
591 587
592 switch (res) { 588 switch (res) {
593 case AcceleratedVideoDecoder::kAllocateNewSurfaces: 589 case AcceleratedVideoDecoder::kAllocateNewSurfaces:
594 DVLOG(1) << "Decoder requesting a new set of surfaces"; 590 DVLOG(1) << "Decoder requesting a new set of surfaces";
595 message_loop_->PostTask(FROM_HERE, base::Bind( 591 message_loop_->PostTask(
596 &VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange, weak_this_, 592 FROM_HERE,
597 decoder_->GetRequiredNumOfPictures(), 593 base::Bind(&VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange,
598 decoder_->GetPicSize())); 594 weak_this_, decoder_->GetRequiredNumOfPictures(),
595 decoder_->GetPicSize()));
599 // We'll get rescheduled once ProvidePictureBuffers() finishes. 596 // We'll get rescheduled once ProvidePictureBuffers() finishes.
600 return; 597 return;
601 598
602 case AcceleratedVideoDecoder::kRanOutOfStreamData: 599 case AcceleratedVideoDecoder::kRanOutOfStreamData:
603 ReturnCurrInputBuffer_Locked(); 600 ReturnCurrInputBuffer_Locked();
604 break; 601 break;
605 602
606 case AcceleratedVideoDecoder::kRanOutOfSurfaces: 603 case AcceleratedVideoDecoder::kRanOutOfSurfaces:
607 // No more output buffers in the decoder, try getting more or go to 604 // No more output buffers in the decoder, try getting more or go to
608 // sleep waiting for them. 605 // sleep waiting for them.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 644
648 if (!pending_output_cbs_.empty() || 645 if (!pending_output_cbs_.empty() ||
649 pictures_.size() != available_va_surfaces_.size()) { 646 pictures_.size() != available_va_surfaces_.size()) {
650 // Either: 647 // Either:
651 // 1. Not all pending pending output callbacks have been executed yet. 648 // 1. Not all pending pending output callbacks have been executed yet.
652 // Wait for the client to return enough pictures and retry later. 649 // Wait for the client to return enough pictures and retry later.
653 // 2. The above happened and all surface release callbacks have been posted 650 // 2. The above happened and all surface release callbacks have been posted
654 // as the result, but not all have executed yet. Post ourselves after them 651 // as the result, but not all have executed yet. Post ourselves after them
655 // to let them release surfaces. 652 // to let them release surfaces.
656 DVLOG(2) << "Awaiting pending output/surface release callbacks to finish"; 653 DVLOG(2) << "Awaiting pending output/surface release callbacks to finish";
657 message_loop_->PostTask(FROM_HERE, base::Bind( 654 message_loop_->PostTask(
658 &VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange, weak_this_)); 655 FROM_HERE,
656 base::Bind(&VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange,
657 weak_this_));
659 return; 658 return;
660 } 659 }
661 660
662 // All surfaces released, destroy them and dismiss all PictureBuffers. 661 // All surfaces released, destroy them and dismiss all PictureBuffers.
663 awaiting_va_surfaces_recycle_ = false; 662 awaiting_va_surfaces_recycle_ = false;
664 available_va_surfaces_.clear(); 663 available_va_surfaces_.clear();
665 vaapi_wrapper_->DestroySurfaces(); 664 vaapi_wrapper_->DestroySurfaces();
666 665
667 for (Pictures::iterator iter = pictures_.begin(); iter != pictures_.end(); 666 for (Pictures::iterator iter = pictures_.begin(); iter != pictures_.end();
668 ++iter) { 667 ++iter) {
669 DVLOG(2) << "Dismissing picture id: " << iter->first; 668 DVLOG(2) << "Dismissing picture id: " << iter->first;
670 if (client_) 669 if (client_)
671 client_->DismissPictureBuffer(iter->first); 670 client_->DismissPictureBuffer(iter->first);
672 } 671 }
673 pictures_.clear(); 672 pictures_.clear();
674 673
675 // And ask for a new set as requested. 674 // And ask for a new set as requested.
676 DVLOG(1) << "Requesting " << requested_num_pics_ << " pictures of size: " 675 DVLOG(1) << "Requesting " << requested_num_pics_
677 << requested_pic_size_.ToString(); 676 << " pictures of size: " << requested_pic_size_.ToString();
678 677
679 message_loop_->PostTask( 678 message_loop_->PostTask(
680 FROM_HERE, 679 FROM_HERE,
681 base::Bind(&Client::ProvidePictureBuffers, client_, requested_num_pics_, 680 base::Bind(&Client::ProvidePictureBuffers, client_, requested_num_pics_,
682 1, requested_pic_size_, VaapiPicture::GetGLTextureTarget())); 681 1, requested_pic_size_, VaapiPicture::GetGLTextureTarget()));
683 } 682 }
684 683
685 void VaapiVideoDecodeAccelerator::Decode( 684 void VaapiVideoDecodeAccelerator::Decode(
686 const media::BitstreamBuffer& bitstream_buffer) { 685 const media::BitstreamBuffer& bitstream_buffer) {
687 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 686 DCHECK_EQ(message_loop_, base::MessageLoop::current());
(...skipping 15 matching lines...) Expand all
703 base::AutoLock auto_lock(lock_); 702 base::AutoLock auto_lock(lock_);
704 switch (state_) { 703 switch (state_) {
705 case kIdle: 704 case kIdle:
706 state_ = kDecoding; 705 state_ = kDecoding;
707 decoder_thread_task_runner_->PostTask( 706 decoder_thread_task_runner_->PostTask(
708 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask, 707 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::DecodeTask,
709 base::Unretained(this))); 708 base::Unretained(this)));
710 break; 709 break;
711 710
712 case kDecoding: 711 case kDecoding:
713 // Decoder already running, fallthrough. 712 // Decoder already running, fallthrough.
714 case kResetting: 713 case kResetting:
715 // When resetting, allow accumulating bitstream buffers, so that 714 // When resetting, allow accumulating bitstream buffers, so that
716 // the client can queue after-seek-buffers while we are finishing with 715 // the client can queue after-seek-buffers while we are finishing with
717 // the before-seek one. 716 // the before-seek one.
718 break; 717 break;
719 718
720 default: 719 default:
721 RETURN_AND_NOTIFY_ON_FAILURE(false, 720 RETURN_AND_NOTIFY_ON_FAILURE(
722 "Decode request from client in invalid state: " << state_, 721 false, "Decode request from client in invalid state: " << state_,
723 PLATFORM_FAILURE, ); 722 PLATFORM_FAILURE, );
724 break; 723 break;
725 } 724 }
726 } 725 }
727 726
728 void VaapiVideoDecodeAccelerator::RecycleVASurfaceID( 727 void VaapiVideoDecodeAccelerator::RecycleVASurfaceID(
729 VASurfaceID va_surface_id) { 728 VASurfaceID va_surface_id) {
730 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 729 DCHECK_EQ(message_loop_, base::MessageLoop::current());
731 base::AutoLock auto_lock(lock_); 730 base::AutoLock auto_lock(lock_);
732 731
733 available_va_surfaces_.push_back(va_surface_id); 732 available_va_surfaces_.push_back(va_surface_id);
734 surfaces_available_.Signal(); 733 surfaces_available_.Signal();
735 } 734 }
736 735
737 void VaapiVideoDecodeAccelerator::AssignPictureBuffers( 736 void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
738 const std::vector<media::PictureBuffer>& buffers) { 737 const std::vector<media::PictureBuffer>& buffers) {
739 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 738 DCHECK_EQ(message_loop_, base::MessageLoop::current());
740 739
741 base::AutoLock auto_lock(lock_); 740 base::AutoLock auto_lock(lock_);
742 DCHECK(pictures_.empty()); 741 DCHECK(pictures_.empty());
743 742
744 while (!output_buffers_.empty()) 743 while (!output_buffers_.empty())
745 output_buffers_.pop(); 744 output_buffers_.pop();
746 745
747 RETURN_AND_NOTIFY_ON_FAILURE( 746 RETURN_AND_NOTIFY_ON_FAILURE(buffers.size() >= requested_num_pics_,
748 buffers.size() >= requested_num_pics_, 747 "Got an invalid number of picture buffers. (Got "
749 "Got an invalid number of picture buffers. (Got " << buffers.size() 748 << buffers.size() << ", requested "
750 << ", requested " << requested_num_pics_ << ")", INVALID_ARGUMENT, ); 749 << requested_num_pics_ << ")",
750 INVALID_ARGUMENT, );
751 DCHECK(requested_pic_size_ == buffers[0].size()); 751 DCHECK(requested_pic_size_ == buffers[0].size());
752 752
753 std::vector<VASurfaceID> va_surface_ids; 753 std::vector<VASurfaceID> va_surface_ids;
754 RETURN_AND_NOTIFY_ON_FAILURE( 754 RETURN_AND_NOTIFY_ON_FAILURE(
755 vaapi_wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420, requested_pic_size_, 755 vaapi_wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420, requested_pic_size_,
756 buffers.size(), &va_surface_ids), 756 buffers.size(), &va_surface_ids),
757 "Failed creating VA Surfaces", PLATFORM_FAILURE, ); 757 "Failed creating VA Surfaces", PLATFORM_FAILURE, );
758 DCHECK_EQ(va_surface_ids.size(), buffers.size()); 758 DCHECK_EQ(va_surface_ids.size(), buffers.size());
759 759
760 for (size_t i = 0; i < buffers.size(); ++i) { 760 for (size_t i = 0; i < buffers.size(); ++i) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 813
814 // First flush all the pictures that haven't been outputted, notifying the 814 // First flush all the pictures that haven't been outputted, notifying the
815 // client to output them. 815 // client to output them.
816 bool res = decoder_->Flush(); 816 bool res = decoder_->Flush();
817 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.", 817 RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.",
818 PLATFORM_FAILURE, ); 818 PLATFORM_FAILURE, );
819 819
820 // Put the decoder in idle state, ready to resume. 820 // Put the decoder in idle state, ready to resume.
821 decoder_->Reset(); 821 decoder_->Reset();
822 822
823 message_loop_->PostTask(FROM_HERE, base::Bind( 823 message_loop_->PostTask(
824 &VaapiVideoDecodeAccelerator::FinishFlush, weak_this_)); 824 FROM_HERE,
825 base::Bind(&VaapiVideoDecodeAccelerator::FinishFlush, weak_this_));
825 } 826 }
826 827
827 void VaapiVideoDecodeAccelerator::Flush() { 828 void VaapiVideoDecodeAccelerator::Flush() {
828 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 829 DCHECK_EQ(message_loop_, base::MessageLoop::current());
829 DVLOG(1) << "Got flush request"; 830 DVLOG(1) << "Got flush request";
830 831
831 base::AutoLock auto_lock(lock_); 832 base::AutoLock auto_lock(lock_);
832 state_ = kFlushing; 833 state_ = kFlushing;
833 // Queue a flush task after all existing decoding tasks to clean up. 834 // Queue a flush task after all existing decoding tasks to clean up.
834 decoder_thread_task_runner_->PostTask( 835 decoder_thread_task_runner_->PostTask(
(...skipping 17 matching lines...) Expand all
852 853
853 // Still waiting for textures from client to finish outputting all pending 854 // Still waiting for textures from client to finish outputting all pending
854 // frames. Try again later. 855 // frames. Try again later.
855 if (!pending_output_cbs_.empty()) { 856 if (!pending_output_cbs_.empty()) {
856 finish_flush_pending_ = true; 857 finish_flush_pending_ = true;
857 return; 858 return;
858 } 859 }
859 860
860 state_ = kIdle; 861 state_ = kIdle;
861 862
862 message_loop_->PostTask(FROM_HERE, base::Bind( 863 message_loop_->PostTask(FROM_HERE,
863 &Client::NotifyFlushDone, client_)); 864 base::Bind(&Client::NotifyFlushDone, client_));
864 865
865 DVLOG(1) << "Flush finished"; 866 DVLOG(1) << "Flush finished";
866 } 867 }
867 868
868 void VaapiVideoDecodeAccelerator::ResetTask() { 869 void VaapiVideoDecodeAccelerator::ResetTask() {
869 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 870 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
870 DVLOG(1) << "ResetTask"; 871 DVLOG(1) << "ResetTask";
871 872
872 // All the decoding tasks from before the reset request from client are done 873 // All the decoding tasks from before the reset request from client are done
873 // by now, as this task was scheduled after them and client is expected not 874 // by now, as this task was scheduled after them and client is expected not
874 // to call Decode() after Reset() and before NotifyResetDone. 875 // to call Decode() after Reset() and before NotifyResetDone.
875 decoder_->Reset(); 876 decoder_->Reset();
876 877
877 base::AutoLock auto_lock(lock_); 878 base::AutoLock auto_lock(lock_);
878 879
879 // Return current input buffer, if present. 880 // Return current input buffer, if present.
880 if (curr_input_buffer_.get()) 881 if (curr_input_buffer_.get())
881 ReturnCurrInputBuffer_Locked(); 882 ReturnCurrInputBuffer_Locked();
882 883
883 // And let client know that we are done with reset. 884 // And let client know that we are done with reset.
884 message_loop_->PostTask(FROM_HERE, base::Bind( 885 message_loop_->PostTask(
885 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); 886 FROM_HERE,
887 base::Bind(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
886 } 888 }
887 889
888 void VaapiVideoDecodeAccelerator::Reset() { 890 void VaapiVideoDecodeAccelerator::Reset() {
889 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 891 DCHECK_EQ(message_loop_, base::MessageLoop::current());
890 DVLOG(1) << "Got reset request"; 892 DVLOG(1) << "Got reset request";
891 893
892 // This will make any new decode tasks exit early. 894 // This will make any new decode tasks exit early.
893 base::AutoLock auto_lock(lock_); 895 base::AutoLock auto_lock(lock_);
894 state_ = kResetting; 896 state_ = kResetting;
895 finish_flush_pending_ = false; 897 finish_flush_pending_ = false;
896 898
897 // Drop all remaining input buffers, if present. 899 // Drop all remaining input buffers, if present.
898 while (!input_buffers_.empty()) { 900 while (!input_buffers_.empty()) {
899 message_loop_->PostTask(FROM_HERE, base::Bind( 901 message_loop_->PostTask(
900 &Client::NotifyEndOfBitstreamBuffer, client_, 902 FROM_HERE, base::Bind(&Client::NotifyEndOfBitstreamBuffer, client_,
901 input_buffers_.front()->id)); 903 input_buffers_.front()->id));
902 input_buffers_.pop(); 904 input_buffers_.pop();
903 } 905 }
904 906
905 decoder_thread_task_runner_->PostTask( 907 decoder_thread_task_runner_->PostTask(
906 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::ResetTask, 908 FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::ResetTask,
907 base::Unretained(this))); 909 base::Unretained(this)));
908 910
909 input_ready_.Signal(); 911 input_ready_.Signal();
910 surfaces_available_.Signal(); 912 surfaces_available_.Signal();
911 } 913 }
912 914
913 void VaapiVideoDecodeAccelerator::FinishReset() { 915 void VaapiVideoDecodeAccelerator::FinishReset() {
914 DCHECK_EQ(message_loop_, base::MessageLoop::current()); 916 DCHECK_EQ(message_loop_, base::MessageLoop::current());
915 DVLOG(1) << "FinishReset"; 917 DVLOG(1) << "FinishReset";
916 base::AutoLock auto_lock(lock_); 918 base::AutoLock auto_lock(lock_);
917 919
918 if (state_ != kResetting) { 920 if (state_ != kResetting) {
919 DCHECK(state_ == kDestroying || state_ == kUninitialized) << state_; 921 DCHECK(state_ == kDestroying || state_ == kUninitialized) << state_;
920 return; // We could've gotten destroyed already. 922 return; // We could've gotten destroyed already.
921 } 923 }
922 924
923 // Drop pending outputs. 925 // Drop pending outputs.
924 while (!pending_output_cbs_.empty()) 926 while (!pending_output_cbs_.empty())
925 pending_output_cbs_.pop(); 927 pending_output_cbs_.pop();
926 928
927 if (awaiting_va_surfaces_recycle_) { 929 if (awaiting_va_surfaces_recycle_) {
928 // Decoder requested a new surface set while we were waiting for it to 930 // Decoder requested a new surface set while we were waiting for it to
929 // finish the last DecodeTask, running at the time of Reset(). 931 // finish the last DecodeTask, running at the time of Reset().
930 // Let the surface set change finish first before resetting. 932 // Let the surface set change finish first before resetting.
931 message_loop_->PostTask(FROM_HERE, base::Bind( 933 message_loop_->PostTask(
932 &VaapiVideoDecodeAccelerator::FinishReset, weak_this_)); 934 FROM_HERE,
935 base::Bind(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
933 return; 936 return;
934 } 937 }
935 938
936 num_stream_bufs_at_decoder_ = 0; 939 num_stream_bufs_at_decoder_ = 0;
937 state_ = kIdle; 940 state_ = kIdle;
938 941
939 message_loop_->PostTask(FROM_HERE, base::Bind( 942 message_loop_->PostTask(FROM_HERE,
940 &Client::NotifyResetDone, client_)); 943 base::Bind(&Client::NotifyResetDone, client_));
941 944
942 // The client might have given us new buffers via Decode() while we were 945 // The client might have given us new buffers via Decode() while we were
943 // resetting and might be waiting for our move, and not call Decode() anymore 946 // resetting and might be waiting for our move, and not call Decode() anymore
944 // until we return something. Post a DecodeTask() so that we won't 947 // until we return something. Post a DecodeTask() so that we won't
945 // sleep forever waiting for Decode() in that case. Having two of them 948 // sleep forever waiting for Decode() in that case. Having two of them
946 // in the pipe is harmless, the additional one will return as soon as it sees 949 // in the pipe is harmless, the additional one will return as soon as it sees
947 // that we are back in kDecoding state. 950 // that we are back in kDecoding state.
948 if (!input_buffers_.empty()) { 951 if (!input_buffers_.empty()) {
949 state_ = kDecoding; 952 state_ = kDecoding;
950 decoder_thread_task_runner_->PostTask( 953 decoder_thread_task_runner_->PostTask(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 1053 }
1051 1054
1052 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::VaapiH264Accelerator( 1055 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::VaapiH264Accelerator(
1053 VaapiVideoDecodeAccelerator* vaapi_dec, 1056 VaapiVideoDecodeAccelerator* vaapi_dec,
1054 VaapiWrapper* vaapi_wrapper) 1057 VaapiWrapper* vaapi_wrapper)
1055 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) { 1058 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) {
1056 DCHECK(vaapi_wrapper_); 1059 DCHECK(vaapi_wrapper_);
1057 DCHECK(vaapi_dec_); 1060 DCHECK(vaapi_dec_);
1058 } 1061 }
1059 1062
1060 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::~VaapiH264Accelerator() { 1063 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::~VaapiH264Accelerator() {}
1061 }
1062 1064
1063 scoped_refptr<H264Picture> 1065 scoped_refptr<H264Picture>
1064 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::CreateH264Picture() { 1066 VaapiVideoDecodeAccelerator::VaapiH264Accelerator::CreateH264Picture() {
1065 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface(); 1067 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface();
1066 if (!va_surface) 1068 if (!va_surface)
1067 return nullptr; 1069 return nullptr;
1068 1070
1069 return new VaapiH264Picture(va_surface); 1071 return new VaapiH264Picture(va_surface);
1070 } 1072 }
1071 1073
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 for (int i = 0; i < 16; ++i) 1152 for (int i = 0; i < 16; ++i)
1151 InitVAPicture(&pic_param.ReferenceFrames[i]); 1153 InitVAPicture(&pic_param.ReferenceFrames[i]);
1152 1154
1153 // And fill it with picture info from DPB. 1155 // And fill it with picture info from DPB.
1154 FillVARefFramesFromDPB(dpb, pic_param.ReferenceFrames, 1156 FillVARefFramesFromDPB(dpb, pic_param.ReferenceFrames,
1155 arraysize(pic_param.ReferenceFrames)); 1157 arraysize(pic_param.ReferenceFrames));
1156 1158
1157 pic_param.num_ref_frames = sps->max_num_ref_frames; 1159 pic_param.num_ref_frames = sps->max_num_ref_frames;
1158 1160
1159 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, 1161 if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType,
1160 sizeof(pic_param), 1162 sizeof(pic_param), &pic_param))
1161 &pic_param))
1162 return false; 1163 return false;
1163 1164
1164 VAIQMatrixBufferH264 iq_matrix_buf; 1165 VAIQMatrixBufferH264 iq_matrix_buf;
1165 memset(&iq_matrix_buf, 0, sizeof(iq_matrix_buf)); 1166 memset(&iq_matrix_buf, 0, sizeof(iq_matrix_buf));
1166 1167
1167 if (pps->pic_scaling_matrix_present_flag) { 1168 if (pps->pic_scaling_matrix_present_flag) {
1168 for (int i = 0; i < 6; ++i) { 1169 for (int i = 0; i < 6; ++i) {
1169 for (int j = 0; j < 16; ++j) 1170 for (int j = 0; j < 16; ++j)
1170 iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j]; 1171 iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j];
1171 } 1172 }
1172 1173
1173 for (int i = 0; i < 2; ++i) { 1174 for (int i = 0; i < 2; ++i) {
1174 for (int j = 0; j < 64; ++j) 1175 for (int j = 0; j < 64; ++j)
1175 iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j]; 1176 iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j];
1176 } 1177 }
1177 } else { 1178 } else {
1178 for (int i = 0; i < 6; ++i) { 1179 for (int i = 0; i < 6; ++i) {
1179 for (int j = 0; j < 16; ++j) 1180 for (int j = 0; j < 16; ++j)
1180 iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j]; 1181 iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j];
1181 } 1182 }
1182 1183
1183 for (int i = 0; i < 2; ++i) { 1184 for (int i = 0; i < 2; ++i) {
1184 for (int j = 0; j < 64; ++j) 1185 for (int j = 0; j < 64; ++j)
1185 iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j]; 1186 iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j];
1186 } 1187 }
1187 } 1188 }
1188 1189
1189 return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, 1190 return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType,
1190 sizeof(iq_matrix_buf), 1191 sizeof(iq_matrix_buf), &iq_matrix_buf);
1191 &iq_matrix_buf);
1192 } 1192 }
1193 1193
1194 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitSlice( 1194 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitSlice(
1195 const media::H264PPS* pps, 1195 const media::H264PPS* pps,
1196 const media::H264SliceHeader* slice_hdr, 1196 const media::H264SliceHeader* slice_hdr,
1197 const H264Picture::Vector& ref_pic_list0, 1197 const H264Picture::Vector& ref_pic_list0,
1198 const H264Picture::Vector& ref_pic_list1, 1198 const H264Picture::Vector& ref_pic_list1,
1199 const scoped_refptr<H264Picture>& pic, 1199 const scoped_refptr<H264Picture>& pic,
1200 const uint8_t* data, 1200 const uint8_t* data,
1201 size_t size) { 1201 size_t size) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 FillVAPicture(&slice_param.RefPicList0[i], ref_pic_list0[i]); 1281 FillVAPicture(&slice_param.RefPicList0[i], ref_pic_list0[i]);
1282 } 1282 }
1283 for (size_t i = 0; 1283 for (size_t i = 0;
1284 i < ref_pic_list1.size() && i < arraysize(slice_param.RefPicList1); 1284 i < ref_pic_list1.size() && i < arraysize(slice_param.RefPicList1);
1285 ++i) { 1285 ++i) {
1286 if (ref_pic_list1[i]) 1286 if (ref_pic_list1[i])
1287 FillVAPicture(&slice_param.RefPicList1[i], ref_pic_list1[i]); 1287 FillVAPicture(&slice_param.RefPicList1[i], ref_pic_list1[i]);
1288 } 1288 }
1289 1289
1290 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, 1290 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType,
1291 sizeof(slice_param), 1291 sizeof(slice_param), &slice_param))
1292 &slice_param))
1293 return false; 1292 return false;
1294 1293
1295 // Can't help it, blame libva... 1294 // Can't help it, blame libva...
1296 void* non_const_ptr = const_cast<uint8_t*>(data); 1295 void* non_const_ptr = const_cast<uint8_t*>(data);
1297 return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size, 1296 return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size,
1298 non_const_ptr); 1297 non_const_ptr);
1299 } 1298 }
1300 1299
1301 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitDecode( 1300 bool VaapiVideoDecodeAccelerator::VaapiH264Accelerator::SubmitDecode(
1302 const scoped_refptr<H264Picture>& pic) { 1301 const scoped_refptr<H264Picture>& pic) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 } 1382 }
1384 1383
1385 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::VaapiVP8Accelerator( 1384 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::VaapiVP8Accelerator(
1386 VaapiVideoDecodeAccelerator* vaapi_dec, 1385 VaapiVideoDecodeAccelerator* vaapi_dec,
1387 VaapiWrapper* vaapi_wrapper) 1386 VaapiWrapper* vaapi_wrapper)
1388 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) { 1387 : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) {
1389 DCHECK(vaapi_wrapper_); 1388 DCHECK(vaapi_wrapper_);
1390 DCHECK(vaapi_dec_); 1389 DCHECK(vaapi_dec_);
1391 } 1390 }
1392 1391
1393 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::~VaapiVP8Accelerator() { 1392 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::~VaapiVP8Accelerator() {}
1394 }
1395 1393
1396 scoped_refptr<VP8Picture> 1394 scoped_refptr<VP8Picture>
1397 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::CreateVP8Picture() { 1395 VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::CreateVP8Picture() {
1398 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface(); 1396 scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface();
1399 if (!va_surface) 1397 if (!va_surface)
1400 return nullptr; 1398 return nullptr;
1401 1399
1402 return new VaapiVP8Picture(va_surface); 1400 return new VaapiVP8Picture(va_surface);
1403 } 1401 }
1404 1402
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 "incorrect quantization matrix size"); 1437 "incorrect quantization matrix size");
1440 iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q); 1438 iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q);
1441 iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta); 1439 iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta);
1442 iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta); 1440 iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta);
1443 iq_matrix_buf.quantization_index[i][3] = CLAMP_Q(q + quant_hdr.y2_ac_delta); 1441 iq_matrix_buf.quantization_index[i][3] = CLAMP_Q(q + quant_hdr.y2_ac_delta);
1444 iq_matrix_buf.quantization_index[i][4] = CLAMP_Q(q + quant_hdr.uv_dc_delta); 1442 iq_matrix_buf.quantization_index[i][4] = CLAMP_Q(q + quant_hdr.uv_dc_delta);
1445 iq_matrix_buf.quantization_index[i][5] = CLAMP_Q(q + quant_hdr.uv_ac_delta); 1443 iq_matrix_buf.quantization_index[i][5] = CLAMP_Q(q + quant_hdr.uv_ac_delta);
1446 #undef CLAMP_Q 1444 #undef CLAMP_Q
1447 } 1445 }
1448 1446
1449 if (!vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, 1447 if (!vaapi_wrapper_->SubmitBuffer(
1450 sizeof(VAIQMatrixBufferVP8), 1448 VAIQMatrixBufferType, sizeof(VAIQMatrixBufferVP8), &iq_matrix_buf))
1451 &iq_matrix_buf))
1452 return false; 1449 return false;
1453 1450
1454 VAProbabilityDataBufferVP8 prob_buf; 1451 VAProbabilityDataBufferVP8 prob_buf;
1455 memset(&prob_buf, 0, sizeof(VAProbabilityDataBufferVP8)); 1452 memset(&prob_buf, 0, sizeof(VAProbabilityDataBufferVP8));
1456 1453
1457 const media::Vp8EntropyHeader& entr_hdr = frame_hdr->entropy_hdr; 1454 const media::Vp8EntropyHeader& entr_hdr = frame_hdr->entropy_hdr;
1458 ARRAY_MEMCPY_CHECKED(prob_buf.dct_coeff_probs, entr_hdr.coeff_probs); 1455 ARRAY_MEMCPY_CHECKED(prob_buf.dct_coeff_probs, entr_hdr.coeff_probs);
1459 1456
1460 if (!vaapi_wrapper_->SubmitBuffer(VAProbabilityBufferType, 1457 if (!vaapi_wrapper_->SubmitBuffer(VAProbabilityBufferType,
1461 sizeof(VAProbabilityDataBufferVP8), 1458 sizeof(VAProbabilityDataBufferVP8),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 lf_level = sgmnt_hdr.lf_update_value[i]; 1523 lf_level = sgmnt_hdr.lf_update_value[i];
1527 else 1524 else
1528 lf_level += sgmnt_hdr.lf_update_value[i]; 1525 lf_level += sgmnt_hdr.lf_update_value[i];
1529 } 1526 }
1530 1527
1531 // Clamp to [0..63] range. 1528 // Clamp to [0..63] range.
1532 lf_level = std::min(std::max(lf_level, 0), 63); 1529 lf_level = std::min(std::max(lf_level, 0), 63);
1533 pic_param.loop_filter_level[i] = lf_level; 1530 pic_param.loop_filter_level[i] = lf_level;
1534 } 1531 }
1535 1532
1536 static_assert(arraysize(lf_hdr.ref_frame_delta) == 1533 static_assert(
1537 arraysize(pic_param.loop_filter_deltas_ref_frame) && 1534 arraysize(lf_hdr.ref_frame_delta) ==
1538 arraysize(lf_hdr.mb_mode_delta) == 1535 arraysize(pic_param.loop_filter_deltas_ref_frame) &&
1539 arraysize(pic_param.loop_filter_deltas_mode) && 1536 arraysize(lf_hdr.mb_mode_delta) ==
1540 arraysize(lf_hdr.ref_frame_delta) == 1537 arraysize(pic_param.loop_filter_deltas_mode) &&
1541 arraysize(lf_hdr.mb_mode_delta), 1538 arraysize(lf_hdr.ref_frame_delta) == arraysize(lf_hdr.mb_mode_delta),
1542 "loop filter deltas arrays size mismatch"); 1539 "loop filter deltas arrays size mismatch");
1543 for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) { 1540 for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) {
1544 pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i]; 1541 pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i];
1545 pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i]; 1542 pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i];
1546 } 1543 }
1547 1544
1548 #define FHDR_TO_PP(a) pic_param.a = frame_hdr->a 1545 #define FHDR_TO_PP(a) pic_param.a = frame_hdr->a
1549 FHDR_TO_PP(prob_skip_false); 1546 FHDR_TO_PP(prob_skip_false);
1550 FHDR_TO_PP(prob_intra); 1547 FHDR_TO_PP(prob_intra);
1551 FHDR_TO_PP(prob_last); 1548 FHDR_TO_PP(prob_last);
1552 FHDR_TO_PP(prob_gf); 1549 FHDR_TO_PP(prob_gf);
(...skipping 28 matching lines...) Expand all
1581 for (size_t i = 0; i < frame_hdr->num_of_dct_partitions; ++i) 1578 for (size_t i = 0; i < frame_hdr->num_of_dct_partitions; ++i)
1582 slice_param.partition_size[i + 1] = frame_hdr->dct_partition_sizes[i]; 1579 slice_param.partition_size[i + 1] = frame_hdr->dct_partition_sizes[i];
1583 1580
1584 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, 1581 if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType,
1585 sizeof(VASliceParameterBufferVP8), 1582 sizeof(VASliceParameterBufferVP8),
1586 &slice_param)) 1583 &slice_param))
1587 return false; 1584 return false;
1588 1585
1589 void* non_const_ptr = const_cast<uint8_t*>(frame_hdr->data); 1586 void* non_const_ptr = const_cast<uint8_t*>(frame_hdr->data);
1590 if (!vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, 1587 if (!vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType,
1591 frame_hdr->frame_size, 1588 frame_hdr->frame_size, non_const_ptr))
1592 non_const_ptr))
1593 return false; 1589 return false;
1594 1590
1595 scoped_refptr<VaapiDecodeSurface> dec_surface = 1591 scoped_refptr<VaapiDecodeSurface> dec_surface =
1596 VP8PictureToVaapiDecodeSurface(pic); 1592 VP8PictureToVaapiDecodeSurface(pic);
1597 1593
1598 return vaapi_dec_->DecodeSurface(dec_surface); 1594 return vaapi_dec_->DecodeSurface(dec_surface);
1599 } 1595 }
1600 1596
1601 bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::OutputPicture( 1597 bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::OutputPicture(
1602 const scoped_refptr<VP8Picture>& pic) { 1598 const scoped_refptr<VP8Picture>& pic) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 CHECK(vaapi_pic); 1766 CHECK(vaapi_pic);
1771 return vaapi_pic->dec_surface(); 1767 return vaapi_pic->dec_surface();
1772 } 1768 }
1773 1769
1774 // static 1770 // static
1775 media::VideoDecodeAccelerator::SupportedProfiles 1771 media::VideoDecodeAccelerator::SupportedProfiles
1776 VaapiVideoDecodeAccelerator::GetSupportedProfiles() { 1772 VaapiVideoDecodeAccelerator::GetSupportedProfiles() {
1777 return VaapiWrapper::GetSupportedDecodeProfiles(); 1773 return VaapiWrapper::GetSupportedDecodeProfiles();
1778 } 1774 }
1779 1775
1780 } // namespace content 1776 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/vaapi_video_decode_accelerator.h ('k') | media/gpu/vaapi_video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698