v4llookup.cc revision 5f93d0a140515e3b8cdd1b9a4c6f5871144e5dee
1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch/* 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * libjingle 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * Copyright 2009 Google Inc. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * Redistribution and use in source and binary forms, with or without 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * modification, are permitted provided that the following conditions are met: 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * this list of conditions and the following disclaimer. 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * this list of conditions and the following disclaimer in the documentation 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * and/or other materials provided with the distribution. 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 3. The name of the author may not be used to endorse or promote products 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * derived from this software without specific prior written permission. 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch */ 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch/* 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * Author: lexnikitin@google.com (Alexey Nikitin) 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * V4LLookup provides basic functionality to work with V2L2 devices in Linux 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * The functionality is implemented as a class with virtual methods for 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * the purpose of unit testing. 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch */ 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "talk/media/devices/v4llookup.h" 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <errno.h> 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <fcntl.h> 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <linux/types.h> 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <linux/videodev2.h> 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <string.h> 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <sys/ioctl.h> 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <sys/stat.h> 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <sys/types.h> 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <unistd.h> 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "webrtc/base/logging.h" 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace cricket { 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochV4LLookup *V4LLookup::v4l_lookup_ = NULL; 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool V4LLookup::CheckIsV4L2Device(const std::string& device_path) { 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // check device major/minor numbers are in the range for video devices. 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch struct stat s; 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (lstat(device_path.c_str(), &s) != 0 || !S_ISCHR(s.st_mode)) return false; 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int video_fd = -1; 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_v4l2 = false; 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // check major/minur device numbers are in range for video device 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (major(s.st_rdev) == 81) { 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dev_t num = minor(s.st_rdev); 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (num <= 63) { 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch video_fd = ::open(device_path.c_str(), O_RDONLY | O_NONBLOCK); 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((video_fd >= 0) || (errno == EBUSY)) { 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ::v4l2_capability video_caps; 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch memset(&video_caps, 0, sizeof(video_caps)); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((errno == EBUSY) || 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (::ioctl(video_fd, VIDIOC_QUERYCAP, &video_caps) >= 0 && 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (video_caps.capabilities & V4L2_CAP_VIDEO_CAPTURE))) { 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LOG(LS_INFO) << "Found V4L2 capture device " << device_path; 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_v4l2 = true; 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LOG_ERRNO(LS_ERROR) << "VIDIOC_QUERYCAP failed for " << device_path; 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LOG_ERRNO(LS_ERROR) << "Failed to open " << device_path; 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (video_fd >= 0) 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ::close(video_fd); 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return is_v4l2; 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 92}; // namespace cricket 93