| 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 |