| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/video/capture/linux/video_capture_device_linux.h" | 5 #include "media/video/capture/linux/video_capture_device_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <poll.h> | 9 #include <poll.h> |
| 10 #if defined(OS_OPENBSD) | 10 #if defined(OS_OPENBSD) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "base/bind.h" | 21 #include "base/bind.h" |
| 22 #include "base/files/file_enumerator.h" | 22 #include "base/files/file_enumerator.h" |
| 23 #include "base/files/scoped_file.h" | 23 #include "base/files/scoped_file.h" |
| 24 #include "base/posix/eintr_wrapper.h" | 24 #include "base/posix/eintr_wrapper.h" |
| 25 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
| 26 | 26 |
| 27 namespace media { | 27 namespace media { |
| 28 | 28 |
| 29 #define GET_V4L2_FOURCC_CHAR(a, index) ((char)( ((a) >> (8 * index)) & 0xff)) | 29 #define GET_V4L2_FOURCC_CHAR(a, index) ((char)( ((a) >> (8 * index)) & 0xff)) |
| 30 | 30 |
| 31 // Max number of video buffers VideoCaptureDeviceLinux can allocate. | 31 // Desired number of video buffers to allocate. The actual number of allocated |
| 32 const uint32 kMaxVideoBuffers = 2; | 32 // buffers by v4l2 driver can be higher or lower than this number. |
| 33 // kNumVideoBuffers should not be too small, or Chrome may not return enough |
| 34 // buffers back to driver in time. |
| 35 const uint32 kNumVideoBuffers = 4; |
| 33 // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw. | 36 // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw. |
| 34 enum { kCaptureTimeoutMs = 200 }; | 37 enum { kCaptureTimeoutMs = 200 }; |
| 35 // The number of continuous timeouts tolerated before treated as error. | 38 // The number of continuous timeouts tolerated before treated as error. |
| 36 enum { kContinuousTimeoutLimit = 10 }; | 39 enum { kContinuousTimeoutLimit = 10 }; |
| 37 // MJPEG is preferred if the width or height is larger than this. | 40 // MJPEG is preferred if the width or height is larger than this. |
| 38 enum { kMjpegWidth = 640 }; | 41 enum { kMjpegWidth = 640 }; |
| 39 enum { kMjpegHeight = 480 }; | 42 enum { kMjpegHeight = 480 }; |
| 40 // Typical framerate, in fps | 43 // Typical framerate, in fps |
| 41 enum { kTypicalFramerate = 30 }; | 44 enum { kTypicalFramerate = 30 }; |
| 42 | 45 |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 v4l2_task_runner_->PostTask( | 459 v4l2_task_runner_->PostTask( |
| 457 FROM_HERE, | 460 FROM_HERE, |
| 458 base::Bind(&VideoCaptureDeviceLinux::V4L2CaptureDelegate::DoCapture, | 461 base::Bind(&VideoCaptureDeviceLinux::V4L2CaptureDelegate::DoCapture, |
| 459 this)); | 462 this)); |
| 460 } | 463 } |
| 461 | 464 |
| 462 bool VideoCaptureDeviceLinux::V4L2CaptureDelegate::AllocateVideoBuffers() { | 465 bool VideoCaptureDeviceLinux::V4L2CaptureDelegate::AllocateVideoBuffers() { |
| 463 v4l2_requestbuffers r_buffer = {}; | 466 v4l2_requestbuffers r_buffer = {}; |
| 464 r_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 467 r_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 465 r_buffer.memory = V4L2_MEMORY_MMAP; | 468 r_buffer.memory = V4L2_MEMORY_MMAP; |
| 466 r_buffer.count = kMaxVideoBuffers; | 469 r_buffer.count = kNumVideoBuffers; |
| 467 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_REQBUFS, &r_buffer)) < 0) { | 470 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_REQBUFS, &r_buffer)) < 0) { |
| 468 DLOG(ERROR) << "Error requesting MMAP buffers from V4L2"; | 471 DLOG(ERROR) << "Error requesting MMAP buffers from V4L2"; |
| 469 return false; | 472 return false; |
| 470 } | 473 } |
| 471 DCHECK_EQ(r_buffer.count, kMaxVideoBuffers); | |
| 472 r_buffer.count = std::min(r_buffer.count, kMaxVideoBuffers); | |
| 473 buffer_pool_size_ = r_buffer.count; | 474 buffer_pool_size_ = r_buffer.count; |
| 474 buffer_pool_ = new Buffer[buffer_pool_size_]; | 475 buffer_pool_ = new Buffer[buffer_pool_size_]; |
| 475 for (unsigned int i = 0; i < r_buffer.count; ++i) { | 476 for (unsigned int i = 0; i < r_buffer.count; ++i) { |
| 476 v4l2_buffer buffer = {}; | 477 v4l2_buffer buffer = {}; |
| 477 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 478 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 478 buffer.memory = V4L2_MEMORY_MMAP; | 479 buffer.memory = V4L2_MEMORY_MMAP; |
| 479 buffer.index = i; | 480 buffer.index = i; |
| 480 buffer.length = 1; | 481 buffer.length = 1; |
| 481 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYBUF, &buffer)) < 0) { | 482 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYBUF, &buffer)) < 0) { |
| 482 DLOG(ERROR) << "Error querying status of a MMAP V4L2 buffer"; | 483 DLOG(ERROR) << "Error querying status of a MMAP V4L2 buffer"; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 } | 525 } |
| 525 | 526 |
| 526 void VideoCaptureDeviceLinux::V4L2CaptureDelegate::SetErrorState( | 527 void VideoCaptureDeviceLinux::V4L2CaptureDelegate::SetErrorState( |
| 527 const std::string& reason) { | 528 const std::string& reason) { |
| 528 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 529 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 529 is_capturing_ = false; | 530 is_capturing_ = false; |
| 530 client_->OnError(reason); | 531 client_->OnError(reason); |
| 531 } | 532 } |
| 532 | 533 |
| 533 } // namespace media | 534 } // namespace media |
| OLD | NEW |