Added V4L2 query
git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@2827 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
parent
54dc3b9668
commit
afe253b71a
|
@ -715,428 +715,480 @@ void LocalCamera::Terminate()
|
||||||
close( vid_fd );
|
close( vid_fd );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocalCamera::GetCurrentSettings( const char *device, char *output, 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 )
|
|
||||||
{
|
|
||||||
Error( "Failed to open video device %s: %s", device, strerror(errno) );
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output+strlen(output), "Error, failed to open video device %s: %s\n", device, strerror(errno) );
|
|
||||||
else
|
|
||||||
sprintf( output+strlen(output), "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ZM_V4L2
|
|
||||||
//if ( v4l_version == 2 )
|
|
||||||
if ( true )
|
|
||||||
{
|
|
||||||
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) );
|
|
||||||
else
|
|
||||||
sprintf( output, "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
#define capString(test,prefix,yesString,noString,capability) \
|
#define capString(test,prefix,yesString,noString,capability) \
|
||||||
(test) ? (prefix yesString " " capability "\n") : (prefix noString " " capability "\n")
|
(test) ? (prefix yesString " " capability "\n") : (prefix noString " " capability "\n")
|
||||||
|
|
||||||
if ( verbose )
|
bool LocalCamera::GetCurrentSettings( const char *device, char *output, int version, bool verbose )
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), "General Capabilities\n" );
|
output[0] = 0;
|
||||||
sprintf( output+strlen(output), " Driver: %s\n", vid_cap.driver );
|
|
||||||
sprintf( output+strlen(output), " Card: %s\n", vid_cap.card );
|
char queryDevice[PATH_MAX] = "";
|
||||||
sprintf( output+strlen(output), " Bus: %s\n", vid_cap.bus_info );
|
int devIndex = 0;
|
||||||
sprintf( output+strlen(output), " Version: %u.%u.%u\n", (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff );
|
do
|
||||||
sprintf( output+strlen(output), " Type: 0x%x\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s", vid_cap.capabilities,
|
{
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_CAPTURE, " ", "Supports", "Does not support", "video capture (X)" ),
|
if ( device )
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT, " ", "Supports", "Does not support", "video output" ),
|
strcpy( queryDevice, device );
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_OVERLAY, " ", "Supports", "Does not support", "frame buffer overlay" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_VBI_CAPTURE, " ", "Supports", "Does not support", "VBI capture" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_VBI_OUTPUT, " ", "Supports", "Does not support", "VBI output" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_SLICED_VBI_CAPTURE, " ", "Supports", "Does not support", "sliced VBI capture" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_SLICED_VBI_OUTPUT, " ", "Supports", "Does not support", "sliced VBI output" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT_OVERLAY, " ", "Supports", "Does not support", "video output overlay" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_TUNER, " ", "Has", "Does not have", "tuner" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_AUDIO, " ", "Has", "Does not have", "audio in and/or out" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_RADIO, " ", "Has", "Does not have", "radio" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_READWRITE, " ", "Supports", "Does not support", "read/write i/o (X)" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_ASYNCIO, " ", "Supports", "Does not support", "async i/o" ),
|
|
||||||
capString( vid_cap.capabilities&V4L2_CAP_STREAMING, " ", "Supports", "Does not support", "streaming i/o (X)" )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
sprintf( queryDevice, "/dev/video%d", devIndex );
|
||||||
|
if ( (vid_fd = open(queryDevice, O_RDWR)) <= 0 )
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), "D:%s ", vid_cap.driver );
|
if ( device )
|
||||||
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" );
|
|
||||||
struct v4l2_standard standard;
|
|
||||||
int standardIndex = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
memset( &standard, 0, sizeof(standard) );
|
|
||||||
standard.index = standardIndex;
|
|
||||||
|
|
||||||
if ( vidioctl( vid_fd, VIDIOC_ENUMSTD, &standard ) < 0 )
|
|
||||||
{
|
{
|
||||||
if ( errno == EINVAL )
|
Error( "Failed to open video device %s: %s", queryDevice, strerror(errno) );
|
||||||
{
|
|
||||||
standardIndex = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Error( "Failed to enumerate standard %d: %s", standard.index, strerror(errno) );
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output, "Error, failed to enumerate standard %d: %s\n", standard.index, strerror(errno) );
|
|
||||||
else
|
|
||||||
sprintf( output, "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output+strlen(output), " %s\n", standard.name );
|
|
||||||
else
|
|
||||||
sprintf( output+strlen(output), "S:%s ", standard.name );
|
|
||||||
}
|
|
||||||
while ( standardIndex++ >= 0 );
|
|
||||||
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output+strlen(output), " Formats:\n" );
|
|
||||||
struct v4l2_fmtdesc format;
|
|
||||||
int formatIndex = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
memset( &format, 0, sizeof(format) );
|
|
||||||
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
||||||
format.index = formatIndex;
|
|
||||||
|
|
||||||
if ( vidioctl( vid_fd, VIDIOC_ENUM_FMT, &format ) < 0 )
|
|
||||||
{
|
|
||||||
if ( errno == EINVAL )
|
|
||||||
{
|
|
||||||
formatIndex = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Error( "Failed to enumerate format %d: %s", format.index, strerror(errno) );
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output, "Error, failed to enumerate format %d: %s\n", format.index, strerror(errno) );
|
|
||||||
else
|
|
||||||
sprintf( output, "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
while ( formatIndex++ >= 0 );
|
|
||||||
|
|
||||||
struct v4l2_cropcap cropcap;
|
|
||||||
memset( &cropcap, 0, sizeof(cropcap) );
|
|
||||||
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
||||||
if ( vidioctl( vid_fd, VIDIOC_CROPCAP, &cropcap ) < 0 )
|
|
||||||
{
|
|
||||||
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) );
|
|
||||||
else
|
|
||||||
sprintf( output, "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
if ( verbose )
|
|
||||||
{
|
|
||||||
sprintf( output+strlen(output), "Crop Capabilities\n" );
|
|
||||||
sprintf( output+strlen(output), " Bounds: %d x %d\n", cropcap.bounds.width, cropcap.bounds.height );
|
|
||||||
sprintf( output+strlen(output), " Default: %d x %d\n", cropcap.defrect.width, cropcap.defrect.height );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf( output+strlen(output), "B:%dx%d ", cropcap.bounds.width, cropcap.bounds.height );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct v4l2_crop crop;
|
|
||||||
memset( &crop, 0, sizeof(crop) );
|
|
||||||
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
||||||
if ( vidioctl( vid_fd, VIDIOC_G_CROP, &crop ) < 0 )
|
|
||||||
{
|
|
||||||
Error( "Failed to query crop: %s", strerror(errno) );
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output, "Error, failed to query crop %s: %s\n", device, 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;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
memset( &input, 0, sizeof(input) );
|
|
||||||
input.index = inputIndex;
|
|
||||||
|
|
||||||
if ( vidioctl( vid_fd, VIDIOC_ENUMINPUT, &input ) < 0 )
|
|
||||||
{
|
|
||||||
if ( errno == EINVAL )
|
|
||||||
{
|
|
||||||
inputIndex = -1;
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( false )
|
|
||||||
if ( vidioctl( vid_fd, VIDIOC_S_INPUT, &input.index ) < 0 )
|
|
||||||
{
|
|
||||||
Error( "Failed to set video input %d: %s", input.index, strerror(errno) );
|
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf( output, "Error, failed to switch to input %d: %s\n", input.index, 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 ( 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", queryDevice, strerror(errno) );
|
||||||
else
|
else
|
||||||
sprintf( output, "error%d\n", errno );
|
sprintf( output, "error%d\n", errno );
|
||||||
return( false );
|
return( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), "Input %d\n", input.index );
|
sprintf( output+strlen(output), "General Capabilities\n" );
|
||||||
sprintf( output+strlen(output), " Name: %s\n", input.name );
|
sprintf( output+strlen(output), " Driver: %s\n", vid_cap.driver );
|
||||||
sprintf( output+strlen(output), " Type: %s\n", input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown") );
|
sprintf( output+strlen(output), " Card: %s\n", vid_cap.card );
|
||||||
sprintf( output+strlen(output), " Audioset: %08x\n", input.audioset );
|
sprintf( output+strlen(output), " Bus: %s\n", vid_cap.bus_info );
|
||||||
sprintf( output+strlen(output), " Standards: 0x%llx\n", input.std );
|
sprintf( output+strlen(output), " Version: %u.%u.%u\n", (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff );
|
||||||
|
sprintf( output+strlen(output), " Type: 0x%x\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s", vid_cap.capabilities,
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_CAPTURE, " ", "Supports", "Does not support", "video capture (X)" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT, " ", "Supports", "Does not support", "video output" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_OVERLAY, " ", "Supports", "Does not support", "frame buffer overlay" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_VBI_CAPTURE, " ", "Supports", "Does not support", "VBI capture" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_VBI_OUTPUT, " ", "Supports", "Does not support", "VBI output" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_SLICED_VBI_CAPTURE, " ", "Supports", "Does not support", "sliced VBI capture" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_SLICED_VBI_OUTPUT, " ", "Supports", "Does not support", "sliced VBI output" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT_OVERLAY, " ", "Supports", "Does not support", "video output overlay" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_TUNER, " ", "Has", "Does not have", "tuner" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_AUDIO, " ", "Has", "Does not have", "audio in and/or out" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_RADIO, " ", "Has", "Does not have", "radio" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_READWRITE, " ", "Supports", "Does not support", "read/write i/o (X)" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_ASYNCIO, " ", "Supports", "Does not support", "async i/o" ),
|
||||||
|
capString( vid_cap.capabilities&V4L2_CAP_STREAMING, " ", "Supports", "Does not support", "streaming i/o (X)" )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), "i%d:%s ", input.index, input.name );
|
sprintf( output+strlen(output), "D:%s|", vid_cap.driver );
|
||||||
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), "C:%s|", vid_cap.card );
|
||||||
sprintf( output+strlen(output), "i%dS:%llx ", input.index, input.std );
|
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 )
|
if ( verbose )
|
||||||
|
sprintf( output+strlen(output), " Standards:\n" );
|
||||||
|
else
|
||||||
|
sprintf( output+strlen(output), "S:" );
|
||||||
|
struct v4l2_standard standard;
|
||||||
|
int standardIndex = 0;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_POWER, "Power ", "off", "on", " (X)" ) );
|
memset( &standard, 0, sizeof(standard) );
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_SIGNAL, "Signal ", "not detected", "detected", " (X)" ) );
|
standard.index = standardIndex;
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_COLOR, "Colour Signal ", "not detected", "detected", "" ) );
|
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_H_LOCK, "Horizontal Lock ", "not detected", "detected", "" ) );
|
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ( inputIndex++ >= 0 );
|
|
||||||
if ( !verbose )
|
|
||||||
output[strlen(output)-1] = '\n';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif // ZM_V4L2
|
|
||||||
{
|
|
||||||
struct video_capability vid_cap;
|
|
||||||
if ( ioctl( vid_fd, VIDIOCGCAP, &vid_cap ) < 0 )
|
|
||||||
{
|
|
||||||
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) );
|
|
||||||
else
|
|
||||||
sprintf( output, "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
if ( verbose )
|
|
||||||
{
|
|
||||||
sprintf( output+strlen(output), "Video Capabilities\n" );
|
|
||||||
sprintf( output+strlen(output), " Name: %s\n", vid_cap.name );
|
|
||||||
sprintf( output+strlen(output), " Type: %d\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s", vid_cap.type,
|
|
||||||
vid_cap.type&VID_TYPE_CAPTURE?" Can capture\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_TUNER?" Can tune\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_TELETEXT?" Does teletext\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_OVERLAY?" Overlay onto frame buffer\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_CHROMAKEY?" Overlay by chromakey\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_CLIPPING?" Can clip\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_FRAMERAM?" Uses the frame buffer memory\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_SCALES?" Scalable\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_MONOCHROME?" Monochrome only\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_SUBCAPTURE?" Can capture subareas of the image\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_MPEG_DECODER?" Can decode MPEG streams\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_MPEG_ENCODER?" Can encode MPEG streams\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_MJPEG_DECODER?" Can decode MJPEG streams\n":"",
|
|
||||||
vid_cap.type&VID_TYPE_MJPEG_ENCODER?" Can encode MJPEG streams\n":""
|
|
||||||
);
|
|
||||||
sprintf( output+strlen(output), " Video Channels: %d\n", vid_cap.channels );
|
|
||||||
sprintf( output+strlen(output), " Audio Channels: %d\n", vid_cap.audios );
|
|
||||||
sprintf( output+strlen(output), " Maximum Width: %d\n", vid_cap.maxwidth );
|
|
||||||
sprintf( output+strlen(output), " Maximum Height: %d\n", vid_cap.maxheight );
|
|
||||||
sprintf( output+strlen(output), " Minimum Width: %d\n", vid_cap.minwidth );
|
|
||||||
sprintf( output+strlen(output), " Minimum Height: %d\n", vid_cap.minheight );
|
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct video_window vid_win;
|
if ( vidioctl( vid_fd, VIDIOC_ENUMSTD, &standard ) < 0 )
|
||||||
if ( ioctl( vid_fd, VIDIOCGWIN, &vid_win ) < 0 )
|
{
|
||||||
{
|
if ( errno == EINVAL )
|
||||||
Error( "Failed to get window attributes: %s", strerror(errno) );
|
{
|
||||||
if ( verbose )
|
standardIndex = -1;
|
||||||
sprintf( output, "Error, failed to get window attributes: %s\n", strerror(errno) );
|
break;
|
||||||
else
|
}
|
||||||
sprintf( output, "error%d\n", errno );
|
else
|
||||||
return( false );
|
{
|
||||||
}
|
Error( "Failed to enumerate standard %d: %s", standard.index, strerror(errno) );
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
{
|
sprintf( output, "Error, failed to enumerate standard %d: %s\n", standard.index, strerror(errno) );
|
||||||
sprintf( output+strlen(output), "Window Attributes\n" );
|
else
|
||||||
sprintf( output+strlen(output), " X Offset: %d\n", vid_win.x );
|
sprintf( output, "error%d\n", errno );
|
||||||
sprintf( output+strlen(output), " Y Offset: %d\n", vid_win.y );
|
return( false );
|
||||||
sprintf( output+strlen(output), " Width: %d\n", vid_win.width );
|
}
|
||||||
sprintf( output+strlen(output), " Height: %d\n", vid_win.height );
|
}
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct video_picture vid_pic;
|
|
||||||
if ( ioctl( vid_fd, VIDIOCGPICT, &vid_pic ) < 0 )
|
|
||||||
{
|
|
||||||
Error( "Failed to get picture attributes: %s", strerror(errno) );
|
|
||||||
if ( verbose )
|
|
||||||
sprintf( output, "Error, failed to get picture attributes: %s\n", strerror(errno) );
|
|
||||||
else
|
|
||||||
sprintf( output, "error%d\n", errno );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
if ( verbose )
|
|
||||||
{
|
|
||||||
sprintf( output+strlen(output), "Picture Attributes\n" );
|
|
||||||
sprintf( output+strlen(output), " Palette: %d - %s\n", vid_pic.palette,
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_GREY?"Linear greyscale":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_HI240?"High 240 cube (BT848)":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_RGB565?"565 16 bit RGB":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_RGB24?"24bit RGB":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_RGB32?"32bit RGB":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_RGB555?"555 15bit RGB":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV422?"YUV422 capture":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUYV?"YUYV":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_UYVY?"UVYV":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV420?"YUV420":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV411?"YUV411 capture":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_RAW?"RAW capture (BT848)":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUYV?"YUYV":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV422?"YUV422":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV422P?"YUV 4:2:2 Planar":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV411P?"YUV 4:1:1 Planar":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV420P?"YUV 4:2:0 Planar":(
|
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV410P?"YUV 4:1:0 Planar":"Unknown"
|
|
||||||
))))))))))))))))));
|
|
||||||
sprintf( output+strlen(output), " Colour Depth: %d\n", vid_pic.depth );
|
|
||||||
sprintf( output+strlen(output), " Brightness: %d\n", vid_pic.brightness );
|
|
||||||
sprintf( output+strlen(output), " Hue: %d\n", vid_pic.hue );
|
|
||||||
sprintf( output+strlen(output), " Colour :%d\n", vid_pic.colour );
|
|
||||||
sprintf( output+strlen(output), " Contrast: %d\n", vid_pic.contrast );
|
|
||||||
sprintf( output+strlen(output), " Whiteness: %d\n", vid_pic.whiteness );
|
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int chan = 0; chan < vid_cap.channels; chan++ )
|
|
||||||
{
|
|
||||||
struct video_channel vid_src;
|
|
||||||
vid_src.channel = chan;
|
|
||||||
if ( ioctl( vid_fd, VIDIOCGCHAN, &vid_src ) < 0 )
|
|
||||||
{
|
|
||||||
Error( "Failed to get channel %d attributes: %s", chan, strerror(errno) );
|
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf( output, "Error, failed to get channel %d attributes: %s\n", chan, strerror(errno) );
|
sprintf( output+strlen(output), " %s\n", standard.name );
|
||||||
|
else
|
||||||
|
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
|
||||||
|
{
|
||||||
|
memset( &format, 0, sizeof(format) );
|
||||||
|
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
format.index = formatIndex;
|
||||||
|
|
||||||
|
if ( vidioctl( vid_fd, VIDIOC_ENUM_FMT, &format ) < 0 )
|
||||||
|
{
|
||||||
|
if ( errno == EINVAL )
|
||||||
|
{
|
||||||
|
formatIndex = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error( "Failed to enumerate format %d: %s", format.index, strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to enumerate format %d: %s\n", format.index, strerror(errno) );
|
||||||
|
else
|
||||||
|
sprintf( output, "error%d\n", errno );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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), "%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) );
|
||||||
|
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
if ( vidioctl( vid_fd, VIDIOC_CROPCAP, &cropcap ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to query crop capabilities: %s", strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to query crop capabilities %s: %s\n", queryDevice, strerror(errno) );
|
||||||
else
|
else
|
||||||
sprintf( output, "error%d\n", errno );
|
sprintf( output, "error%d\n", errno );
|
||||||
return( false );
|
return( false );
|
||||||
}
|
}
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), "Channel %d Attributes\n", chan );
|
sprintf( output+strlen(output), "Crop Capabilities\n" );
|
||||||
sprintf( output+strlen(output), " Name: %s\n", vid_src.name );
|
sprintf( output+strlen(output), " Bounds: %d x %d\n", cropcap.bounds.width, cropcap.bounds.height );
|
||||||
sprintf( output+strlen(output), " Channel: %d\n", vid_src.channel );
|
sprintf( output+strlen(output), " Default: %d x %d\n", cropcap.defrect.width, cropcap.defrect.height );
|
||||||
sprintf( output+strlen(output), " Flags: %d\n%s%s", vid_src.flags,
|
|
||||||
vid_src.flags&VIDEO_VC_TUNER?" Channel has a tuner\n":"",
|
|
||||||
vid_src.flags&VIDEO_VC_AUDIO?" Channel has audio\n":""
|
|
||||||
);
|
|
||||||
sprintf( output+strlen(output), " Type: %d - %s\n", vid_src.type,
|
|
||||||
vid_src.type==VIDEO_TYPE_TV?"TV":(
|
|
||||||
vid_src.type==VIDEO_TYPE_CAMERA?"Camera":"Unknown"
|
|
||||||
));
|
|
||||||
sprintf( output+strlen(output), " Format: %d - %s\n", vid_src.norm,
|
|
||||||
vid_src.norm==VIDEO_MODE_PAL?"PAL":(
|
|
||||||
vid_src.norm==VIDEO_MODE_NTSC?"NTSC":(
|
|
||||||
vid_src.norm==VIDEO_MODE_SECAM?"SECAM":(
|
|
||||||
vid_src.norm==VIDEO_MODE_AUTO?"AUTO":"Unknown"
|
|
||||||
))));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf( output+strlen(output), "n%d:%s,", chan, vid_src.name );
|
sprintf( output+strlen(output), "B:%dx%d|", cropcap.bounds.width, cropcap.bounds.height );
|
||||||
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)?"":"," );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct v4l2_crop crop;
|
||||||
|
memset( &crop, 0, sizeof(crop) );
|
||||||
|
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
if ( vidioctl( vid_fd, VIDIOC_G_CROP, &crop ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to query crop: %s", strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
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 );
|
||||||
|
|
||||||
|
struct v4l2_input input;
|
||||||
|
int inputIndex = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
inputIndex = -1;
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( vidioctl( vid_fd, VIDIOC_S_INPUT, &input.index ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to set video input %d: %s", input.index, strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to switch to input %d: %s\n", input.index, strerror(errno) );
|
||||||
|
else
|
||||||
|
sprintf( output, "error%d\n", errno );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
sprintf( output+strlen(output), " Input %d\n", input.index );
|
||||||
|
sprintf( output+strlen(output), " Name: %s\n", input.name );
|
||||||
|
sprintf( output+strlen(output), " Type: %s\n", input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown") );
|
||||||
|
sprintf( output+strlen(output), " Audioset: %08x\n", input.audioset );
|
||||||
|
sprintf( output+strlen(output), " Standards: 0x%llx\n", input.std );
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_POWER, "Power ", "off", "on", " (X)" ) );
|
||||||
|
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_SIGNAL, "Signal ", "not detected", "detected", " (X)" ) );
|
||||||
|
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_COLOR, "Colour Signal ", "not detected", "detected", "" ) );
|
||||||
|
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_H_LOCK, "Horizontal Lock ", "not detected", "detected", "" ) );
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( inputIndex++ >= 0 );
|
||||||
|
if ( !verbose )
|
||||||
|
output[strlen(output)-1] = '\n';
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif // ZM_V4L2
|
||||||
|
{
|
||||||
|
struct video_capability vid_cap;
|
||||||
|
if ( ioctl( vid_fd, VIDIOCGCAP, &vid_cap ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to get video capabilities: %s", strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to get video capabilities %s: %s\n", queryDevice, strerror(errno) );
|
||||||
|
else
|
||||||
|
sprintf( output, "error%d\n", errno );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
sprintf( output+strlen(output), "Video Capabilities\n" );
|
||||||
|
sprintf( output+strlen(output), " Name: %s\n", vid_cap.name );
|
||||||
|
sprintf( output+strlen(output), " Type: %d\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s", vid_cap.type,
|
||||||
|
vid_cap.type&VID_TYPE_CAPTURE?" Can capture\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_TUNER?" Can tune\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_TELETEXT?" Does teletext\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_OVERLAY?" Overlay onto frame buffer\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_CHROMAKEY?" Overlay by chromakey\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_CLIPPING?" Can clip\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_FRAMERAM?" Uses the frame buffer memory\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_SCALES?" Scalable\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_MONOCHROME?" Monochrome only\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_SUBCAPTURE?" Can capture subareas of the image\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_MPEG_DECODER?" Can decode MPEG streams\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_MPEG_ENCODER?" Can encode MPEG streams\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_MJPEG_DECODER?" Can decode MJPEG streams\n":"",
|
||||||
|
vid_cap.type&VID_TYPE_MJPEG_ENCODER?" Can encode MJPEG streams\n":""
|
||||||
|
);
|
||||||
|
sprintf( output+strlen(output), " Video Channels: %d\n", vid_cap.channels );
|
||||||
|
sprintf( output+strlen(output), " Audio Channels: %d\n", vid_cap.audios );
|
||||||
|
sprintf( output+strlen(output), " Maximum Width: %d\n", vid_cap.maxwidth );
|
||||||
|
sprintf( output+strlen(output), " Maximum Height: %d\n", vid_cap.maxheight );
|
||||||
|
sprintf( output+strlen(output), " Minimum Width: %d\n", vid_cap.minwidth );
|
||||||
|
sprintf( output+strlen(output), " Minimum Height: %d\n", vid_cap.minheight );
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct video_window vid_win;
|
||||||
|
if ( ioctl( vid_fd, VIDIOCGWIN, &vid_win ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to get window attributes: %s", strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to get window attributes: %s\n", strerror(errno) );
|
||||||
|
else
|
||||||
|
sprintf( output, "error%d\n", errno );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
sprintf( output+strlen(output), "Window Attributes\n" );
|
||||||
|
sprintf( output+strlen(output), " X Offset: %d\n", vid_win.x );
|
||||||
|
sprintf( output+strlen(output), " Y Offset: %d\n", vid_win.y );
|
||||||
|
sprintf( output+strlen(output), " Width: %d\n", vid_win.width );
|
||||||
|
sprintf( output+strlen(output), " Height: %d\n", vid_win.height );
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct video_picture vid_pic;
|
||||||
|
if ( ioctl( vid_fd, VIDIOCGPICT, &vid_pic ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to get picture attributes: %s", strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to get picture attributes: %s\n", strerror(errno) );
|
||||||
|
else
|
||||||
|
sprintf( output, "error%d\n", errno );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
sprintf( output+strlen(output), "Picture Attributes\n" );
|
||||||
|
sprintf( output+strlen(output), " Palette: %d - %s\n", vid_pic.palette,
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_GREY?"Linear greyscale":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_HI240?"High 240 cube (BT848)":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_RGB565?"565 16 bit RGB":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_RGB24?"24bit RGB":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_RGB32?"32bit RGB":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_RGB555?"555 15bit RGB":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV422?"YUV422 capture":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUYV?"YUYV":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_UYVY?"UVYV":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV420?"YUV420":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV411?"YUV411 capture":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_RAW?"RAW capture (BT848)":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUYV?"YUYV":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV422?"YUV422":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV422P?"YUV 4:2:2 Planar":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV411P?"YUV 4:1:1 Planar":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV420P?"YUV 4:2:0 Planar":(
|
||||||
|
vid_pic.palette==VIDEO_PALETTE_YUV410P?"YUV 4:1:0 Planar":"Unknown"
|
||||||
|
))))))))))))))))));
|
||||||
|
sprintf( output+strlen(output), " Colour Depth: %d\n", vid_pic.depth );
|
||||||
|
sprintf( output+strlen(output), " Brightness: %d\n", vid_pic.brightness );
|
||||||
|
sprintf( output+strlen(output), " Hue: %d\n", vid_pic.hue );
|
||||||
|
sprintf( output+strlen(output), " Colour :%d\n", vid_pic.colour );
|
||||||
|
sprintf( output+strlen(output), " Contrast: %d\n", vid_pic.contrast );
|
||||||
|
sprintf( output+strlen(output), " Whiteness: %d\n", vid_pic.whiteness );
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int chan = 0; chan < vid_cap.channels; chan++ )
|
||||||
|
{
|
||||||
|
struct video_channel vid_src;
|
||||||
|
vid_src.channel = chan;
|
||||||
|
if ( ioctl( vid_fd, VIDIOCGCHAN, &vid_src ) < 0 )
|
||||||
|
{
|
||||||
|
Error( "Failed to get channel %d attributes: %s", chan, strerror(errno) );
|
||||||
|
if ( verbose )
|
||||||
|
sprintf( output, "Error, failed to get channel %d attributes: %s\n", chan, strerror(errno) );
|
||||||
|
else
|
||||||
|
sprintf( output, "error%d\n", errno );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
sprintf( output+strlen(output), "Channel %d Attributes\n", chan );
|
||||||
|
sprintf( output+strlen(output), " Name: %s\n", vid_src.name );
|
||||||
|
sprintf( output+strlen(output), " Channel: %d\n", vid_src.channel );
|
||||||
|
sprintf( output+strlen(output), " Flags: %d\n%s%s", vid_src.flags,
|
||||||
|
vid_src.flags&VIDEO_VC_TUNER?" Channel has a tuner\n":"",
|
||||||
|
vid_src.flags&VIDEO_VC_AUDIO?" Channel has audio\n":""
|
||||||
|
);
|
||||||
|
sprintf( output+strlen(output), " Type: %d - %s\n", vid_src.type,
|
||||||
|
vid_src.type==VIDEO_TYPE_TV?"TV":(
|
||||||
|
vid_src.type==VIDEO_TYPE_CAMERA?"Camera":"Unknown"
|
||||||
|
));
|
||||||
|
sprintf( output+strlen(output), " Format: %d - %s\n", vid_src.norm,
|
||||||
|
vid_src.norm==VIDEO_MODE_PAL?"PAL":(
|
||||||
|
vid_src.norm==VIDEO_MODE_NTSC?"NTSC":(
|
||||||
|
vid_src.norm==VIDEO_MODE_SECAM?"SECAM":(
|
||||||
|
vid_src.norm==VIDEO_MODE_AUTO?"AUTO":"Unknown"
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
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)?"":"," );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !verbose )
|
||||||
|
output[strlen(output)-1] = '\n';
|
||||||
|
}
|
||||||
|
close( vid_fd );
|
||||||
|
if ( device )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
while ( ++devIndex < 32 );
|
||||||
return( true );
|
return( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ public:
|
||||||
int Capture( Image &image );
|
int Capture( Image &image );
|
||||||
int PostCapture();
|
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
|
#endif // ZM_LOCAL_CAMERA_H
|
||||||
|
|
70
src/zmu.cpp
70
src/zmu.cpp
|
@ -35,7 +35,8 @@ void Usage( int status=-1 )
|
||||||
fprintf( stderr, " -v, --verbose : Produce more verbose output\n" );
|
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, " -l, --list : List the current status of active (or all with -v) monitors\n" );
|
||||||
fprintf( stderr, "Options for use with devices:\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, " -q, --query : Query the current settings for the device\n" );
|
||||||
fprintf( stderr, "Options for use with monitors:\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" );
|
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[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"device", 1, 0, 'd'},
|
{"device", 2, 0, 'd'},
|
||||||
{"monitor", 1, 0, 'm'},
|
{"monitor", 1, 0, 'm'},
|
||||||
{"verbose", 0, 0, 'v'},
|
{"verbose", 0, 0, 'v'},
|
||||||
{"image", 2, 0, 'i'},
|
{"image", 2, 0, 'i'},
|
||||||
|
@ -165,12 +166,14 @@ int main( int argc, char *argv[] )
|
||||||
{"query", 0, 0, 'q'},
|
{"query", 0, 0, 'q'},
|
||||||
{"username", 1, 0, 'U'},
|
{"username", 1, 0, 'U'},
|
||||||
{"password", 1, 0, 'P'},
|
{"password", 1, 0, 'P'},
|
||||||
|
{"auth", 1, 0, 'A'},
|
||||||
|
{"version", 1, 0, 'V'},
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
{"list", 0, 0, 'l'},
|
{"list", 0, 0, 'l'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *device = "";
|
const char *device = 0;
|
||||||
int mon_id = 0;
|
int mon_id = 0;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
int function = ZMU_BOGUS;
|
int function = ZMU_BOGUS;
|
||||||
|
@ -181,15 +184,20 @@ int main( int argc, char *argv[] )
|
||||||
int contrast = -1;
|
int contrast = -1;
|
||||||
int hue = -1;
|
int hue = -1;
|
||||||
int colour = -1;
|
int colour = -1;
|
||||||
char *zone_string = 0;
|
char *zoneString = 0;
|
||||||
char *username = 0;
|
char *username = 0;
|
||||||
char *password = 0;
|
char *password = 0;
|
||||||
char *auth = 0;
|
char *auth = 0;
|
||||||
|
#ifdef ZM_V4L2
|
||||||
|
int v4lVersion = 2;
|
||||||
|
#else // ZM_V4L2
|
||||||
|
int v4lVersion = 1;
|
||||||
|
#endif // ZM_V4L2
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int option_index = 0;
|
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)
|
if (c == -1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -198,7 +206,8 @@ int main( int argc, char *argv[] )
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'd':
|
case 'd':
|
||||||
device = optarg;
|
if ( optarg )
|
||||||
|
device = optarg;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
mon_id = atoi(optarg);
|
mon_id = atoi(optarg);
|
||||||
|
@ -212,9 +221,7 @@ int main( int argc, char *argv[] )
|
||||||
case 'i':
|
case 'i':
|
||||||
function |= ZMU_IMAGE;
|
function |= ZMU_IMAGE;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
|
||||||
image_idx = atoi( optarg );
|
image_idx = atoi( optarg );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
scale = atoi(optarg);
|
scale = atoi(optarg);
|
||||||
|
@ -222,9 +229,7 @@ int main( int argc, char *argv[] )
|
||||||
case 't':
|
case 't':
|
||||||
function |= ZMU_TIME;
|
function |= ZMU_TIME;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
|
||||||
image_idx = atoi( optarg );
|
image_idx = atoi( optarg );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
function |= ZMU_READ_IDX;
|
function |= ZMU_READ_IDX;
|
||||||
|
@ -241,9 +246,7 @@ int main( int argc, char *argv[] )
|
||||||
case 'z':
|
case 'z':
|
||||||
function |= ZMU_ZONES;
|
function |= ZMU_ZONES;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
zoneString = optarg;
|
||||||
zone_string = optarg;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
function |= ZMU_ALARM;
|
function |= ZMU_ALARM;
|
||||||
|
@ -275,30 +278,22 @@ int main( int argc, char *argv[] )
|
||||||
case 'B':
|
case 'B':
|
||||||
function |= ZMU_BRIGHTNESS;
|
function |= ZMU_BRIGHTNESS;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
|
||||||
brightness = atoi( optarg );
|
brightness = atoi( optarg );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
function |= ZMU_CONTRAST;
|
function |= ZMU_CONTRAST;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
|
||||||
contrast = atoi( optarg );
|
contrast = atoi( optarg );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
function |= ZMU_HUE;
|
function |= ZMU_HUE;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
|
||||||
hue = atoi( optarg );
|
hue = atoi( optarg );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
function |= ZMU_COLOUR;
|
function |= ZMU_COLOUR;
|
||||||
if ( optarg )
|
if ( optarg )
|
||||||
{
|
|
||||||
colour = atoi( optarg );
|
colour = atoi( optarg );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
username = optarg;
|
username = optarg;
|
||||||
|
@ -309,6 +304,9 @@ int main( int argc, char *argv[] )
|
||||||
case 'A':
|
case 'A':
|
||||||
auth = optarg;
|
auth = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'V':
|
||||||
|
v4lVersion = (atoi(optarg)==1)?1:2;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
Usage( 0 );
|
Usage( 0 );
|
||||||
break;
|
break;
|
||||||
|
@ -333,7 +331,7 @@ int main( int argc, char *argv[] )
|
||||||
Usage();
|
Usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( device[0] && !(function&ZMU_QUERY) )
|
if ( device && !(function&ZMU_QUERY) )
|
||||||
{
|
{
|
||||||
fprintf( stderr, "Error, -d option cannot be used with this option\n" );
|
fprintf( stderr, "Error, -d option cannot be used with this option\n" );
|
||||||
Usage();
|
Usage();
|
||||||
|
@ -401,17 +399,7 @@ int main( int argc, char *argv[] )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( device[0] )
|
if ( mon_id > 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 )
|
|
||||||
{
|
{
|
||||||
Monitor *monitor = Monitor::Load( mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY );
|
Monitor *monitor = Monitor::Load( mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY );
|
||||||
if ( monitor )
|
if ( monitor )
|
||||||
|
@ -516,7 +504,7 @@ int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
printf( "Dumping zone image to %s-Zones.jpg\n", monitor->Name() );
|
printf( "Dumping zone image to %s-Zones.jpg\n", monitor->Name() );
|
||||||
monitor->DumpZoneImage( zone_string );
|
monitor->DumpZoneImage( zoneString );
|
||||||
}
|
}
|
||||||
if ( function & ZMU_ALARM )
|
if ( function & ZMU_ALARM )
|
||||||
{
|
{
|
||||||
|
@ -568,9 +556,9 @@ int main( int argc, char *argv[] )
|
||||||
}
|
}
|
||||||
if ( function & ZMU_QUERY )
|
if ( function & ZMU_QUERY )
|
||||||
{
|
{
|
||||||
char mon_string[16382] = "";
|
char monString[16382] = "";
|
||||||
monitor->DumpSettings( mon_string, verbose );
|
monitor->DumpSettings( monString, verbose );
|
||||||
printf( "%s\n", mon_string );
|
printf( "%s\n", monString );
|
||||||
}
|
}
|
||||||
if ( function & ZMU_BRIGHTNESS )
|
if ( function & ZMU_BRIGHTNESS )
|
||||||
{
|
{
|
||||||
|
@ -666,6 +654,14 @@ int main( int argc, char *argv[] )
|
||||||
}
|
}
|
||||||
else
|
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 )
|
if ( function & ZMU_LIST )
|
||||||
{
|
{
|
||||||
char sql[BUFSIZ];
|
char sql[BUFSIZ];
|
||||||
|
|
Loading…
Reference in New Issue