summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-15 18:15:51 +0000
committermcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-15 18:15:51 +0000
commit085e86b29b27304e02a229e81e52de50c5a19a5b (patch)
treece149f41c1c4c75a8b759bcab0e34fe55cc331bf
parent5337eda506eb68908a4a3489ce5d99cb716fb2c5 (diff)
downloadchromium_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
-rw-r--r--media/media.gyp2
-rw-r--r--media/video/capture/android/video_capture_device_android.cc35
-rw-r--r--media/video/capture/android/video_capture_device_android.h8
-rw-r--r--media/video/capture/android/video_capture_device_factory_android.cc56
-rw-r--r--media/video/capture/android/video_capture_device_factory_android.h26
-rw-r--r--media/video/capture/linux/video_capture_device_factory_linux.cc171
-rw-r--r--media/video/capture/linux/video_capture_device_factory_linux.h37
-rw-r--r--media/video/capture/linux/video_capture_device_linux.cc174
-rw-r--r--media/video/capture/linux/video_capture_device_linux.h4
-rw-r--r--media/video/capture/video_capture_device_factory.cc10
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());