Chromium Code Reviews| 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 "media/gpu/v4l2_slice_video_decode_accelerator.h" | 5 #include "media/gpu/v4l2_slice_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
| 10 #include <poll.h> | 10 #include <poll.h> |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 } else { | 506 } else { |
| 507 DVLOG(1) << "No GL callbacks provided, initializing without GL support"; | 507 DVLOG(1) << "No GL callbacks provided, initializing without GL support"; |
| 508 } | 508 } |
| 509 | 509 |
| 510 // Capabilities check. | 510 // Capabilities check. |
| 511 struct v4l2_capability caps; | 511 struct v4l2_capability caps; |
| 512 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; | 512 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
| 513 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); | 513 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); |
| 514 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 514 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
| 515 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" | 515 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" |
| 516 ", caps check failed: 0x" | 516 << ", caps check failed: 0x" << std::hex << caps.capabilities; |
| 517 << std::hex << caps.capabilities; | |
| 518 return false; | 517 return false; |
| 519 } | 518 } |
| 520 | 519 |
| 521 if (!SetupFormats()) | 520 if (!SetupFormats()) |
| 522 return false; | 521 return false; |
| 523 | 522 |
| 524 if (!decoder_thread_.Start()) { | 523 if (!decoder_thread_.Start()) { |
| 525 DLOG(ERROR) << "Initialize(): device thread failed to start"; | 524 DLOG(ERROR) << "Initialize(): device thread failed to start"; |
| 526 return false; | 525 return false; |
| 527 } | 526 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 struct v4l2_plane planes[VIDEO_MAX_PLANES]; | 690 struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| 692 struct v4l2_buffer buffer; | 691 struct v4l2_buffer buffer; |
| 693 memset(&buffer, 0, sizeof(buffer)); | 692 memset(&buffer, 0, sizeof(buffer)); |
| 694 memset(planes, 0, sizeof(planes)); | 693 memset(planes, 0, sizeof(planes)); |
| 695 buffer.index = i; | 694 buffer.index = i; |
| 696 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 695 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
| 697 buffer.memory = V4L2_MEMORY_MMAP; | 696 buffer.memory = V4L2_MEMORY_MMAP; |
| 698 buffer.m.planes = planes; | 697 buffer.m.planes = planes; |
| 699 buffer.length = input_planes_count_; | 698 buffer.length = input_planes_count_; |
| 700 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); | 699 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); |
| 701 void* address = device_->Mmap(nullptr, buffer.m.planes[0].length, | 700 void* address = device_->Mmap(nullptr, |
| 702 PROT_READ | PROT_WRITE, MAP_SHARED, | 701 buffer.m.planes[0].length, |
| 702 PROT_READ | PROT_WRITE, | |
| 703 MAP_SHARED, | |
| 703 buffer.m.planes[0].m.mem_offset); | 704 buffer.m.planes[0].m.mem_offset); |
| 704 if (address == MAP_FAILED) { | 705 if (address == MAP_FAILED) { |
| 705 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; | 706 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; |
| 706 return false; | 707 return false; |
| 707 } | 708 } |
| 708 input_buffer_map_[i].address = address; | 709 input_buffer_map_[i].address = address; |
| 709 input_buffer_map_[i].length = buffer.m.planes[0].length; | 710 input_buffer_map_[i].length = buffer.m.planes[0].length; |
| 710 } | 711 } |
| 711 | 712 |
| 712 return true; | 713 return true; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 851 } | 852 } |
| 852 | 853 |
| 853 DVLOGF(4) << "Scheduling device poll task"; | 854 DVLOGF(4) << "Scheduling device poll task"; |
| 854 | 855 |
| 855 device_poll_thread_.message_loop()->PostTask( | 856 device_poll_thread_.message_loop()->PostTask( |
| 856 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DevicePollTask, | 857 FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DevicePollTask, |
| 857 base::Unretained(this), true)); | 858 base::Unretained(this), true)); |
| 858 | 859 |
| 859 DVLOGF(2) << "buffer counts: " | 860 DVLOGF(2) << "buffer counts: " |
| 860 << "INPUT[" << decoder_input_queue_.size() << "]" | 861 << "INPUT[" << decoder_input_queue_.size() << "]" |
| 861 << " => DEVICE[" << free_input_buffers_.size() << "+" | 862 << " => DEVICE[" |
| 862 << input_buffer_queued_count_ << "/" << input_buffer_map_.size() | 863 << free_input_buffers_.size() << "+" |
| 863 << "]->[" << free_output_buffers_.size() << "+" | 864 << input_buffer_queued_count_ << "/" |
| 864 << output_buffer_queued_count_ << "/" << output_buffer_map_.size() | 865 << input_buffer_map_.size() << "]->[" |
| 865 << "]" | 866 << free_output_buffers_.size() << "+" |
| 867 << output_buffer_queued_count_ << "/" | |
| 868 << output_buffer_map_.size() << "]" | |
| 866 << " => DISPLAYQ[" << decoder_display_queue_.size() << "]" | 869 << " => DISPLAYQ[" << decoder_display_queue_.size() << "]" |
| 867 << " => CLIENT[" << surfaces_at_display_.size() << "]"; | 870 << " => CLIENT[" << surfaces_at_display_.size() << "]"; |
| 868 } | 871 } |
| 869 | 872 |
| 870 void V4L2SliceVideoDecodeAccelerator::Enqueue( | 873 void V4L2SliceVideoDecodeAccelerator::Enqueue( |
| 871 const scoped_refptr<V4L2DecodeSurface>& dec_surface) { | 874 const scoped_refptr<V4L2DecodeSurface>& dec_surface) { |
| 872 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 875 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
| 873 | 876 |
| 874 const int old_inputs_queued = input_buffer_queued_count_; | 877 const int old_inputs_queued = input_buffer_queued_count_; |
| 875 const int old_outputs_queued = output_buffer_queued_count_; | 878 const int old_outputs_queued = output_buffer_queued_count_; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 break; | 948 break; |
| 946 } | 949 } |
| 947 PLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF"; | 950 PLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF"; |
| 948 NOTIFY_ERROR(PLATFORM_FAILURE); | 951 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 949 return; | 952 return; |
| 950 } | 953 } |
| 951 OutputRecord& output_record = output_buffer_map_[dqbuf.index]; | 954 OutputRecord& output_record = output_buffer_map_[dqbuf.index]; |
| 952 DCHECK(output_record.at_device); | 955 DCHECK(output_record.at_device); |
| 953 output_record.at_device = false; | 956 output_record.at_device = false; |
| 954 output_buffer_queued_count_--; | 957 output_buffer_queued_count_--; |
| 955 DVLOGF(3) << "Dequeued output=" << dqbuf.index << " count " | 958 DVLOGF(3) << "Dequeued output=" << dqbuf.index |
| 956 << output_buffer_queued_count_; | 959 << " count " << output_buffer_queued_count_; |
| 957 | 960 |
| 958 V4L2DecodeSurfaceByOutputId::iterator it = | 961 V4L2DecodeSurfaceByOutputId::iterator it = |
| 959 surfaces_at_device_.find(dqbuf.index); | 962 surfaces_at_device_.find(dqbuf.index); |
| 960 if (it == surfaces_at_device_.end()) { | 963 if (it == surfaces_at_device_.end()) { |
| 961 DLOG(ERROR) << "Got invalid surface from device."; | 964 DLOG(ERROR) << "Got invalid surface from device."; |
| 962 NOTIFY_ERROR(PLATFORM_FAILURE); | 965 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 963 } | 966 } |
| 964 | 967 |
| 965 it->second->SetDecoded(); | 968 it->second->SetDecoded(); |
| 966 surfaces_at_device_.erase(it); | 969 surfaces_at_device_.erase(it); |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1497 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask( | 1500 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask( |
| 1498 const std::vector<media::PictureBuffer>& buffers) { | 1501 const std::vector<media::PictureBuffer>& buffers) { |
| 1499 DVLOGF(3); | 1502 DVLOGF(3); |
| 1500 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); | 1503 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); |
| 1501 DCHECK_EQ(state_, kAwaitingPictureBuffers); | 1504 DCHECK_EQ(state_, kAwaitingPictureBuffers); |
| 1502 | 1505 |
| 1503 const uint32_t req_buffer_count = decoder_->GetRequiredNumOfPictures(); | 1506 const uint32_t req_buffer_count = decoder_->GetRequiredNumOfPictures(); |
| 1504 | 1507 |
| 1505 if (buffers.size() < req_buffer_count) { | 1508 if (buffers.size() < req_buffer_count) { |
| 1506 DLOG(ERROR) << "Failed to provide requested picture buffers. " | 1509 DLOG(ERROR) << "Failed to provide requested picture buffers. " |
| 1507 << "(Got " << buffers.size() << ", requested " | 1510 << "(Got " << buffers.size() |
| 1508 << req_buffer_count << ")"; | 1511 << ", requested " << req_buffer_count << ")"; |
| 1509 NOTIFY_ERROR(INVALID_ARGUMENT); | 1512 NOTIFY_ERROR(INVALID_ARGUMENT); |
| 1510 return; | 1513 return; |
| 1511 } | 1514 } |
| 1512 | 1515 |
| 1513 // Allocate the output buffers. | 1516 // Allocate the output buffers. |
| 1514 struct v4l2_requestbuffers reqbufs; | 1517 struct v4l2_requestbuffers reqbufs; |
| 1515 memset(&reqbufs, 0, sizeof(reqbufs)); | 1518 memset(&reqbufs, 0, sizeof(reqbufs)); |
| 1516 reqbufs.count = buffers.size(); | 1519 reqbufs.count = buffers.size(); |
| 1517 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1520 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 1518 reqbufs.memory = | 1521 reqbufs.memory = |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2053 const H264Picture::Vector& ref_pic_listp0, | 2056 const H264Picture::Vector& ref_pic_listp0, |
| 2054 const H264Picture::Vector& ref_pic_listb0, | 2057 const H264Picture::Vector& ref_pic_listb0, |
| 2055 const H264Picture::Vector& ref_pic_listb1, | 2058 const H264Picture::Vector& ref_pic_listb1, |
| 2056 const scoped_refptr<H264Picture>& pic) { | 2059 const scoped_refptr<H264Picture>& pic) { |
| 2057 struct v4l2_ext_control ctrl; | 2060 struct v4l2_ext_control ctrl; |
| 2058 std::vector<struct v4l2_ext_control> ctrls; | 2061 std::vector<struct v4l2_ext_control> ctrls; |
| 2059 | 2062 |
| 2060 struct v4l2_ctrl_h264_sps v4l2_sps; | 2063 struct v4l2_ctrl_h264_sps v4l2_sps; |
| 2061 memset(&v4l2_sps, 0, sizeof(v4l2_sps)); | 2064 memset(&v4l2_sps, 0, sizeof(v4l2_sps)); |
| 2062 v4l2_sps.constraint_set_flags = | 2065 v4l2_sps.constraint_set_flags = |
| 2063 sps->constraint_set0_flag | 2066 sps->constraint_set0_flag ? V4L2_H264_SPS_CONSTRAINT_SET0_FLAG : 0 | |
|
kcwu
2016/05/12 09:42:42
Will git cl format be happier with parentheses?
I
Pawel Osciak
2016/05/13 06:07:22
Indeed! Thank you.
| |
| 2064 ? V4L2_H264_SPS_CONSTRAINT_SET0_FLAG | 2067 sps->constraint_set1_flag ? V4L2_H264_SPS_CONSTRAINT_SET1_FLAG : 0 | |
| 2065 : 0 | sps->constraint_set1_flag | 2068 sps->constraint_set2_flag ? V4L2_H264_SPS_CONSTRAINT_SET2_FLAG : 0 | |
| 2066 ? V4L2_H264_SPS_CONSTRAINT_SET1_FLAG | 2069 sps->constraint_set3_flag ? V4L2_H264_SPS_CONSTRAINT_SET3_FLAG : 0 | |
| 2067 : 0 | sps->constraint_set2_flag | 2070 sps->constraint_set4_flag ? V4L2_H264_SPS_CONSTRAINT_SET4_FLAG : 0 | |
| 2068 ? V4L2_H264_SPS_CONSTRAINT_SET2_FLAG | 2071 sps->constraint_set5_flag ? V4L2_H264_SPS_CONSTRAINT_SET5_FLAG : 0; |
| 2069 : 0 | sps->constraint_set3_flag | |
| 2070 ? V4L2_H264_SPS_CONSTRAINT_SET3_FLAG | |
| 2071 : 0 | sps->constraint_set4_flag | |
| 2072 ? V4L2_H264_SPS_CONSTRAINT_SET4_FLAG | |
| 2073 : 0 | sps->constraint_set5_flag | |
| 2074 ? V4L2_H264_SPS_CONSTRAINT_SET5_FLAG | |
| 2075 : 0; | |
| 2076 #define SPS_TO_V4L2SPS(a) v4l2_sps.a = sps->a | 2072 #define SPS_TO_V4L2SPS(a) v4l2_sps.a = sps->a |
| 2077 SPS_TO_V4L2SPS(profile_idc); | 2073 SPS_TO_V4L2SPS(profile_idc); |
| 2078 SPS_TO_V4L2SPS(level_idc); | 2074 SPS_TO_V4L2SPS(level_idc); |
| 2079 SPS_TO_V4L2SPS(seq_parameter_set_id); | 2075 SPS_TO_V4L2SPS(seq_parameter_set_id); |
| 2080 SPS_TO_V4L2SPS(chroma_format_idc); | 2076 SPS_TO_V4L2SPS(chroma_format_idc); |
| 2081 SPS_TO_V4L2SPS(bit_depth_luma_minus8); | 2077 SPS_TO_V4L2SPS(bit_depth_luma_minus8); |
| 2082 SPS_TO_V4L2SPS(bit_depth_chroma_minus8); | 2078 SPS_TO_V4L2SPS(bit_depth_chroma_minus8); |
| 2083 SPS_TO_V4L2SPS(log2_max_frame_num_minus4); | 2079 SPS_TO_V4L2SPS(log2_max_frame_num_minus4); |
| 2084 SPS_TO_V4L2SPS(pic_order_cnt_type); | 2080 SPS_TO_V4L2SPS(pic_order_cnt_type); |
| 2085 SPS_TO_V4L2SPS(log2_max_pic_order_cnt_lsb_minus4); | 2081 SPS_TO_V4L2SPS(log2_max_pic_order_cnt_lsb_minus4); |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2805 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { | 2801 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { |
| 2806 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 2802 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
| 2807 if (!device) | 2803 if (!device) |
| 2808 return SupportedProfiles(); | 2804 return SupportedProfiles(); |
| 2809 | 2805 |
| 2810 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), | 2806 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
| 2811 supported_input_fourccs_); | 2807 supported_input_fourccs_); |
| 2812 } | 2808 } |
| 2813 | 2809 |
| 2814 } // namespace media | 2810 } // namespace media |
| OLD | NEW |