| 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 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); | 267 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); |
| 268 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 268 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
| 269 LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP" | 269 LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP" |
| 270 << ", caps check failed: 0x" << std::hex << caps.capabilities; | 270 << ", caps check failed: 0x" << std::hex << caps.capabilities; |
| 271 return false; | 271 return false; |
| 272 } | 272 } |
| 273 | 273 |
| 274 if (!SetupFormats()) | 274 if (!SetupFormats()) |
| 275 return false; | 275 return false; |
| 276 | 276 |
| 277 // Subscribe to the resolution change event. | |
| 278 struct v4l2_event_subscription sub; | |
| 279 memset(&sub, 0, sizeof(sub)); | |
| 280 sub.type = V4L2_EVENT_SOURCE_CHANGE; | |
| 281 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_SUBSCRIBE_EVENT, &sub); | |
| 282 | |
| 283 if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) { | 277 if (video_profile_ >= H264PROFILE_MIN && video_profile_ <= H264PROFILE_MAX) { |
| 284 decoder_h264_parser_.reset(new H264Parser()); | 278 decoder_h264_parser_.reset(new H264Parser()); |
| 285 } | 279 } |
| 286 | 280 |
| 287 if (!CreateInputBuffers()) | |
| 288 return false; | |
| 289 | |
| 290 decoder_cmd_supported_ = IsDecoderCmdSupported(); | |
| 291 | |
| 292 if (!decoder_thread_.Start()) { | 281 if (!decoder_thread_.Start()) { |
| 293 LOGF(ERROR) << "decoder thread failed to start"; | 282 LOGF(ERROR) << "decoder thread failed to start"; |
| 294 return false; | 283 return false; |
| 295 } | 284 } |
| 296 | 285 |
| 297 decoder_state_ = kInitialized; | 286 decoder_state_ = kInitialized; |
| 298 output_mode_ = config.output_mode; | 287 output_mode_ = config.output_mode; |
| 299 | 288 |
| 300 // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here. | 289 // InitializeTask will NOTIFY_ERROR on failure. |
| 301 decoder_thread_.task_runner()->PostTask( | 290 decoder_thread_.task_runner()->PostTask( |
| 302 FROM_HERE, base::Bind(base::IgnoreResult( | 291 FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::InitializeTask, |
| 303 &V4L2VideoDecodeAccelerator::StartDevicePoll), | |
| 304 base::Unretained(this))); | 292 base::Unretained(this))); |
| 305 | 293 |
| 306 return true; | 294 return true; |
| 307 } | 295 } |
| 308 | 296 |
| 297 void V4L2VideoDecodeAccelerator::InitializeTask() { |
| 298 DVLOGF(3); |
| 299 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
| 300 DCHECK_EQ(decoder_state_, kInitialized); |
| 301 |
| 302 // Subscribe to the resolution change event. |
| 303 struct v4l2_event_subscription sub; |
| 304 memset(&sub, 0, sizeof(sub)); |
| 305 sub.type = V4L2_EVENT_SOURCE_CHANGE; |
| 306 IOCTL_OR_ERROR_RETURN(VIDIOC_SUBSCRIBE_EVENT, &sub); |
| 307 |
| 308 if (!CreateInputBuffers()) { |
| 309 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 310 return; |
| 311 } |
| 312 |
| 313 decoder_cmd_supported_ = IsDecoderCmdSupported(); |
| 314 |
| 315 if (!StartDevicePoll()) |
| 316 return; |
| 317 } |
| 318 |
| 309 void V4L2VideoDecodeAccelerator::Decode( | 319 void V4L2VideoDecodeAccelerator::Decode( |
| 310 const BitstreamBuffer& bitstream_buffer) { | 320 const BitstreamBuffer& bitstream_buffer) { |
| 311 DVLOGF(1) << "input_id=" << bitstream_buffer.id() | 321 DVLOGF(1) << "input_id=" << bitstream_buffer.id() |
| 312 << ", size=" << bitstream_buffer.size(); | 322 << ", size=" << bitstream_buffer.size(); |
| 313 DCHECK(decode_task_runner_->BelongsToCurrentThread()); | 323 DCHECK(decode_task_runner_->BelongsToCurrentThread()); |
| 314 | 324 |
| 315 if (bitstream_buffer.id() < 0) { | 325 if (bitstream_buffer.id() < 0) { |
| 316 LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); | 326 LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); |
| 317 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) | 327 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) |
| 318 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); | 328 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); |
| (...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2122 DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString() | 2132 DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString() |
| 2123 << ", top-left is not origin"; | 2133 << ", top-left is not origin"; |
| 2124 return coded_size; | 2134 return coded_size; |
| 2125 } | 2135 } |
| 2126 | 2136 |
| 2127 return rect.size(); | 2137 return rect.size(); |
| 2128 } | 2138 } |
| 2129 | 2139 |
| 2130 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { | 2140 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() { |
| 2131 DVLOGF(3); | 2141 DVLOGF(3); |
| 2142 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
| 2132 // We always run this as we prepare to initialize. | 2143 // We always run this as we prepare to initialize. |
| 2133 DCHECK_EQ(decoder_state_, kUninitialized); | 2144 DCHECK_EQ(decoder_state_, kInitialized); |
| 2134 DCHECK(!input_streamon_); | 2145 DCHECK(!input_streamon_); |
| 2135 DCHECK(input_buffer_map_.empty()); | 2146 DCHECK(input_buffer_map_.empty()); |
| 2136 | 2147 |
| 2137 struct v4l2_requestbuffers reqbufs; | 2148 struct v4l2_requestbuffers reqbufs; |
| 2138 memset(&reqbufs, 0, sizeof(reqbufs)); | 2149 memset(&reqbufs, 0, sizeof(reqbufs)); |
| 2139 reqbufs.count = kInputBufferCount; | 2150 reqbufs.count = kInputBufferCount; |
| 2140 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 2151 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
| 2141 reqbufs.memory = V4L2_MEMORY_MMAP; | 2152 reqbufs.memory = V4L2_MEMORY_MMAP; |
| 2142 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); | 2153 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs); |
| 2143 input_buffer_map_.resize(reqbufs.count); | 2154 input_buffer_map_.resize(reqbufs.count); |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2624 StartResolutionChange(); | 2635 StartResolutionChange(); |
| 2625 } | 2636 } |
| 2626 } | 2637 } |
| 2627 | 2638 |
| 2628 void V4L2VideoDecodeAccelerator::ImageProcessorError() { | 2639 void V4L2VideoDecodeAccelerator::ImageProcessorError() { |
| 2629 LOGF(ERROR) << "Image processor error"; | 2640 LOGF(ERROR) << "Image processor error"; |
| 2630 NOTIFY_ERROR(PLATFORM_FAILURE); | 2641 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 2631 } | 2642 } |
| 2632 | 2643 |
| 2633 } // namespace media | 2644 } // namespace media |
| OLD | NEW |