Commit c766ec29 authored by Lei Zhang's avatar Lei Zhang Committed by Commit Bot

Fix nits in V4L2CaptureDelegate.

Change-Id: I3716899d74877992ad3b85a82eda82a17dcf142e
Reviewed-on: https://chromium-review.googlesource.com/1215049
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589990}
parent f56c92f9
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
...@@ -38,30 +39,32 @@ using media::mojom::MeteringMode; ...@@ -38,30 +39,32 @@ using media::mojom::MeteringMode;
namespace media { namespace media {
namespace {
// Desired number of video buffers to allocate. The actual number of allocated // Desired number of video buffers to allocate. The actual number of allocated
// buffers by v4l2 driver can be higher or lower than this number. // buffers by v4l2 driver can be higher or lower than this number.
// kNumVideoBuffers should not be too small, or Chrome may not return enough // kNumVideoBuffers should not be too small, or Chrome may not return enough
// buffers back to driver in time. // buffers back to driver in time.
const uint32_t kNumVideoBuffers = 4; constexpr uint32_t kNumVideoBuffers = 4;
// Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw. // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw.
// This value has been fine tuned. Before changing or modifying it see // This value has been fine tuned. Before changing or modifying it see
// https://crbug.com/470717 // https://crbug.com/470717
const int kCaptureTimeoutMs = 1000; constexpr int kCaptureTimeoutMs = 1000;
// The number of continuous timeouts tolerated before treated as error. // The number of continuous timeouts tolerated before treated as error.
const int kContinuousTimeoutLimit = 10; constexpr int kContinuousTimeoutLimit = 10;
// MJPEG is preferred if the requested width or height is larger than this. // MJPEG is preferred if the requested width or height is larger than this.
const int kMjpegWidth = 640; constexpr int kMjpegWidth = 640;
const int kMjpegHeight = 480; constexpr int kMjpegHeight = 480;
// Typical framerate, in fps // Typical framerate, in fps
const int kTypicalFramerate = 30; constexpr int kTypicalFramerate = 30;
// V4L2 color formats supported by V4L2CaptureDelegate derived classes. // V4L2 color formats supported by V4L2CaptureDelegate derived classes.
// This list is ordered by precedence of use -- but see caveats for MJPEG. // This list is ordered by precedence of use -- but see caveats for MJPEG.
static struct { struct {
uint32_t fourcc; uint32_t fourcc;
VideoPixelFormat pixel_format; VideoPixelFormat pixel_format;
size_t num_planes; size_t num_planes;
} const kSupportedFormatsAndPlanarity[] = { } constexpr kSupportedFormatsAndPlanarity[] = {
{V4L2_PIX_FMT_YUV420, PIXEL_FORMAT_I420, 1}, {V4L2_PIX_FMT_YUV420, PIXEL_FORMAT_I420, 1},
{V4L2_PIX_FMT_Y16, PIXEL_FORMAT_Y16, 1}, {V4L2_PIX_FMT_Y16, PIXEL_FORMAT_Y16, 1},
{V4L2_PIX_FMT_Z16, PIXEL_FORMAT_Y16, 1}, {V4L2_PIX_FMT_Z16, PIXEL_FORMAT_Y16, 1},
...@@ -81,20 +84,20 @@ static struct { ...@@ -81,20 +84,20 @@ static struct {
}; };
// Maximum number of ioctl retries before giving up trying to reset controls. // Maximum number of ioctl retries before giving up trying to reset controls.
const int kMaxIOCtrlRetries = 5; constexpr int kMaxIOCtrlRetries = 5;
// Base id and class identifier for Controls to be reset. // Base id and class identifier for Controls to be reset.
static struct { struct {
uint32_t control_base; uint32_t control_base;
uint32_t class_id; uint32_t class_id;
} const kControls[] = {{V4L2_CID_USER_BASE, V4L2_CID_USER_CLASS}, } constexpr kControls[] = {{V4L2_CID_USER_BASE, V4L2_CID_USER_CLASS},
{V4L2_CID_CAMERA_CLASS_BASE, V4L2_CID_CAMERA_CLASS}}; {V4L2_CID_CAMERA_CLASS_BASE, V4L2_CID_CAMERA_CLASS}};
// Fill in |format| with the given parameters. // Fill in |format| with the given parameters.
static void FillV4L2Format(v4l2_format* format, void FillV4L2Format(v4l2_format* format,
uint32_t width, uint32_t width,
uint32_t height, uint32_t height,
uint32_t pixelformat_fourcc) { uint32_t pixelformat_fourcc) {
memset(format, 0, sizeof(*format)); memset(format, 0, sizeof(*format));
format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format->fmt.pix.width = width; format->fmt.pix.width = width;
...@@ -103,15 +106,14 @@ static void FillV4L2Format(v4l2_format* format, ...@@ -103,15 +106,14 @@ static void FillV4L2Format(v4l2_format* format,
} }
// Fills all parts of |buffer|. // Fills all parts of |buffer|.
static void FillV4L2Buffer(v4l2_buffer* buffer, int index) { void FillV4L2Buffer(v4l2_buffer* buffer, int index) {
memset(buffer, 0, sizeof(*buffer)); memset(buffer, 0, sizeof(*buffer));
buffer->memory = V4L2_MEMORY_MMAP; buffer->memory = V4L2_MEMORY_MMAP;
buffer->index = index; buffer->index = index;
buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
} }
static void FillV4L2RequestBuffer(v4l2_requestbuffers* request_buffer, void FillV4L2RequestBuffer(v4l2_requestbuffers* request_buffer, int count) {
int count) {
memset(request_buffer, 0, sizeof(*request_buffer)); memset(request_buffer, 0, sizeof(*request_buffer));
request_buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; request_buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
request_buffer->memory = V4L2_MEMORY_MMAP; request_buffer->memory = V4L2_MEMORY_MMAP;
...@@ -119,13 +121,13 @@ static void FillV4L2RequestBuffer(v4l2_requestbuffers* request_buffer, ...@@ -119,13 +121,13 @@ static void FillV4L2RequestBuffer(v4l2_requestbuffers* request_buffer,
} }
// Returns the input |fourcc| as a std::string four char representation. // Returns the input |fourcc| as a std::string four char representation.
static std::string FourccToString(uint32_t fourcc) { std::string FourccToString(uint32_t fourcc) {
return base::StringPrintf("%c%c%c%c", fourcc & 0xFF, (fourcc >> 8) & 0xFF, return base::StringPrintf("%c%c%c%c", fourcc & 0xFF, (fourcc >> 8) & 0xFF,
(fourcc >> 16) & 0xFF, (fourcc >> 24) & 0xFF); (fourcc >> 16) & 0xFF, (fourcc >> 24) & 0xFF);
} }
// Determines if |control_id| is special, i.e. controls another one's state. // Determines if |control_id| is special, i.e. controls another one's state.
static bool IsSpecialControl(int control_id) { bool IsSpecialControl(int control_id) {
switch (control_id) { switch (control_id) {
case V4L2_CID_AUTO_WHITE_BALANCE: case V4L2_CID_AUTO_WHITE_BALANCE:
case V4L2_CID_EXPOSURE_AUTO: case V4L2_CID_EXPOSURE_AUTO:
...@@ -146,7 +148,7 @@ static bool IsSpecialControl(int control_id) { ...@@ -146,7 +148,7 @@ static bool IsSpecialControl(int control_id) {
#if !defined(V4L2_CID_PANTILT_CMD) #if !defined(V4L2_CID_PANTILT_CMD)
#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34) #define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34)
#endif #endif
static bool IsBlacklistedControl(int control_id) { bool IsBlacklistedControl(int control_id) {
switch (control_id) { switch (control_id) {
case V4L2_CID_PAN_RELATIVE: case V4L2_CID_PAN_RELATIVE:
case V4L2_CID_TILT_RELATIVE: case V4L2_CID_TILT_RELATIVE:
...@@ -165,12 +167,15 @@ static bool IsBlacklistedControl(int control_id) { ...@@ -165,12 +167,15 @@ static bool IsBlacklistedControl(int control_id) {
return false; return false;
} }
} // namespace
// Class keeping track of a SPLANE V4L2 buffer, mmap()ed on construction and // Class keeping track of a SPLANE V4L2 buffer, mmap()ed on construction and
// munmap()ed on destruction. // munmap()ed on destruction.
class V4L2CaptureDelegate::BufferTracker class V4L2CaptureDelegate::BufferTracker
: public base::RefCounted<BufferTracker> { : public base::RefCounted<BufferTracker> {
public: public:
BufferTracker(V4L2CaptureDevice* v4l2); explicit BufferTracker(V4L2CaptureDevice* v4l2);
// Abstract method to mmap() given |fd| according to |buffer|. // Abstract method to mmap() given |fd| according to |buffer|.
bool Init(int fd, const v4l2_buffer& buffer); bool Init(int fd, const v4l2_buffer& buffer);
...@@ -647,7 +652,9 @@ void V4L2CaptureDelegate::SetPhotoOptions( ...@@ -647,7 +652,9 @@ void V4L2CaptureDelegate::SetPhotoOptions(
void V4L2CaptureDelegate::SetRotation(int rotation) { void V4L2CaptureDelegate::SetRotation(int rotation) {
DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); DCHECK_GE(rotation, 0);
DCHECK_LT(rotation, 360);
DCHECK_EQ(rotation % 90, 0);
rotation_ = rotation; rotation_ = rotation;
} }
...@@ -812,7 +819,7 @@ bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) { ...@@ -812,7 +819,7 @@ bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) {
return false; return false;
} }
const scoped_refptr<BufferTracker> buffer_tracker(new BufferTracker(v4l2_)); const auto buffer_tracker = base::MakeRefCounted<BufferTracker>(v4l2_);
if (!buffer_tracker->Init(device_fd_.get(), buffer)) { if (!buffer_tracker->Init(device_fd_.get(), buffer)) {
DLOG(ERROR) << "Error creating BufferTracker"; DLOG(ERROR) << "Error creating BufferTracker";
return false; return false;
...@@ -885,24 +892,29 @@ void V4L2CaptureDelegate::DoCapture() { ...@@ -885,24 +892,29 @@ void V4L2CaptureDelegate::DoCapture() {
const base::TimeDelta timestamp = now - first_ref_time_; const base::TimeDelta timestamp = now - first_ref_time_;
#ifdef V4L2_BUF_FLAG_ERROR #ifdef V4L2_BUF_FLAG_ERROR
if (buffer.flags & V4L2_BUF_FLAG_ERROR) { bool buf_error_flag_set = buffer.flags & V4L2_BUF_FLAG_ERROR;
#else
bool buf_error_flag_set = false;
#endif
if (buf_error_flag_set) {
#ifdef V4L2_BUF_FLAG_ERROR
LOG(ERROR) << "Dequeued v4l2 buffer contains corrupted data (" LOG(ERROR) << "Dequeued v4l2 buffer contains corrupted data ("
<< buffer.bytesused << " bytes)."; << buffer.bytesused << " bytes).";
buffer.bytesused = 0; buffer.bytesused = 0;
client_->OnFrameDropped( client_->OnFrameDropped(
VideoCaptureFrameDropReason::kV4L2BufferErrorFlagWasSet); VideoCaptureFrameDropReason::kV4L2BufferErrorFlagWasSet);
} else
#endif #endif
if (buffer.bytesused < capture_format_.ImageAllocationSize()) { } else if (buffer.bytesused < capture_format_.ImageAllocationSize()) {
LOG(ERROR) << "Dequeued v4l2 buffer contains invalid length (" LOG(ERROR) << "Dequeued v4l2 buffer contains invalid length ("
<< buffer.bytesused << " bytes)."; << buffer.bytesused << " bytes).";
buffer.bytesused = 0; buffer.bytesused = 0;
client_->OnFrameDropped( client_->OnFrameDropped(
VideoCaptureFrameDropReason::kV4L2InvalidNumberOfBytesInBuffer); VideoCaptureFrameDropReason::kV4L2InvalidNumberOfBytesInBuffer);
} else } else {
client_->OnIncomingCapturedData( client_->OnIncomingCapturedData(
buffer_tracker->start(), buffer_tracker->payload_size(), buffer_tracker->start(), buffer_tracker->payload_size(),
capture_format_, rotation_, now, timestamp); capture_format_, rotation_, now, timestamp);
}
while (!take_photo_callbacks_.empty()) { while (!take_photo_callbacks_.empty()) {
VideoCaptureDevice::TakePhotoCallback cb = VideoCaptureDevice::TakePhotoCallback cb =
...@@ -939,7 +951,7 @@ V4L2CaptureDelegate::BufferTracker::BufferTracker(V4L2CaptureDevice* v4l2) ...@@ -939,7 +951,7 @@ V4L2CaptureDelegate::BufferTracker::BufferTracker(V4L2CaptureDevice* v4l2)
: v4l2_(v4l2) {} : v4l2_(v4l2) {}
V4L2CaptureDelegate::BufferTracker::~BufferTracker() { V4L2CaptureDelegate::BufferTracker::~BufferTracker() {
if (start_ == nullptr) if (!start_)
return; return;
const int result = v4l2_->munmap(start_, length_); const int result = v4l2_->munmap(start_, length_);
PLOG_IF(ERROR, result < 0) << "Error munmap()ing V4L2 buffer"; PLOG_IF(ERROR, result < 0) << "Error munmap()ing V4L2 buffer";
...@@ -949,8 +961,9 @@ bool V4L2CaptureDelegate::BufferTracker::Init(int fd, ...@@ -949,8 +961,9 @@ bool V4L2CaptureDelegate::BufferTracker::Init(int fd,
const v4l2_buffer& buffer) { const v4l2_buffer& buffer) {
// Some devices require mmap() to be called with both READ and WRITE. // Some devices require mmap() to be called with both READ and WRITE.
// See http://crbug.com/178582. // See http://crbug.com/178582.
void* const start = v4l2_->mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, constexpr int kFlags = PROT_READ | PROT_WRITE;
MAP_SHARED, fd, buffer.m.offset); void* const start = v4l2_->mmap(nullptr, buffer.length, kFlags, MAP_SHARED,
fd, buffer.m.offset);
if (start == MAP_FAILED) { if (start == MAP_FAILED) {
DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace";
return false; return false;
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/queue.h" #include "base/containers/queue.h"
#include "base/files/scoped_file.h" #include "base/files/scoped_file.h"
#include "base/macros.h" #include "base/macros.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment