[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libcvd-members] libcvd Makefile.in cvd/Linux/v4lcontrol.h cvd_s...
From: |
Gerhard Reitmayr |
Subject: |
[libcvd-members] libcvd Makefile.in cvd/Linux/v4lcontrol.h cvd_s... |
Date: |
Fri, 28 Jul 2006 14:05:40 +0000 |
CVSROOT: /cvsroot/libcvd
Module name: libcvd
Changes by: Gerhard Reitmayr <gerhard> 06/07/28 14:05:40
Modified files:
. : Makefile.in
Added files:
cvd/Linux : v4lcontrol.h
cvd_src/Linux : v4lcontrol.cc
Log message:
added a class to control parameters of v4l2 devices
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/Makefile.in?cvsroot=libcvd&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/Linux/v4lcontrol.h?cvsroot=libcvd&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd_src/Linux/v4lcontrol.cc?cvsroot=libcvd&rev=1.1
Patches:
Index: Makefile.in
===================================================================
RCS file: /cvsroot/libcvd/libcvd/Makefile.in,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- Makefile.in 6 Jul 2006 16:44:58 -0000 1.47
+++ Makefile.in 28 Jul 2006 14:05:40 -0000 1.48
@@ -156,7 +156,8 @@
ifeq (@have_v4l2buffer@,yes)
CVD_OBJS+=cvd_src/Linux/v4l2buffer.o \
- cvd_src/Linux/v4lbuffer.o
+ cvd_src/Linux/v4lbuffer.o \
+ cvd_src/Linux/v4lcontrol.o
endif
ifeq (@have_v4l1buffer@,yes)
Index: cvd/Linux/v4lcontrol.h
===================================================================
RCS file: cvd/Linux/v4lcontrol.h
diff -N cvd/Linux/v4lcontrol.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cvd/Linux/v4lcontrol.h 28 Jul 2006 14:05:40 -0000 1.1
@@ -0,0 +1,182 @@
+#ifndef CVD_V4LCONTROL_H
+#define CVD_V4LCONTROL_H
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include <linux/videodev.h>
+
+#include <cvd/exceptions.h>
+
+namespace CVD {
+
+namespace Exceptions
+{
+ /// @ingroup gException
+ namespace V4LControl
+ {
+ /// @ingroup gException
+ struct All: public CVD::Exceptions::All
+ {
+ };
+ /// Error opening the device
+ /// @ingroup gException
+ struct DeviceOpen: public All {DeviceOpen(std::string dev); ///< Construct
from the device name
+ };
+
+ /// Unsupported parameter
+ /// @ingroup gException
+ struct ParameterNotSupported: public All {
+ ParameterNotSupported(std::string); ///< Construct from parameter name
+ ParameterNotSupported(unsigned int); ///< Construct from parameter id
+ };
+
+ /// Error querying value
+ /// @ingroup gException
+ struct GetValue: public All {GetValue(std::string); ///< Construct from
parameter name
+ };
+
+ /// Error setting value
+ /// @ingroup gException
+ struct SetValue: public All {SetValue(std::string); ///< Construct from
parameter name
+ };
+
+ /// Error querying device parameters
+ /// @ingroup gException
+ struct QueryParameters: public All {QueryParameters(std::string); ///<
Construct from message
+ };
+
+ }
+}
+
+
+/**
+exposes the V4L2 API to set parameters on a capture device. It can be used
+in parallel to a v4lbuffer object to control and query all parameters
supported.
+Several abstraction levels are supported. On the highest there are individual
+member functions for various fixed parameters. The next level supports
querying and
+setting/getting values for all parameters supported by the driver. Finally,
+low-level access using V4L2 structs is supported as well.
+
address@hidden gVideo
+*/
+class V4LControl {
+public:
+ V4LControl( int fd, bool report = true );
+ V4LControl( const std::string & name, bool report = true );
+
+ /// @name HighLevel
+ /// High level interface to set specific parameters without much hassle.
+ /// These might fail if the parameter is not supported by the device and do
+ /// not throw exceptions. Moreover ranges of parameter values are
abstracted
+ /// to lie within the intervall [0,1].
+ /// If you want to have more control, use the lower level interface
described in
+ /// @ref Generic .
+ //@{
+ void exposure( int );
+ int exposure(void);
+
+ void autoexposure(bool);
+ bool autoexposure();
+
+ void gain( double );
+ double gain(void);
+
+ void autogain(bool);
+ bool autogain(void);
+
+ void brightness(double);
+ double brightness(void);
+
+ void contrast(double);
+ double contrast(void);
+
+ void saturation(double);
+ double saturation(void);
+ //@}
+
+ /// @name Generic
+ /// generic high level interface abstracting the v4l2 structs
+ //@{
+ unsigned int getId( const std::string & name ) const;
+ std::string getName( unsigned int id ) const;
+ std::vector<unsigned int> supportedParameters(void) const;
+ std::vector<std::string> supportedParameterNames(void) const;
+
+ inline bool isSupported( const std::string & name ) const {
+ return (controlNames.find(name) != controlNames.end());
+ }
+ inline void set( const std::string & name, int value ){
+ set(getId(name), value);
+ }
+ inline int get( const std::string & name ){
+ return get(getId(name));
+ }
+ inline int type( const std::string & name ){
+ return type(getId(name));
+ }
+ inline std::map<unsigned int, std::string> menuValues( const std::string &
name ){
+ return menuValues(getId(name));
+ }
+ inline int defaultValue( const std::string & name ){
+ return defaultValue(getId(name));
+ }
+ inline int min( const std::string & name ){
+ return min(getId(name));
+ }
+ inline int max( const std::string & name ){
+ return max(getId(name));
+ }
+ inline int step( const std::string & name ){
+ return step(getId(name));
+ }
+
+ inline bool isSupported( unsigned int id ) const {
+ return (controlData.find(id) != controlData.end());
+ }
+ void set( unsigned int id, int value);
+ int get( unsigned int id );
+ int type( unsigned int id );
+ std::map<unsigned int, std::string> menuValues( unsigned int id ) const ;
+ int defaultValue( unsigned int id ) const;
+ int min( unsigned int id ) const;
+ int max( unsigned int id ) const;
+ int step( unsigned int id ) const;
+ //@}
+
+ /// @name LowLevel
+ /// low level interface using v4l2 structs
+ //@{
+ int getQueryStruct( v4l2_queryctrl & query ) const;
+ void getMenuStruct( unsigned int id, std::vector<v4l2_querymenu> & menu )
const;
+ int setControlStruct( v4l2_control & value );
+ int getControlStruct( v4l2_control & value ) const;
+ //@}
+
+ /// return file descriptor for the opened device
+ inline int getFile(void) const { return device; }
+
+ /// return file name of the opened device
+ inline const std::string & getDevice(void) const { return deviceName; }
+
+ /// set error reporting
+ inline void setReportErrors( bool report ) { reportErrors = report; }
+ inline bool getReportErrors(void) const { return reportErrors; }
+
+protected:
+ int device;
+ std::string deviceName;
+ struct v4l2_control control;
+ bool reportErrors;
+
+ void queryControls(void);
+
+ std::map<std::string, unsigned int> controlNames;
+ std::map<unsigned int, v4l2_queryctrl> controlData;
+ std::map<unsigned int, std::vector<v4l2_querymenu> > menuData;
+};
+
+} // namespace CVD
+
+#endif
Index: cvd_src/Linux/v4lcontrol.cc
===================================================================
RCS file: cvd_src/Linux/v4lcontrol.cc
diff -N cvd_src/Linux/v4lcontrol.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cvd_src/Linux/v4lcontrol.cc 28 Jul 2006 14:05:40 -0000 1.1
@@ -0,0 +1,316 @@
+#include <cvd/Linux/v4lcontrol.h>
+
+#include <iostream>
+#include <sstream>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+using namespace std;
+
+template <typename T>
+static inline double toUnit( T val, T min, T max){
+ double interval = max - min;
+ return (val - min)/interval;
+}
+
+template <typename T>
+static inline T fromUnit( double val, T min, T max){
+ double interval = max - min;
+ return static_cast<T>(val * interval - min);
+}
+
+namespace CVD {
+
+Exceptions::V4LControl::DeviceOpen::DeviceOpen(string device)
+{
+ what = "V4LControl: failed to open \""+device+ "\": " + strerror(errno);
+}
+
+Exceptions::V4LControl::ParameterNotSupported::ParameterNotSupported(string
parameter)
+{
+ what = "V4LControl: parameter \"" + parameter + "\" is not supported.";
+}
+
+Exceptions::V4LControl::ParameterNotSupported::ParameterNotSupported(unsigned
int id)
+{
+ ostringstream os;
+ os << "V4LControl: parameter " << id << " is not supported.";
+ what = os.str();
+}
+
+Exceptions::V4LControl::GetValue::GetValue(string parameter)
+{
+ what = "V4LControl: query value \""+parameter+ "\" failed: " +
strerror(errno);
+}
+
+Exceptions::V4LControl::SetValue::SetValue(string parameter)
+{
+ what = "V4LControl: setting value \""+parameter+ "\" failed: " +
strerror(errno);
+}
+
+Exceptions::V4LControl::QueryParameters::QueryParameters(string msg)
+{
+ what = "V4LControl: Querying parameters failed: \""+msg+ "\": " +
strerror(errno);
+}
+
+V4LControl::V4LControl( int fd, bool report ) : device(fd), deviceName(""),
reportErrors(report) {
+ memset(&control, 0, sizeof(control));
+ queryControls();
+}
+
+V4LControl::V4LControl( const std::string & name, bool report ) : device(0),
deviceName(name), reportErrors(report) {
+ if( -1 == (device = open(deviceName.c_str(), O_RDWR | O_NONBLOCK))){
+ throw Exceptions::V4LControl::DeviceOpen(deviceName);
+ }
+ memset(&control, 0, sizeof(control));
+ queryControls();
+}
+
+void V4LControl::exposure( int value ){
+ if(!isSupported(V4L2_CID_EXPOSURE))
+ return;
+ set(V4L2_CID_EXPOSURE, value);
+}
+
+int V4LControl::exposure(void){
+ if(!isSupported(V4L2_CID_EXPOSURE))
+ return 0;
+ return get(V4L2_CID_EXPOSURE);
+}
+
+void V4LControl::autoexposure(bool value){
+ if(!isSupported("Auto Exposure"))
+ return;
+ set("Auto Exposure", value);
+}
+
+bool V4LControl::autoexposure(){
+ if(!isSupported("Auto Exposure"))
+ return false;
+ return get("Auto Exposure");
+}
+
+void V4LControl::gain( double value ){
+ if(!isSupported(V4L2_CID_GAIN))
+ return;
+ set(V4L2_CID_GAIN, fromUnit(value, min(V4L2_CID_GAIN),
max(V4L2_CID_GAIN)));
+}
+
+double V4LControl::gain(void){
+ if(!isSupported(V4L2_CID_GAIN))
+ return 0;
+ return toUnit(get(V4L2_CID_GAIN), min(V4L2_CID_GAIN), max(V4L2_CID_GAIN));
+}
+
+void V4LControl::autogain(bool value){
+ if(!isSupported(V4L2_CID_AUTOGAIN))
+ return;
+ set(V4L2_CID_AUTOGAIN, value);
+}
+
+bool V4LControl::autogain(void){
+ if(!isSupported(V4L2_CID_AUTOGAIN))
+ return false;
+ return get(V4L2_CID_AUTOGAIN);
+}
+
+void V4LControl::brightness(double value){
+ if(!isSupported(V4L2_CID_BRIGHTNESS))
+ return;
+ set(V4L2_CID_BRIGHTNESS, fromUnit(value, min(V4L2_CID_BRIGHTNESS),
max(V4L2_CID_BRIGHTNESS)));
+}
+
+double V4LControl::brightness(void){
+ if(!isSupported(V4L2_CID_BRIGHTNESS))
+ return 0;
+ return toUnit(get(V4L2_CID_BRIGHTNESS), min(V4L2_CID_BRIGHTNESS),
max(V4L2_CID_BRIGHTNESS));
+}
+
+void V4LControl::contrast(double value){
+ if(!isSupported(V4L2_CID_CONTRAST))
+ return;
+ set(V4L2_CID_CONTRAST, fromUnit(value, min(V4L2_CID_CONTRAST),
max(V4L2_CID_CONTRAST)));
+}
+
+double V4LControl::contrast(void){
+ if(!isSupported(V4L2_CID_CONTRAST))
+ return 0;
+ return toUnit(get(V4L2_CID_CONTRAST), min(V4L2_CID_CONTRAST),
max(V4L2_CID_CONTRAST));
+}
+
+void V4LControl::saturation(double value){
+ if(!isSupported(V4L2_CID_SATURATION))
+ return;
+ set(V4L2_CID_SATURATION, fromUnit(value, min(V4L2_CID_SATURATION),
max(V4L2_CID_SATURATION)));
+}
+
+double V4LControl::saturation(void){
+ if(!isSupported(V4L2_CID_SATURATION))
+ return 0;
+ return toUnit(get(V4L2_CID_SATURATION), min(V4L2_CID_SATURATION),
max(V4L2_CID_SATURATION));
+}
+
+void V4LControl::queryControls(void){
+ controlData.clear();
+ controlNames.clear();
+ menuData.clear();
+
+ struct v4l2_queryctrl queryctrl;
+ memset(&queryctrl, 0, sizeof(queryctrl));
+ for (unsigned int i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) {
+ queryctrl.id = i;
+ if (0 == getQueryStruct(queryctrl)) {
+ if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+ continue;
+ controlData[queryctrl.id] = queryctrl;
+ controlNames[(const char *)queryctrl.name] = queryctrl.id;
+ if (queryctrl.type == V4L2_CTRL_TYPE_MENU) {
+ vector<v4l2_querymenu> menus;
+ getMenuStruct( queryctrl.id, menus);
+ menuData[queryctrl.id].swap(menus);
+ }
+ } else {
+ if (errno != EINVAL) {
+ throw Exceptions::V4LControl::QueryParameters("standard
controls");
+ }
+ }
+ }
+ for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;queryctrl.id++) {
+ if (0 == getQueryStruct(queryctrl)) {
+ if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+ continue;
+ controlData[queryctrl.id] = queryctrl;
+ controlNames[(const char *)queryctrl.name] = queryctrl.id;
+ if (queryctrl.type == V4L2_CTRL_TYPE_MENU) {
+ vector<v4l2_querymenu> menus;
+ getMenuStruct( queryctrl.id, menus);
+ menuData[queryctrl.id].swap(menus);
+ }
+ } else {
+ break;
+ }
+ }
+}
+
+unsigned int V4LControl::getId( const std::string & name ) const {
+ map<string, unsigned int>::const_iterator id = controlNames.find(name);
+ if(id == controlNames.end())
+ return V4L2_CID_LASTP1;
+ return id->second;
+}
+
+string V4LControl::getName( unsigned int id ) const {
+ map<unsigned int, v4l2_queryctrl>::const_iterator control =
controlData.find(id);
+ if(control == controlData.end())
+ return "";
+ return (const char *)control->second.name;
+}
+
+vector<unsigned int> V4LControl::supportedParameters(void) const {
+ vector<unsigned int> result(controlNames.size());
+ vector<unsigned int>::iterator id = result.begin();
+ for(map<string, unsigned int>::const_iterator param =
controlNames.begin(); param != controlNames.end(); ++param, ++id)
+ *id = param->second;
+ return result;
+}
+
+vector<string> V4LControl::supportedParameterNames(void) const {
+ vector<string> result(controlNames.size());
+ vector<string>::iterator id = result.begin();
+ for(map<string, unsigned int>::const_iterator param =
controlNames.begin(); param != controlNames.end(); ++param, ++id)
+ *id = param->first;
+ return result;
+}
+
+void V4LControl::set( unsigned int id, int value){
+ control.id = id;
+ if(!isSupported(control.id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ control.value = value;
+ if(-1 == setControlStruct( control ))
+ if( errno != EBUSY )
+ throw Exceptions::V4LControl::SetValue(getName(id));
+}
+
+int V4LControl::get( unsigned int id ){
+ control.id = id;
+ if(!isSupported(control.id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ if(-1 == getControlStruct( control ))
+ if( errno != EBUSY )
+ throw Exceptions::V4LControl::GetValue(getName(id));
+ return control.value;
+}
+
+int V4LControl::type( unsigned int id ){
+ return controlData[id].type;
+}
+
+map<unsigned int, string> V4LControl::menuValues( unsigned int id ) const {
+ if(!isSupported(id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ map<unsigned int, string> result;
+ const vector<v4l2_querymenu> & menu = menuData.find(id)->second;
+ for(vector<v4l2_querymenu>::const_iterator m = menu.begin(); m !=
menu.end(); m++)
+ result[m->index] = (const char *)m->name;
+ return result;
+}
+
+int V4LControl::defaultValue( unsigned int id ) const {
+ if(!isSupported(id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ return controlData.find(id)->second.default_value;
+}
+
+int V4LControl::min( unsigned int id ) const {
+ if(!isSupported(id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ return controlData.find(id)->second.minimum;
+}
+
+int V4LControl::max( unsigned int id ) const {
+ if(!isSupported(id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ return controlData.find(id)->second.maximum;
+}
+
+int V4LControl::step( unsigned int id ) const{
+ if(!isSupported(id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ return controlData.find(id)->second.step;
+}
+
+int V4LControl::getQueryStruct( v4l2_queryctrl & query ) const {
+ return ioctl (device, VIDIOC_QUERYCTRL, &query);
+}
+
+void V4LControl::getMenuStruct( unsigned int id, vector<v4l2_querymenu> & menu
) const {
+ if(!isSupported(id))
+ throw Exceptions::V4LControl::ParameterNotSupported(id);
+ menu.clear();
+ struct v4l2_querymenu querymenu;
+ memset (&querymenu, 0, sizeof (querymenu));
+ querymenu.id = id;
+ int last;
+ const struct v4l2_queryctrl & data = controlData.find(id)->second;
+
+ for (querymenu.index = data.minimum; querymenu.index <= data.maximum;
querymenu.index++) {
+ if (0 != (last = ioctl (device, VIDIOC_QUERYMENU, &querymenu)))
+ throw Exceptions::V4LControl::QueryParameters("reading menu item");
+ menu.push_back(querymenu);
+ }
+}
+
+int V4LControl::setControlStruct( v4l2_control & control ){
+ return ioctl(device, VIDIOC_S_CTRL, &control);
+}
+
+int V4LControl::getControlStruct( v4l2_control & control ) const {
+ return ioctl(device, VIDIOC_G_CTRL, &control);
+}
+
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libcvd-members] libcvd Makefile.in cvd/Linux/v4lcontrol.h cvd_s...,
Gerhard Reitmayr <=