| Index: media/video/capture/linux/video_capture_device_linux.cc
|
| diff --git a/media/video/capture/linux/video_capture_device_linux.cc b/media/video/capture/linux/video_capture_device_linux.cc
|
| index 6097a1e753c075f90df35a1ec7e54fac1724c832..ec5ac6fd88baf7149e8bdc10d04636d363dc1b63 100644
|
| --- a/media/video/capture/linux/video_capture_device_linux.cc
|
| +++ b/media/video/capture/linux/video_capture_device_linux.cc
|
| @@ -26,6 +26,8 @@
|
|
|
| namespace media {
|
|
|
| +#define GET_V4L2_FOURCC_CHAR(a, index) ((char)( ((a) >> (8 * index)) & 0xff))
|
| +
|
| // Max number of video buffers VideoCaptureDeviceLinux can allocate.
|
| enum { kMaxVideoBuffers = 2 };
|
| // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw.
|
| @@ -55,7 +57,7 @@ static const char kVidPathTemplate[] =
|
| static const char kPidPathTemplate[] =
|
| "/sys/class/video4linux/%s/device/../idProduct";
|
|
|
| -bool ReadIdFile(const std::string path, std::string* id) {
|
| +static bool ReadIdFile(const std::string path, std::string* id) {
|
| char id_buf[kVidPidSize];
|
| FILE* file = fopen(path.c_str(), "rb");
|
| if (!file)
|
| @@ -71,8 +73,8 @@ bool ReadIdFile(const std::string path, std::string* id) {
|
| // This function translates Video4Linux pixel formats to Chromium pixel formats,
|
| // should only support those listed in GetListOfUsableFourCCs.
|
| // static
|
| -VideoPixelFormat VideoCaptureDeviceLinux::V4l2ColorToVideoCaptureColorFormat(
|
| - int32 v4l2_fourcc) {
|
| +VideoPixelFormat VideoCaptureDeviceLinux::V4l2FourCcToChromiumPixelFormat(
|
| + uint32 v4l2_fourcc) {
|
| VideoPixelFormat result = PIXEL_FORMAT_UNKNOWN;
|
| switch (v4l2_fourcc) {
|
| case V4L2_PIX_FMT_YUV420:
|
| @@ -89,24 +91,30 @@ VideoPixelFormat VideoCaptureDeviceLinux::V4l2ColorToVideoCaptureColorFormat(
|
| result = PIXEL_FORMAT_MJPEG;
|
| break;
|
| default:
|
| - DVLOG(1) << "Unsupported pixel format " << std::hex << v4l2_fourcc;
|
| + DVLOG(1) << "Unsupported pixel format: "
|
| + << GET_V4L2_FOURCC_CHAR(v4l2_fourcc, 0)
|
| + << GET_V4L2_FOURCC_CHAR(v4l2_fourcc, 1)
|
| + << GET_V4L2_FOURCC_CHAR(v4l2_fourcc, 2)
|
| + << GET_V4L2_FOURCC_CHAR(v4l2_fourcc, 3);
|
| }
|
| return result;
|
| }
|
|
|
| // static
|
| -void VideoCaptureDeviceLinux::GetListOfUsableFourCCs(bool favour_mjpeg,
|
| - std::list<int>* fourccs) {
|
| +std::list<int> VideoCaptureDeviceLinux::GetListOfUsableFourCCs(
|
| + bool favour_mjpeg) {
|
| + std::list<int> fourccs;
|
| for (size_t i = 0; i < arraysize(kV4l2RawFmts); ++i)
|
| - fourccs->push_back(kV4l2RawFmts[i]);
|
| + fourccs.push_back(kV4l2RawFmts[i]);
|
| if (favour_mjpeg)
|
| - fourccs->push_front(V4L2_PIX_FMT_MJPEG);
|
| + fourccs.push_front(V4L2_PIX_FMT_MJPEG);
|
| else
|
| - fourccs->push_back(V4L2_PIX_FMT_MJPEG);
|
| + fourccs.push_back(V4L2_PIX_FMT_MJPEG);
|
|
|
| // JPEG works as MJPEG on some gspca webcams from field reports.
|
| // Put it as the least preferred format.
|
| - fourccs->push_back(V4L2_PIX_FMT_JPEG);
|
| + fourccs.push_back(V4L2_PIX_FMT_JPEG);
|
| + return fourccs;
|
| }
|
|
|
| const std::string VideoCaptureDevice::Name::GetModel() const {
|
| @@ -227,22 +235,17 @@ void VideoCaptureDeviceLinux::OnAllocateAndStart(int width,
|
|
|
| // Get supported video formats in preferred order.
|
| // For large resolutions, favour mjpeg over raw formats.
|
| - std::list<int> v4l2_formats;
|
| - GetListOfUsableFourCCs(width > kMjpegWidth || height > kMjpegHeight,
|
| - &v4l2_formats);
|
| + const std::list<int>& desired_v4l2_formats =
|
| + GetListOfUsableFourCCs(width > kMjpegWidth || height > kMjpegHeight);
|
| + std::list<int>::const_iterator best = desired_v4l2_formats.end();
|
|
|
| v4l2_fmtdesc fmtdesc = {0};
|
| fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
| -
|
| - // Enumerate image formats.
|
| - std::list<int>::iterator best = v4l2_formats.end();
|
| - while (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_ENUM_FMT, &fmtdesc)) ==
|
| - 0) {
|
| - best = std::find(v4l2_formats.begin(), best, fmtdesc.pixelformat);
|
| - fmtdesc.index++;
|
| + for (; HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_ENUM_FMT, &fmtdesc)) == 0;
|
| + ++fmtdesc.index) {
|
| + best = std::find(desired_v4l2_formats.begin(), best, fmtdesc.pixelformat);
|
| }
|
| -
|
| - if (best == v4l2_formats.end()) {
|
| + if (best == desired_v4l2_formats.end()) {
|
| SetErrorState("Failed to find a supported camera format.");
|
| return;
|
| }
|
| @@ -308,12 +311,10 @@ void VideoCaptureDeviceLinux::OnAllocateAndStart(int width,
|
| video_fmt.fmt.pix.height);
|
| capture_format_.frame_rate = frame_rate;
|
| capture_format_.pixel_format =
|
| - V4l2ColorToVideoCaptureColorFormat(video_fmt.fmt.pix.pixelformat);
|
| + V4l2FourCcToChromiumPixelFormat(video_fmt.fmt.pix.pixelformat);
|
|
|
| - // Start capturing.
|
| if (!AllocateVideoBuffers()) {
|
| - // Error, We can not recover.
|
| - SetErrorState("Allocate buffer failed");
|
| + SetErrorState("Allocate buffers failed");
|
| return;
|
| }
|
|
|
| @@ -340,13 +341,12 @@ void VideoCaptureDeviceLinux::OnStopAndDeAllocate() {
|
| SetErrorState("VIDIOC_STREAMOFF failed");
|
| return;
|
| }
|
| - // We don't dare to deallocate the buffers if we can't stop
|
| - // the capture device.
|
| + // We don't dare to deallocate the buffers if we can't stop the capture
|
| + // device.
|
| DeAllocateVideoBuffers();
|
|
|
| - // We need to close and open the device if we want to change the settings
|
| - // Otherwise VIDIOC_S_FMT will return error
|
| - // Sad but true.
|
| + // We need to close and open the device if we want to change the settings.
|
| + // Otherwise VIDIOC_S_FMT will return error. Sad but true.
|
| device_fd_.reset();
|
| is_capturing_ = false;
|
| client_.reset();
|
|
|