| OLD | NEW |
| 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 return false; | 251 return false; |
| 252 } | 252 } |
| 253 #endif | 253 #endif |
| 254 | 254 |
| 255 // Capabilities check. | 255 // Capabilities check. |
| 256 struct v4l2_capability caps; | 256 struct v4l2_capability caps; |
| 257 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; | 257 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
| 258 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); | 258 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); |
| 259 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 259 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
| 260 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" | 260 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" |
| 261 ", caps check failed: 0x" | 261 << ", caps check failed: 0x" << std::hex << caps.capabilities; |
| 262 << std::hex << caps.capabilities; | |
| 263 return false; | 262 return false; |
| 264 } | 263 } |
| 265 | 264 |
| 266 if (!SetupFormats()) | 265 if (!SetupFormats()) |
| 267 return false; | 266 return false; |
| 268 | 267 |
| 269 // Subscribe to the resolution change event. | 268 // Subscribe to the resolution change event. |
| 270 struct v4l2_event_subscription sub; | 269 struct v4l2_event_subscription sub; |
| 271 memset(&sub, 0, sizeof(sub)); | 270 memset(&sub, 0, sizeof(sub)); |
| 272 sub.type = V4L2_EVENT_SOURCE_CHANGE; | 271 sub.type = V4L2_EVENT_SOURCE_CHANGE; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( | 318 void V4L2VideoDecodeAccelerator::AssignPictureBuffers( |
| 320 const std::vector<media::PictureBuffer>& buffers) { | 319 const std::vector<media::PictureBuffer>& buffers) { |
| 321 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); | 320 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); |
| 322 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 321 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
| 323 | 322 |
| 324 const uint32_t req_buffer_count = | 323 const uint32_t req_buffer_count = |
| 325 output_dpb_size_ + kDpbOutputBufferExtraCount; | 324 output_dpb_size_ + kDpbOutputBufferExtraCount; |
| 326 | 325 |
| 327 if (buffers.size() < req_buffer_count) { | 326 if (buffers.size() < req_buffer_count) { |
| 328 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" | 327 LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" |
| 329 " buffers. (Got " | 328 << " buffers. (Got " << buffers.size() |
| 330 << buffers.size() << ", requested " << req_buffer_count << ")"; | 329 << ", requested " << req_buffer_count << ")"; |
| 331 NOTIFY_ERROR(INVALID_ARGUMENT); | 330 NOTIFY_ERROR(INVALID_ARGUMENT); |
| 332 return; | 331 return; |
| 333 } | 332 } |
| 334 | 333 |
| 335 gfx::GLContext* gl_context = get_gl_context_cb_.Run(); | 334 gfx::GLContext* gl_context = get_gl_context_cb_.Run(); |
| 336 if (!gl_context || !make_context_current_cb_.Run()) { | 335 if (!gl_context || !make_context_current_cb_.Run()) { |
| 337 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; | 336 LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; |
| 338 NOTIFY_ERROR(PLATFORM_FAILURE); | 337 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 339 return; | 338 return; |
| 340 } | 339 } |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() | 1003 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() |
| 1005 // shut it down, in which case we're either in kResetting or kError states | 1004 // shut it down, in which case we're either in kResetting or kError states |
| 1006 // respectively, and we should have early-outed already. | 1005 // respectively, and we should have early-outed already. |
| 1007 DCHECK(device_poll_thread_.message_loop()); | 1006 DCHECK(device_poll_thread_.message_loop()); |
| 1008 // Queue the DevicePollTask() now. | 1007 // Queue the DevicePollTask() now. |
| 1009 device_poll_thread_.message_loop()->PostTask( | 1008 device_poll_thread_.message_loop()->PostTask( |
| 1010 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask, | 1009 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask, |
| 1011 base::Unretained(this), poll_device)); | 1010 base::Unretained(this), poll_device)); |
| 1012 | 1011 |
| 1013 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" | 1012 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" |
| 1014 << decoder_input_queue_.size() << "->" << input_ready_queue_.size() | 1013 << decoder_input_queue_.size() << "->" |
| 1015 << "] => DEVICE[" << free_input_buffers_.size() << "+" | 1014 << input_ready_queue_.size() << "] => DEVICE[" |
| 1016 << input_buffer_queued_count_ << "/" << input_buffer_map_.size() | 1015 << free_input_buffers_.size() << "+" |
| 1017 << "->" << free_output_buffers_.size() << "+" | 1016 << input_buffer_queued_count_ << "/" |
| 1018 << output_buffer_queued_count_ << "/" << output_buffer_map_.size() | 1017 << input_buffer_map_.size() << "->" |
| 1019 << "] => PROCESSOR[" << image_processor_bitstream_buffer_ids_.size() | 1018 << free_output_buffers_.size() << "+" |
| 1020 << "] => CLIENT[" << decoder_frames_at_client_ << "]"; | 1019 << output_buffer_queued_count_ << "/" |
| 1020 << output_buffer_map_.size() << "] => PROCESSOR[" |
| 1021 << image_processor_bitstream_buffer_ids_.size() << "] => CLIENT[" |
| 1022 << decoder_frames_at_client_ << "]"; |
| 1021 | 1023 |
| 1022 ScheduleDecodeBufferTaskIfNeeded(); | 1024 ScheduleDecodeBufferTaskIfNeeded(); |
| 1023 if (resolution_change_pending) | 1025 if (resolution_change_pending) |
| 1024 StartResolutionChange(); | 1026 StartResolutionChange(); |
| 1025 } | 1027 } |
| 1026 | 1028 |
| 1027 void V4L2VideoDecodeAccelerator::Enqueue() { | 1029 void V4L2VideoDecodeAccelerator::Enqueue() { |
| 1028 DVLOG(3) << "Enqueue()"; | 1030 DVLOG(3) << "Enqueue()"; |
| 1029 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1031 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1030 DCHECK_NE(decoder_state_, kUninitialized); | 1032 DCHECK_NE(decoder_state_, kUninitialized); |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 struct v4l2_plane planes[1]; | 1864 struct v4l2_plane planes[1]; |
| 1863 struct v4l2_buffer buffer; | 1865 struct v4l2_buffer buffer; |
| 1864 memset(&buffer, 0, sizeof(buffer)); | 1866 memset(&buffer, 0, sizeof(buffer)); |
| 1865 memset(planes, 0, sizeof(planes)); | 1867 memset(planes, 0, sizeof(planes)); |
| 1866 buffer.index = i; | 1868 buffer.index = i; |
| 1867 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1869 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
| 1868 buffer.memory = V4L2_MEMORY_MMAP; | 1870 buffer.memory = V4L2_MEMORY_MMAP; |
| 1869 buffer.m.planes = planes; | 1871 buffer.m.planes = planes; |
| 1870 buffer.length = 1; | 1872 buffer.length = 1; |
| 1871 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); | 1873 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer); |
| 1872 void* address = | 1874 void* address = device_->Mmap(NULL, |
| 1873 device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE, | 1875 buffer.m.planes[0].length, |
| 1874 MAP_SHARED, buffer.m.planes[0].m.mem_offset); | 1876 PROT_READ | PROT_WRITE, |
| 1877 MAP_SHARED, |
| 1878 buffer.m.planes[0].m.mem_offset); |
| 1875 if (address == MAP_FAILED) { | 1879 if (address == MAP_FAILED) { |
| 1876 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; | 1880 PLOG(ERROR) << "CreateInputBuffers(): mmap() failed"; |
| 1877 return false; | 1881 return false; |
| 1878 } | 1882 } |
| 1879 input_buffer_map_[i].address = address; | 1883 input_buffer_map_[i].address = address; |
| 1880 input_buffer_map_[i].length = buffer.m.planes[0].length; | 1884 input_buffer_map_[i].length = buffer.m.planes[0].length; |
| 1881 } | 1885 } |
| 1882 | 1886 |
| 1883 return true; | 1887 return true; |
| 1884 } | 1888 } |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 Enqueue(); | 2243 Enqueue(); |
| 2240 } | 2244 } |
| 2241 } | 2245 } |
| 2242 | 2246 |
| 2243 void V4L2VideoDecodeAccelerator::ImageProcessorError() { | 2247 void V4L2VideoDecodeAccelerator::ImageProcessorError() { |
| 2244 LOG(ERROR) << "Image processor error"; | 2248 LOG(ERROR) << "Image processor error"; |
| 2245 NOTIFY_ERROR(PLATFORM_FAILURE); | 2249 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 2246 } | 2250 } |
| 2247 | 2251 |
| 2248 } // namespace media | 2252 } // namespace media |
| OLD | NEW |