diff options
author | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 18:15:51 +0000 |
---|---|---|
committer | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 18:15:51 +0000 |
commit | 085e86b29b27304e02a229e81e52de50c5a19a5b (patch) | |
tree | ce149f41c1c4c75a8b759bcab0e34fe55cc331bf | |
parent | 5337eda506eb68908a4a3489ce5d99cb716fb2c5 (diff) | |
download | chromium_src-085e86b29b27304e02a229e81e52de50c5a19a5b.zip chromium_src-085e86b29b27304e02a229e81e52de50c5a19a5b.tar.gz chromium_src-085e86b29b27304e02a229e81e52de50c5a19a5b.tar.bz2 |
VideoCaptureDevice{Linux,Android}: extract Factory methods to class.
Linux: Extract static methods and make a
VideoCaptureDeviceFactoryLinux out of it.
Two anonymous namespace methods are used by both
VCDFLinux and VCDLinux: they are made static
inside the VCDLinux.
Android: There's already a factory wrapping up
the correspondent Java code, so this CL makes
this factory derive from
VideoCaptureDeviceFactory.
TBR= dalecurtis@chromium.org : media/media.gyp
BUG=323913
Review URL: https://codereview.chromium.org/262333004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270738 0039d316-1c4b-4281-b951-d872f2087c98
10 files changed, 329 insertions, 194 deletions
diff --git a/media/media.gyp b/media/media.gyp index fae81bd..db56ca8 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -469,6 +469,8 @@ 'video/capture/file_video_capture_device.h', 'video/capture/file_video_capture_device_factory.h', 'video/capture/file_video_capture_device_factory.cc', + 'video/capture/linux/video_capture_device_factory_linux.cc', + 'video/capture/linux/video_capture_device_factory_linux.h', 'video/capture/linux/video_capture_device_linux.cc', 'video/capture/linux/video_capture_device_linux.h', 'video/capture/mac/avfoundation_glue.h', diff --git a/media/video/capture/android/video_capture_device_android.cc b/media/video/capture/android/video_capture_device_android.cc index 426be13..197ec22 100644 --- a/media/video/capture/android/video_capture_device_android.cc +++ b/media/video/capture/android/video_capture_device_android.cc @@ -21,36 +21,31 @@ using base::android::ScopedJavaLocalRef; namespace media { -//static -void VideoCaptureDevice::GetDeviceNames(Names* device_names) { - VideoCaptureDeviceFactoryAndroid::GetDeviceNames(device_names); -} - // static -void VideoCaptureDevice::GetDeviceSupportedFormats( - const Name& device, - VideoCaptureFormats* capture_formats) { - VideoCaptureDeviceFactoryAndroid::GetDeviceSupportedFormats(device, - capture_formats); +bool VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(JNIEnv* env) { + return RegisterNativesImpl(env); } +// TODO(mcasas): Remove the following static methods when they are no longer +// referenced from VideoCaptureDeviceFactory, i.e. when all OS platforms have +// splitted the VideoCaptureDevice into VideoCaptureDevice and +// VideoCaptureDeviceFactory. + // static VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { - return VideoCaptureDeviceAndroid::Create(device_name); + NOTREACHED(); + return NULL; } - // static -VideoCaptureDevice* VideoCaptureDeviceAndroid::Create(const Name& device_name) { - scoped_ptr<VideoCaptureDeviceAndroid> ret( - new VideoCaptureDeviceAndroid(device_name)); - if (ret->Init()) - return ret.release(); - return NULL; +void VideoCaptureDevice::GetDeviceNames(Names* device_names) { + NOTREACHED(); } // static -bool VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(JNIEnv* env) { - return RegisterNativesImpl(env); +void VideoCaptureDevice::GetDeviceSupportedFormats( + const Name& device, + VideoCaptureFormats* supported_formats) { + NOTREACHED(); } const std::string VideoCaptureDevice::Name::GetModel() const { diff --git a/media/video/capture/android/video_capture_device_android.h b/media/video/capture/android/video_capture_device_android.h index 958036f..1a2e8b8 100644 --- a/media/video/capture/android/video_capture_device_android.h +++ b/media/video/capture/android/video_capture_device_android.h @@ -30,11 +30,17 @@ class MEDIA_EXPORT VideoCaptureDeviceAndroid : public VideoCaptureDevice { #undef DEFINE_ANDROID_IMAGEFORMAT }; + explicit VideoCaptureDeviceAndroid(const Name& device_name); virtual ~VideoCaptureDeviceAndroid(); static VideoCaptureDevice* Create(const Name& device_name); static bool RegisterVideoCaptureDevice(JNIEnv* env); + // Registers the Java VideoCaptureDevice pointer, used by the rest of the + // methods of the class to operate the Java capture code. This method must be + // called after the class constructor and before AllocateAndStart(). + bool Init(); + // VideoCaptureDevice implementation. virtual void AllocateAndStart(const VideoCaptureParams& params, scoped_ptr<Client> client) OVERRIDE; @@ -55,8 +61,6 @@ class MEDIA_EXPORT VideoCaptureDeviceAndroid : public VideoCaptureDevice { kError // Hit error. User needs to recover by destroying the object. }; - explicit VideoCaptureDeviceAndroid(const Name& device_name); - bool Init(); VideoPixelFormat GetColorspace(); void SetErrorState(const std::string& reason); diff --git a/media/video/capture/android/video_capture_device_factory_android.cc b/media/video/capture/android/video_capture_device_factory_android.cc index e9a806a..99ed492 100644 --- a/media/video/capture/android/video_capture_device_factory_android.cc +++ b/media/video/capture/android/video_capture_device_factory_android.cc @@ -9,6 +9,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "jni/VideoCaptureFactory_jni.h" +#include "media/video/capture/android/video_capture_device_android.h" using base::android::AttachCurrentThread; using base::android::ScopedJavaLocalRef; @@ -16,8 +17,43 @@ using base::android::ScopedJavaLocalRef; namespace media { // static +bool VideoCaptureDeviceFactoryAndroid::RegisterVideoCaptureDeviceFactory( + JNIEnv* env) { + return RegisterNativesImpl(env); +} + +//static +ScopedJavaLocalRef<jobject> +VideoCaptureDeviceFactoryAndroid::createVideoCaptureAndroid( + int id, + jlong nativeVideoCaptureDeviceAndroid) { + return (Java_VideoCaptureFactory_createVideoCapture( + AttachCurrentThread(), + base::android::GetApplicationContext(), + id, + nativeVideoCaptureDeviceAndroid)); +} + +scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryAndroid::Create( + const VideoCaptureDevice::Name& device_name) { + DCHECK(thread_checker_.CalledOnValidThread()); + int id; + if (!base::StringToInt(device_name.id(), &id)) + return scoped_ptr<VideoCaptureDevice>(); + + VideoCaptureDeviceAndroid* video_capture_device( + new VideoCaptureDeviceAndroid(device_name)); + + if (video_capture_device->Init()) + return scoped_ptr<VideoCaptureDevice>(video_capture_device); + + DLOG(ERROR) << "Error creating Video Capture Device."; + return scoped_ptr<VideoCaptureDevice>(); +} + void VideoCaptureDeviceFactoryAndroid::GetDeviceNames( VideoCaptureDevice::Names* device_names) { + DCHECK(thread_checker_.CalledOnValidThread()); device_names->clear(); JNIEnv* env = AttachCurrentThread(); @@ -45,10 +81,10 @@ void VideoCaptureDeviceFactoryAndroid::GetDeviceNames( } } -// static void VideoCaptureDeviceFactoryAndroid::GetDeviceSupportedFormats( const VideoCaptureDevice::Name& device, VideoCaptureFormats* capture_formats) { + DCHECK(thread_checker_.CalledOnValidThread()); int id; if (!base::StringToInt(device.id(), &id)) return; @@ -91,22 +127,4 @@ void VideoCaptureDeviceFactoryAndroid::GetDeviceSupportedFormats( } } -//static -ScopedJavaLocalRef<jobject> -VideoCaptureDeviceFactoryAndroid::createVideoCaptureAndroid( - int id, - jlong nativeVideoCaptureDeviceAndroid) { - return (Java_VideoCaptureFactory_createVideoCapture( - AttachCurrentThread(), - base::android::GetApplicationContext(), - id, - nativeVideoCaptureDeviceAndroid)); -} - -// static -bool VideoCaptureDeviceFactoryAndroid::RegisterVideoCaptureDeviceFactory( - JNIEnv* env) { - return RegisterNativesImpl(env); -} - } // namespace media diff --git a/media/video/capture/android/video_capture_device_factory_android.h b/media/video/capture/android/video_capture_device_factory_android.h index b52d4f0..d87416f 100644 --- a/media/video/capture/android/video_capture_device_factory_android.h +++ b/media/video/capture/android/video_capture_device_factory_android.h @@ -5,6 +5,8 @@ #ifndef MEDIA_VIDEO_CAPTURE_ANDROID_VIDEO_CAPTURE_DEVICE_FACTORY_ANDROID_H_ #define MEDIA_VIDEO_CAPTURE_ANDROID_VIDEO_CAPTURE_DEVICE_FACTORY_ANDROID_H_ +#include "media/video/capture/video_capture_device_factory.h" + #include <jni.h> #include "base/android/scoped_java_ref.h" @@ -14,7 +16,8 @@ namespace media { // VideoCaptureDeviceFactory on Android. This class implements the static // VideoCapture methods and the factory of VideoCaptureAndroid. -class MEDIA_EXPORT VideoCaptureDeviceFactoryAndroid { +class MEDIA_EXPORT VideoCaptureDeviceFactoryAndroid : + public VideoCaptureDeviceFactory { public: // Automatically generated enum to interface with Java world. enum AndroidImageFormat { @@ -22,19 +25,24 @@ class MEDIA_EXPORT VideoCaptureDeviceFactoryAndroid { #include "media/video/capture/android/imageformat_list.h" #undef DEFINE_ANDROID_IMAGEFORMAT }; - - virtual ~VideoCaptureDeviceFactoryAndroid(); - - static void GetDeviceNames(VideoCaptureDevice::Names* device_names); - static void GetDeviceSupportedFormats( - const VideoCaptureDevice::Name& device, - VideoCaptureFormats* capture_formats); static bool RegisterVideoCaptureDeviceFactory(JNIEnv* env); static base::android::ScopedJavaLocalRef<jobject> createVideoCaptureAndroid( int id, jlong nativeVideoCaptureDeviceAndroid); -}; + VideoCaptureDeviceFactoryAndroid() {} + virtual ~VideoCaptureDeviceFactoryAndroid() {} + + virtual scoped_ptr<VideoCaptureDevice> Create( + const VideoCaptureDevice::Name& device_name) OVERRIDE; + virtual void GetDeviceNames(VideoCaptureDevice::Names* device_names) OVERRIDE; + virtual void GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) OVERRIDE; + + private: + + DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceFactoryAndroid);}; } // namespace media #endif // MEDIA_VIDEO_CAPTURE_ANDROID_VIDEO_CAPTURE_DEVICE_FACTORY_ANDROID_H_ diff --git a/media/video/capture/linux/video_capture_device_factory_linux.cc b/media/video/capture/linux/video_capture_device_factory_linux.cc new file mode 100644 index 0000000..b2981d4 --- /dev/null +++ b/media/video/capture/linux/video_capture_device_factory_linux.cc @@ -0,0 +1,171 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/video/capture/linux/video_capture_device_factory_linux.h" + +#include <errno.h> +#include <fcntl.h> +#if defined(OS_OPENBSD) +#include <sys/videoio.h> +#else +#include <linux/videodev2.h> +#endif +#include <sys/ioctl.h> + +#include "base/files/file_enumerator.h" +#include "base/files/scoped_file.h" +#include "base/posix/eintr_wrapper.h" +#include "base/strings/stringprintf.h" +#include "media/video/capture/linux/video_capture_device_linux.h" + +namespace media { + +static bool HasUsableFormats(int fd) { + v4l2_fmtdesc fmtdesc; + std::list<int> usable_fourccs; + + media::VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false, + &usable_fourccs); + + memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc)); + fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + while (HANDLE_EINTR(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; +} + +scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryLinux::Create( + const VideoCaptureDevice::Name& device_name) { + DCHECK(thread_checker_.CalledOnValidThread()); + VideoCaptureDeviceLinux* self = new VideoCaptureDeviceLinux(device_name); + if (!self) + return scoped_ptr<VideoCaptureDevice>(); + // Test opening the device driver. This is to make sure it is available. + // We will reopen it again in our worker thread when someone + // allocates the camera. + base::ScopedFD fd(HANDLE_EINTR(open(device_name.id().c_str(), O_RDONLY))); + if (!fd.is_valid()) { + DVLOG(1) << "Cannot open device"; + delete self; + return scoped_ptr<VideoCaptureDevice>(); + } + + return scoped_ptr<VideoCaptureDevice>(self); +} + +void VideoCaptureDeviceFactoryLinux::GetDeviceNames( + VideoCaptureDevice::Names* const device_names) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(device_names->empty()); + base::FilePath path("/dev/"); + base::FileEnumerator enumerator( + path, false, base::FileEnumerator::FILES, "video*"); + + while (!enumerator.Next().empty()) { + base::FileEnumerator::FileInfo info = enumerator.GetInfo(); + + std::string unique_id = path.value() + info.GetName().value(); + base::ScopedFD fd(HANDLE_EINTR(open(unique_id.c_str(), O_RDONLY))); + if (!fd.is_valid()) { + // Failed to open this device. + continue; + } + // Test if this is a V4L2 capture device. + v4l2_capability cap; + if ((HANDLE_EINTR(ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) && + (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && + !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + // This is a V4L2 video capture device + if (HasUsableFormats(fd.get())) { + VideoCaptureDevice::Name device_name(base::StringPrintf("%s", cap.card), + unique_id); + device_names->push_back(device_name); + } else { + DVLOG(1) << "No usable formats reported by " << info.GetName().value(); + } + } + } +} + +void VideoCaptureDeviceFactoryLinux::GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (device.id().empty()) + return; + base::ScopedFD fd(HANDLE_EINTR(open(device.id().c_str(), O_RDONLY))); + if (!fd.is_valid()) { + // Failed to open this device. + return; + } + supported_formats->clear(); + + // Retrieve the caps one by one, first get pixel format, then sizes, then + // frame rates. See http://linuxtv.org/downloads/v4l-dvb-apis for reference. + v4l2_fmtdesc pixel_format = {}; + pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + while (HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FMT, &pixel_format)) == 0) { + VideoCaptureFormat supported_format; + supported_format.pixel_format = + VideoCaptureDeviceLinux::V4l2ColorToVideoCaptureColorFormat( + (int32)pixel_format.pixelformat); + if (supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN) { + ++pixel_format.index; + continue; + } + + v4l2_frmsizeenum frame_size = {}; + frame_size.pixel_format = pixel_format.pixelformat; + while (HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FRAMESIZES, &frame_size)) == + 0) { + if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { + supported_format.frame_size.SetSize( + frame_size.discrete.width, frame_size.discrete.height); + } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE) { + // TODO(mcasas): see http://crbug.com/249953, support these devices. + NOTIMPLEMENTED(); + } else if (frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { + // TODO(mcasas): see http://crbug.com/249953, support these devices. + NOTIMPLEMENTED(); + } + v4l2_frmivalenum frame_interval = {}; + frame_interval.pixel_format = pixel_format.pixelformat; + frame_interval.width = frame_size.discrete.width; + frame_interval.height = frame_size.discrete.height; + while (HANDLE_EINTR(ioctl( + fd.get(), VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval)) == 0) { + if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { + if (frame_interval.discrete.numerator != 0) { + supported_format.frame_rate = + static_cast<float>(frame_interval.discrete.denominator) / + static_cast<float>(frame_interval.discrete.numerator); + } else { + supported_format.frame_rate = 0; + } + } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) { + // TODO(mcasas): see http://crbug.com/249953, support these devices. + NOTIMPLEMENTED(); + break; + } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) { + // TODO(mcasas): see http://crbug.com/249953, support these devices. + NOTIMPLEMENTED(); + break; + } + supported_formats->push_back(supported_format); + ++frame_interval.index; + } + ++frame_size.index; + } + ++pixel_format.index; + } + return; +} + +} // namespace media diff --git a/media/video/capture/linux/video_capture_device_factory_linux.h b/media/video/capture/linux/video_capture_device_factory_linux.h new file mode 100644 index 0000000..975a205 --- /dev/null +++ b/media/video/capture/linux/video_capture_device_factory_linux.h @@ -0,0 +1,37 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Implementation of a VideoCaptureDeviceFactoryLinux class. + +#ifndef MEDIA_VIDEO_CAPTURE_LINUX_VIDEO_CAPTURE_DEVICE_FACTORY_LINUX_H_ +#define MEDIA_VIDEO_CAPTURE_LINUX_VIDEO_CAPTURE_DEVICE_FACTORY_LINUX_H_ + +#include "media/video/capture/video_capture_device_factory.h" + +#include "media/video/capture/video_capture_types.h" + +namespace media { + +// Extension of VideoCaptureDeviceFactory to create and manipulate Linux +// devices. +class MEDIA_EXPORT VideoCaptureDeviceFactoryLinux + : public VideoCaptureDeviceFactory { + public: + VideoCaptureDeviceFactoryLinux() {} + virtual ~VideoCaptureDeviceFactoryLinux() {} + + virtual scoped_ptr<VideoCaptureDevice> Create( + const VideoCaptureDevice::Name& device_name) OVERRIDE; + virtual void GetDeviceNames(VideoCaptureDevice::Names* device_names) OVERRIDE; + virtual void GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) OVERRIDE; + + private: + + DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceFactoryLinux); +}; + +} // namespace media +#endif // MEDIA_VIDEO_CAPTURE_LINUX_VIDEO_CAPTURE_DEVICE_FACTORY_LINUX_H_ diff --git a/media/video/capture/linux/video_capture_device_linux.cc b/media/video/capture/linux/video_capture_device_linux.cc index 6893743..232978a 100644 --- a/media/video/capture/linux/video_capture_device_linux.cc +++ b/media/video/capture/linux/video_capture_device_linux.cc @@ -56,9 +56,23 @@ static const char kVidPathTemplate[] = static const char kPidPathTemplate[] = "/sys/class/video4linux/%s/device/../idProduct"; +bool ReadIdFile(const std::string path, std::string* id) { + char id_buf[kVidPidSize]; + FILE* file = fopen(path.c_str(), "rb"); + if (!file) + return false; + const bool success = fread(id_buf, kVidPidSize, 1, file) == 1; + fclose(file); + if (!success) + return false; + id->append(id_buf, kVidPidSize); + return true; +} + // This function translates Video4Linux pixel formats to Chromium pixel formats, // should only support those listed in GetListOfUsableFourCCs. -static VideoPixelFormat V4l2ColorToVideoCaptureColorFormat( +// static +VideoPixelFormat VideoCaptureDeviceLinux::V4l2ColorToVideoCaptureColorFormat( int32 v4l2_fourcc) { VideoPixelFormat result = PIXEL_FORMAT_UNKNOWN; switch (v4l2_fourcc) { @@ -78,7 +92,9 @@ static VideoPixelFormat V4l2ColorToVideoCaptureColorFormat( return result; } -static void GetListOfUsableFourCCs(bool favour_mjpeg, std::list<int>* fourccs) { +// static +void VideoCaptureDeviceLinux::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) @@ -91,139 +107,26 @@ static void GetListOfUsableFourCCs(bool favour_mjpeg, std::list<int>* fourccs) { fourccs->push_back(V4L2_PIX_FMT_JPEG); } -static bool HasUsableFormats(int fd) { - v4l2_fmtdesc fmtdesc; - std::list<int> usable_fourccs; - - GetListOfUsableFourCCs(false, &usable_fourccs); +// TODO(mcasas): Remove the following static methods when they are no longer +// referenced from VideoCaptureDeviceFactory, i.e. when all OS platforms have +// splitted the VideoCaptureDevice into VideoCaptureDevice and +// VideoCaptureDeviceFactory. - memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc)); - fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - while (HANDLE_EINTR(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; +// static +VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { + NOTREACHED(); + return NULL; } - +// static void VideoCaptureDevice::GetDeviceNames(Names* device_names) { - DCHECK(device_names->empty()); - base::FilePath path("/dev/"); - base::FileEnumerator enumerator( - path, false, base::FileEnumerator::FILES, "video*"); - - while (!enumerator.Next().empty()) { - base::FileEnumerator::FileInfo info = enumerator.GetInfo(); - - std::string unique_id = path.value() + info.GetName().value(); - base::ScopedFD fd(HANDLE_EINTR(open(unique_id.c_str(), O_RDONLY))); - if (!fd.is_valid()) { - // Failed to open this device. - continue; - } - // Test if this is a V4L2 capture device. - v4l2_capability cap; - if ((HANDLE_EINTR(ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) && - (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && - !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { - // This is a V4L2 video capture device - if (HasUsableFormats(fd.get())) { - Name device_name(base::StringPrintf("%s", cap.card), unique_id); - device_names->push_back(device_name); - } else { - DVLOG(1) << "No usable formats reported by " << info.GetName().value(); - } - } - } + NOTREACHED(); } +// static void VideoCaptureDevice::GetDeviceSupportedFormats( const Name& device, VideoCaptureFormats* supported_formats) { - if (device.id().empty()) - return; - base::ScopedFD fd(HANDLE_EINTR(open(device.id().c_str(), O_RDONLY))); - if (!fd.is_valid()) { - // Failed to open this device. - return; - } - supported_formats->clear(); - - // Retrieve the caps one by one, first get pixel format, then sizes, then - // frame rates. See http://linuxtv.org/downloads/v4l-dvb-apis for reference. - v4l2_fmtdesc pixel_format = {}; - pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - while (HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FMT, &pixel_format)) == 0) { - VideoCaptureFormat supported_format; - supported_format.pixel_format = - V4l2ColorToVideoCaptureColorFormat((int32)pixel_format.pixelformat); - if (supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN) { - ++pixel_format.index; - continue; - } - - v4l2_frmsizeenum frame_size = {}; - frame_size.pixel_format = pixel_format.pixelformat; - while (HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FRAMESIZES, &frame_size)) == - 0) { - if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { - supported_format.frame_size.SetSize( - frame_size.discrete.width, frame_size.discrete.height); - } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE) { - // TODO(mcasas): see http://crbug.com/249953, support these devices. - NOTIMPLEMENTED(); - } else if (frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { - // TODO(mcasas): see http://crbug.com/249953, support these devices. - NOTIMPLEMENTED(); - } - v4l2_frmivalenum frame_interval = {}; - frame_interval.pixel_format = pixel_format.pixelformat; - frame_interval.width = frame_size.discrete.width; - frame_interval.height = frame_size.discrete.height; - while (HANDLE_EINTR(ioctl( - fd.get(), VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval)) == 0) { - if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { - if (frame_interval.discrete.numerator != 0) { - supported_format.frame_rate = - static_cast<float>(frame_interval.discrete.denominator) / - static_cast<float>(frame_interval.discrete.numerator); - } else { - supported_format.frame_rate = 0; - } - } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) { - // TODO(mcasas): see http://crbug.com/249953, support these devices. - NOTIMPLEMENTED(); - break; - } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) { - // TODO(mcasas): see http://crbug.com/249953, support these devices. - NOTIMPLEMENTED(); - break; - } - supported_formats->push_back(supported_format); - ++frame_interval.index; - } - ++frame_size.index; - } - ++pixel_format.index; - } - return; -} - -static bool ReadIdFile(const std::string path, std::string* id) { - char id_buf[kVidPidSize]; - FILE* file = fopen(path.c_str(), "rb"); - if (!file) - return false; - const bool success = fread(id_buf, kVidPidSize, 1, file) == 1; - fclose(file); - if (!success) - return false; - id->append(id_buf, kVidPidSize); - return true; + NOTREACHED(); } const std::string VideoCaptureDevice::Name::GetModel() const { @@ -248,23 +151,6 @@ const std::string VideoCaptureDevice::Name::GetModel() const { return usb_id; } -VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { - VideoCaptureDeviceLinux* self = new VideoCaptureDeviceLinux(device_name); - if (!self) - return NULL; - // Test opening the device driver. This is to make sure it is available. - // We will reopen it again in our worker thread when someone - // allocates the camera. - base::ScopedFD fd(HANDLE_EINTR(open(device_name.id().c_str(), O_RDONLY))); - if (!fd.is_valid()) { - DVLOG(1) << "Cannot open device"; - delete self; - return NULL; - } - - return self; -} - VideoCaptureDeviceLinux::VideoCaptureDeviceLinux(const Name& device_name) : state_(kIdle), device_name_(device_name), diff --git a/media/video/capture/linux/video_capture_device_linux.h b/media/video/capture/linux/video_capture_device_linux.h index 6a8dcee..303da31 100644 --- a/media/video/capture/linux/video_capture_device_linux.h +++ b/media/video/capture/linux/video_capture_device_linux.h @@ -22,6 +22,10 @@ namespace media { class VideoCaptureDeviceLinux : public VideoCaptureDevice { public: + static VideoPixelFormat V4l2ColorToVideoCaptureColorFormat(int32 v4l2_fourcc); + static void GetListOfUsableFourCCs(bool favour_mjpeg, + std::list<int>* fourccs); + explicit VideoCaptureDeviceLinux(const Name& device_name); virtual ~VideoCaptureDeviceLinux(); diff --git a/media/video/capture/video_capture_device_factory.cc b/media/video/capture/video_capture_device_factory.cc index 661900c..7f6e924 100644 --- a/media/video/capture/video_capture_device_factory.cc +++ b/media/video/capture/video_capture_device_factory.cc @@ -11,6 +11,10 @@ #if defined(OS_MACOSX) #include "media/video/capture/mac/video_capture_device_factory_mac.h" +#elif defined(OS_LINUX) +#include "media/video/capture/linux/video_capture_device_factory_linux.h" +#elif defined(OS_ANDROID) +#include "media/video/capture/android/video_capture_device_factory_android.h" #endif namespace media { @@ -33,6 +37,12 @@ scoped_ptr<VideoCaptureDeviceFactory> #if defined(OS_MACOSX) return scoped_ptr<VideoCaptureDeviceFactory>(new VideoCaptureDeviceFactoryMac()); +#elif defined(OS_LINUX) + return scoped_ptr<VideoCaptureDeviceFactory>(new + VideoCaptureDeviceFactoryLinux()); +#elif defined(OS_ANDROID) + return scoped_ptr<VideoCaptureDeviceFactory>(new + VideoCaptureDeviceFactoryAndroid()); #else return scoped_ptr<VideoCaptureDeviceFactory>(new VideoCaptureDeviceFactory()); |