diff options
author | posciak@chromium.org <posciak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-22 10:18:20 +0000 |
---|---|---|
committer | posciak@chromium.org <posciak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-22 10:18:20 +0000 |
commit | 3fa20980170df3b92b4bdd121d9da32e6c32b528 (patch) | |
tree | a1b1d797dce82bf8fba79c8a3f081a3b1ba2072f /media/video | |
parent | 136affa2d85f7091b9c0a9c3460e032acf41306a (diff) | |
download | chromium_src-3fa20980170df3b92b4bdd121d9da32e6c32b528.zip chromium_src-3fa20980170df3b92b4bdd121d9da32e6c32b528.tar.gz chromium_src-3fa20980170df3b92b4bdd121d9da32e6c32b528.tar.bz2 |
Verify that cameras support desired formats.
Add a check whether a camera supports formats that we are interested in.
Without this it'd be possible that we'd favor a camera that doesn't support
desired formats over one that would, but with a lower video node number.
This also adds MJPEG as an option even if the resolution is lower than
minimum MJPEG resolution as the last choice, while keeping it the first
choice for resolutions larger/equal to minimum MJPEG resolution.
BUG=166299
Review URL: https://chromiumcodereview.appspot.com/11585013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/video')
-rw-r--r-- | media/video/capture/linux/video_capture_device_linux.cc | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/media/video/capture/linux/video_capture_device_linux.cc b/media/video/capture/linux/video_capture_device_linux.cc index 64654fd..8d7aaee 100644 --- a/media/video/capture/linux/video_capture_device_linux.cc +++ b/media/video/capture/linux/video_capture_device_linux.cc @@ -71,6 +71,34 @@ static VideoCaptureCapability::Format V4l2ColorToVideoCaptureColorFormat( return result; } +static void GetListOfUsableFourCCs(bool favour_mjpeg, std::list<int>* fourccs) { + for (size_t i = 0; i < arraysize(kV4l2RawFmts); ++i) + fourccs->push_back(kV4l2RawFmts[i]); + if (favour_mjpeg) + fourccs->push_front(V4L2_PIX_FMT_MJPEG); + else + fourccs->push_back(V4L2_PIX_FMT_MJPEG); +} + +static bool HasUsableFormats(int fd) { + v4l2_fmtdesc fmtdesc; + std::list<int> usable_fourccs; + + GetListOfUsableFourCCs(false, &usable_fourccs); + + memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc)); + fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { + if (std::find(usable_fourccs.begin(), usable_fourccs.end(), + fmtdesc.pixelformat) != usable_fourccs.end()) + return true; + + fmtdesc.index++; + } + return false; +} + void VideoCaptureDevice::GetDeviceNames(Names* device_names) { int fd = -1; @@ -97,8 +125,12 @@ void VideoCaptureDevice::GetDeviceNames(Names* device_names) { (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { // This is a V4L2 video capture device - name.device_name = StringPrintf("%s", cap.card); - device_names->push_back(name); + if (HasUsableFormats(fd)) { + name.device_name = StringPrintf("%s", cap.card); + device_names->push_back(name); + } else { + DVLOG(1) << "No usable formats reported by " << info.filename; + } } close(fd); } @@ -232,16 +264,12 @@ void VideoCaptureDeviceLinux::OnAllocate(int width, // Some device failed in first VIDIOC_TRY_FMT with EBUSY or EIO. // But second VIDIOC_TRY_FMT succeeds. // See http://crbug.com/94134. - // For large resolutions, favour mjpeg over raw formats. bool format_match = false; std::list<int> v4l2_formats; - if (width > kMjpegWidth || height > kMjpegHeight) { - v4l2_formats.push_back(V4L2_PIX_FMT_MJPEG); - } - for (size_t i = 0; i < arraysize(kV4l2RawFmts); ++i) { - v4l2_formats.push_back(kV4l2RawFmts[i]); - } + // For large resolutions, favour mjpeg over raw formats. + GetListOfUsableFourCCs(width > kMjpegWidth || height > kMjpegHeight, + &v4l2_formats); for (std::list<int>::const_iterator it = v4l2_formats.begin(); it != v4l2_formats.end() && !format_match; ++it) { |