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

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

Issue 2896193002: v4l2_vda: Adjust the DVLOG levels. (Closed)
Patch Set: Created 3 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/v4l2_video_decode_accelerator.h" 5 #include "media/gpu/v4l2_video_decode_accelerator.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <linux/videodev2.h> 10 #include <linux/videodev2.h>
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 DCHECK(!device_poll_thread_.IsRunning()); 193 DCHECK(!device_poll_thread_.IsRunning());
194 194
195 // These maps have members that should be manually destroyed, e.g. file 195 // These maps have members that should be manually destroyed, e.g. file
196 // descriptors, mmap() segments, etc. 196 // descriptors, mmap() segments, etc.
197 DCHECK(input_buffer_map_.empty()); 197 DCHECK(input_buffer_map_.empty());
198 DCHECK(output_buffer_map_.empty()); 198 DCHECK(output_buffer_map_.empty());
199 } 199 }
200 200
201 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, 201 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
202 Client* client) { 202 Client* client) {
203 DVLOGF(3) << "profile: " << config.profile 203 DVLOGF(2) << "profile: " << config.profile
204 << ", output_mode=" << static_cast<int>(config.output_mode); 204 << ", output_mode=" << static_cast<int>(config.output_mode);
205 DCHECK(child_task_runner_->BelongsToCurrentThread()); 205 DCHECK(child_task_runner_->BelongsToCurrentThread());
206 DCHECK_EQ(decoder_state_, kUninitialized); 206 DCHECK_EQ(decoder_state_, kUninitialized);
207 207
208 if (config.is_encrypted()) { 208 if (config.is_encrypted()) {
209 NOTREACHED() << "Encrypted streams are not supported for this VDA"; 209 NOTREACHED() << "Encrypted streams are not supported for this VDA";
210 return false; 210 return false;
211 } 211 }
212 212
213 if (config.output_mode != Config::OutputMode::ALLOCATE && 213 if (config.output_mode != Config::OutputMode::ALLOCATE &&
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 288
289 // InitializeTask will NOTIFY_ERROR on failure. 289 // InitializeTask will NOTIFY_ERROR on failure.
290 decoder_thread_.task_runner()->PostTask( 290 decoder_thread_.task_runner()->PostTask(
291 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::InitializeTask, 291 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::InitializeTask,
292 base::Unretained(this))); 292 base::Unretained(this)));
293 293
294 return true; 294 return true;
295 } 295 }
296 296
297 void V4L2VideoDecodeAccelerator::InitializeTask() { 297 void V4L2VideoDecodeAccelerator::InitializeTask() {
298 DVLOGF(3); 298 DVLOGF(2);
299 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 299 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
300 DCHECK_EQ(decoder_state_, kInitialized); 300 DCHECK_EQ(decoder_state_, kInitialized);
301 301
302 // Subscribe to the resolution change event. 302 // Subscribe to the resolution change event.
303 struct v4l2_event_subscription sub; 303 struct v4l2_event_subscription sub;
304 memset(&sub, 0, sizeof(sub)); 304 memset(&sub, 0, sizeof(sub));
305 sub.type = V4L2_EVENT_SOURCE_CHANGE; 305 sub.type = V4L2_EVENT_SOURCE_CHANGE;
306 IOCTL_OR_ERROR_RETURN(VIDIOC_SUBSCRIBE_EVENT, &sub); 306 IOCTL_OR_ERROR_RETURN(VIDIOC_SUBSCRIBE_EVENT, &sub);
307 307
308 if (!CreateInputBuffers()) { 308 if (!CreateInputBuffers()) {
309 NOTIFY_ERROR(PLATFORM_FAILURE); 309 NOTIFY_ERROR(PLATFORM_FAILURE);
310 return; 310 return;
311 } 311 }
312 312
313 decoder_cmd_supported_ = IsDecoderCmdSupported(); 313 decoder_cmd_supported_ = IsDecoderCmdSupported();
314 314
315 if (!StartDevicePoll()) 315 if (!StartDevicePoll())
316 return; 316 return;
317 } 317 }
318 318
319 void V4L2VideoDecodeAccelerator::Decode( 319 void V4L2VideoDecodeAccelerator::Decode(
320 const BitstreamBuffer& bitstream_buffer) { 320 const BitstreamBuffer& bitstream_buffer) {
321 DVLOGF(1) << "input_id=" << bitstream_buffer.id() 321 DVLOGF(4) << "input_id=" << bitstream_buffer.id()
322 << ", size=" << bitstream_buffer.size(); 322 << ", size=" << bitstream_buffer.size();
323 DCHECK(decode_task_runner_->BelongsToCurrentThread()); 323 DCHECK(decode_task_runner_->BelongsToCurrentThread());
324 324
325 if (bitstream_buffer.id() < 0) { 325 if (bitstream_buffer.id() < 0) {
326 LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); 326 LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
327 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 327 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
328 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 328 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
329 NOTIFY_ERROR(INVALID_ARGUMENT); 329 NOTIFY_ERROR(INVALID_ARGUMENT);
330 return; 330 return;
331 } 331 }
332 332
333 // DecodeTask() will take care of running a DecodeBufferTask(). 333 // DecodeTask() will take care of running a DecodeBufferTask().
334 decoder_thread_.task_runner()->PostTask( 334 decoder_thread_.task_runner()->PostTask(
335 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeTask, 335 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeTask,
336 base::Unretained(this), bitstream_buffer)); 336 base::Unretained(this), bitstream_buffer));
337 } 337 }
338 338
339 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( 339 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
340 const std::vector<PictureBuffer>& buffers) { 340 const std::vector<PictureBuffer>& buffers) {
341 DVLOGF(3) << "buffer_count=" << buffers.size(); 341 DVLOGF(2) << "buffer_count=" << buffers.size();
342 DCHECK(child_task_runner_->BelongsToCurrentThread()); 342 DCHECK(child_task_runner_->BelongsToCurrentThread());
343 343
344 decoder_thread_.task_runner()->PostTask( 344 decoder_thread_.task_runner()->PostTask(
345 FROM_HERE, 345 FROM_HERE,
346 base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask, 346 base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask,
347 base::Unretained(this), buffers)); 347 base::Unretained(this), buffers));
348 } 348 }
349 349
350 void V4L2VideoDecodeAccelerator::AssignPictureBuffersTask( 350 void V4L2VideoDecodeAccelerator::AssignPictureBuffersTask(
351 const std::vector<PictureBuffer>& buffers) { 351 const std::vector<PictureBuffer>& buffers) {
352 DVLOGF(3); 352 DVLOGF(2);
353 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 353 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
354 DCHECK_EQ(decoder_state_, kAwaitingPictureBuffers); 354 DCHECK_EQ(decoder_state_, kAwaitingPictureBuffers);
355 355
356 uint32_t req_buffer_count = output_dpb_size_ + kDpbOutputBufferExtraCount; 356 uint32_t req_buffer_count = output_dpb_size_ + kDpbOutputBufferExtraCount;
357 if (image_processor_device_) 357 if (image_processor_device_)
358 req_buffer_count += kDpbOutputBufferExtraCountForImageProcessor; 358 req_buffer_count += kDpbOutputBufferExtraCountForImageProcessor;
359 359
360 if (buffers.size() < req_buffer_count) { 360 if (buffers.size() < req_buffer_count) {
361 LOGF(ERROR) << "Failed to provide requested picture buffers. (Got " 361 LOGF(ERROR) << "Failed to provide requested picture buffers. (Got "
362 << buffers.size() << ", requested " << req_buffer_count << ")"; 362 << buffers.size() << ", requested " << req_buffer_count << ")";
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 ImportBufferForPictureTask( 432 ImportBufferForPictureTask(
433 output_record.picture_id, std::move(dmabuf_fds), 433 output_record.picture_id, std::move(dmabuf_fds),
434 egl_image_size_.width() * plane_horiz_bits_per_pixel / 8); 434 egl_image_size_.width() * plane_horiz_bits_per_pixel / 8);
435 } // else we'll get triggered via ImportBufferForPicture() from client. 435 } // else we'll get triggered via ImportBufferForPicture() from client.
436 436
437 DVLOGF(3) << "buffer[" << i << "]: picture_id=" << output_record.picture_id; 437 DVLOGF(3) << "buffer[" << i << "]: picture_id=" << output_record.picture_id;
438 } 438 }
439 439
440 if (output_mode_ == Config::OutputMode::ALLOCATE) { 440 if (output_mode_ == Config::OutputMode::ALLOCATE) {
441 DCHECK_EQ(kAwaitingPictureBuffers, decoder_state_); 441 DCHECK_EQ(kAwaitingPictureBuffers, decoder_state_);
442 DVLOGF(1) << "Change state to kDecoding"; 442 DVLOGF(1) << "Change state to kDecoding";
Pawel Osciak 2017/05/23 09:49:21 2 or 3?
Owen Lin 2017/06/02 08:51:44 Done.
443 decoder_state_ = kDecoding; 443 decoder_state_ = kDecoding;
444 if (reset_pending_) { 444 if (reset_pending_) {
445 FinishReset(); 445 FinishReset();
446 return; 446 return;
447 } 447 }
448 ScheduleDecodeBufferTaskIfNeeded(); 448 ScheduleDecodeBufferTaskIfNeeded();
449 } 449 }
450 } 450 }
451 451
452 void V4L2VideoDecodeAccelerator::CreateEGLImageFor( 452 void V4L2VideoDecodeAccelerator::CreateEGLImageFor(
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 NOTIFY_ERROR(INVALID_ARGUMENT); 603 NOTIFY_ERROR(INVALID_ARGUMENT);
604 return; 604 return;
605 } 605 }
606 int adjusted_coded_width = stride * 8 / plane_horiz_bits_per_pixel; 606 int adjusted_coded_width = stride * 8 / plane_horiz_bits_per_pixel;
607 607
608 if (image_processor_device_ && !image_processor_) { 608 if (image_processor_device_ && !image_processor_) {
609 // This is the first buffer import. Create the image processor and change 609 // This is the first buffer import. Create the image processor and change
610 // the decoder state. The client may adjust the coded width. We don't have 610 // the decoder state. The client may adjust the coded width. We don't have
611 // the final coded size in AssignPictureBuffers yet. Use the adjusted coded 611 // the final coded size in AssignPictureBuffers yet. Use the adjusted coded
612 // width to create the image processor. 612 // width to create the image processor.
613 DVLOGF(3) << "Original egl_image_size=" << egl_image_size_.ToString() 613 DVLOGF(3) << "Original egl_image_size=" << egl_image_size_.ToString()
Pawel Osciak 2017/05/23 09:49:21 2?
Owen Lin 2017/06/02 08:51:43 Done.
614 << ", adjusted coded width=" << adjusted_coded_width; 614 << ", adjusted coded width=" << adjusted_coded_width;
615 DCHECK_GE(adjusted_coded_width, egl_image_size_.width()); 615 DCHECK_GE(adjusted_coded_width, egl_image_size_.width());
616 egl_image_size_.set_width(adjusted_coded_width); 616 egl_image_size_.set_width(adjusted_coded_width);
617 if (!CreateImageProcessor()) 617 if (!CreateImageProcessor())
618 return; 618 return;
619 DCHECK_EQ(kAwaitingPictureBuffers, decoder_state_); 619 DCHECK_EQ(kAwaitingPictureBuffers, decoder_state_);
620 DVLOGF(1) << "Change state to kDecoding"; 620 DVLOGF(2) << "Change state to kDecoding";
621 decoder_state_ = kDecoding; 621 decoder_state_ = kDecoding;
622 if (reset_pending_) { 622 if (reset_pending_) {
623 FinishReset(); 623 FinishReset();
624 } 624 }
625 } else { 625 } else {
626 DCHECK_EQ(egl_image_size_.width(), adjusted_coded_width); 626 DCHECK_EQ(egl_image_size_.width(), adjusted_coded_width);
627 } 627 }
628 628
629 size_t index = iter - output_buffer_map_.begin(); 629 size_t index = iter - output_buffer_map_.begin();
630 DCHECK_EQ(std::count(free_output_buffers_.begin(), free_output_buffers_.end(), 630 DCHECK_EQ(std::count(free_output_buffers_.begin(), free_output_buffers_.end(),
(...skipping 20 matching lines...) Expand all
651 iter->processor_output_fds.swap(dmabuf_fds); 651 iter->processor_output_fds.swap(dmabuf_fds);
652 free_output_buffers_.push_back(index); 652 free_output_buffers_.push_back(index);
653 if (decoder_state_ != kChangingResolution) { 653 if (decoder_state_ != kChangingResolution) {
654 Enqueue(); 654 Enqueue();
655 ScheduleDecodeBufferTaskIfNeeded(); 655 ScheduleDecodeBufferTaskIfNeeded();
656 } 656 }
657 } 657 }
658 } 658 }
659 659
660 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) { 660 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
661 DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id; 661 DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id;
662 // Must be run on child thread, as we'll insert a sync in the EGL context. 662 // Must be run on child thread, as we'll insert a sync in the EGL context.
663 DCHECK(child_task_runner_->BelongsToCurrentThread()); 663 DCHECK(child_task_runner_->BelongsToCurrentThread());
664 664
665 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref; 665 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref;
666 666
667 if (!make_context_current_cb_.is_null()) { 667 if (!make_context_current_cb_.is_null()) {
668 if (!make_context_current_cb_.Run()) { 668 if (!make_context_current_cb_.Run()) {
669 LOGF(ERROR) << "could not make context current"; 669 LOGF(ERROR) << "could not make context current";
670 NOTIFY_ERROR(PLATFORM_FAILURE); 670 NOTIFY_ERROR(PLATFORM_FAILURE);
671 return; 671 return;
(...skipping 13 matching lines...) Expand all
685 egl_sync_ref.reset(new EGLSyncKHRRef(egl_display_, egl_sync)); 685 egl_sync_ref.reset(new EGLSyncKHRRef(egl_display_, egl_sync));
686 } 686 }
687 687
688 decoder_thread_.task_runner()->PostTask( 688 decoder_thread_.task_runner()->PostTask(
689 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ReusePictureBufferTask, 689 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
690 base::Unretained(this), picture_buffer_id, 690 base::Unretained(this), picture_buffer_id,
691 base::Passed(&egl_sync_ref))); 691 base::Passed(&egl_sync_ref)));
692 } 692 }
693 693
694 void V4L2VideoDecodeAccelerator::Flush() { 694 void V4L2VideoDecodeAccelerator::Flush() {
695 DVLOGF(3); 695 DVLOGF(2);
696 DCHECK(child_task_runner_->BelongsToCurrentThread()); 696 DCHECK(child_task_runner_->BelongsToCurrentThread());
697 decoder_thread_.task_runner()->PostTask( 697 decoder_thread_.task_runner()->PostTask(
698 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FlushTask, 698 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FlushTask,
699 base::Unretained(this))); 699 base::Unretained(this)));
700 } 700 }
701 701
702 void V4L2VideoDecodeAccelerator::Reset() { 702 void V4L2VideoDecodeAccelerator::Reset() {
703 DVLOGF(3); 703 DVLOGF(2);
704 DCHECK(child_task_runner_->BelongsToCurrentThread()); 704 DCHECK(child_task_runner_->BelongsToCurrentThread());
705 decoder_thread_.task_runner()->PostTask( 705 decoder_thread_.task_runner()->PostTask(
706 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetTask, 706 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetTask,
707 base::Unretained(this))); 707 base::Unretained(this)));
708 } 708 }
709 709
710 void V4L2VideoDecodeAccelerator::Destroy() { 710 void V4L2VideoDecodeAccelerator::Destroy() {
711 DVLOGF(3); 711 DVLOGF(2);
712 DCHECK(child_task_runner_->BelongsToCurrentThread()); 712 DCHECK(child_task_runner_->BelongsToCurrentThread());
713 713
714 // We're destroying; cancel all callbacks. 714 // We're destroying; cancel all callbacks.
715 client_ptr_factory_.reset(); 715 client_ptr_factory_.reset();
716 weak_this_factory_.InvalidateWeakPtrs(); 716 weak_this_factory_.InvalidateWeakPtrs();
717 717
718 // If the decoder thread is running, destroy using posted task. 718 // If the decoder thread is running, destroy using posted task.
719 if (decoder_thread_.IsRunning()) { 719 if (decoder_thread_.IsRunning()) {
720 decoder_thread_.task_runner()->PostTask( 720 decoder_thread_.task_runner()->PostTask(
721 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DestroyTask, 721 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DestroyTask,
(...skipping 23 matching lines...) Expand all
745 scoped_refptr<V4L2Device> device = V4L2Device::Create(); 745 scoped_refptr<V4L2Device> device = V4L2Device::Create();
746 if (!device) 746 if (!device)
747 return SupportedProfiles(); 747 return SupportedProfiles();
748 748
749 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), 749 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_),
750 supported_input_fourccs_); 750 supported_input_fourccs_);
751 } 751 }
752 752
753 void V4L2VideoDecodeAccelerator::DecodeTask( 753 void V4L2VideoDecodeAccelerator::DecodeTask(
754 const BitstreamBuffer& bitstream_buffer) { 754 const BitstreamBuffer& bitstream_buffer) {
755 DVLOGF(3) << "input_id=" << bitstream_buffer.id(); 755 DVLOGF(4) << "input_id=" << bitstream_buffer.id();
756 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 756 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
757 DCHECK_NE(decoder_state_, kUninitialized); 757 DCHECK_NE(decoder_state_, kUninitialized);
758 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id", 758 TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id",
759 bitstream_buffer.id()); 759 bitstream_buffer.id());
760 760
761 std::unique_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 761 std::unique_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
762 decode_client_, decode_task_runner_, 762 decode_client_, decode_task_runner_,
763 std::unique_ptr<SharedMemoryRegion>( 763 std::unique_ptr<SharedMemoryRegion>(
764 new SharedMemoryRegion(bitstream_buffer, true)), 764 new SharedMemoryRegion(bitstream_buffer, true)),
765 bitstream_buffer.id())); 765 bitstream_buffer.id()));
766 766
767 // Skip empty buffer. 767 // Skip empty buffer.
768 if (bitstream_buffer.size() == 0) 768 if (bitstream_buffer.size() == 0)
769 return; 769 return;
770 770
771 if (!bitstream_record->shm->Map()) { 771 if (!bitstream_record->shm->Map()) {
772 LOGF(ERROR) << "could not map bitstream_buffer"; 772 LOGF(ERROR) << "could not map bitstream_buffer";
773 NOTIFY_ERROR(UNREADABLE_INPUT); 773 NOTIFY_ERROR(UNREADABLE_INPUT);
774 return; 774 return;
775 } 775 }
776 DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory(); 776 DVLOGF(4) << "mapped at=" << bitstream_record->shm->memory();
777 777
778 if (decoder_state_ == kResetting || decoder_flushing_) { 778 if (decoder_state_ == kResetting || decoder_flushing_) {
779 // In the case that we're resetting or flushing, we need to delay decoding 779 // In the case that we're resetting or flushing, we need to delay decoding
780 // the BitstreamBuffers that come after the Reset() or Flush() call. When 780 // the BitstreamBuffers that come after the Reset() or Flush() call. When
781 // we're here, we know that this DecodeTask() was scheduled by a Decode() 781 // we're here, we know that this DecodeTask() was scheduled by a Decode()
782 // call that came after (in the client thread) the Reset() or Flush() call; 782 // call that came after (in the client thread) the Reset() or Flush() call;
783 // thus set up the delay if necessary. 783 // thus set up the delay if necessary.
784 if (decoder_delay_bitstream_buffer_id_ == -1) 784 if (decoder_delay_bitstream_buffer_id_ == -1)
785 decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id; 785 decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id;
786 } else if (decoder_state_ == kError) { 786 } else if (decoder_state_ == kError) {
787 DVLOGF(2) << "early out: kError state"; 787 DVLOGF(2) << "early out: kError state";
788 return; 788 return;
789 } 789 }
790 790
791 decoder_input_queue_.push( 791 decoder_input_queue_.push(
792 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); 792 linked_ptr<BitstreamBufferRef>(bitstream_record.release()));
793 decoder_decode_buffer_tasks_scheduled_++; 793 decoder_decode_buffer_tasks_scheduled_++;
794 DecodeBufferTask(); 794 DecodeBufferTask();
795 } 795 }
796 796
797 void V4L2VideoDecodeAccelerator::DecodeBufferTask() { 797 void V4L2VideoDecodeAccelerator::DecodeBufferTask() {
798 DVLOGF(3); 798 DVLOGF(4);
799 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 799 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
800 DCHECK_NE(decoder_state_, kUninitialized); 800 DCHECK_NE(decoder_state_, kUninitialized);
801 TRACE_EVENT0("Video Decoder", "V4L2VDA::DecodeBufferTask"); 801 TRACE_EVENT0("Video Decoder", "V4L2VDA::DecodeBufferTask");
802 802
803 decoder_decode_buffer_tasks_scheduled_--; 803 decoder_decode_buffer_tasks_scheduled_--;
804 804
805 if (decoder_state_ != kInitialized && decoder_state_ != kDecoding) { 805 if (decoder_state_ != kInitialized && decoder_state_ != kDecoding) {
806 DVLOGF(2) << "early out: state=" << decoder_state_; 806 DVLOGF(2) << "early out: state=" << decoder_state_;
807 return; 807 return;
808 } 808 }
809 809
810 if (decoder_current_bitstream_buffer_ == NULL) { 810 if (decoder_current_bitstream_buffer_ == NULL) {
811 if (decoder_input_queue_.empty()) { 811 if (decoder_input_queue_.empty()) {
812 // We're waiting for a new buffer -- exit without scheduling a new task. 812 // We're waiting for a new buffer -- exit without scheduling a new task.
813 return; 813 return;
814 } 814 }
815 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front(); 815 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front();
816 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) { 816 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) {
817 // We're asked to delay decoding on this and subsequent buffers. 817 // We're asked to delay decoding on this and subsequent buffers.
818 return; 818 return;
819 } 819 }
820 820
821 // Setup to use the next buffer. 821 // Setup to use the next buffer.
822 decoder_current_bitstream_buffer_.reset(buffer_ref.release()); 822 decoder_current_bitstream_buffer_.reset(buffer_ref.release());
823 decoder_input_queue_.pop(); 823 decoder_input_queue_.pop();
824 const auto& shm = decoder_current_bitstream_buffer_->shm; 824 const auto& shm = decoder_current_bitstream_buffer_->shm;
825 if (shm) { 825 if (shm) {
826 DVLOGF(3) << "reading input_id=" 826 DVLOGF(4) << "reading input_id="
827 << decoder_current_bitstream_buffer_->input_id 827 << decoder_current_bitstream_buffer_->input_id
828 << ", addr=" << shm->memory() << ", size=" << shm->size(); 828 << ", addr=" << shm->memory() << ", size=" << shm->size();
829 } else { 829 } else {
830 DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId); 830 DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId);
831 DVLOGF(3) << "reading input_id=kFlushBufferId"; 831 DVLOGF(4) << "reading input_id=kFlushBufferId";
832 } 832 }
833 } 833 }
834 bool schedule_task = false; 834 bool schedule_task = false;
835 size_t decoded_size = 0; 835 size_t decoded_size = 0;
836 const auto& shm = decoder_current_bitstream_buffer_->shm; 836 const auto& shm = decoder_current_bitstream_buffer_->shm;
837 if (!shm) { 837 if (!shm) {
838 // This is a dummy buffer, queued to flush the pipe. Flush. 838 // This is a dummy buffer, queued to flush the pipe. Flush.
839 DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId); 839 DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId);
840 // Enqueue a buffer guaranteed to be empty. To do that, we flush the 840 // Enqueue a buffer guaranteed to be empty. To do that, we flush the
841 // current input, enqueue no data to the next frame, then flush that down. 841 // current input, enqueue no data to the next frame, then flush that down.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 // Failed during decode. 890 // Failed during decode.
891 return; 891 return;
892 } 892 }
893 893
894 if (schedule_task) { 894 if (schedule_task) {
895 decoder_current_bitstream_buffer_->bytes_used += decoded_size; 895 decoder_current_bitstream_buffer_->bytes_used += decoded_size;
896 if ((shm ? shm->size() : 0) == 896 if ((shm ? shm->size() : 0) ==
897 decoder_current_bitstream_buffer_->bytes_used) { 897 decoder_current_bitstream_buffer_->bytes_used) {
898 // Our current bitstream buffer is done; return it. 898 // Our current bitstream buffer is done; return it.
899 int32_t input_id = decoder_current_bitstream_buffer_->input_id; 899 int32_t input_id = decoder_current_bitstream_buffer_->input_id;
900 DVLOGF(3) << "finished input_id=" << input_id; 900 DVLOGF(4) << "finished input_id=" << input_id;
901 // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer(). 901 // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer().
902 decoder_current_bitstream_buffer_.reset(); 902 decoder_current_bitstream_buffer_.reset();
903 } 903 }
904 ScheduleDecodeBufferTaskIfNeeded(); 904 ScheduleDecodeBufferTaskIfNeeded();
905 } 905 }
906 } 906 }
907 907
908 bool V4L2VideoDecodeAccelerator::AdvanceFrameFragment(const uint8_t* data, 908 bool V4L2VideoDecodeAccelerator::AdvanceFrameFragment(const uint8_t* data,
909 size_t size, 909 size_t size,
910 size_t* endpos) { 910 size_t* endpos) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 decoder_decode_buffer_tasks_scheduled_++; 1002 decoder_decode_buffer_tasks_scheduled_++;
1003 decoder_thread_.task_runner()->PostTask( 1003 decoder_thread_.task_runner()->PostTask(
1004 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeBufferTask, 1004 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DecodeBufferTask,
1005 base::Unretained(this))); 1005 base::Unretained(this)));
1006 } 1006 }
1007 } 1007 }
1008 1008
1009 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(const void* data, 1009 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(const void* data,
1010 size_t size, 1010 size_t size,
1011 size_t* endpos) { 1011 size_t* endpos) {
1012 DVLOGF(3) << "data=" << data << ", size=" << size; 1012 DVLOGF(4) << "data=" << data << ", size=" << size;
1013 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1013 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1014 DCHECK_EQ(decoder_state_, kInitialized); 1014 DCHECK_EQ(decoder_state_, kInitialized);
1015 // Initial decode. We haven't been able to get output stream format info yet. 1015 // Initial decode. We haven't been able to get output stream format info yet.
1016 // Get it, and start decoding. 1016 // Get it, and start decoding.
1017 1017
1018 // Copy in and send to HW. 1018 // Copy in and send to HW.
1019 if (!AppendToInputFrame(data, size)) 1019 if (!AppendToInputFrame(data, size))
1020 return false; 1020 return false;
1021 1021
1022 // If we only have a partial frame, don't flush and process yet. 1022 // If we only have a partial frame, don't flush and process yet.
(...skipping 15 matching lines...) Expand all
1038 1038
1039 *endpos = size; 1039 *endpos = size;
1040 1040
1041 if (again) { 1041 if (again) {
1042 // Need more stream to decode format, return true and schedule next buffer. 1042 // Need more stream to decode format, return true and schedule next buffer.
1043 return true; 1043 return true;
1044 } 1044 }
1045 1045
1046 // Run this initialization only on first startup. 1046 // Run this initialization only on first startup.
1047 if (output_buffer_map_.empty()) { 1047 if (output_buffer_map_.empty()) {
1048 DVLOGF(3) << "running initialization"; 1048 DVLOGF(4) << "running initialization";
1049 // Success! Setup our parameters. 1049 // Success! Setup our parameters.
1050 if (!CreateBuffersForFormat(format, visible_size)) 1050 if (!CreateBuffersForFormat(format, visible_size))
1051 return false; 1051 return false;
1052 // We are waiting for AssignPictureBuffers. Do not set the state to 1052 // We are waiting for AssignPictureBuffers. Do not set the state to
1053 // kDecoding. 1053 // kDecoding.
1054 } else { 1054 } else {
1055 decoder_state_ = kDecoding; 1055 decoder_state_ = kDecoding;
1056 ScheduleDecodeBufferTaskIfNeeded(); 1056 ScheduleDecodeBufferTaskIfNeeded();
1057 } 1057 }
1058 return true; 1058 return true;
1059 } 1059 }
1060 1060
1061 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue(const void* data, 1061 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue(const void* data,
1062 size_t size) { 1062 size_t size) {
1063 DVLOGF(3) << "data=" << data << ", size=" << size; 1063 DVLOGF(4) << "data=" << data << ", size=" << size;
1064 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1064 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1065 DCHECK_EQ(decoder_state_, kDecoding); 1065 DCHECK_EQ(decoder_state_, kDecoding);
1066 1066
1067 // Both of these calls will set kError state if they fail. 1067 // Both of these calls will set kError state if they fail.
1068 // Only flush the frame if it's complete. 1068 // Only flush the frame if it's complete.
1069 return (AppendToInputFrame(data, size) && 1069 return (AppendToInputFrame(data, size) &&
1070 (decoder_partial_frame_pending_ || FlushInputFrame())); 1070 (decoder_partial_frame_pending_ || FlushInputFrame()));
1071 } 1071 }
1072 1072
1073 bool V4L2VideoDecodeAccelerator::AppendToInputFrame(const void* data, 1073 bool V4L2VideoDecodeAccelerator::AppendToInputFrame(const void* data,
1074 size_t size) { 1074 size_t size) {
1075 DVLOGF(3); 1075 DVLOGF(3);
Pawel Osciak 2017/05/23 09:49:22 4?
Owen Lin 2017/06/02 08:51:43 Done.
1076 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1076 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1077 DCHECK_NE(decoder_state_, kUninitialized); 1077 DCHECK_NE(decoder_state_, kUninitialized);
1078 DCHECK_NE(decoder_state_, kResetting); 1078 DCHECK_NE(decoder_state_, kResetting);
1079 DCHECK_NE(decoder_state_, kError); 1079 DCHECK_NE(decoder_state_, kError);
1080 // This routine can handle data == NULL and size == 0, which occurs when 1080 // This routine can handle data == NULL and size == 0, which occurs when
1081 // we queue an empty buffer for the purposes of flushing the pipe. 1081 // we queue an empty buffer for the purposes of flushing the pipe.
1082 1082
1083 // Flush if we're too big 1083 // Flush if we're too big
1084 if (decoder_current_input_buffer_ != -1) { 1084 if (decoder_current_input_buffer_ != -1) {
1085 InputRecord& input_record = 1085 InputRecord& input_record =
1086 input_buffer_map_[decoder_current_input_buffer_]; 1086 input_buffer_map_[decoder_current_input_buffer_];
1087 if (input_record.bytes_used + size > input_record.length) { 1087 if (input_record.bytes_used + size > input_record.length) {
1088 if (!FlushInputFrame()) 1088 if (!FlushInputFrame())
1089 return false; 1089 return false;
1090 decoder_current_input_buffer_ = -1; 1090 decoder_current_input_buffer_ = -1;
1091 } 1091 }
1092 } 1092 }
1093 1093
1094 // Try to get an available input buffer 1094 // Try to get an available input buffer
1095 if (decoder_current_input_buffer_ == -1) { 1095 if (decoder_current_input_buffer_ == -1) {
1096 if (free_input_buffers_.empty()) { 1096 if (free_input_buffers_.empty()) {
1097 // See if we can get more free buffers from HW 1097 // See if we can get more free buffers from HW
1098 Dequeue(); 1098 Dequeue();
1099 if (free_input_buffers_.empty()) { 1099 if (free_input_buffers_.empty()) {
1100 // Nope! 1100 // Nope!
1101 DVLOGF(2) << "stalled for input buffers"; 1101 DVLOGF(2) << "stalled for input buffers";
Pawel Osciak 2017/05/23 09:49:21 3, this is a very frequent print that doesn't give
Owen Lin 2017/06/02 08:51:44 Thanks.
1102 return false; 1102 return false;
1103 } 1103 }
1104 } 1104 }
1105 decoder_current_input_buffer_ = free_input_buffers_.back(); 1105 decoder_current_input_buffer_ = free_input_buffers_.back();
1106 free_input_buffers_.pop_back(); 1106 free_input_buffers_.pop_back();
1107 InputRecord& input_record = 1107 InputRecord& input_record =
1108 input_buffer_map_[decoder_current_input_buffer_]; 1108 input_buffer_map_[decoder_current_input_buffer_];
1109 DCHECK_EQ(input_record.bytes_used, 0); 1109 DCHECK_EQ(input_record.bytes_used, 0);
1110 DCHECK_EQ(input_record.input_id, -1); 1110 DCHECK_EQ(input_record.input_id, -1);
1111 DCHECK(decoder_current_bitstream_buffer_ != NULL); 1111 DCHECK(decoder_current_bitstream_buffer_ != NULL);
(...skipping 17 matching lines...) Expand all
1129 } 1129 }
1130 memcpy(reinterpret_cast<uint8_t*>(input_record.address) + 1130 memcpy(reinterpret_cast<uint8_t*>(input_record.address) +
1131 input_record.bytes_used, 1131 input_record.bytes_used,
1132 data, size); 1132 data, size);
1133 input_record.bytes_used += size; 1133 input_record.bytes_used += size;
1134 1134
1135 return true; 1135 return true;
1136 } 1136 }
1137 1137
1138 bool V4L2VideoDecodeAccelerator::FlushInputFrame() { 1138 bool V4L2VideoDecodeAccelerator::FlushInputFrame() {
1139 DVLOGF(3); 1139 DVLOGF(2);
Pawel Osciak 2017/05/23 09:49:22 I think this is actually a part of each frame task
Owen Lin 2017/06/02 08:51:44 Ah, Right. I was confused with Flush. It is not ab
1140 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1140 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1141 DCHECK_NE(decoder_state_, kUninitialized); 1141 DCHECK_NE(decoder_state_, kUninitialized);
1142 DCHECK_NE(decoder_state_, kResetting); 1142 DCHECK_NE(decoder_state_, kResetting);
1143 DCHECK_NE(decoder_state_, kError); 1143 DCHECK_NE(decoder_state_, kError);
1144 1144
1145 if (decoder_current_input_buffer_ == -1) 1145 if (decoder_current_input_buffer_ == -1)
1146 return true; 1146 return true;
1147 1147
1148 InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_]; 1148 InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
1149 DCHECK_NE(input_record.input_id, -1); 1149 DCHECK_NE(input_record.input_id, -1);
1150 DCHECK(input_record.input_id != kFlushBufferId || 1150 DCHECK(input_record.input_id != kFlushBufferId ||
1151 input_record.bytes_used == 0); 1151 input_record.bytes_used == 0);
1152 // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we 1152 // * if input_id >= 0, this input buffer was prompted by a bitstream buffer we
1153 // got from the client. We can skip it if it is empty. 1153 // got from the client. We can skip it if it is empty.
1154 // * if input_id < 0 (should be kFlushBufferId in this case), this input 1154 // * if input_id < 0 (should be kFlushBufferId in this case), this input
1155 // buffer was prompted by a flush buffer, and should be queued even when 1155 // buffer was prompted by a flush buffer, and should be queued even when
1156 // empty. 1156 // empty.
1157 if (input_record.input_id >= 0 && input_record.bytes_used == 0) { 1157 if (input_record.input_id >= 0 && input_record.bytes_used == 0) {
1158 input_record.input_id = -1; 1158 input_record.input_id = -1;
1159 free_input_buffers_.push_back(decoder_current_input_buffer_); 1159 free_input_buffers_.push_back(decoder_current_input_buffer_);
1160 decoder_current_input_buffer_ = -1; 1160 decoder_current_input_buffer_ = -1;
1161 return true; 1161 return true;
1162 } 1162 }
1163 1163
1164 // Queue it. 1164 // Queue it.
1165 input_ready_queue_.push(decoder_current_input_buffer_); 1165 input_ready_queue_.push(decoder_current_input_buffer_);
1166 decoder_current_input_buffer_ = -1; 1166 decoder_current_input_buffer_ = -1;
1167 DVLOGF(3) << "submitting input_id=" << input_record.input_id; 1167 DVLOGF(2) << "submitting input_id=" << input_record.input_id;
Pawel Osciak 2017/05/23 09:49:21 Ditto.
Owen Lin 2017/06/02 08:51:43 Done.
1168 // Enqueue once since there's new available input for it. 1168 // Enqueue once since there's new available input for it.
1169 Enqueue(); 1169 Enqueue();
1170 1170
1171 return (decoder_state_ != kError); 1171 return (decoder_state_ != kError);
1172 } 1172 }
1173 1173
1174 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) { 1174 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) {
1175 DVLOGF(3); 1175 DVLOGF(3);
1176 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1176 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1177 DCHECK_NE(decoder_state_, kUninitialized); 1177 DCHECK_NE(decoder_state_, kUninitialized);
1178 TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask"); 1178 TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask");
1179 1179
1180 if (decoder_state_ == kResetting) { 1180 if (decoder_state_ == kResetting) {
1181 DVLOGF(2) << "early out: kResetting state"; 1181 DVLOGF(3) << "early out: kResetting state";
1182 return; 1182 return;
1183 } else if (decoder_state_ == kError) { 1183 } else if (decoder_state_ == kError) {
1184 DVLOGF(2) << "early out: kError state"; 1184 DVLOGF(3) << "early out: kError state";
1185 return; 1185 return;
1186 } else if (decoder_state_ == kChangingResolution) { 1186 } else if (decoder_state_ == kChangingResolution) {
1187 DVLOGF(2) << "early out: kChangingResolution state"; 1187 DVLOGF(3) << "early out: kChangingResolution state";
1188 return; 1188 return;
1189 } 1189 }
1190 1190
1191 bool resolution_change_pending = false; 1191 bool resolution_change_pending = false;
1192 if (event_pending) 1192 if (event_pending)
1193 resolution_change_pending = DequeueResolutionChangeEvent(); 1193 resolution_change_pending = DequeueResolutionChangeEvent();
1194 Dequeue(); 1194 Dequeue();
1195 Enqueue(); 1195 Enqueue();
1196 1196
1197 // Clear the interrupt fd. 1197 // Clear the interrupt fd.
(...skipping 13 matching lines...) Expand all
1211 // * device_poll_thread_ is running normally 1211 // * device_poll_thread_ is running normally
1212 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() 1212 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask()
1213 // shut it down, in which case we're either in kResetting or kError states 1213 // shut it down, in which case we're either in kResetting or kError states
1214 // respectively, and we should have early-outed already. 1214 // respectively, and we should have early-outed already.
1215 DCHECK(device_poll_thread_.message_loop()); 1215 DCHECK(device_poll_thread_.message_loop());
1216 // Queue the DevicePollTask() now. 1216 // Queue the DevicePollTask() now.
1217 device_poll_thread_.task_runner()->PostTask( 1217 device_poll_thread_.task_runner()->PostTask(
1218 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask, 1218 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask,
1219 base::Unretained(this), poll_device)); 1219 base::Unretained(this), poll_device));
1220 1220
1221 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" 1221 DVLOG(3) << "ServiceDeviceTask(): buffer counts: DEC["
Pawel Osciak 2017/05/23 09:49:21 This is per frame, but actually quite useful at 3
Owen Lin 2017/06/02 08:51:43 Done.
1222 << decoder_input_queue_.size() << "->" 1222 << decoder_input_queue_.size() << "->" << input_ready_queue_.size()
Pawel Osciak 2017/05/23 09:49:21 Could we keep the original formatting please, I fe
Owen Lin 2017/06/02 08:51:43 OK. But it is the result of "git cl format", we wi
Pawel Osciak 2017/06/08 03:57:11 Yes, unfortunately.
1223 << input_ready_queue_.size() << "] => DEVICE[" 1223 << "] => DEVICE[" << free_input_buffers_.size() << "+"
1224 << free_input_buffers_.size() << "+" 1224 << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
1225 << input_buffer_queued_count_ << "/" 1225 << "->" << free_output_buffers_.size() << "+"
1226 << input_buffer_map_.size() << "->" 1226 << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
1227 << free_output_buffers_.size() << "+" 1227 << "] => PROCESSOR[" << image_processor_bitstream_buffer_ids_.size()
1228 << output_buffer_queued_count_ << "/" 1228 << "] => CLIENT[" << decoder_frames_at_client_ << "]";
1229 << output_buffer_map_.size() << "] => PROCESSOR["
1230 << image_processor_bitstream_buffer_ids_.size() << "] => CLIENT["
1231 << decoder_frames_at_client_ << "]";
1232 1229
1233 ScheduleDecodeBufferTaskIfNeeded(); 1230 ScheduleDecodeBufferTaskIfNeeded();
1234 if (resolution_change_pending) 1231 if (resolution_change_pending)
1235 StartResolutionChange(); 1232 StartResolutionChange();
1236 } 1233 }
1237 1234
1238 void V4L2VideoDecodeAccelerator::Enqueue() { 1235 void V4L2VideoDecodeAccelerator::Enqueue() {
1239 DVLOGF(3); 1236 DVLOGF(3);
Pawel Osciak 2017/05/23 09:49:21 4?
Owen Lin 2017/06/02 08:51:43 Done.
1240 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1237 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1241 DCHECK_NE(decoder_state_, kUninitialized); 1238 DCHECK_NE(decoder_state_, kUninitialized);
1242 TRACE_EVENT0("Video Decoder", "V4L2VDA::Enqueue"); 1239 TRACE_EVENT0("Video Decoder", "V4L2VDA::Enqueue");
1243 1240
1244 // Drain the pipe of completed decode buffers. 1241 // Drain the pipe of completed decode buffers.
1245 const int old_inputs_queued = input_buffer_queued_count_; 1242 const int old_inputs_queued = input_buffer_queued_count_;
1246 while (!input_ready_queue_.empty()) { 1243 while (!input_ready_queue_.empty()) {
1247 const int buffer = input_ready_queue_.front(); 1244 const int buffer = input_ready_queue_.front();
1248 InputRecord& input_record = input_buffer_map_[buffer]; 1245 InputRecord& input_record = input_buffer_map_[buffer];
1249 if (input_record.input_id == kFlushBufferId && decoder_cmd_supported_) { 1246 if (input_record.input_id == kFlushBufferId && decoder_cmd_supported_) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1301 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1305 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type); 1302 IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
1306 output_streamon_ = true; 1303 output_streamon_ = true;
1307 } 1304 }
1308 } 1305 }
1309 } 1306 }
1310 1307
1311 bool V4L2VideoDecodeAccelerator::DequeueResolutionChangeEvent() { 1308 bool V4L2VideoDecodeAccelerator::DequeueResolutionChangeEvent() {
1312 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1309 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1313 DCHECK_NE(decoder_state_, kUninitialized); 1310 DCHECK_NE(decoder_state_, kUninitialized);
1314 DVLOGF(3); 1311 DVLOGF(3);
Pawel Osciak 2017/05/23 09:49:21 2?
Owen Lin 2017/06/02 08:51:44 Done.
1315 1312
1316 struct v4l2_event ev; 1313 struct v4l2_event ev;
1317 memset(&ev, 0, sizeof(ev)); 1314 memset(&ev, 0, sizeof(ev));
1318 1315
1319 while (device_->Ioctl(VIDIOC_DQEVENT, &ev) == 0) { 1316 while (device_->Ioctl(VIDIOC_DQEVENT, &ev) == 0) {
1320 if (ev.type == V4L2_EVENT_SOURCE_CHANGE) { 1317 if (ev.type == V4L2_EVENT_SOURCE_CHANGE) {
1321 if (ev.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) { 1318 if (ev.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) {
1322 DVLOGF(3) << "got resolution change event."; 1319 DVLOGF(3) << "got resolution change event.";
Pawel Osciak 2017/05/23 09:49:21 2?
Owen Lin 2017/06/02 08:51:43 Done.
1323 return true; 1320 return true;
1324 } 1321 }
1325 } else { 1322 } else {
1326 LOGF(ERROR) << "got an event (" << ev.type 1323 LOGF(ERROR) << "got an event (" << ev.type
1327 << ") we haven't subscribed to."; 1324 << ") we haven't subscribed to.";
1328 } 1325 }
1329 } 1326 }
1330 return false; 1327 return false;
1331 } 1328 }
1332 1329
1333 void V4L2VideoDecodeAccelerator::Dequeue() { 1330 void V4L2VideoDecodeAccelerator::Dequeue() {
1334 DVLOGF(3); 1331 DVLOGF(3);
Pawel Osciak 2017/05/23 09:49:21 Perhaps 4?
Owen Lin 2017/06/02 08:51:43 Done.
1335 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1332 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1336 DCHECK_NE(decoder_state_, kUninitialized); 1333 DCHECK_NE(decoder_state_, kUninitialized);
1337 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue"); 1334 TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue");
1338 1335
1339 while (input_buffer_queued_count_ > 0) { 1336 while (input_buffer_queued_count_ > 0) {
1340 if (!DequeueInputBuffer()) 1337 if (!DequeueInputBuffer())
1341 break; 1338 break;
1342 } 1339 }
1343 while (output_buffer_queued_count_ > 0) { 1340 while (output_buffer_queued_count_ > 0) {
1344 if (!DequeueOutputBuffer()) 1341 if (!DequeueOutputBuffer())
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 DCHECK_EQ(output_record.state, kAtDevice); 1411 DCHECK_EQ(output_record.state, kAtDevice);
1415 DCHECK_NE(output_record.picture_id, -1); 1412 DCHECK_NE(output_record.picture_id, -1);
1416 output_buffer_queued_count_--; 1413 output_buffer_queued_count_--;
1417 if (dqbuf.m.planes[0].bytesused == 0) { 1414 if (dqbuf.m.planes[0].bytesused == 0) {
1418 // This is an empty output buffer returned as part of a flush. 1415 // This is an empty output buffer returned as part of a flush.
1419 output_record.state = kFree; 1416 output_record.state = kFree;
1420 free_output_buffers_.push_back(dqbuf.index); 1417 free_output_buffers_.push_back(dqbuf.index);
1421 } else { 1418 } else {
1422 int32_t bitstream_buffer_id = dqbuf.timestamp.tv_sec; 1419 int32_t bitstream_buffer_id = dqbuf.timestamp.tv_sec;
1423 DCHECK_GE(bitstream_buffer_id, 0); 1420 DCHECK_GE(bitstream_buffer_id, 0);
1424 DVLOGF(3) << "Dequeue output buffer: dqbuf index=" << dqbuf.index 1421 DVLOGF(3) << "Dequeue output buffer: dqbuf index=" << dqbuf.index
Pawel Osciak 2017/05/23 09:49:22 Perhaps 4?
Owen Lin 2017/06/02 08:51:43 Done.
1425 << " bitstream input_id=" << bitstream_buffer_id; 1422 << " bitstream input_id=" << bitstream_buffer_id;
1426 if (image_processor_device_) { 1423 if (image_processor_device_) {
1427 if (!ProcessFrame(bitstream_buffer_id, dqbuf.index)) { 1424 if (!ProcessFrame(bitstream_buffer_id, dqbuf.index)) {
1428 DLOGF(ERROR) << "Processing frame failed"; 1425 DLOGF(ERROR) << "Processing frame failed";
1429 NOTIFY_ERROR(PLATFORM_FAILURE); 1426 NOTIFY_ERROR(PLATFORM_FAILURE);
1430 return false; 1427 return false;
1431 } 1428 }
1432 } else { 1429 } else {
1433 output_record.state = kAtClient; 1430 output_record.state = kAtClient;
1434 decoder_frames_at_client_++; 1431 decoder_frames_at_client_++;
(...skipping 14 matching lines...) Expand all
1449 struct v4l2_decoder_cmd cmd; 1446 struct v4l2_decoder_cmd cmd;
1450 memset(&cmd, 0, sizeof(cmd)); 1447 memset(&cmd, 0, sizeof(cmd));
1451 cmd.cmd = V4L2_DEC_CMD_START; 1448 cmd.cmd = V4L2_DEC_CMD_START;
1452 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_DECODER_CMD, &cmd); 1449 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_DECODER_CMD, &cmd);
1453 } 1450 }
1454 } 1451 }
1455 return true; 1452 return true;
1456 } 1453 }
1457 1454
1458 bool V4L2VideoDecodeAccelerator::EnqueueInputRecord() { 1455 bool V4L2VideoDecodeAccelerator::EnqueueInputRecord() {
1459 DVLOGF(3); 1456 DVLOGF(3);
Pawel Osciak 2017/05/23 09:49:22 Perhaps 4?
Owen Lin 2017/06/02 08:51:43 Done.
1460 DCHECK(!input_ready_queue_.empty()); 1457 DCHECK(!input_ready_queue_.empty());
1461 1458
1462 // Enqueue an input (VIDEO_OUTPUT) buffer. 1459 // Enqueue an input (VIDEO_OUTPUT) buffer.
1463 const int buffer = input_ready_queue_.front(); 1460 const int buffer = input_ready_queue_.front();
1464 InputRecord& input_record = input_buffer_map_[buffer]; 1461 InputRecord& input_record = input_buffer_map_[buffer];
1465 DCHECK(!input_record.at_device); 1462 DCHECK(!input_record.at_device);
1466 struct v4l2_buffer qbuf; 1463 struct v4l2_buffer qbuf;
1467 struct v4l2_plane qbuf_plane; 1464 struct v4l2_plane qbuf_plane;
1468 memset(&qbuf, 0, sizeof(qbuf)); 1465 memset(&qbuf, 0, sizeof(qbuf));
1469 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1466 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1470 qbuf.index = buffer; 1467 qbuf.index = buffer;
1471 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1468 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1472 qbuf.timestamp.tv_sec = input_record.input_id; 1469 qbuf.timestamp.tv_sec = input_record.input_id;
1473 qbuf.memory = V4L2_MEMORY_MMAP; 1470 qbuf.memory = V4L2_MEMORY_MMAP;
1474 qbuf.m.planes = &qbuf_plane; 1471 qbuf.m.planes = &qbuf_plane;
1475 qbuf.m.planes[0].bytesused = input_record.bytes_used; 1472 qbuf.m.planes[0].bytesused = input_record.bytes_used;
1476 qbuf.length = 1; 1473 qbuf.length = 1;
1477 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 1474 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
1478 input_ready_queue_.pop(); 1475 input_ready_queue_.pop();
1479 input_record.at_device = true; 1476 input_record.at_device = true;
1480 input_buffer_queued_count_++; 1477 input_buffer_queued_count_++;
1481 DVLOGF(3) << "enqueued input_id=" << input_record.input_id 1478 DVLOGF(3) << "enqueued input_id=" << input_record.input_id
Pawel Osciak 2017/05/23 09:49:21 Perhaps 4?
Owen Lin 2017/06/02 08:51:43 Done.
1482 << " size=" << input_record.bytes_used; 1479 << " size=" << input_record.bytes_used;
1483 return true; 1480 return true;
1484 } 1481 }
1485 1482
1486 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() { 1483 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() {
1487 DCHECK(!free_output_buffers_.empty()); 1484 DCHECK(!free_output_buffers_.empty());
1488 1485
1489 // Enqueue an output (VIDEO_CAPTURE) buffer. 1486 // Enqueue an output (VIDEO_CAPTURE) buffer.
1490 const int buffer = free_output_buffers_.front(); 1487 const int buffer = free_output_buffers_.front();
1491 DVLOGF(3) << "buffer " << buffer; 1488 DVLOGF(3) << "buffer " << buffer;
Pawel Osciak 2017/05/23 09:49:21 Perhaps 4?
Owen Lin 2017/06/02 08:51:43 Done.
1492 OutputRecord& output_record = output_buffer_map_[buffer]; 1489 OutputRecord& output_record = output_buffer_map_[buffer];
1493 DCHECK_EQ(output_record.state, kFree); 1490 DCHECK_EQ(output_record.state, kFree);
1494 DCHECK_NE(output_record.picture_id, -1); 1491 DCHECK_NE(output_record.picture_id, -1);
1495 if (output_record.egl_sync != EGL_NO_SYNC_KHR) { 1492 if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
1496 TRACE_EVENT0("Video Decoder", 1493 TRACE_EVENT0("Video Decoder",
1497 "V4L2VDA::EnqueueOutputRecord: eglClientWaitSyncKHR"); 1494 "V4L2VDA::EnqueueOutputRecord: eglClientWaitSyncKHR");
1498 // If we have to wait for completion, wait. Note that 1495 // If we have to wait for completion, wait. Note that
1499 // free_output_buffers_ is a FIFO queue, so we always wait on the 1496 // free_output_buffers_ is a FIFO queue, so we always wait on the
1500 // buffer that has been in the queue the longest. 1497 // buffer that has been in the queue the longest.
1501 if (eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0, 1498 if (eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
(...skipping 12 matching lines...) Expand all
1514 std::unique_ptr<struct v4l2_plane[]> qbuf_planes( 1511 std::unique_ptr<struct v4l2_plane[]> qbuf_planes(
1515 new v4l2_plane[output_planes_count_]); 1512 new v4l2_plane[output_planes_count_]);
1516 memset(&qbuf, 0, sizeof(qbuf)); 1513 memset(&qbuf, 0, sizeof(qbuf));
1517 memset(qbuf_planes.get(), 0, 1514 memset(qbuf_planes.get(), 0,
1518 sizeof(struct v4l2_plane) * output_planes_count_); 1515 sizeof(struct v4l2_plane) * output_planes_count_);
1519 qbuf.index = buffer; 1516 qbuf.index = buffer;
1520 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1517 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1521 qbuf.memory = V4L2_MEMORY_MMAP; 1518 qbuf.memory = V4L2_MEMORY_MMAP;
1522 qbuf.m.planes = qbuf_planes.get(); 1519 qbuf.m.planes = qbuf_planes.get();
1523 qbuf.length = output_planes_count_; 1520 qbuf.length = output_planes_count_;
1524 DVLOGF(2) << "qbuf.index=" << qbuf.index; 1521 DVLOGF(3) << "qbuf.index=" << qbuf.index;
Pawel Osciak 2017/05/23 09:49:21 Perhaps 4?
Owen Lin 2017/06/02 08:51:43 Done.
1525 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 1522 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
1526 free_output_buffers_.pop_front(); 1523 free_output_buffers_.pop_front();
1527 output_record.state = kAtDevice; 1524 output_record.state = kAtDevice;
1528 output_buffer_queued_count_++; 1525 output_buffer_queued_count_++;
1529 return true; 1526 return true;
1530 } 1527 }
1531 1528
1532 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask( 1529 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask(
1533 int32_t picture_buffer_id, 1530 int32_t picture_buffer_id,
1534 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref) { 1531 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref) {
1535 DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id; 1532 DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id;
1536 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1533 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1537 TRACE_EVENT0("Video Decoder", "V4L2VDA::ReusePictureBufferTask"); 1534 TRACE_EVENT0("Video Decoder", "V4L2VDA::ReusePictureBufferTask");
1538 1535
1539 // We run ReusePictureBufferTask even if we're in kResetting. 1536 // We run ReusePictureBufferTask even if we're in kResetting.
1540 if (decoder_state_ == kError) { 1537 if (decoder_state_ == kError) {
1541 DVLOGF(2) << "early out: kError state"; 1538 DVLOGF(4) << "early out: kError state";
1542 return; 1539 return;
1543 } 1540 }
1544 1541
1545 if (decoder_state_ == kChangingResolution) { 1542 if (decoder_state_ == kChangingResolution) {
1546 DVLOGF(2) << "early out: kChangingResolution"; 1543 DVLOGF(4) << "early out: kChangingResolution";
1547 return; 1544 return;
1548 } 1545 }
1549 1546
1550 size_t index; 1547 size_t index;
1551 for (index = 0; index < output_buffer_map_.size(); ++index) 1548 for (index = 0; index < output_buffer_map_.size(); ++index)
1552 if (output_buffer_map_[index].picture_id == picture_buffer_id) 1549 if (output_buffer_map_[index].picture_id == picture_buffer_id)
1553 break; 1550 break;
1554 1551
1555 if (index >= output_buffer_map_.size()) { 1552 if (index >= output_buffer_map_.size()) {
1556 // It's possible that we've already posted a DismissPictureBuffer for this 1553 // It's possible that we've already posted a DismissPictureBuffer for this
(...skipping 20 matching lines...) Expand all
1577 if (egl_sync_ref) { 1574 if (egl_sync_ref) {
1578 output_record.egl_sync = egl_sync_ref->egl_sync; 1575 output_record.egl_sync = egl_sync_ref->egl_sync;
1579 // Take ownership of the EGLSync. 1576 // Take ownership of the EGLSync.
1580 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; 1577 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1581 } 1578 }
1582 // We got a buffer back, so enqueue it back. 1579 // We got a buffer back, so enqueue it back.
1583 Enqueue(); 1580 Enqueue();
1584 } 1581 }
1585 1582
1586 void V4L2VideoDecodeAccelerator::FlushTask() { 1583 void V4L2VideoDecodeAccelerator::FlushTask() {
1587 DVLOGF(3); 1584 DVLOGF(2);
1588 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1585 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1589 TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask"); 1586 TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask");
1590 1587
1591 // Flush outstanding buffers. 1588 // Flush outstanding buffers.
1592 if (decoder_state_ == kInitialized) { 1589 if (decoder_state_ == kInitialized) {
1593 // There's nothing in the pipe, so return done immediately. 1590 // There's nothing in the pipe, so return done immediately.
1594 DVLOGF(3) << "returning flush"; 1591 DVLOGF(2) << "returning flush";
1595 child_task_runner_->PostTask(FROM_HERE, 1592 child_task_runner_->PostTask(FROM_HERE,
1596 base::Bind(&Client::NotifyFlushDone, client_)); 1593 base::Bind(&Client::NotifyFlushDone, client_));
1597 return; 1594 return;
1598 } else if (decoder_state_ == kError) { 1595 } else if (decoder_state_ == kError) {
1599 DVLOGF(2) << "early out: kError state"; 1596 DVLOGF(2) << "early out: kError state";
1600 return; 1597 return;
1601 } 1598 }
1602 1599
1603 // We don't support stacked flushing. 1600 // We don't support stacked flushing.
1604 DCHECK(!decoder_flushing_); 1601 DCHECK(!decoder_flushing_);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 // For now, do the streamoff-streamon cycle to satisfy Exynos and not freeze 1655 // For now, do the streamoff-streamon cycle to satisfy Exynos and not freeze
1659 // when doing MSE. This should be harmless otherwise. 1656 // when doing MSE. This should be harmless otherwise.
1660 if (!(StopDevicePoll() && StopOutputStream() && StopInputStream())) 1657 if (!(StopDevicePoll() && StopOutputStream() && StopInputStream()))
1661 return; 1658 return;
1662 1659
1663 if (!StartDevicePoll()) 1660 if (!StartDevicePoll())
1664 return; 1661 return;
1665 1662
1666 decoder_delay_bitstream_buffer_id_ = -1; 1663 decoder_delay_bitstream_buffer_id_ = -1;
1667 decoder_flushing_ = false; 1664 decoder_flushing_ = false;
1668 DVLOGF(3) << "returning flush"; 1665 DVLOGF(2) << "returning flush";
1669 child_task_runner_->PostTask(FROM_HERE, 1666 child_task_runner_->PostTask(FROM_HERE,
1670 base::Bind(&Client::NotifyFlushDone, client_)); 1667 base::Bind(&Client::NotifyFlushDone, client_));
1671 1668
1672 // While we were flushing, we early-outed DecodeBufferTask()s. 1669 // While we were flushing, we early-outed DecodeBufferTask()s.
1673 ScheduleDecodeBufferTaskIfNeeded(); 1670 ScheduleDecodeBufferTaskIfNeeded();
1674 } 1671 }
1675 1672
1676 bool V4L2VideoDecodeAccelerator::IsDecoderCmdSupported() { 1673 bool V4L2VideoDecodeAccelerator::IsDecoderCmdSupported() {
1677 // CMD_STOP should always succeed. If the decoder is started, the command can 1674 // CMD_STOP should always succeed. If the decoder is started, the command can
1678 // flush it. If the decoder is stopped, the command does nothing. We use this 1675 // flush it. If the decoder is stopped, the command does nothing. We use this
1679 // to know if a driver supports V4L2_DEC_CMD_STOP to flush. 1676 // to know if a driver supports V4L2_DEC_CMD_STOP to flush.
1680 struct v4l2_decoder_cmd cmd; 1677 struct v4l2_decoder_cmd cmd;
1681 memset(&cmd, 0, sizeof(cmd)); 1678 memset(&cmd, 0, sizeof(cmd));
1682 cmd.cmd = V4L2_DEC_CMD_STOP; 1679 cmd.cmd = V4L2_DEC_CMD_STOP;
1683 if (device_->Ioctl(VIDIOC_TRY_DECODER_CMD, &cmd) != 0) { 1680 if (device_->Ioctl(VIDIOC_TRY_DECODER_CMD, &cmd) != 0) {
1684 DVLOGF(3) "V4L2_DEC_CMD_STOP is not supported."; 1681 DVLOGF(2) "V4L2_DEC_CMD_STOP is not supported.";
1685 return false; 1682 return false;
1686 } 1683 }
1687 1684
1688 return true; 1685 return true;
1689 } 1686 }
1690 1687
1691 bool V4L2VideoDecodeAccelerator::SendDecoderCmdStop() { 1688 bool V4L2VideoDecodeAccelerator::SendDecoderCmdStop() {
1692 DVLOGF(2); 1689 DVLOGF(2);
1693 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1690 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1694 DCHECK(!flush_awaiting_last_output_buffer_); 1691 DCHECK(!flush_awaiting_last_output_buffer_);
1695 1692
1696 struct v4l2_decoder_cmd cmd; 1693 struct v4l2_decoder_cmd cmd;
1697 memset(&cmd, 0, sizeof(cmd)); 1694 memset(&cmd, 0, sizeof(cmd));
1698 cmd.cmd = V4L2_DEC_CMD_STOP; 1695 cmd.cmd = V4L2_DEC_CMD_STOP;
1699 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_DECODER_CMD, &cmd); 1696 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_DECODER_CMD, &cmd);
1700 flush_awaiting_last_output_buffer_ = true; 1697 flush_awaiting_last_output_buffer_ = true;
1701 1698
1702 return true; 1699 return true;
1703 } 1700 }
1704 1701
1705 void V4L2VideoDecodeAccelerator::ResetTask() { 1702 void V4L2VideoDecodeAccelerator::ResetTask() {
1706 DVLOGF(3); 1703 DVLOGF(2);
1707 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1704 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1708 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask"); 1705 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask");
1709 1706
1710 if (decoder_state_ == kError) { 1707 if (decoder_state_ == kError) {
1711 DVLOGF(2) << "early out: kError state"; 1708 DVLOGF(2) << "early out: kError state";
1712 return; 1709 return;
1713 } 1710 }
1714 decoder_current_bitstream_buffer_.reset(); 1711 decoder_current_bitstream_buffer_.reset();
1715 while (!decoder_input_queue_.empty()) 1712 while (!decoder_input_queue_.empty())
1716 decoder_input_queue_.pop(); 1713 decoder_input_queue_.pop();
1717 1714
1718 decoder_current_input_buffer_ = -1; 1715 decoder_current_input_buffer_ = -1;
1719 1716
1720 // If we are in the middle of switching resolutions or awaiting picture 1717 // If we are in the middle of switching resolutions or awaiting picture
1721 // buffers, postpone reset until it's done. We don't have to worry about 1718 // buffers, postpone reset until it's done. We don't have to worry about
1722 // timing of this wrt to decoding, because output pipe is already 1719 // timing of this wrt to decoding, because output pipe is already
1723 // stopped if we are changing resolution. We will come back here after 1720 // stopped if we are changing resolution. We will come back here after
1724 // we are done. 1721 // we are done.
1725 DCHECK(!reset_pending_); 1722 DCHECK(!reset_pending_);
1726 if (decoder_state_ == kChangingResolution || 1723 if (decoder_state_ == kChangingResolution ||
1727 decoder_state_ == kAwaitingPictureBuffers) { 1724 decoder_state_ == kAwaitingPictureBuffers) {
1728 reset_pending_ = true; 1725 reset_pending_ = true;
1729 return; 1726 return;
1730 } 1727 }
1731 FinishReset(); 1728 FinishReset();
1732 } 1729 }
1733 1730
1734 void V4L2VideoDecodeAccelerator::FinishReset() { 1731 void V4L2VideoDecodeAccelerator::FinishReset() {
1735 DVLOGF(3); 1732 DVLOGF(2);
1736 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1733 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1737 1734
1738 reset_pending_ = false; 1735 reset_pending_ = false;
1739 // After the output stream is stopped, the codec should not post any 1736 // After the output stream is stopped, the codec should not post any
1740 // resolution change events. So we dequeue the resolution change event 1737 // resolution change events. So we dequeue the resolution change event
1741 // afterwards. The event could be posted before or while stopping the output 1738 // afterwards. The event could be posted before or while stopping the output
1742 // stream. The codec will expect the buffer of new size after the seek, so 1739 // stream. The codec will expect the buffer of new size after the seek, so
1743 // we need to handle the resolution change event first. 1740 // we need to handle the resolution change event first.
1744 if (!(StopDevicePoll() && StopOutputStream())) 1741 if (!(StopDevicePoll() && StopOutputStream()))
1745 return; 1742 return;
(...skipping 21 matching lines...) Expand all
1767 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1764 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
1768 // jobs will early-out in the kResetting state. 1765 // jobs will early-out in the kResetting state.
1769 decoder_state_ = kResetting; 1766 decoder_state_ = kResetting;
1770 SendPictureReady(); // Send all pending PictureReady. 1767 SendPictureReady(); // Send all pending PictureReady.
1771 decoder_thread_.task_runner()->PostTask( 1768 decoder_thread_.task_runner()->PostTask(
1772 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetDoneTask, 1769 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetDoneTask,
1773 base::Unretained(this))); 1770 base::Unretained(this)));
1774 } 1771 }
1775 1772
1776 void V4L2VideoDecodeAccelerator::ResetDoneTask() { 1773 void V4L2VideoDecodeAccelerator::ResetDoneTask() {
1777 DVLOGF(3); 1774 DVLOGF(2);
1778 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1775 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1779 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); 1776 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask");
1780 1777
1781 if (decoder_state_ == kError) { 1778 if (decoder_state_ == kError) {
1782 DVLOGF(2) << "early out: kError state"; 1779 DVLOGF(2) << "early out: kError state";
1783 return; 1780 return;
1784 } 1781 }
1785 1782
1786 // Start poll thread if NotifyFlushDoneIfNeeded has not already. 1783 // Start poll thread if NotifyFlushDoneIfNeeded has not already.
1787 if (!device_poll_thread_.IsRunning()) { 1784 if (!device_poll_thread_.IsRunning()) {
(...skipping 13 matching lines...) Expand all
1801 decoder_partial_frame_pending_ = false; 1798 decoder_partial_frame_pending_ = false;
1802 decoder_delay_bitstream_buffer_id_ = -1; 1799 decoder_delay_bitstream_buffer_id_ = -1;
1803 child_task_runner_->PostTask(FROM_HERE, 1800 child_task_runner_->PostTask(FROM_HERE,
1804 base::Bind(&Client::NotifyResetDone, client_)); 1801 base::Bind(&Client::NotifyResetDone, client_));
1805 1802
1806 // While we were resetting, we early-outed DecodeBufferTask()s. 1803 // While we were resetting, we early-outed DecodeBufferTask()s.
1807 ScheduleDecodeBufferTaskIfNeeded(); 1804 ScheduleDecodeBufferTaskIfNeeded();
1808 } 1805 }
1809 1806
1810 void V4L2VideoDecodeAccelerator::DestroyTask() { 1807 void V4L2VideoDecodeAccelerator::DestroyTask() {
1811 DVLOGF(3); 1808 DVLOGF(2);
1812 TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask"); 1809 TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask");
1813 1810
1814 // DestroyTask() should run regardless of decoder_state_. 1811 // DestroyTask() should run regardless of decoder_state_.
1815 1812
1816 StopDevicePoll(); 1813 StopDevicePoll();
1817 StopOutputStream(); 1814 StopOutputStream();
1818 StopInputStream(); 1815 StopInputStream();
1819 1816
1820 decoder_current_bitstream_buffer_.reset(); 1817 decoder_current_bitstream_buffer_.reset();
1821 decoder_current_input_buffer_ = -1; 1818 decoder_current_input_buffer_ = -1;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 // Clear the interrupt now, to be sure. 1869 // Clear the interrupt now, to be sure.
1873 if (!device_->ClearDevicePollInterrupt()) { 1870 if (!device_->ClearDevicePollInterrupt()) {
1874 NOTIFY_ERROR(PLATFORM_FAILURE); 1871 NOTIFY_ERROR(PLATFORM_FAILURE);
1875 return false; 1872 return false;
1876 } 1873 }
1877 DVLOGF(3) << "device poll stopped"; 1874 DVLOGF(3) << "device poll stopped";
1878 return true; 1875 return true;
1879 } 1876 }
1880 1877
1881 bool V4L2VideoDecodeAccelerator::StopOutputStream() { 1878 bool V4L2VideoDecodeAccelerator::StopOutputStream() {
1882 DVLOGF(3); 1879 DVLOGF(2);
1883 if (!output_streamon_) 1880 if (!output_streamon_)
1884 return true; 1881 return true;
1885 1882
1886 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1883 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1887 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type); 1884 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type);
1888 output_streamon_ = false; 1885 output_streamon_ = false;
1889 1886
1890 // Output stream is stopped. No need to wait for the buffer anymore. 1887 // Output stream is stopped. No need to wait for the buffer anymore.
1891 flush_awaiting_last_output_buffer_ = false; 1888 flush_awaiting_last_output_buffer_ = false;
1892 1889
1893 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 1890 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
1894 // After streamoff, the device drops ownership of all buffers, even if we 1891 // After streamoff, the device drops ownership of all buffers, even if we
1895 // don't dequeue them explicitly. Some of them may still be owned by the 1892 // don't dequeue them explicitly. Some of them may still be owned by the
1896 // client however. Reuse only those that aren't. 1893 // client however. Reuse only those that aren't.
1897 OutputRecord& output_record = output_buffer_map_[i]; 1894 OutputRecord& output_record = output_buffer_map_[i];
1898 if (output_record.state == kAtDevice) { 1895 if (output_record.state == kAtDevice) {
1899 output_record.state = kFree; 1896 output_record.state = kFree;
1900 free_output_buffers_.push_back(i); 1897 free_output_buffers_.push_back(i);
1901 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); 1898 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
1902 } 1899 }
1903 } 1900 }
1904 output_buffer_queued_count_ = 0; 1901 output_buffer_queued_count_ = 0;
1905 return true; 1902 return true;
1906 } 1903 }
1907 1904
1908 bool V4L2VideoDecodeAccelerator::StopInputStream() { 1905 bool V4L2VideoDecodeAccelerator::StopInputStream() {
1909 DVLOGF(3); 1906 DVLOGF(2);
1910 if (!input_streamon_) 1907 if (!input_streamon_)
1911 return true; 1908 return true;
1912 1909
1913 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1910 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1914 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type); 1911 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type);
1915 input_streamon_ = false; 1912 input_streamon_ = false;
1916 1913
1917 // Reset accounting info for input. 1914 // Reset accounting info for input.
1918 while (!input_ready_queue_.empty()) 1915 while (!input_ready_queue_.empty())
1919 input_ready_queue_.pop(); 1916 input_ready_queue_.pop();
1920 free_input_buffers_.clear(); 1917 free_input_buffers_.clear();
1921 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 1918 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
1922 free_input_buffers_.push_back(i); 1919 free_input_buffers_.push_back(i);
1923 input_buffer_map_[i].at_device = false; 1920 input_buffer_map_[i].at_device = false;
1924 input_buffer_map_[i].bytes_used = 0; 1921 input_buffer_map_[i].bytes_used = 0;
1925 input_buffer_map_[i].input_id = -1; 1922 input_buffer_map_[i].input_id = -1;
1926 } 1923 }
1927 input_buffer_queued_count_ = 0; 1924 input_buffer_queued_count_ = 0;
1928 1925
1929 return true; 1926 return true;
1930 } 1927 }
1931 1928
1932 void V4L2VideoDecodeAccelerator::StartResolutionChange() { 1929 void V4L2VideoDecodeAccelerator::StartResolutionChange() {
1933 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1930 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1934 DCHECK_NE(decoder_state_, kUninitialized); 1931 DCHECK_NE(decoder_state_, kUninitialized);
1935 DCHECK_NE(decoder_state_, kResetting); 1932 DCHECK_NE(decoder_state_, kResetting);
1936 1933
1937 DVLOGF(3) << "Initiate resolution change"; 1934 DVLOGF(2) << "Initiate resolution change";
1938 1935
1939 if (!(StopDevicePoll() && StopOutputStream())) 1936 if (!(StopDevicePoll() && StopOutputStream()))
1940 return; 1937 return;
1941 1938
1942 decoder_state_ = kChangingResolution; 1939 decoder_state_ = kChangingResolution;
1943 SendPictureReady(); // Send all pending PictureReady. 1940 SendPictureReady(); // Send all pending PictureReady.
1944 1941
1945 if (!image_processor_bitstream_buffer_ids_.empty()) { 1942 if (!image_processor_bitstream_buffer_ids_.empty()) {
1946 DVLOGF(3) << "Wait image processor to finish before destroying buffers."; 1943 DVLOGF(2) << "Wait image processor to finish before destroying buffers.";
1947 return; 1944 return;
1948 } 1945 }
1949 1946
1950 if (image_processor_) 1947 if (image_processor_)
1951 image_processor_.release()->Destroy(); 1948 image_processor_.release()->Destroy();
1952 1949
1953 if (!DestroyOutputBuffers()) { 1950 if (!DestroyOutputBuffers()) {
1954 LOGF(ERROR) << "Failed destroying output buffers."; 1951 LOGF(ERROR) << "Failed destroying output buffers.";
1955 NOTIFY_ERROR(PLATFORM_FAILURE); 1952 NOTIFY_ERROR(PLATFORM_FAILURE);
1956 return; 1953 return;
1957 } 1954 }
1958 1955
1959 FinishResolutionChange(); 1956 FinishResolutionChange();
1960 } 1957 }
1961 1958
1962 void V4L2VideoDecodeAccelerator::FinishResolutionChange() { 1959 void V4L2VideoDecodeAccelerator::FinishResolutionChange() {
1963 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 1960 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
1964 DCHECK_EQ(decoder_state_, kChangingResolution); 1961 DCHECK_EQ(decoder_state_, kChangingResolution);
1965 DVLOGF(3); 1962 DVLOGF(2);
1966 1963
1967 if (decoder_state_ == kError) { 1964 if (decoder_state_ == kError) {
1968 DVLOGF(2) << "early out: kError state"; 1965 DVLOGF(2) << "early out: kError state";
1969 return; 1966 return;
1970 } 1967 }
1971 1968
1972 struct v4l2_format format; 1969 struct v4l2_format format;
1973 bool again; 1970 bool again;
1974 gfx::Size visible_size; 1971 gfx::Size visible_size;
1975 bool ret = GetFormatInfo(&format, &visible_size, &again); 1972 bool ret = GetFormatInfo(&format, &visible_size, &again);
1976 if (!ret || again) { 1973 if (!ret || again) {
1977 LOGF(ERROR) << "Couldn't get format information after resolution change"; 1974 LOGF(ERROR) << "Couldn't get format information after resolution change";
1978 NOTIFY_ERROR(PLATFORM_FAILURE); 1975 NOTIFY_ERROR(PLATFORM_FAILURE);
1979 return; 1976 return;
1980 } 1977 }
1981 1978
1982 if (!CreateBuffersForFormat(format, visible_size)) { 1979 if (!CreateBuffersForFormat(format, visible_size)) {
1983 LOGF(ERROR) << "Couldn't reallocate buffers after resolution change"; 1980 LOGF(ERROR) << "Couldn't reallocate buffers after resolution change";
1984 NOTIFY_ERROR(PLATFORM_FAILURE); 1981 NOTIFY_ERROR(PLATFORM_FAILURE);
1985 return; 1982 return;
1986 } 1983 }
1987 1984
1988 if (!StartDevicePoll()) 1985 if (!StartDevicePoll())
1989 return; 1986 return;
1990 } 1987 }
1991 1988
1992 void V4L2VideoDecodeAccelerator::DevicePollTask(bool poll_device) { 1989 void V4L2VideoDecodeAccelerator::DevicePollTask(bool poll_device) {
1993 DVLOGF(3); 1990 DVLOGF(3);
Pawel Osciak 2017/05/23 09:49:21 4 perhaps?
Owen Lin 2017/06/02 08:51:43 Done.
1994 DCHECK(device_poll_thread_.task_runner()->BelongsToCurrentThread()); 1991 DCHECK(device_poll_thread_.task_runner()->BelongsToCurrentThread());
1995 TRACE_EVENT0("Video Decoder", "V4L2VDA::DevicePollTask"); 1992 TRACE_EVENT0("Video Decoder", "V4L2VDA::DevicePollTask");
1996 1993
1997 bool event_pending = false; 1994 bool event_pending = false;
1998 1995
1999 if (!device_->Poll(poll_device, &event_pending)) { 1996 if (!device_->Poll(poll_device, &event_pending)) {
2000 NOTIFY_ERROR(PLATFORM_FAILURE); 1997 NOTIFY_ERROR(PLATFORM_FAILURE);
2001 return; 1998 return;
2002 } 1999 }
2003 2000
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2089 if (!V4L2ImageProcessor::TryOutputFormat( 2086 if (!V4L2ImageProcessor::TryOutputFormat(
2090 output_format_fourcc_, egl_image_format_fourcc_, &egl_image_size_, 2087 output_format_fourcc_, egl_image_format_fourcc_, &egl_image_size_,
2091 &egl_image_planes_count_)) { 2088 &egl_image_planes_count_)) {
2092 LOGF(ERROR) << "Fail to get output size and plane count of processor"; 2089 LOGF(ERROR) << "Fail to get output size and plane count of processor";
2093 return false; 2090 return false;
2094 } 2091 }
2095 } else { 2092 } else {
2096 egl_image_size_ = coded_size_; 2093 egl_image_size_ = coded_size_;
2097 egl_image_planes_count_ = output_planes_count_; 2094 egl_image_planes_count_ = output_planes_count_;
2098 } 2095 }
2099 DVLOGF(3) << "new resolution: " << coded_size_.ToString() 2096 DVLOGF(2) << "new resolution: " << coded_size_.ToString()
2100 << ", visible size: " << visible_size_.ToString() 2097 << ", visible size: " << visible_size_.ToString()
2101 << ", decoder output planes count: " << output_planes_count_ 2098 << ", decoder output planes count: " << output_planes_count_
2102 << ", EGLImage size: " << egl_image_size_.ToString() 2099 << ", EGLImage size: " << egl_image_size_.ToString()
2103 << ", EGLImage plane count: " << egl_image_planes_count_; 2100 << ", EGLImage plane count: " << egl_image_planes_count_;
2104 2101
2105 return CreateOutputBuffers(); 2102 return CreateOutputBuffers();
2106 } 2103 }
2107 2104
2108 gfx::Size V4L2VideoDecodeAccelerator::GetVisibleSize( 2105 gfx::Size V4L2VideoDecodeAccelerator::GetVisibleSize(
2109 const gfx::Size& coded_size) { 2106 const gfx::Size& coded_size) {
2110 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2107 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2111 2108
2112 struct v4l2_crop crop_arg; 2109 struct v4l2_crop crop_arg;
2113 memset(&crop_arg, 0, sizeof(crop_arg)); 2110 memset(&crop_arg, 0, sizeof(crop_arg));
2114 crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2111 crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2115 2112
2116 if (device_->Ioctl(VIDIOC_G_CROP, &crop_arg) != 0) { 2113 if (device_->Ioctl(VIDIOC_G_CROP, &crop_arg) != 0) {
2117 PLOGF(ERROR) << "ioctl() VIDIOC_G_CROP failed"; 2114 PLOGF(ERROR) << "ioctl() VIDIOC_G_CROP failed";
2118 return coded_size; 2115 return coded_size;
2119 } 2116 }
2120 2117
2121 gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width, 2118 gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width,
2122 crop_arg.c.height); 2119 crop_arg.c.height);
2123 DVLOGF(3) << "visible rectangle is " << rect.ToString(); 2120 DVLOGF(2) << "visible rectangle is " << rect.ToString();
2124 if (!gfx::Rect(coded_size).Contains(rect)) { 2121 if (!gfx::Rect(coded_size).Contains(rect)) {
2125 DLOGF(ERROR) << "visible rectangle " << rect.ToString() 2122 DLOGF(ERROR) << "visible rectangle " << rect.ToString()
2126 << " is not inside coded size " << coded_size.ToString(); 2123 << " is not inside coded size " << coded_size.ToString();
2127 return coded_size; 2124 return coded_size;
2128 } 2125 }
2129 if (rect.IsEmpty()) { 2126 if (rect.IsEmpty()) {
2130 DLOGF(ERROR) << "visible size is empty"; 2127 DLOGF(ERROR) << "visible size is empty";
2131 return coded_size; 2128 return coded_size;
2132 } 2129 }
2133 2130
2134 // Chrome assume picture frame is coded at (0, 0). 2131 // Chrome assume picture frame is coded at (0, 0).
2135 if (!rect.origin().IsOrigin()) { 2132 if (!rect.origin().IsOrigin()) {
2136 DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString() 2133 DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString()
2137 << ", top-left is not origin"; 2134 << ", top-left is not origin";
2138 return coded_size; 2135 return coded_size;
2139 } 2136 }
2140 2137
2141 return rect.size(); 2138 return rect.size();
2142 } 2139 }
2143 2140
2144 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { 2141 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
2145 DVLOGF(3); 2142 DVLOGF(2);
2146 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2143 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2147 // We always run this as we prepare to initialize. 2144 // We always run this as we prepare to initialize.
2148 DCHECK_EQ(decoder_state_, kInitialized); 2145 DCHECK_EQ(decoder_state_, kInitialized);
2149 DCHECK(!input_streamon_); 2146 DCHECK(!input_streamon_);
2150 DCHECK(input_buffer_map_.empty()); 2147 DCHECK(input_buffer_map_.empty());
2151 2148
2152 struct v4l2_requestbuffers reqbufs; 2149 struct v4l2_requestbuffers reqbufs;
2153 memset(&reqbufs, 0, sizeof(reqbufs)); 2150 memset(&reqbufs, 0, sizeof(reqbufs));
2154 reqbufs.count = kInputBufferCount; 2151 reqbufs.count = kInputBufferCount;
2155 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2152 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2289 std::vector<uint32_t> processor_input_formats = 2286 std::vector<uint32_t> processor_input_formats =
2290 V4L2ImageProcessor::GetSupportedInputFormats(); 2287 V4L2ImageProcessor::GetSupportedInputFormats();
2291 2288
2292 struct v4l2_fmtdesc fmtdesc; 2289 struct v4l2_fmtdesc fmtdesc;
2293 memset(&fmtdesc, 0, sizeof(fmtdesc)); 2290 memset(&fmtdesc, 0, sizeof(fmtdesc));
2294 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2291 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2295 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { 2292 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
2296 if (std::find(processor_input_formats.begin(), 2293 if (std::find(processor_input_formats.begin(),
2297 processor_input_formats.end(), 2294 processor_input_formats.end(),
2298 fmtdesc.pixelformat) != processor_input_formats.end()) { 2295 fmtdesc.pixelformat) != processor_input_formats.end()) {
2299 DVLOGF(1) << "Image processor input format=" << fmtdesc.description; 2296 DVLOGF(2) << "Image processor input format=" << fmtdesc.description;
2300 return fmtdesc.pixelformat; 2297 return fmtdesc.pixelformat;
2301 } 2298 }
2302 ++fmtdesc.index; 2299 ++fmtdesc.index;
2303 } 2300 }
2304 return 0; 2301 return 0;
2305 } 2302 }
2306 2303
2307 uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorOutputFormat() { 2304 uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorOutputFormat() {
2308 // Prefer YVU420 and NV12 because ArcGpuVideoDecodeAccelerator only supports 2305 // Prefer YVU420 and NV12 because ArcGpuVideoDecodeAccelerator only supports
2309 // single physical plane. Prefer YVU420 over NV12 because chrome rendering 2306 // single physical plane. Prefer YVU420 over NV12 because chrome rendering
(...skipping 10 matching lines...) Expand all
2320 2317
2321 std::vector<uint32_t> processor_output_formats = 2318 std::vector<uint32_t> processor_output_formats =
2322 V4L2ImageProcessor::GetSupportedOutputFormats(); 2319 V4L2ImageProcessor::GetSupportedOutputFormats();
2323 2320
2324 // Move the preferred formats to the front. 2321 // Move the preferred formats to the front.
2325 std::sort(processor_output_formats.begin(), processor_output_formats.end(), 2322 std::sort(processor_output_formats.begin(), processor_output_formats.end(),
2326 preferred_formats_first); 2323 preferred_formats_first);
2327 2324
2328 for (uint32_t processor_output_format : processor_output_formats) { 2325 for (uint32_t processor_output_format : processor_output_formats) {
2329 if (device_->CanCreateEGLImageFrom(processor_output_format)) { 2326 if (device_->CanCreateEGLImageFrom(processor_output_format)) {
2330 DVLOGF(1) << "Image processor output format=" << processor_output_format; 2327 DVLOGF(2) << "Image processor output format=" << processor_output_format;
2331 return processor_output_format; 2328 return processor_output_format;
2332 } 2329 }
2333 } 2330 }
2334 2331
2335 return 0; 2332 return 0;
2336 } 2333 }
2337 2334
2338 bool V4L2VideoDecodeAccelerator::ResetImageProcessor() { 2335 bool V4L2VideoDecodeAccelerator::ResetImageProcessor() {
2339 DVLOGF(3); 2336 DVLOGF(2);
2340 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2337 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2341 2338
2342 if (!image_processor_->Reset()) 2339 if (!image_processor_->Reset())
2343 return false; 2340 return false;
2344 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 2341 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
2345 OutputRecord& output_record = output_buffer_map_[i]; 2342 OutputRecord& output_record = output_buffer_map_[i];
2346 if (output_record.state == kAtProcessor) { 2343 if (output_record.state == kAtProcessor) {
2347 output_record.state = kFree; 2344 output_record.state = kFree;
2348 free_output_buffers_.push_back(i); 2345 free_output_buffers_.push_back(i);
2349 } 2346 }
2350 } 2347 }
2351 while (!image_processor_bitstream_buffer_ids_.empty()) 2348 while (!image_processor_bitstream_buffer_ids_.empty())
2352 image_processor_bitstream_buffer_ids_.pop(); 2349 image_processor_bitstream_buffer_ids_.pop();
2353 2350
2354 return true; 2351 return true;
2355 } 2352 }
2356 2353
2357 bool V4L2VideoDecodeAccelerator::CreateImageProcessor() { 2354 bool V4L2VideoDecodeAccelerator::CreateImageProcessor() {
2358 DVLOGF(3); 2355 DVLOGF(2);
2359 DCHECK(!image_processor_); 2356 DCHECK(!image_processor_);
2360 image_processor_.reset(new V4L2ImageProcessor(image_processor_device_)); 2357 image_processor_.reset(new V4L2ImageProcessor(image_processor_device_));
2361 v4l2_memory output_memory_type = 2358 v4l2_memory output_memory_type =
2362 (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP 2359 (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP
2363 : V4L2_MEMORY_DMABUF); 2360 : V4L2_MEMORY_DMABUF);
2364 // Unretained is safe because |this| owns image processor and there will be 2361 // Unretained is safe because |this| owns image processor and there will be
2365 // no callbacks after processor destroys. 2362 // no callbacks after processor destroys.
2366 if (!image_processor_->Initialize( 2363 if (!image_processor_->Initialize(
2367 V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_), 2364 V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_),
2368 V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_), 2365 V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_),
2369 V4L2_MEMORY_DMABUF, output_memory_type, visible_size_, coded_size_, 2366 V4L2_MEMORY_DMABUF, output_memory_type, visible_size_, coded_size_,
2370 visible_size_, egl_image_size_, output_buffer_map_.size(), 2367 visible_size_, egl_image_size_, output_buffer_map_.size(),
2371 base::Bind(&V4L2VideoDecodeAccelerator::ImageProcessorError, 2368 base::Bind(&V4L2VideoDecodeAccelerator::ImageProcessorError,
2372 base::Unretained(this)))) { 2369 base::Unretained(this)))) {
2373 LOGF(ERROR) << "Initialize image processor failed"; 2370 LOGF(ERROR) << "Initialize image processor failed";
2374 NOTIFY_ERROR(PLATFORM_FAILURE); 2371 NOTIFY_ERROR(PLATFORM_FAILURE);
2375 return false; 2372 return false;
2376 } 2373 }
2377 DVLOGF(3) << "image_processor_->output_allocated_size()=" 2374 DVLOGF(2) << "image_processor_->output_allocated_size()="
2378 << image_processor_->output_allocated_size().ToString(); 2375 << image_processor_->output_allocated_size().ToString();
2379 DCHECK(image_processor_->output_allocated_size() == egl_image_size_); 2376 DCHECK(image_processor_->output_allocated_size() == egl_image_size_);
2380 if (image_processor_->input_allocated_size() != coded_size_) { 2377 if (image_processor_->input_allocated_size() != coded_size_) {
2381 LOGF(ERROR) << "Image processor should be able to take the output coded " 2378 LOGF(ERROR) << "Image processor should be able to take the output coded "
2382 << "size of decoder " << coded_size_.ToString() 2379 << "size of decoder " << coded_size_.ToString()
2383 << " without adjusting to " 2380 << " without adjusting to "
2384 << image_processor_->input_allocated_size().ToString(); 2381 << image_processor_->input_allocated_size().ToString();
2385 NOTIFY_ERROR(PLATFORM_FAILURE); 2382 NOTIFY_ERROR(PLATFORM_FAILURE);
2386 return false; 2383 return false;
2387 } 2384 }
2388 return true; 2385 return true;
2389 } 2386 }
2390 2387
2391 bool V4L2VideoDecodeAccelerator::ProcessFrame(int32_t bitstream_buffer_id, 2388 bool V4L2VideoDecodeAccelerator::ProcessFrame(int32_t bitstream_buffer_id,
2392 int output_buffer_index) { 2389 int output_buffer_index) {
2393 DVLOGF(3); 2390 DVLOGF(4);
2394 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2391 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2395 2392
2396 OutputRecord& output_record = output_buffer_map_[output_buffer_index]; 2393 OutputRecord& output_record = output_buffer_map_[output_buffer_index];
2397 DCHECK_EQ(output_record.state, kAtDevice); 2394 DCHECK_EQ(output_record.state, kAtDevice);
2398 output_record.state = kAtProcessor; 2395 output_record.state = kAtProcessor;
2399 image_processor_bitstream_buffer_ids_.push(bitstream_buffer_id); 2396 image_processor_bitstream_buffer_ids_.push(bitstream_buffer_id);
2400 std::vector<int> processor_input_fds; 2397 std::vector<int> processor_input_fds;
2401 for (auto& fd : output_record.processor_input_fds) { 2398 for (auto& fd : output_record.processor_input_fds) {
2402 processor_input_fds.push_back(fd.get()); 2399 processor_input_fds.push_back(fd.get());
2403 } 2400 }
(...skipping 16 matching lines...) Expand all
2420 // Unretained is safe because |this| owns image processor and there will 2417 // Unretained is safe because |this| owns image processor and there will
2421 // be no callbacks after processor destroys. 2418 // be no callbacks after processor destroys.
2422 image_processor_->Process( 2419 image_processor_->Process(
2423 input_frame, output_buffer_index, std::move(processor_output_fds), 2420 input_frame, output_buffer_index, std::move(processor_output_fds),
2424 base::Bind(&V4L2VideoDecodeAccelerator::FrameProcessed, 2421 base::Bind(&V4L2VideoDecodeAccelerator::FrameProcessed,
2425 base::Unretained(this), bitstream_buffer_id)); 2422 base::Unretained(this), bitstream_buffer_id));
2426 return true; 2423 return true;
2427 } 2424 }
2428 2425
2429 bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() { 2426 bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() {
2430 DVLOGF(3); 2427 DVLOGF(2);
2431 DCHECK(decoder_state_ == kInitialized || 2428 DCHECK(decoder_state_ == kInitialized ||
2432 decoder_state_ == kChangingResolution); 2429 decoder_state_ == kChangingResolution);
2433 DCHECK(!output_streamon_); 2430 DCHECK(!output_streamon_);
2434 DCHECK(output_buffer_map_.empty()); 2431 DCHECK(output_buffer_map_.empty());
2435 2432
2436 // Number of output buffers we need. 2433 // Number of output buffers we need.
2437 struct v4l2_control ctrl; 2434 struct v4l2_control ctrl;
2438 memset(&ctrl, 0, sizeof(ctrl)); 2435 memset(&ctrl, 0, sizeof(ctrl));
2439 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; 2436 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
2440 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl); 2437 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl);
(...skipping 27 matching lines...) Expand all
2468 // non-slice NALUs and could even get another resolution change before we were 2465 // non-slice NALUs and could even get another resolution change before we were
2469 // done with this one. After we get the buffers, we'll go back into kIdle and 2466 // done with this one. After we get the buffers, we'll go back into kIdle and
2470 // kick off further event processing, and eventually go back into kDecoding 2467 // kick off further event processing, and eventually go back into kDecoding
2471 // once no more events are pending (if any). 2468 // once no more events are pending (if any).
2472 decoder_state_ = kAwaitingPictureBuffers; 2469 decoder_state_ = kAwaitingPictureBuffers;
2473 2470
2474 return true; 2471 return true;
2475 } 2472 }
2476 2473
2477 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { 2474 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() {
2478 DVLOGF(3); 2475 DVLOGF(2);
2479 DCHECK(!decoder_thread_.IsRunning() || 2476 DCHECK(!decoder_thread_.IsRunning() ||
2480 decoder_thread_.task_runner()->BelongsToCurrentThread()); 2477 decoder_thread_.task_runner()->BelongsToCurrentThread());
2481 DCHECK(!input_streamon_); 2478 DCHECK(!input_streamon_);
2482 2479
2483 if (input_buffer_map_.empty()) 2480 if (input_buffer_map_.empty())
2484 return; 2481 return;
2485 2482
2486 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { 2483 for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
2487 if (input_buffer_map_[i].address != NULL) { 2484 if (input_buffer_map_[i].address != NULL) {
2488 device_->Munmap(input_buffer_map_[i].address, 2485 device_->Munmap(input_buffer_map_[i].address,
2489 input_buffer_map_[i].length); 2486 input_buffer_map_[i].length);
2490 } 2487 }
2491 } 2488 }
2492 2489
2493 struct v4l2_requestbuffers reqbufs; 2490 struct v4l2_requestbuffers reqbufs;
2494 memset(&reqbufs, 0, sizeof(reqbufs)); 2491 memset(&reqbufs, 0, sizeof(reqbufs));
2495 reqbufs.count = 0; 2492 reqbufs.count = 0;
2496 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2493 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2497 reqbufs.memory = V4L2_MEMORY_MMAP; 2494 reqbufs.memory = V4L2_MEMORY_MMAP;
2498 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); 2495 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
2499 2496
2500 input_buffer_map_.clear(); 2497 input_buffer_map_.clear();
2501 free_input_buffers_.clear(); 2498 free_input_buffers_.clear();
2502 } 2499 }
2503 2500
2504 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() { 2501 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() {
2505 DVLOGF(3); 2502 DVLOGF(2);
2506 DCHECK(!decoder_thread_.IsRunning() || 2503 DCHECK(!decoder_thread_.IsRunning() ||
2507 decoder_thread_.task_runner()->BelongsToCurrentThread()); 2504 decoder_thread_.task_runner()->BelongsToCurrentThread());
2508 DCHECK(!output_streamon_); 2505 DCHECK(!output_streamon_);
2509 bool success = true; 2506 bool success = true;
2510 2507
2511 if (output_buffer_map_.empty()) 2508 if (output_buffer_map_.empty())
2512 return true; 2509 return true;
2513 2510
2514 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { 2511 for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
2515 OutputRecord& output_record = output_buffer_map_[i]; 2512 OutputRecord& output_record = output_buffer_map_[i];
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 free_output_buffers_.pop_front(); 2547 free_output_buffers_.pop_front();
2551 output_buffer_queued_count_ = 0; 2548 output_buffer_queued_count_ = 0;
2552 // The client may still hold some buffers. The texture holds a reference to 2549 // The client may still hold some buffers. The texture holds a reference to
2553 // the buffer. It is OK to free the buffer and destroy EGLImage here. 2550 // the buffer. It is OK to free the buffer and destroy EGLImage here.
2554 decoder_frames_at_client_ = 0; 2551 decoder_frames_at_client_ = 0;
2555 2552
2556 return success; 2553 return success;
2557 } 2554 }
2558 2555
2559 void V4L2VideoDecodeAccelerator::SendPictureReady() { 2556 void V4L2VideoDecodeAccelerator::SendPictureReady() {
2560 DVLOGF(3); 2557 DVLOGF(4);
2561 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2558 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2562 bool send_now = (decoder_state_ == kChangingResolution || 2559 bool send_now = (decoder_state_ == kChangingResolution ||
2563 decoder_state_ == kResetting || decoder_flushing_); 2560 decoder_state_ == kResetting || decoder_flushing_);
2564 while (pending_picture_ready_.size() > 0) { 2561 while (pending_picture_ready_.size() > 0) {
2565 bool cleared = pending_picture_ready_.front().cleared; 2562 bool cleared = pending_picture_ready_.front().cleared;
2566 const Picture& picture = pending_picture_ready_.front().picture; 2563 const Picture& picture = pending_picture_ready_.front().picture;
2567 if (cleared && picture_clearing_count_ == 0) { 2564 if (cleared && picture_clearing_count_ == 0) {
2568 // This picture is cleared. It can be posted to a thread different than 2565 // This picture is cleared. It can be posted to a thread different than
2569 // the main GPU thread to reduce latency. This should be the case after 2566 // the main GPU thread to reduce latency. This should be the case after
2570 // all pictures are cleared at the beginning. 2567 // all pictures are cleared at the beginning.
2571 decode_task_runner_->PostTask( 2568 decode_task_runner_->PostTask(
2572 FROM_HERE, 2569 FROM_HERE,
2573 base::Bind(&Client::PictureReady, decode_client_, picture)); 2570 base::Bind(&Client::PictureReady, decode_client_, picture));
2574 pending_picture_ready_.pop(); 2571 pending_picture_ready_.pop();
2575 } else if (!cleared || send_now) { 2572 } else if (!cleared || send_now) {
2576 DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared 2573 DVLOGF(4) << "cleared=" << pending_picture_ready_.front().cleared
2577 << ", decoder_state_=" << decoder_state_ 2574 << ", decoder_state_=" << decoder_state_
2578 << ", decoder_flushing_=" << decoder_flushing_ 2575 << ", decoder_flushing_=" << decoder_flushing_
2579 << ", picture_clearing_count_=" << picture_clearing_count_; 2576 << ", picture_clearing_count_=" << picture_clearing_count_;
2580 // If the picture is not cleared, post it to the child thread because it 2577 // If the picture is not cleared, post it to the child thread because it
2581 // has to be cleared in the child thread. A picture only needs to be 2578 // has to be cleared in the child thread. A picture only needs to be
2582 // cleared once. If the decoder is changing resolution, resetting or 2579 // cleared once. If the decoder is changing resolution, resetting or
2583 // flushing, send all pictures to ensure PictureReady arrive before 2580 // flushing, send all pictures to ensure PictureReady arrive before
2584 // ProvidePictureBuffers, NotifyResetDone, or NotifyFlushDone. 2581 // ProvidePictureBuffers, NotifyResetDone, or NotifyFlushDone.
2585 child_task_runner_->PostTaskAndReply( 2582 child_task_runner_->PostTaskAndReply(
2586 FROM_HERE, base::Bind(&Client::PictureReady, client_, picture), 2583 FROM_HERE, base::Bind(&Client::PictureReady, client_, picture),
2587 // Unretained is safe. If Client::PictureReady gets to run, |this| is 2584 // Unretained is safe. If Client::PictureReady gets to run, |this| is
2588 // alive. Destroy() will wait the decode thread to finish. 2585 // alive. Destroy() will wait the decode thread to finish.
2589 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared, 2586 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared,
2590 base::Unretained(this))); 2587 base::Unretained(this)));
2591 picture_clearing_count_++; 2588 picture_clearing_count_++;
2592 pending_picture_ready_.pop(); 2589 pending_picture_ready_.pop();
2593 } else { 2590 } else {
2594 // This picture is cleared. But some pictures are about to be cleared on 2591 // This picture is cleared. But some pictures are about to be cleared on
2595 // the child thread. To preserve the order, do not send this until those 2592 // the child thread. To preserve the order, do not send this until those
2596 // pictures are cleared. 2593 // pictures are cleared.
2597 break; 2594 break;
2598 } 2595 }
2599 } 2596 }
2600 } 2597 }
2601 2598
2602 void V4L2VideoDecodeAccelerator::PictureCleared() { 2599 void V4L2VideoDecodeAccelerator::PictureCleared() {
2603 DVLOGF(3) << "clearing count=" << picture_clearing_count_; 2600 DVLOGF(4) << "clearing count=" << picture_clearing_count_;
2604 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2601 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2605 DCHECK_GT(picture_clearing_count_, 0); 2602 DCHECK_GT(picture_clearing_count_, 0);
2606 picture_clearing_count_--; 2603 picture_clearing_count_--;
2607 SendPictureReady(); 2604 SendPictureReady();
2608 } 2605 }
2609 2606
2610 void V4L2VideoDecodeAccelerator::FrameProcessed(int32_t bitstream_buffer_id, 2607 void V4L2VideoDecodeAccelerator::FrameProcessed(int32_t bitstream_buffer_id,
2611 int output_buffer_index) { 2608 int output_buffer_index) {
2612 DVLOGF(3) << "output_buffer_index=" << output_buffer_index 2609 DVLOGF(4) << "output_buffer_index=" << output_buffer_index
2613 << ", bitstream_buffer_id=" << bitstream_buffer_id; 2610 << ", bitstream_buffer_id=" << bitstream_buffer_id;
2614 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 2611 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
2615 DCHECK(!image_processor_bitstream_buffer_ids_.empty()); 2612 DCHECK(!image_processor_bitstream_buffer_ids_.empty());
2616 DCHECK(image_processor_bitstream_buffer_ids_.front() == bitstream_buffer_id); 2613 DCHECK(image_processor_bitstream_buffer_ids_.front() == bitstream_buffer_id);
2617 DCHECK_GE(output_buffer_index, 0); 2614 DCHECK_GE(output_buffer_index, 0);
2618 DCHECK_LT(output_buffer_index, static_cast<int>(output_buffer_map_.size())); 2615 DCHECK_LT(output_buffer_index, static_cast<int>(output_buffer_map_.size()));
2619 2616
2620 OutputRecord& output_record = output_buffer_map_[output_buffer_index]; 2617 OutputRecord& output_record = output_buffer_map_[output_buffer_index];
2621 DVLOGF(3) << "picture_id=" << output_record.picture_id; 2618 DVLOGF(4) << "picture_id=" << output_record.picture_id;
2622 DCHECK_EQ(output_record.state, kAtProcessor); 2619 DCHECK_EQ(output_record.state, kAtProcessor);
2623 DCHECK_NE(output_record.picture_id, -1); 2620 DCHECK_NE(output_record.picture_id, -1);
2624 2621
2625 // Send the processed frame to render. 2622 // Send the processed frame to render.
2626 output_record.state = kAtClient; 2623 output_record.state = kAtClient;
2627 decoder_frames_at_client_++; 2624 decoder_frames_at_client_++;
2628 image_processor_bitstream_buffer_ids_.pop(); 2625 image_processor_bitstream_buffer_ids_.pop();
2629 // TODO(hubbe): Insert correct color space. http://crbug.com/647725 2626 // TODO(hubbe): Insert correct color space. http://crbug.com/647725
2630 const Picture picture(output_record.picture_id, bitstream_buffer_id, 2627 const Picture picture(output_record.picture_id, bitstream_buffer_id,
2631 gfx::Rect(visible_size_), gfx::ColorSpace(), false); 2628 gfx::Rect(visible_size_), gfx::ColorSpace(), false);
2632 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture)); 2629 pending_picture_ready_.push(PictureRecord(output_record.cleared, picture));
2633 SendPictureReady(); 2630 SendPictureReady();
2634 output_record.cleared = true; 2631 output_record.cleared = true;
2635 // Flush or resolution change may be waiting image processor to finish. 2632 // Flush or resolution change may be waiting image processor to finish.
2636 if (image_processor_bitstream_buffer_ids_.empty()) { 2633 if (image_processor_bitstream_buffer_ids_.empty()) {
2637 NotifyFlushDoneIfNeeded(); 2634 NotifyFlushDoneIfNeeded();
2638 if (decoder_state_ == kChangingResolution) 2635 if (decoder_state_ == kChangingResolution)
2639 StartResolutionChange(); 2636 StartResolutionChange();
2640 } 2637 }
2641 } 2638 }
2642 2639
2643 void V4L2VideoDecodeAccelerator::ImageProcessorError() { 2640 void V4L2VideoDecodeAccelerator::ImageProcessorError() {
2644 LOGF(ERROR) << "Image processor error"; 2641 LOGF(ERROR) << "Image processor error";
2645 NOTIFY_ERROR(PLATFORM_FAILURE); 2642 NOTIFY_ERROR(PLATFORM_FAILURE);
2646 } 2643 }
2647 2644
2648 } // namespace media 2645 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698