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

Side by Side Diff: content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc

Issue 1134113002: content/common: Remove use of MessageLoopProxy and deprecated MessageLoop APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Android build fix. Created 5 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <fcntl.h> 5 #include <fcntl.h>
6 #include <linux/videodev2.h> 6 #include <linux/videodev2.h>
7 #include <poll.h> 7 #include <poll.h>
8 #include <sys/eventfd.h> 8 #include <sys/eventfd.h>
9 #include <sys/ioctl.h> 9 #include <sys/ioctl.h>
10 #include <sys/mman.h> 10 #include <sys/mman.h>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/message_loop/message_loop_proxy.h"
18 #include "base/numerics/safe_conversions.h" 17 #include "base/numerics/safe_conversions.h"
19 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
20 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" 19 #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h"
21 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/media_switches.h" 21 #include "media/base/media_switches.h"
23 #include "ui/gl/scoped_binders.h" 22 #include "ui/gl/scoped_binders.h"
24 23
25 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " 24 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): "
26 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): " 25 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): "
27 26
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 at_client(false), 154 at_client(false),
156 picture_id(-1), 155 picture_id(-1),
157 egl_image(EGL_NO_IMAGE_KHR), 156 egl_image(EGL_NO_IMAGE_KHR),
158 egl_sync(EGL_NO_SYNC_KHR), 157 egl_sync(EGL_NO_SYNC_KHR),
159 cleared(false) { 158 cleared(false) {
160 } 159 }
161 160
162 struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef { 161 struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef {
163 BitstreamBufferRef( 162 BitstreamBufferRef(
164 base::WeakPtr<VideoDecodeAccelerator::Client>& client, 163 base::WeakPtr<VideoDecodeAccelerator::Client>& client,
165 const scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, 164 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
166 base::SharedMemory* shm, 165 base::SharedMemory* shm,
167 size_t size, 166 size_t size,
168 int32 input_id); 167 int32 input_id);
169 ~BitstreamBufferRef(); 168 ~BitstreamBufferRef();
170 const base::WeakPtr<VideoDecodeAccelerator::Client> client; 169 const base::WeakPtr<VideoDecodeAccelerator::Client> client;
171 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy; 170 const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner;
172 const scoped_ptr<base::SharedMemory> shm; 171 const scoped_ptr<base::SharedMemory> shm;
173 const size_t size; 172 const size_t size;
174 off_t bytes_used; 173 off_t bytes_used;
175 const int32 input_id; 174 const int32 input_id;
176 }; 175 };
177 176
178 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( 177 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef(
179 base::WeakPtr<VideoDecodeAccelerator::Client>& client, 178 base::WeakPtr<VideoDecodeAccelerator::Client>& client,
180 const scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, 179 const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
181 base::SharedMemory* shm, 180 base::SharedMemory* shm,
182 size_t size, 181 size_t size,
183 int32 input_id) 182 int32 input_id)
184 : client(client), 183 : client(client),
185 client_message_loop_proxy(client_message_loop_proxy), 184 client_task_runner(client_task_runner),
186 shm(shm), 185 shm(shm),
187 size(size), 186 size(size),
188 bytes_used(0), 187 bytes_used(0),
189 input_id(input_id) { 188 input_id(input_id) {
190 } 189 }
191 190
192 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 191 V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
193 if (input_id >= 0) { 192 if (input_id >= 0) {
194 DVLOGF(5) << "returning input_id: " << input_id; 193 DVLOGF(5) << "returning input_id: " << input_id;
195 client_message_loop_proxy->PostTask( 194 client_task_runner->PostTask(
196 FROM_HERE, 195 FROM_HERE,
197 base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, 196 base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer,
198 client, input_id)); 197 client, input_id));
199 } 198 }
200 } 199 }
201 200
202 struct V4L2SliceVideoDecodeAccelerator::EGLSyncKHRRef { 201 struct V4L2SliceVideoDecodeAccelerator::EGLSyncKHRRef {
203 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); 202 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync);
204 ~EGLSyncKHRRef(); 203 ~EGLSyncKHRRef();
205 EGLDisplay const egl_display; 204 EGLDisplay const egl_display;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 372
374 V4L2VP8Picture::~V4L2VP8Picture() { 373 V4L2VP8Picture::~V4L2VP8Picture() {
375 } 374 }
376 375
377 V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator( 376 V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator(
378 const scoped_refptr<V4L2Device>& device, 377 const scoped_refptr<V4L2Device>& device,
379 EGLDisplay egl_display, 378 EGLDisplay egl_display,
380 EGLContext egl_context, 379 EGLContext egl_context,
381 const base::WeakPtr<Client>& io_client, 380 const base::WeakPtr<Client>& io_client,
382 const base::Callback<bool(void)>& make_context_current, 381 const base::Callback<bool(void)>& make_context_current,
383 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) 382 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
384 : input_planes_count_(0), 383 : input_planes_count_(0),
385 output_planes_count_(0), 384 output_planes_count_(0),
386 child_message_loop_proxy_(base::MessageLoopProxy::current()), 385 child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
387 io_message_loop_proxy_(io_message_loop_proxy), 386 io_task_runner_(io_task_runner),
388 io_client_(io_client), 387 io_client_(io_client),
389 device_(device), 388 device_(device),
390 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"), 389 decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"),
391 device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"), 390 device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"),
392 input_streamon_(false), 391 input_streamon_(false),
393 input_buffer_queued_count_(0), 392 input_buffer_queued_count_(0),
394 output_streamon_(false), 393 output_streamon_(false),
395 output_buffer_queued_count_(0), 394 output_buffer_queued_count_(0),
396 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), 395 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
397 output_format_fourcc_(0), 396 output_format_fourcc_(0),
398 state_(kUninitialized), 397 state_(kUninitialized),
399 decoder_flushing_(false), 398 decoder_flushing_(false),
400 decoder_resetting_(false), 399 decoder_resetting_(false),
401 surface_set_change_pending_(false), 400 surface_set_change_pending_(false),
402 picture_clearing_count_(0), 401 picture_clearing_count_(0),
403 pictures_assigned_(false, false), 402 pictures_assigned_(false, false),
404 make_context_current_(make_context_current), 403 make_context_current_(make_context_current),
405 egl_display_(egl_display), 404 egl_display_(egl_display),
406 egl_context_(egl_context), 405 egl_context_(egl_context),
407 weak_this_factory_(this) { 406 weak_this_factory_(this) {
408 weak_this_ = weak_this_factory_.GetWeakPtr(); 407 weak_this_ = weak_this_factory_.GetWeakPtr();
409 } 408 }
410 409
411 V4L2SliceVideoDecodeAccelerator::~V4L2SliceVideoDecodeAccelerator() { 410 V4L2SliceVideoDecodeAccelerator::~V4L2SliceVideoDecodeAccelerator() {
412 DVLOGF(2); 411 DVLOGF(2);
413 412
414 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 413 DCHECK(child_task_runner_->BelongsToCurrentThread());
415 DCHECK(!decoder_thread_.IsRunning()); 414 DCHECK(!decoder_thread_.IsRunning());
416 DCHECK(!device_poll_thread_.IsRunning()); 415 DCHECK(!device_poll_thread_.IsRunning());
417 416
418 DCHECK(input_buffer_map_.empty()); 417 DCHECK(input_buffer_map_.empty());
419 DCHECK(output_buffer_map_.empty()); 418 DCHECK(output_buffer_map_.empty());
420 } 419 }
421 420
422 void V4L2SliceVideoDecodeAccelerator::NotifyError(Error error) { 421 void V4L2SliceVideoDecodeAccelerator::NotifyError(Error error) {
423 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { 422 if (!child_task_runner_->BelongsToCurrentThread()) {
424 child_message_loop_proxy_->PostTask( 423 child_task_runner_->PostTask(
425 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::NotifyError, 424 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::NotifyError,
426 weak_this_, error)); 425 weak_this_, error));
427 return; 426 return;
428 } 427 }
429 428
430 if (client_) { 429 if (client_) {
431 client_->NotifyError(error); 430 client_->NotifyError(error);
432 client_ptr_factory_.reset(); 431 client_ptr_factory_.reset();
433 } 432 }
434 } 433 }
435 434
436 bool V4L2SliceVideoDecodeAccelerator::Initialize( 435 bool V4L2SliceVideoDecodeAccelerator::Initialize(
437 media::VideoCodecProfile profile, 436 media::VideoCodecProfile profile,
438 VideoDecodeAccelerator::Client* client) { 437 VideoDecodeAccelerator::Client* client) {
439 DVLOGF(3) << "profile: " << profile; 438 DVLOGF(3) << "profile: " << profile;
440 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 439 DCHECK(child_task_runner_->BelongsToCurrentThread());
441 DCHECK_EQ(state_, kUninitialized); 440 DCHECK_EQ(state_, kUninitialized);
442 441
443 client_ptr_factory_.reset( 442 client_ptr_factory_.reset(
444 new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client)); 443 new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client));
445 client_ = client_ptr_factory_->GetWeakPtr(); 444 client_ = client_ptr_factory_->GetWeakPtr();
446 445
447 video_profile_ = profile; 446 video_profile_ = profile;
448 447
449 if (video_profile_ >= media::H264PROFILE_MIN && 448 if (video_profile_ >= media::H264PROFILE_MIN &&
450 video_profile_ <= media::H264PROFILE_MAX) { 449 video_profile_ <= media::H264PROFILE_MAX) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 return false; 491 return false;
493 } 492 }
494 493
495 if (!SetupFormats()) 494 if (!SetupFormats())
496 return false; 495 return false;
497 496
498 if (!decoder_thread_.Start()) { 497 if (!decoder_thread_.Start()) {
499 DLOG(ERROR) << "Initialize(): device thread failed to start"; 498 DLOG(ERROR) << "Initialize(): device thread failed to start";
500 return false; 499 return false;
501 } 500 }
502 decoder_thread_proxy_ = decoder_thread_.message_loop_proxy(); 501 decoder_thread_proxy_ = decoder_thread_.task_runner();
no sievers 2015/05/12 18:11:30 nit: consider renaming |decoder_thread_proxy_|
Sami 2015/05/13 18:17:52 Done.
503 502
504 state_ = kInitialized; 503 state_ = kInitialized;
505 504
506 // InitializeTask will NOTIFY_ERROR on failure. 505 // InitializeTask will NOTIFY_ERROR on failure.
507 decoder_thread_proxy_->PostTask( 506 decoder_thread_proxy_->PostTask(
508 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::InitializeTask, 507 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::InitializeTask,
509 base::Unretained(this))); 508 base::Unretained(this)));
510 509
511 DVLOGF(1) << "V4L2SliceVideoDecodeAccelerator initialized"; 510 DVLOGF(1) << "V4L2SliceVideoDecodeAccelerator initialized";
512 return true; 511 return true;
513 } 512 }
514 513
515 void V4L2SliceVideoDecodeAccelerator::InitializeTask() { 514 void V4L2SliceVideoDecodeAccelerator::InitializeTask() {
516 DVLOGF(3); 515 DVLOGF(3);
517 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 516 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
518 DCHECK_EQ(state_, kInitialized); 517 DCHECK_EQ(state_, kInitialized);
519 518
520 if (!CreateInputBuffers()) 519 if (!CreateInputBuffers())
521 NOTIFY_ERROR(PLATFORM_FAILURE); 520 NOTIFY_ERROR(PLATFORM_FAILURE);
522 521
523 // Output buffers will be created once decoder gives us information 522 // Output buffers will be created once decoder gives us information
524 // about their size and required count. 523 // about their size and required count.
525 state_ = kDecoding; 524 state_ = kDecoding;
526 } 525 }
527 526
528 void V4L2SliceVideoDecodeAccelerator::Destroy() { 527 void V4L2SliceVideoDecodeAccelerator::Destroy() {
529 DVLOGF(3); 528 DVLOGF(3);
530 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 529 DCHECK(child_task_runner_->BelongsToCurrentThread());
531 530
532 if (decoder_thread_.IsRunning()) { 531 if (decoder_thread_.IsRunning()) {
533 decoder_thread_proxy_->PostTask( 532 decoder_thread_proxy_->PostTask(
534 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DestroyTask, 533 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DestroyTask,
535 base::Unretained(this))); 534 base::Unretained(this)));
536 535
537 // Wait for tasks to finish/early-exit. 536 // Wait for tasks to finish/early-exit.
538 decoder_thread_.Stop(); 537 decoder_thread_.Stop();
539 } 538 }
540 539
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 PLOG(ERROR) << "Could not allocate enough output buffers"; 716 PLOG(ERROR) << "Could not allocate enough output buffers";
718 return false; 717 return false;
719 } 718 }
720 719
721 output_buffer_map_.resize(reqbufs.count); 720 output_buffer_map_.resize(reqbufs.count);
722 721
723 DVLOGF(3) << "buffer_count=" << output_buffer_map_.size() 722 DVLOGF(3) << "buffer_count=" << output_buffer_map_.size()
724 << ", visible size=" << visible_size_.ToString() 723 << ", visible size=" << visible_size_.ToString()
725 << ", coded size=" << coded_size_.ToString(); 724 << ", coded size=" << coded_size_.ToString();
726 725
727 child_message_loop_proxy_->PostTask( 726 child_task_runner_->PostTask(
728 FROM_HERE, 727 FROM_HERE,
729 base::Bind(&VideoDecodeAccelerator::Client::ProvidePictureBuffers, 728 base::Bind(&VideoDecodeAccelerator::Client::ProvidePictureBuffers,
730 client_, output_buffer_map_.size(), coded_size_, 729 client_, output_buffer_map_.size(), coded_size_,
731 device_->GetTextureTarget())); 730 device_->GetTextureTarget()));
732 731
733 // Wait for the client to call AssignPictureBuffers() on the Child thread. 732 // Wait for the client to call AssignPictureBuffers() on the Child thread.
734 // We do this, because if we continue decoding without finishing buffer 733 // We do this, because if we continue decoding without finishing buffer
735 // allocation, we may end up Resetting before AssignPictureBuffers arrives, 734 // allocation, we may end up Resetting before AssignPictureBuffers arrives,
736 // resulting in unnecessary complications and subtle bugs. 735 // resulting in unnecessary complications and subtle bugs.
737 pictures_assigned_.Wait(); 736 pictures_assigned_.Wait();
(...skipping 20 matching lines...) Expand all
758 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 757 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
759 758
760 input_buffer_map_.clear(); 759 input_buffer_map_.clear();
761 free_input_buffers_.clear(); 760 free_input_buffers_.clear();
762 } 761 }
763 762
764 void V4L2SliceVideoDecodeAccelerator::DismissPictures( 763 void V4L2SliceVideoDecodeAccelerator::DismissPictures(
765 std::vector<int32> picture_buffer_ids, 764 std::vector<int32> picture_buffer_ids,
766 base::WaitableEvent* done) { 765 base::WaitableEvent* done) {
767 DVLOGF(3); 766 DVLOGF(3);
768 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 767 DCHECK(child_task_runner_->BelongsToCurrentThread());
769 768
770 for (auto picture_buffer_id : picture_buffer_ids) { 769 for (auto picture_buffer_id : picture_buffer_ids) {
771 DVLOGF(1) << "dismissing PictureBuffer id=" << picture_buffer_id; 770 DVLOGF(1) << "dismissing PictureBuffer id=" << picture_buffer_id;
772 client_->DismissPictureBuffer(picture_buffer_id); 771 client_->DismissPictureBuffer(picture_buffer_id);
773 } 772 }
774 773
775 done->Signal(); 774 done->Signal();
776 } 775 }
777 776
778 void V4L2SliceVideoDecodeAccelerator::DevicePollTask(bool poll_device) { 777 void V4L2SliceVideoDecodeAccelerator::DevicePollTask(bool poll_device) {
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 decoder_display_queue_.pop(); 1151 decoder_display_queue_.pop();
1153 1152
1154 DVLOGF(3) << "Device poll stopped"; 1153 DVLOGF(3) << "Device poll stopped";
1155 return true; 1154 return true;
1156 } 1155 }
1157 1156
1158 void V4L2SliceVideoDecodeAccelerator::Decode( 1157 void V4L2SliceVideoDecodeAccelerator::Decode(
1159 const media::BitstreamBuffer& bitstream_buffer) { 1158 const media::BitstreamBuffer& bitstream_buffer) {
1160 DVLOGF(3) << "input_id=" << bitstream_buffer.id() 1159 DVLOGF(3) << "input_id=" << bitstream_buffer.id()
1161 << ", size=" << bitstream_buffer.size(); 1160 << ", size=" << bitstream_buffer.size();
1162 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 1161 DCHECK(io_task_runner_->BelongsToCurrentThread());
1163 1162
1164 decoder_thread_proxy_->PostTask( 1163 decoder_thread_proxy_->PostTask(
1165 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DecodeTask, 1164 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DecodeTask,
1166 base::Unretained(this), bitstream_buffer)); 1165 base::Unretained(this), bitstream_buffer));
1167 } 1166 }
1168 1167
1169 void V4L2SliceVideoDecodeAccelerator::DecodeTask( 1168 void V4L2SliceVideoDecodeAccelerator::DecodeTask(
1170 const media::BitstreamBuffer& bitstream_buffer) { 1169 const media::BitstreamBuffer& bitstream_buffer) {
1171 DVLOGF(3) << "input_id=" << bitstream_buffer.id() 1170 DVLOGF(3) << "input_id=" << bitstream_buffer.id()
1172 << " size=" << bitstream_buffer.size(); 1171 << " size=" << bitstream_buffer.size();
1173 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 1172 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
1174 1173
1175 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 1174 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
1176 io_client_, io_message_loop_proxy_, 1175 io_client_, io_task_runner_,
1177 new base::SharedMemory(bitstream_buffer.handle(), true), 1176 new base::SharedMemory(bitstream_buffer.handle(), true),
1178 bitstream_buffer.size(), bitstream_buffer.id())); 1177 bitstream_buffer.size(), bitstream_buffer.id()));
1179 if (!bitstream_record->shm->Map(bitstream_buffer.size())) { 1178 if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
1180 LOGF(ERROR) << "Could not map bitstream_buffer"; 1179 LOGF(ERROR) << "Could not map bitstream_buffer";
1181 NOTIFY_ERROR(UNREADABLE_INPUT); 1180 NOTIFY_ERROR(UNREADABLE_INPUT);
1182 return; 1181 return;
1183 } 1182 }
1184 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); 1183 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory();
1185 1184
1186 decoder_input_queue_.push( 1185 decoder_input_queue_.push(
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 1332
1334 for (auto output_record : output_buffer_map_) { 1333 for (auto output_record : output_buffer_map_) {
1335 DCHECK(!output_record.at_device); 1334 DCHECK(!output_record.at_device);
1336 1335
1337 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { 1336 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1338 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) 1337 if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE)
1339 DVLOGF(1) << "eglDestroySyncKHR failed."; 1338 DVLOGF(1) << "eglDestroySyncKHR failed.";
1340 } 1339 }
1341 1340
1342 if (output_record.egl_image != EGL_NO_IMAGE_KHR) { 1341 if (output_record.egl_image != EGL_NO_IMAGE_KHR) {
1343 child_message_loop_proxy_->PostTask( 1342 child_task_runner_->PostTask(
1344 FROM_HERE, 1343 FROM_HERE,
1345 base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage), device_, 1344 base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage), device_,
1346 egl_display_, output_record.egl_image)); 1345 egl_display_, output_record.egl_image));
1347 } 1346 }
1348 1347
1349 picture_buffers_to_dismiss.push_back(output_record.picture_id); 1348 picture_buffers_to_dismiss.push_back(output_record.picture_id);
1350 } 1349 }
1351 1350
1352 if (dismiss) { 1351 if (dismiss) {
1353 DVLOGF(2) << "Scheduling picture dismissal"; 1352 DVLOGF(2) << "Scheduling picture dismissal";
1354 base::WaitableEvent done(false, false); 1353 base::WaitableEvent done(false, false);
1355 child_message_loop_proxy_->PostTask( 1354 child_task_runner_->PostTask(
1356 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DismissPictures, 1355 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DismissPictures,
1357 weak_this_, picture_buffers_to_dismiss, &done)); 1356 weak_this_, picture_buffers_to_dismiss, &done));
1358 done.Wait(); 1357 done.Wait();
1359 } 1358 }
1360 1359
1361 // At this point client can't call ReusePictureBuffer on any of the pictures 1360 // At this point client can't call ReusePictureBuffer on any of the pictures
1362 // anymore, so it's safe to destroy. 1361 // anymore, so it's safe to destroy.
1363 return DestroyOutputBuffers(); 1362 return DestroyOutputBuffers();
1364 } 1363 }
1365 1364
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1399 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1401 reqbufs.memory = V4L2_MEMORY_MMAP; 1400 reqbufs.memory = V4L2_MEMORY_MMAP;
1402 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); 1401 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
1403 1402
1404 return true; 1403 return true;
1405 } 1404 }
1406 1405
1407 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers( 1406 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers(
1408 const std::vector<media::PictureBuffer>& buffers) { 1407 const std::vector<media::PictureBuffer>& buffers) {
1409 DVLOGF(3); 1408 DVLOGF(3);
1410 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1409 DCHECK(child_task_runner_->BelongsToCurrentThread());
1411 1410
1412 if (buffers.size() != output_buffer_map_.size()) { 1411 if (buffers.size() != output_buffer_map_.size()) {
1413 DLOG(ERROR) << "Failed to provide requested picture buffers. " 1412 DLOG(ERROR) << "Failed to provide requested picture buffers. "
1414 << "(Got " << buffers.size() 1413 << "(Got " << buffers.size()
1415 << ", requested " << output_buffer_map_.size() << ")"; 1414 << ", requested " << output_buffer_map_.size() << ")";
1416 NOTIFY_ERROR(INVALID_ARGUMENT); 1415 NOTIFY_ERROR(INVALID_ARGUMENT);
1417 return; 1416 return;
1418 } 1417 }
1419 1418
1420 if (!make_context_current_.Run()) { 1419 if (!make_context_current_.Run()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 output_record.picture_id = buffers[i].id(); 1458 output_record.picture_id = buffers[i].id();
1460 free_output_buffers_.push_back(i); 1459 free_output_buffers_.push_back(i);
1461 DVLOGF(3) << "buffer[" << i << "]: picture_id=" << output_record.picture_id; 1460 DVLOGF(3) << "buffer[" << i << "]: picture_id=" << output_record.picture_id;
1462 } 1461 }
1463 1462
1464 pictures_assigned_.Signal(); 1463 pictures_assigned_.Signal();
1465 } 1464 }
1466 1465
1467 void V4L2SliceVideoDecodeAccelerator::ReusePictureBuffer( 1466 void V4L2SliceVideoDecodeAccelerator::ReusePictureBuffer(
1468 int32 picture_buffer_id) { 1467 int32 picture_buffer_id) {
1469 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1468 DCHECK(child_task_runner_->BelongsToCurrentThread());
1470 DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id; 1469 DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id;
1471 1470
1472 if (!make_context_current_.Run()) { 1471 if (!make_context_current_.Run()) {
1473 LOGF(ERROR) << "could not make context current"; 1472 LOGF(ERROR) << "could not make context current";
1474 NOTIFY_ERROR(PLATFORM_FAILURE); 1473 NOTIFY_ERROR(PLATFORM_FAILURE);
1475 return; 1474 return;
1476 } 1475 }
1477 1476
1478 EGLSyncKHR egl_sync = 1477 EGLSyncKHR egl_sync =
1479 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 1478 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 DCHECK(!output_record.at_device); 1521 DCHECK(!output_record.at_device);
1523 output_record.at_client = false; 1522 output_record.at_client = false;
1524 output_record.egl_sync = egl_sync_ref->egl_sync; 1523 output_record.egl_sync = egl_sync_ref->egl_sync;
1525 // Take ownership of the EGLSync. 1524 // Take ownership of the EGLSync.
1526 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; 1525 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1527 surfaces_at_display_.erase(it); 1526 surfaces_at_display_.erase(it);
1528 } 1527 }
1529 1528
1530 void V4L2SliceVideoDecodeAccelerator::Flush() { 1529 void V4L2SliceVideoDecodeAccelerator::Flush() {
1531 DVLOGF(3); 1530 DVLOGF(3);
1532 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1531 DCHECK(child_task_runner_->BelongsToCurrentThread());
1533 1532
1534 decoder_thread_proxy_->PostTask( 1533 decoder_thread_proxy_->PostTask(
1535 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::FlushTask, 1534 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::FlushTask,
1536 base::Unretained(this))); 1535 base::Unretained(this)));
1537 } 1536 }
1538 1537
1539 void V4L2SliceVideoDecodeAccelerator::FlushTask() { 1538 void V4L2SliceVideoDecodeAccelerator::FlushTask() {
1540 DVLOGF(3); 1539 DVLOGF(3);
1541 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 1540 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
1542 1541
1543 if (!decoder_input_queue_.empty()) { 1542 if (!decoder_input_queue_.empty()) {
1544 // We are not done with pending inputs, so queue an empty buffer, 1543 // We are not done with pending inputs, so queue an empty buffer,
1545 // which - when reached - will trigger flush sequence. 1544 // which - when reached - will trigger flush sequence.
1546 decoder_input_queue_.push( 1545 decoder_input_queue_.push(
1547 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1546 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1548 io_client_, io_message_loop_proxy_, nullptr, 0, kFlushBufferId))); 1547 io_client_, io_task_runner_, nullptr, 0, kFlushBufferId)));
1549 return; 1548 return;
1550 } 1549 }
1551 1550
1552 // No more inputs pending, so just finish flushing here. 1551 // No more inputs pending, so just finish flushing here.
1553 InitiateFlush(); 1552 InitiateFlush();
1554 } 1553 }
1555 1554
1556 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() { 1555 void V4L2SliceVideoDecodeAccelerator::InitiateFlush() {
1557 DVLOGF(3); 1556 DVLOGF(3);
1558 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 1557 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 // we will have all remaining PictureReady() posted to the client and we 1596 // we will have all remaining PictureReady() posted to the client and we
1598 // can post NotifyFlushDone(). 1597 // can post NotifyFlushDone().
1599 DCHECK(decoder_display_queue_.empty()); 1598 DCHECK(decoder_display_queue_.empty());
1600 1599
1601 // Decoder should have already returned all surfaces and all surfaces are 1600 // Decoder should have already returned all surfaces and all surfaces are
1602 // out of hardware. There can be no other owners of input buffers. 1601 // out of hardware. There can be no other owners of input buffers.
1603 DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size()); 1602 DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size());
1604 1603
1605 SendPictureReady(); 1604 SendPictureReady();
1606 1605
1607 child_message_loop_proxy_->PostTask( 1606 child_task_runner_->PostTask(FROM_HERE,
1608 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1607 base::Bind(&Client::NotifyFlushDone, client_));
1609 1608
1610 decoder_flushing_ = false; 1609 decoder_flushing_ = false;
1611 1610
1612 DVLOGF(3) << "Flush finished"; 1611 DVLOGF(3) << "Flush finished";
1613 state_ = kDecoding; 1612 state_ = kDecoding;
1614 ScheduleDecodeBufferTaskIfNeeded(); 1613 ScheduleDecodeBufferTaskIfNeeded();
1615 } 1614 }
1616 1615
1617 void V4L2SliceVideoDecodeAccelerator::Reset() { 1616 void V4L2SliceVideoDecodeAccelerator::Reset() {
1618 DVLOGF(3); 1617 DVLOGF(3);
1619 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1618 DCHECK(child_task_runner_->BelongsToCurrentThread());
1620 1619
1621 decoder_thread_proxy_->PostTask( 1620 decoder_thread_proxy_->PostTask(
1622 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::ResetTask, 1621 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::ResetTask,
1623 base::Unretained(this))); 1622 base::Unretained(this)));
1624 } 1623 }
1625 1624
1626 void V4L2SliceVideoDecodeAccelerator::ResetTask() { 1625 void V4L2SliceVideoDecodeAccelerator::ResetTask() {
1627 DVLOGF(3); 1626 DVLOGF(3);
1628 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 1627 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
1629 1628
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 // simply mark them all as available. 1672 // simply mark them all as available.
1674 DCHECK_EQ(input_buffer_queued_count_, 0); 1673 DCHECK_EQ(input_buffer_queued_count_, 0);
1675 free_input_buffers_.clear(); 1674 free_input_buffers_.clear();
1676 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 1675 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
1677 DCHECK(!input_buffer_map_[i].at_device); 1676 DCHECK(!input_buffer_map_[i].at_device);
1678 ReuseInputBuffer(i); 1677 ReuseInputBuffer(i);
1679 } 1678 }
1680 1679
1681 decoder_resetting_ = false; 1680 decoder_resetting_ = false;
1682 1681
1683 child_message_loop_proxy_->PostTask( 1682 child_task_runner_->PostTask(FROM_HERE,
1684 FROM_HERE, base::Bind(&Client::NotifyResetDone, client_)); 1683 base::Bind(&Client::NotifyResetDone, client_));
1685 1684
1686 DVLOGF(3) << "Reset finished"; 1685 DVLOGF(3) << "Reset finished";
1687 1686
1688 state_ = kDecoding; 1687 state_ = kDecoding;
1689 ScheduleDecodeBufferTaskIfNeeded(); 1688 ScheduleDecodeBufferTaskIfNeeded();
1690 } 1689 }
1691 1690
1692 void V4L2SliceVideoDecodeAccelerator::SetErrorState(Error error) { 1691 void V4L2SliceVideoDecodeAccelerator::SetErrorState(Error error) {
1693 // We can touch decoder_state_ only if this is the decoder thread or the 1692 // We can touch decoder_state_ only if this is the decoder thread or the
1694 // decoder thread isn't running. 1693 // decoder thread isn't running.
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread()); 2447 DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
2449 bool resetting_or_flushing = (decoder_resetting_ || decoder_flushing_); 2448 bool resetting_or_flushing = (decoder_resetting_ || decoder_flushing_);
2450 while (!pending_picture_ready_.empty()) { 2449 while (!pending_picture_ready_.empty()) {
2451 bool cleared = pending_picture_ready_.front().cleared; 2450 bool cleared = pending_picture_ready_.front().cleared;
2452 const media::Picture& picture = pending_picture_ready_.front().picture; 2451 const media::Picture& picture = pending_picture_ready_.front().picture;
2453 if (cleared && picture_clearing_count_ == 0) { 2452 if (cleared && picture_clearing_count_ == 0) {
2454 DVLOGF(4) << "Posting picture ready to IO for: " 2453 DVLOGF(4) << "Posting picture ready to IO for: "
2455 << picture.picture_buffer_id(); 2454 << picture.picture_buffer_id();
2456 // This picture is cleared. Post it to IO thread to reduce latency. This 2455 // This picture is cleared. Post it to IO thread to reduce latency. This
2457 // should be the case after all pictures are cleared at the beginning. 2456 // should be the case after all pictures are cleared at the beginning.
2458 io_message_loop_proxy_->PostTask( 2457 io_task_runner_->PostTask(
2459 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); 2458 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
2460 pending_picture_ready_.pop(); 2459 pending_picture_ready_.pop();
2461 } else if (!cleared || resetting_or_flushing) { 2460 } else if (!cleared || resetting_or_flushing) {
2462 DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared 2461 DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared
2463 << ", decoder_resetting_=" << decoder_resetting_ 2462 << ", decoder_resetting_=" << decoder_resetting_
2464 << ", decoder_flushing_=" << decoder_flushing_ 2463 << ", decoder_flushing_=" << decoder_flushing_
2465 << ", picture_clearing_count_=" << picture_clearing_count_; 2464 << ", picture_clearing_count_=" << picture_clearing_count_;
2466 DVLOGF(4) << "Posting picture ready to GPU for: " 2465 DVLOGF(4) << "Posting picture ready to GPU for: "
2467 << picture.picture_buffer_id(); 2466 << picture.picture_buffer_id();
2468 // If the picture is not cleared, post it to the child thread because it 2467 // If the picture is not cleared, post it to the child thread because it
2469 // has to be cleared in the child thread. A picture only needs to be 2468 // has to be cleared in the child thread. A picture only needs to be
2470 // cleared once. If the decoder is resetting or flushing, send all 2469 // cleared once. If the decoder is resetting or flushing, send all
2471 // pictures to ensure PictureReady arrive before reset or flush done. 2470 // pictures to ensure PictureReady arrive before reset or flush done.
2472 child_message_loop_proxy_->PostTaskAndReply( 2471 child_task_runner_->PostTaskAndReply(
2473 FROM_HERE, base::Bind(&Client::PictureReady, client_, picture), 2472 FROM_HERE, base::Bind(&Client::PictureReady, client_, picture),
2474 // Unretained is safe. If Client::PictureReady gets to run, |this| is 2473 // Unretained is safe. If Client::PictureReady gets to run, |this| is
2475 // alive. Destroy() will wait the decode thread to finish. 2474 // alive. Destroy() will wait the decode thread to finish.
2476 base::Bind(&V4L2SliceVideoDecodeAccelerator::PictureCleared, 2475 base::Bind(&V4L2SliceVideoDecodeAccelerator::PictureCleared,
2477 base::Unretained(this))); 2476 base::Unretained(this)));
2478 picture_clearing_count_++; 2477 picture_clearing_count_++;
2479 pending_picture_ready_.pop(); 2478 pending_picture_ready_.pop();
2480 } else { 2479 } else {
2481 // This picture is cleared. But some pictures are about to be cleared on 2480 // This picture is cleared. But some pictures are about to be cleared on
2482 // the child thread. To preserve the order, do not send this until those 2481 // the child thread. To preserve the order, do not send this until those
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 profile.profile = media::VP8PROFILE_ANY; 2532 profile.profile = media::VP8PROFILE_ANY;
2534 profiles.push_back(profile); 2533 profiles.push_back(profile);
2535 break; 2534 break;
2536 } 2535 }
2537 } 2536 }
2538 2537
2539 return profiles; 2538 return profiles;
2540 } 2539 }
2541 2540
2542 } // namespace content 2541 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698