Added V4L2 query

git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@2827 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
stan 2009-03-31 12:57:34 +00:00
parent 54dc3b9668
commit afe253b71a
3 changed files with 474 additions and 426 deletions

View File

@ -715,37 +715,55 @@ void LocalCamera::Terminate()
close( vid_fd );
}
bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool verbose )
#define capString(test,prefix,yesString,noString,capability) \
(test) ? (prefix yesString " " capability "\n") : (prefix noString " " capability "\n")
bool LocalCamera::GetCurrentSettings( const char *device, char *output, int version, bool verbose )
{
output[0] = 0;
if ( verbose )
sprintf( output, output+strlen(output), "Checking Video Device: %s\n", device );
if ( (vid_fd = open(device, O_RDWR)) <= 0 )
char queryDevice[PATH_MAX] = "";
int devIndex = 0;
do
{
Error( "Failed to open video device %s: %s", device, strerror(errno) );
if ( device )
strcpy( queryDevice, device );
else
sprintf( queryDevice, "/dev/video%d", devIndex );
if ( (vid_fd = open(queryDevice, O_RDWR)) <= 0 )
{
if ( device )
{
Error( "Failed to open video device %s: %s", queryDevice, strerror(errno) );
if ( verbose )
sprintf( output+strlen(output), "Error, failed to open video device %s: %s\n", device, strerror(errno) );
sprintf( output+strlen(output), "Error, failed to open video device %s: %s\n", queryDevice, strerror(errno) );
else
sprintf( output+strlen(output), "error%d\n", errno );
return( false );
}
else
{
return( true );
}
}
if ( verbose )
sprintf( output+strlen(output), "Video Device: %s\n", queryDevice );
else
sprintf( output+strlen(output), "d:%s|", queryDevice );
#ifdef ZM_V4L2
//if ( v4l_version == 2 )
if ( true )
if ( version == 2 )
{
struct v4l2_capability vid_cap;
if ( vidioctl( vid_fd, VIDIOC_QUERYCAP, &vid_cap ) < 0 )
{
Error( "Failed to query video device: %s", strerror(errno) );
if ( verbose )
sprintf( output, "Error, failed to query video capabilities %s: %s\n", device, strerror(errno) );
sprintf( output, "Error, failed to query video capabilities %s: %s\n", queryDevice, strerror(errno) );
else
sprintf( output, "error%d\n", errno );
return( false );
}
#define capString(test,prefix,yesString,noString,capability) \
(test) ? (prefix yesString " " capability "\n") : (prefix noString " " capability "\n")
if ( verbose )
{
@ -773,15 +791,17 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "D:%s ", vid_cap.driver );
sprintf( output+strlen(output), "C:%s ", vid_cap.card );
sprintf( output+strlen(output), "B:%s ", vid_cap.bus_info );
sprintf( output+strlen(output), "V:%u.%u.%u ", (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff );
sprintf( output+strlen(output), "T:0x%x ", vid_cap.capabilities );
sprintf( output+strlen(output), "D:%s|", vid_cap.driver );
sprintf( output+strlen(output), "C:%s|", vid_cap.card );
sprintf( output+strlen(output), "B:%s|", vid_cap.bus_info );
sprintf( output+strlen(output), "V:%u.%u.%u|", (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff );
sprintf( output+strlen(output), "T:0x%x|", vid_cap.capabilities );
}
if ( verbose )
sprintf( output+strlen(output), " Standards:\n" );
else
sprintf( output+strlen(output), "S:" );
struct v4l2_standard standard;
int standardIndex = 0;
do
@ -809,12 +829,16 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
if ( verbose )
sprintf( output+strlen(output), " %s\n", standard.name );
else
sprintf( output+strlen(output), "S:%s ", standard.name );
sprintf( output+strlen(output), "%s/", standard.name );
}
while ( standardIndex++ >= 0 );
if ( !verbose )
output[strlen(output)-1] = '|';
if ( verbose )
sprintf( output+strlen(output), " Formats:\n" );
else
sprintf( output+strlen(output), "F:" );
struct v4l2_fmtdesc format;
int formatIndex = 0;
do
@ -843,9 +867,11 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
if ( verbose )
sprintf( output+strlen(output), " %s (%c%c%c%c)\n", format.description, format.pixelformat&0xff, (format.pixelformat>>8)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>24)&0xff );
else
sprintf( output+strlen(output), "F:%c%c%c%c ", format.pixelformat&0xff, (format.pixelformat>>8)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>24)&0xff );
sprintf( output+strlen(output), "%c%c%c%c/", format.pixelformat&0xff, (format.pixelformat>>8)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>24)&0xff );
}
while ( formatIndex++ >= 0 );
if ( !verbose )
output[strlen(output)-1] = '|';
struct v4l2_cropcap cropcap;
memset( &cropcap, 0, sizeof(cropcap) );
@ -854,7 +880,7 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
{
Error( "Failed to query crop capabilities: %s", strerror(errno) );
if ( verbose )
sprintf( output, "Error, failed to query crop capabilities %s: %s\n", device, strerror(errno) );
sprintf( output, "Error, failed to query crop capabilities %s: %s\n", queryDevice, strerror(errno) );
else
sprintf( output, "error%d\n", errno );
return( false );
@ -867,7 +893,7 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "B:%dx%d ", cropcap.bounds.width, cropcap.bounds.height );
sprintf( output+strlen(output), "B:%dx%d|", cropcap.bounds.width, cropcap.bounds.height );
}
struct v4l2_crop crop;
@ -877,23 +903,13 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
{
Error( "Failed to query crop: %s", strerror(errno) );
if ( verbose )
sprintf( output, "Error, failed to query crop %s: %s\n", device, strerror(errno) );
sprintf( output, "Error, failed to query crop %s: %s\n", queryDevice, strerror(errno) );
else
sprintf( output, "error%d\n", errno );
return( false );
}
if ( verbose )
{
sprintf( output+strlen(output), " Current: %d x %d\n", crop.c.width, crop.c.height );
}
else
{
//sprintf( output+strlen(output), "D:%s ", vid_cap.driver );
//sprintf( output+strlen(output), "C:%s ", vid_cap.card );
//sprintf( output+strlen(output), "B:%s ", vid_cap.bus_info );
//sprintf( output+strlen(output), "V:%u.%u.%u ", (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff );
//sprintf( output+strlen(output), "T:0x%x ", vid_cap.capabilities );
}
struct v4l2_input input;
int inputIndex = 0;
@ -902,6 +918,36 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
memset( &input, 0, sizeof(input) );
input.index = inputIndex;
if ( vidioctl( vid_fd, VIDIOC_ENUMINPUT, &input ) < 0 )
{
if ( errno == EINVAL )
{
break;
}
else
{
Error( "Failed to enumerate input %d: %s", input.index, strerror(errno) );
if ( verbose )
sprintf( output, "Error, failed to enumerate input %d: %s\n", input.index, strerror(errno) );
else
sprintf( output, "error%d\n", errno );
return( false );
}
}
}
while ( inputIndex++ >= 0 );
if ( verbose )
sprintf( output+strlen(output), "Inputs: %d\n", inputIndex );
else
sprintf( output+strlen(output), "I:%d|", inputIndex );
inputIndex = 0;
do
{
memset( &input, 0, sizeof(input) );
input.index = inputIndex;
if ( vidioctl( vid_fd, VIDIOC_ENUMINPUT, &input ) < 0 )
{
if ( errno == EINVAL )
@ -920,7 +966,6 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
}
if ( false )
if ( vidioctl( vid_fd, VIDIOC_S_INPUT, &input.index ) < 0 )
{
Error( "Failed to set video input %d: %s", input.index, strerror(errno) );
@ -941,9 +986,9 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "i%d:%s ", input.index, input.name );
sprintf( output+strlen(output), "i%dT:%s ", input.index, input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown") );
sprintf( output+strlen(output), "i%dS:%llx ", input.index, input.std );
sprintf( output+strlen(output), "i%d:%s|", input.index, input.name );
sprintf( output+strlen(output), "i%dT:%s|", input.index, input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown") );
sprintf( output+strlen(output), "i%dS:%llx|", input.index, input.std );
}
if ( verbose )
@ -955,10 +1000,10 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "i%dSP:%d ", input.index, input.status&V4L2_IN_ST_NO_POWER?0:1 );
sprintf( output+strlen(output), "i%dSS:%d ", input.index, input.status&V4L2_IN_ST_NO_SIGNAL?0:1 );
sprintf( output+strlen(output), "i%dSC:%d ", input.index, input.status&V4L2_IN_ST_NO_COLOR?0:1 );
sprintf( output+strlen(output), "i%dHP:%d ", input.index, input.status&V4L2_IN_ST_NO_H_LOCK?0:1 );
sprintf( output+strlen(output), "i%dSP:%d|", input.index, input.status&V4L2_IN_ST_NO_POWER?0:1 );
sprintf( output+strlen(output), "i%dSS:%d|", input.index, input.status&V4L2_IN_ST_NO_SIGNAL?0:1 );
sprintf( output+strlen(output), "i%dSC:%d|", input.index, input.status&V4L2_IN_ST_NO_COLOR?0:1 );
sprintf( output+strlen(output), "i%dHP:%d|", input.index, input.status&V4L2_IN_ST_NO_H_LOCK?0:1 );
}
}
while ( inputIndex++ >= 0 );
@ -973,7 +1018,7 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
{
Error( "Failed to get video capabilities: %s", strerror(errno) );
if ( verbose )
sprintf( output, "Error, failed to get video capabilities %s: %s\n", device, strerror(errno) );
sprintf( output, "Error, failed to get video capabilities %s: %s\n", queryDevice, strerror(errno) );
else
sprintf( output, "error%d\n", errno );
return( false );
@ -1007,14 +1052,14 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "N:%s,", vid_cap.name );
sprintf( output+strlen(output), "T:%d,", vid_cap.type );
sprintf( output+strlen(output), "nC:%d,", vid_cap.channels );
sprintf( output+strlen(output), "nA:%d,", vid_cap.audios );
sprintf( output+strlen(output), "mxW:%d,", vid_cap.maxwidth );
sprintf( output+strlen(output), "mxH:%d,", vid_cap.maxheight );
sprintf( output+strlen(output), "mnW:%d,", vid_cap.minwidth );
sprintf( output+strlen(output), "mnH:%d,", vid_cap.minheight );
sprintf( output+strlen(output), "N:%s|", vid_cap.name );
sprintf( output+strlen(output), "T:%d|", vid_cap.type );
sprintf( output+strlen(output), "nC:%d|", vid_cap.channels );
sprintf( output+strlen(output), "nA:%d|", vid_cap.audios );
sprintf( output+strlen(output), "mxW:%d|", vid_cap.maxwidth );
sprintf( output+strlen(output), "mxH:%d|", vid_cap.maxheight );
sprintf( output+strlen(output), "mnW:%d|", vid_cap.minwidth );
sprintf( output+strlen(output), "mnH:%d|", vid_cap.minheight );
}
struct video_window vid_win;
@ -1037,10 +1082,10 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "X:%d,", vid_win.x );
sprintf( output+strlen(output), "Y:%d,", vid_win.y );
sprintf( output+strlen(output), "W:%d,", vid_win.width );
sprintf( output+strlen(output), "H:%d,", vid_win.height );
sprintf( output+strlen(output), "X:%d|", vid_win.x );
sprintf( output+strlen(output), "Y:%d|", vid_win.y );
sprintf( output+strlen(output), "W:%d|", vid_win.width );
sprintf( output+strlen(output), "H:%d|", vid_win.height );
}
struct video_picture vid_pic;
@ -1085,13 +1130,13 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "P:%d,", vid_pic.palette );
sprintf( output+strlen(output), "D:%d,", vid_pic.depth );
sprintf( output+strlen(output), "B:%d,", vid_pic.brightness );
sprintf( output+strlen(output), "h:%d,", vid_pic.hue );
sprintf( output+strlen(output), "Cl:%d,", vid_pic.colour );
sprintf( output+strlen(output), "Cn:%d,", vid_pic.contrast );
sprintf( output+strlen(output), "w:%d,", vid_pic.whiteness );
sprintf( output+strlen(output), "P:%d|", vid_pic.palette );
sprintf( output+strlen(output), "D:%d|", vid_pic.depth );
sprintf( output+strlen(output), "B:%d|", vid_pic.brightness );
sprintf( output+strlen(output), "h:%d|", vid_pic.hue );
sprintf( output+strlen(output), "Cl:%d|", vid_pic.colour );
sprintf( output+strlen(output), "Cn:%d|", vid_pic.contrast );
sprintf( output+strlen(output), "w:%d|", vid_pic.whiteness );
}
for ( int chan = 0; chan < vid_cap.channels; chan++ )
@ -1129,14 +1174,21 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, bool ver
}
else
{
sprintf( output+strlen(output), "n%d:%s,", chan, vid_src.name );
sprintf( output+strlen(output), "C%d:%d,", chan, vid_src.channel );
sprintf( output+strlen(output), "Fl%d:%x,", chan, vid_src.flags );
sprintf( output+strlen(output), "T%d:%d", chan, vid_src.type );
sprintf( output+strlen(output), "F%d:%d%s,", chan, vid_src.norm, chan==(vid_cap.channels-1)?"":"," );
sprintf( output+strlen(output), "n%d:%s|", chan, vid_src.name );
sprintf( output+strlen(output), "C%d:%d|", chan, vid_src.channel );
sprintf( output+strlen(output), "Fl%d:%x|", chan, vid_src.flags );
sprintf( output+strlen(output), "T%d:%d|", chan, vid_src.type );
sprintf( output+strlen(output), "F%d:%d%s|", chan, vid_src.norm, chan==(vid_cap.channels-1)?"":"," );
}
}
if ( !verbose )
output[strlen(output)-1] = '\n';
}
close( vid_fd );
if ( device )
break;
}
while ( ++devIndex < 32 );
return( true );
}

View File

@ -130,7 +130,7 @@ public:
int Capture( Image &image );
int PostCapture();
static bool GetCurrentSettings( const char *device, char *output, bool verbose );
static bool GetCurrentSettings( const char *device, char *output, int version, bool verbose );
};
#endif // ZM_LOCAL_CAMERA_H

View File

@ -35,7 +35,8 @@ void Usage( int status=-1 )
fprintf( stderr, " -v, --verbose : Produce more verbose output\n" );
fprintf( stderr, " -l, --list : List the current status of active (or all with -v) monitors\n" );
fprintf( stderr, "Options for use with devices:\n" );
fprintf( stderr, " -d, --device <device_path> : Get the current video device settings for <device_path>\n" );
fprintf( stderr, " -d, --device [device_path] : Get the current video device settings for [device_path] or all devices\n" );
fprintf( stderr, " -V, --version <V4L version> : Set the Video 4 Linux API version to use for the query, use 1 or 2\n" );
fprintf( stderr, " -q, --query : Query the current settings for the device\n" );
fprintf( stderr, "Options for use with monitors:\n" );
fprintf( stderr, " -m, --monitor <monitor_id> : Specify which monitor to address, default 1 if absent\n" );
@ -138,7 +139,7 @@ bool ValidateAccess( User *user, int mon_id, int function )
int main( int argc, char *argv[] )
{
static struct option long_options[] = {
{"device", 1, 0, 'd'},
{"device", 2, 0, 'd'},
{"monitor", 1, 0, 'm'},
{"verbose", 0, 0, 'v'},
{"image", 2, 0, 'i'},
@ -165,12 +166,14 @@ int main( int argc, char *argv[] )
{"query", 0, 0, 'q'},
{"username", 1, 0, 'U'},
{"password", 1, 0, 'P'},
{"auth", 1, 0, 'A'},
{"version", 1, 0, 'V'},
{"help", 0, 0, 'h'},
{"list", 0, 0, 'l'},
{0, 0, 0, 0}
};
const char *device = "";
const char *device = 0;
int mon_id = 0;
bool verbose = false;
int function = ZMU_BOGUS;
@ -181,15 +184,20 @@ int main( int argc, char *argv[] )
int contrast = -1;
int hue = -1;
int colour = -1;
char *zone_string = 0;
char *zoneString = 0;
char *username = 0;
char *password = 0;
char *auth = 0;
#ifdef ZM_V4L2
int v4lVersion = 2;
#else // ZM_V4L2
int v4lVersion = 1;
#endif // ZM_V4L2
while (1)
{
int option_index = 0;
int c = getopt_long (argc, argv, "d:m:vsEDLurwei::S:t::fz::ancqhlB::C::H::O::U:P:A:", long_options, &option_index);
int c = getopt_long (argc, argv, "d:m:vsEDLurwei::S:t::fz::ancqhlB::C::H::O::U:P:A:V:", long_options, &option_index);
if (c == -1)
{
break;
@ -198,6 +206,7 @@ int main( int argc, char *argv[] )
switch (c)
{
case 'd':
if ( optarg )
device = optarg;
break;
case 'm':
@ -212,9 +221,7 @@ int main( int argc, char *argv[] )
case 'i':
function |= ZMU_IMAGE;
if ( optarg )
{
image_idx = atoi( optarg );
}
break;
case 'S':
scale = atoi(optarg);
@ -222,9 +229,7 @@ int main( int argc, char *argv[] )
case 't':
function |= ZMU_TIME;
if ( optarg )
{
image_idx = atoi( optarg );
}
break;
case 'R':
function |= ZMU_READ_IDX;
@ -241,9 +246,7 @@ int main( int argc, char *argv[] )
case 'z':
function |= ZMU_ZONES;
if ( optarg )
{
zone_string = optarg;
}
zoneString = optarg;
break;
case 'a':
function |= ZMU_ALARM;
@ -275,30 +278,22 @@ int main( int argc, char *argv[] )
case 'B':
function |= ZMU_BRIGHTNESS;
if ( optarg )
{
brightness = atoi( optarg );
}
break;
case 'C':
function |= ZMU_CONTRAST;
if ( optarg )
{
contrast = atoi( optarg );
}
break;
case 'H':
function |= ZMU_HUE;
if ( optarg )
{
hue = atoi( optarg );
}
break;
case 'O':
function |= ZMU_COLOUR;
if ( optarg )
{
colour = atoi( optarg );
}
break;
case 'U':
username = optarg;
@ -309,6 +304,9 @@ int main( int argc, char *argv[] )
case 'A':
auth = optarg;
break;
case 'V':
v4lVersion = (atoi(optarg)==1)?1:2;
break;
case 'h':
Usage( 0 );
break;
@ -333,7 +331,7 @@ int main( int argc, char *argv[] )
Usage();
}
if ( device[0] && !(function&ZMU_QUERY) )
if ( device && !(function&ZMU_QUERY) )
{
fprintf( stderr, "Error, -d option cannot be used with this option\n" );
Usage();
@ -401,17 +399,7 @@ int main( int argc, char *argv[] )
}
if ( device[0] )
{
if ( function & ZMU_QUERY )
{
char vid_string[BUFSIZ] = "";
bool ok = LocalCamera::GetCurrentSettings( device, vid_string, verbose );
printf( "%s", vid_string );
exit( ok?0:-1 );
}
}
else if ( mon_id > 0 )
if ( mon_id > 0 )
{
Monitor *monitor = Monitor::Load( mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY );
if ( monitor )
@ -516,7 +504,7 @@ int main( int argc, char *argv[] )
{
if ( verbose )
printf( "Dumping zone image to %s-Zones.jpg\n", monitor->Name() );
monitor->DumpZoneImage( zone_string );
monitor->DumpZoneImage( zoneString );
}
if ( function & ZMU_ALARM )
{
@ -568,9 +556,9 @@ int main( int argc, char *argv[] )
}
if ( function & ZMU_QUERY )
{
char mon_string[16382] = "";
monitor->DumpSettings( mon_string, verbose );
printf( "%s\n", mon_string );
char monString[16382] = "";
monitor->DumpSettings( monString, verbose );
printf( "%s\n", monString );
}
if ( function & ZMU_BRIGHTNESS )
{
@ -666,6 +654,14 @@ int main( int argc, char *argv[] )
}
else
{
if ( function & ZMU_QUERY )
{
char vidString[0x10000] = "";
bool ok = LocalCamera::GetCurrentSettings( device, vidString, v4lVersion, verbose );
printf( "%s", vidString );
exit( ok?0:-1 );
}
if ( function & ZMU_LIST )
{
char sql[BUFSIZ];