OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <fcntl.h> | 5 #include <fcntl.h> |
6 #include <linux/videodev2.h> | 6 #include <linux/videodev2.h> |
7 #include <poll.h> | 7 #include <poll.h> |
8 #include <sys/eventfd.h> | 8 #include <sys/eventfd.h> |
9 #include <sys/ioctl.h> | 9 #include <sys/ioctl.h> |
10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 coded_size_.SetSize(base::checked_cast<int>(format.fmt.pix_mp.width), | 705 coded_size_.SetSize(base::checked_cast<int>(format.fmt.pix_mp.width), |
706 base::checked_cast<int>(format.fmt.pix_mp.height)); | 706 base::checked_cast<int>(format.fmt.pix_mp.height)); |
707 DCHECK_EQ(coded_size_.width() % 16, 0); | 707 DCHECK_EQ(coded_size_.width() % 16, 0); |
708 DCHECK_EQ(coded_size_.height() % 16, 0); | 708 DCHECK_EQ(coded_size_.height() % 16, 0); |
709 | 709 |
710 if (!gfx::Rect(coded_size_).Contains(gfx::Rect(visible_size_))) { | 710 if (!gfx::Rect(coded_size_).Contains(gfx::Rect(visible_size_))) { |
711 LOG(ERROR) << "Got invalid adjusted coded size: " << coded_size_.ToString(); | 711 LOG(ERROR) << "Got invalid adjusted coded size: " << coded_size_.ToString(); |
712 return false; | 712 return false; |
713 } | 713 } |
714 | 714 |
715 struct v4l2_requestbuffers reqbufs; | 715 DVLOGF(3) << "buffer_count=" << num_pictures |
716 memset(&reqbufs, 0, sizeof(reqbufs)); | |
717 reqbufs.count = num_pictures; | |
718 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
719 reqbufs.memory = V4L2_MEMORY_MMAP; | |
720 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); | |
721 | |
722 if (reqbufs.count < num_pictures) { | |
723 PLOG(ERROR) << "Could not allocate enough output buffers"; | |
724 return false; | |
725 } | |
726 | |
727 output_buffer_map_.resize(reqbufs.count); | |
728 | |
729 DVLOGF(3) << "buffer_count=" << output_buffer_map_.size() | |
730 << ", visible size=" << visible_size_.ToString() | 716 << ", visible size=" << visible_size_.ToString() |
731 << ", coded size=" << coded_size_.ToString(); | 717 << ", coded size=" << coded_size_.ToString(); |
732 | 718 |
733 child_task_runner_->PostTask( | 719 child_task_runner_->PostTask( |
734 FROM_HERE, | 720 FROM_HERE, |
735 base::Bind(&VideoDecodeAccelerator::Client::ProvidePictureBuffers, | 721 base::Bind(&VideoDecodeAccelerator::Client::ProvidePictureBuffers, |
736 client_, output_buffer_map_.size(), coded_size_, | 722 client_, num_pictures, coded_size_, |
737 device_->GetTextureTarget())); | 723 device_->GetTextureTarget())); |
738 | 724 |
739 // Wait for the client to call AssignPictureBuffers() on the Child thread. | 725 // Wait for the client to call AssignPictureBuffers() on the Child thread. |
740 // We do this, because if we continue decoding without finishing buffer | 726 // We do this, because if we continue decoding without finishing buffer |
741 // allocation, we may end up Resetting before AssignPictureBuffers arrives, | 727 // allocation, we may end up Resetting before AssignPictureBuffers arrives, |
742 // resulting in unnecessary complications and subtle bugs. | 728 // resulting in unnecessary complications and subtle bugs. |
743 pictures_assigned_.Wait(); | 729 pictures_assigned_.Wait(); |
744 | 730 |
745 return true; | 731 return true; |
746 } | 732 } |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1408 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); | 1394 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); |
1409 | 1395 |
1410 return true; | 1396 return true; |
1411 } | 1397 } |
1412 | 1398 |
1413 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers( | 1399 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers( |
1414 const std::vector<media::PictureBuffer>& buffers) { | 1400 const std::vector<media::PictureBuffer>& buffers) { |
1415 DVLOGF(3); | 1401 DVLOGF(3); |
1416 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 1402 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
1417 | 1403 |
1418 if (buffers.size() != output_buffer_map_.size()) { | 1404 const uint32_t req_buffer_count = decoder_->GetRequiredNumOfPictures(); |
| 1405 |
| 1406 if (buffers.size() < req_buffer_count) { |
1419 DLOG(ERROR) << "Failed to provide requested picture buffers. " | 1407 DLOG(ERROR) << "Failed to provide requested picture buffers. " |
1420 << "(Got " << buffers.size() | 1408 << "(Got " << buffers.size() |
1421 << ", requested " << output_buffer_map_.size() << ")"; | 1409 << ", requested " << req_buffer_count << ")"; |
1422 NOTIFY_ERROR(INVALID_ARGUMENT); | 1410 NOTIFY_ERROR(INVALID_ARGUMENT); |
1423 return; | 1411 return; |
1424 } | 1412 } |
1425 | 1413 |
1426 if (!make_context_current_.Run()) { | 1414 if (!make_context_current_.Run()) { |
1427 DLOG(ERROR) << "could not make context current"; | 1415 DLOG(ERROR) << "could not make context current"; |
1428 NOTIFY_ERROR(PLATFORM_FAILURE); | 1416 NOTIFY_ERROR(PLATFORM_FAILURE); |
1429 return; | 1417 return; |
1430 } | 1418 } |
1431 | 1419 |
1432 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); | 1420 gfx::ScopedTextureBinder bind_restore(GL_TEXTURE_EXTERNAL_OES, 0); |
1433 | 1421 |
1434 // It's safe to manipulate all the buffer state here, because the decoder | 1422 // It's safe to manipulate all the buffer state here, because the decoder |
1435 // thread is waiting on pictures_assigned_. | 1423 // thread is waiting on pictures_assigned_. |
| 1424 |
| 1425 // Allocate the output buffers. |
| 1426 struct v4l2_requestbuffers reqbufs; |
| 1427 memset(&reqbufs, 0, sizeof(reqbufs)); |
| 1428 reqbufs.count = buffers.size(); |
| 1429 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 1430 reqbufs.memory = V4L2_MEMORY_MMAP; |
| 1431 IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs); |
| 1432 |
| 1433 if (reqbufs.count != buffers.size()) { |
| 1434 DLOG(ERROR) << "Could not allocate enough output buffers"; |
| 1435 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 1436 return; |
| 1437 } |
| 1438 |
| 1439 output_buffer_map_.resize(buffers.size()); |
| 1440 |
1436 DCHECK(free_output_buffers_.empty()); | 1441 DCHECK(free_output_buffers_.empty()); |
1437 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 1442 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
1438 DCHECK(buffers[i].size() == coded_size_); | 1443 DCHECK(buffers[i].size() == coded_size_); |
1439 | 1444 |
1440 OutputRecord& output_record = output_buffer_map_[i]; | 1445 OutputRecord& output_record = output_buffer_map_[i]; |
1441 DCHECK(!output_record.at_device); | 1446 DCHECK(!output_record.at_device); |
1442 DCHECK(!output_record.at_client); | 1447 DCHECK(!output_record.at_client); |
1443 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); | 1448 DCHECK_EQ(output_record.egl_image, EGL_NO_IMAGE_KHR); |
1444 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); | 1449 DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR); |
1445 DCHECK_EQ(output_record.picture_id, -1); | 1450 DCHECK_EQ(output_record.picture_id, -1); |
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 if (!device) | 2516 if (!device) |
2512 return SupportedProfiles(); | 2517 return SupportedProfiles(); |
2513 | 2518 |
2514 const uint32_t supported_formats[] = { | 2519 const uint32_t supported_formats[] = { |
2515 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME}; | 2520 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME}; |
2516 return device->GetSupportedDecodeProfiles(arraysize(supported_formats), | 2521 return device->GetSupportedDecodeProfiles(arraysize(supported_formats), |
2517 supported_formats); | 2522 supported_formats); |
2518 } | 2523 } |
2519 | 2524 |
2520 } // namespace content | 2525 } // namespace content |
OLD | NEW |