blob: 0d5f39c193da895e34a33d1623e769306e4a1617 [file] [log] [blame]
/*
* Copyright 2016 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef HAL_USB_V4L2_CAMERA_DEVICE_H_
#define HAL_USB_V4L2_CAMERA_DEVICE_H_
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <base/files/scoped_file.h>
#include <base/synchronization/lock.h>
#include "cros-camera/timezone.h"
#include "hal/usb/common_types.h"
namespace cros {
// The class is thread-safe.
class V4L2CameraDevice {
public:
V4L2CameraDevice();
explicit V4L2CameraDevice(const DeviceInfo& device_info);
virtual ~V4L2CameraDevice();
// Connect camera device with |device_path|. Return 0 if device is opened
// successfully. Otherwise, return -|errno|.
int Connect(const std::string& device_path);
// Disconnect camera device. This function is a no-op if the camera device
// is not connected. If the stream is on, this function will also stop the
// stream.
void Disconnect();
// Enable camera device stream. Setup captured frame with |width|x|height|
// resolution, |pixel_format|, |frame_rate|, and whether we want
// |constant_frame_rate|. Get frame buffer file descriptors |fds| and
// |buffer_size|. |buffer_size| is the size allocated for each buffer. The
// ownership of |fds| are transferred to the caller and |fds| should be closed
// when done. Caller can memory map |fds| and should unmap when done. Return 0
// if device supports the format. Otherwise, return -|errno|. This function
// should be called after Connect().
int StreamOn(uint32_t width,
uint32_t height,
uint32_t pixel_format,
float frame_rate,
bool constant_frame_rate,
std::vector<base::ScopedFD>* fds,
uint32_t* buffer_size);
// Disable camera device stream. Return 0 if device disables stream
// successfully. Otherwise, return -|errno|. This function is a no-op if the
// stream is already stopped.
int StreamOff();
// Get next frame buffer from device. Device returns the corresponding buffer
// with |buffer_id|, |data_size| bytes and its |timestamp| in nanoseconds.
// |data_size| is how many bytes used in the buffer for this frame. Return 0
// if device gets the buffer successfully. Otherwise, return -|errno|. Return
// -EAGAIN immediately if next frame buffer is not ready. This function should
// be called after StreamOn().
int GetNextFrameBuffer(uint32_t* buffer_id,
uint32_t* data_size,
uint64_t* timestamp);
// Return |buffer_id| buffer to device. Return 0 if the buffer is returned
// successfully. Otherwise, return -|errno|. This function should be called
// after StreamOn().
int ReuseFrameBuffer(uint32_t buffer_id);
// TODO(shik): Change the type of |device_path| to base::FilePath.
// Get all supported formats of device by |device_path|. This function can be
// called without calling Connect().
static const SupportedFormats GetDeviceSupportedFormats(
const std::string& device_path);
// Get power frequency supported from device.
static PowerLineFrequency GetPowerLineFrequency(
const std::string& device_path);
static bool IsCameraDevice(const std::string& device_path);
private:
static std::vector<float> GetFrameRateList(int fd,
uint32_t fourcc,
uint32_t width,
uint32_t height);
// This is for suspend/resume feature. USB camera will be enumerated after
// device resumed. But camera device may not be ready immediately.
static int RetryDeviceOpen(const std::string& device_path, int flags);
// Set power frequency supported from device.
int SetPowerLineFrequency(PowerLineFrequency setting);
// Returns true if the current connected device is an external camera.
bool IsExternalCamera();
// The number of video buffers we want to request in kernel.
const int kNumVideoBuffers = 4;
// The opened device fd.
base::ScopedFD device_fd_;
// StreamOn state
bool stream_on_;
// True if the buffer is used by client after GetNextFrameBuffer().
std::vector<bool> buffers_at_client_;
// Keep internal camera devices to distinguish external camera.
// First index is VID:PID and second index is the device info.
std::unordered_map<std::string, DeviceInfo> internal_devices_;
const DeviceInfo device_info_;
// Since V4L2CameraDevice may be called on different threads, this is used to
// guard all variables.
base::Lock lock_;
DISALLOW_COPY_AND_ASSIGN(V4L2CameraDevice);
};
} // namespace cros
#endif // HAL_USB_V4L2_CAMERA_DEVICE_H_