Path: blob/master/modules/videoio/src/cap_unicap.cpp
16354 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// Intel License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2008, Xavier Delacour, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041// 2008-04-27 Xavier Delacour <[email protected]>4243#include "precomp.hpp"44#include <unistd.h>45#include <unicap.h>46extern "C" {47#include <ucil.h>48}4950#ifdef NDEBUG51#define CV_WARN(message)52#else53#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)54#endif5556struct CvCapture_Unicap : public CvCapture57{58CvCapture_Unicap() { init(); }59virtual ~CvCapture_Unicap() { close(); }6061virtual bool open( int index );62virtual void close();6364virtual double getProperty(int) const CV_OVERRIDE;65virtual bool setProperty(int, double) CV_OVERRIDE;66virtual bool grabFrame() CV_OVERRIDE;67virtual IplImage* retrieveFrame(int) CV_OVERRIDE;68virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_UNICAP; }6970bool shutdownDevice();71bool initDevice();7273void init()74{75device_initialized = false;76desired_format = 0;77desired_size = cvSize(0,0);78convert_rgb = false;7980handle = 0;81memset( &device, 0, sizeof(device) );82memset( &format_spec, 0, sizeof(format_spec) );83memset( &format, 0, sizeof(format) );84memset( &raw_buffer, 0, sizeof(raw_buffer) );85memset( &buffer, 0, sizeof(buffer) );8687raw_frame = frame = 0;88}8990bool device_initialized;9192int desired_device;93int desired_format;94CvSize desired_size;95bool convert_rgb;9697unicap_handle_t handle;98unicap_device_t device;99unicap_format_t format_spec;100unicap_format_t format;101unicap_data_buffer_t raw_buffer;102unicap_data_buffer_t buffer;103104IplImage *raw_frame;105IplImage *frame;106};107108bool CvCapture_Unicap::shutdownDevice() {109bool result = false;110CV_FUNCNAME("CvCapture_Unicap::shutdownDevice");111__BEGIN__;112113if (!SUCCESS(unicap_stop_capture(handle)))114CV_ERROR(CV_StsError, "unicap: failed to stop capture on device\n");115116if (!SUCCESS(unicap_close(handle)))117CV_ERROR(CV_StsError, "unicap: failed to close the device\n");118119cvReleaseImage(&raw_frame);120cvReleaseImage(&frame);121122device_initialized = false;123124result = true;125__END__;126return result;127}128129bool CvCapture_Unicap::initDevice() {130bool result = false;131CV_FUNCNAME("CvCapture_Unicap::initDevice");132__BEGIN__;133134if (device_initialized && !shutdownDevice())135return false;136137if(!SUCCESS(unicap_enumerate_devices(NULL, &device, desired_device)))138CV_ERROR(CV_StsError, "unicap: failed to get info for device\n");139140if(!SUCCESS(unicap_open( &handle, &device)))141CV_ERROR(CV_StsError, "unicap: failed to open device\n");142143unicap_void_format(&format_spec);144145if (!SUCCESS(unicap_enumerate_formats(handle, &format_spec, &format, desired_format))) {146shutdownDevice();147CV_ERROR(CV_StsError, "unicap: failed to get video format\n");148}149150int i;151if (format.sizes)152{153for (i = format.size_count - 1; i > 0; i--)154if (format.sizes[i].width == desired_size.width &&155format.sizes[i].height == desired_size.height)156break;157format.size.width = format.sizes[i].width;158format.size.height = format.sizes[i].height;159}160161if (!SUCCESS(unicap_set_format(handle, &format))) {162shutdownDevice();163CV_ERROR(CV_StsError, "unicap: failed to set video format\n");164}165166memset(&raw_buffer, 0x0, sizeof(unicap_data_buffer_t));167raw_frame = cvCreateImage(cvSize(format.size.width,168format.size.height),1698, format.bpp / 8);170memcpy(&raw_buffer.format, &format, sizeof(raw_buffer.format));171raw_buffer.data = (unsigned char*)raw_frame->imageData;172raw_buffer.buffer_size = format.size.width *173format.size.height * format.bpp / 8;174175memset(&buffer, 0x0, sizeof(unicap_data_buffer_t));176memcpy(&buffer.format, &format, sizeof(buffer.format));177178buffer.format.fourcc = UCIL_FOURCC('B','G','R','3');179buffer.format.bpp = 24;180// * todo support greyscale output181// buffer.format.fourcc = UCIL_FOURCC('G','R','E','Y');182// buffer.format.bpp = 8;183184frame = cvCreateImage(cvSize(buffer.format.size.width,185buffer.format.size.height),1868, buffer.format.bpp / 8);187buffer.data = (unsigned char*)frame->imageData;188buffer.buffer_size = buffer.format.size.width *189buffer.format.size.height * buffer.format.bpp / 8;190191if(!SUCCESS(unicap_start_capture(handle))) {192shutdownDevice();193CV_ERROR(CV_StsError, "unicap: failed to start capture on device\n");194}195196device_initialized = true;197result = true;198__END__;199return result;200}201202void CvCapture_Unicap::close() {203if(device_initialized)204shutdownDevice();205}206207bool CvCapture_Unicap::grabFrame() {208bool result = false;209210CV_FUNCNAME("CvCapture_Unicap::grabFrame");211__BEGIN__;212213unicap_data_buffer_t *returned_buffer;214215int retry_count = 100;216217while (retry_count--) {218if(!SUCCESS(unicap_queue_buffer(handle, &raw_buffer)))219CV_ERROR(CV_StsError, "unicap: failed to queue a buffer on device\n");220221if(SUCCESS(unicap_wait_buffer(handle, &returned_buffer)))222{223result = true;224EXIT;225}226227CV_WARN("unicap: failed to wait for buffer on device\n");228usleep(100 * 1000);229}230231__END__;232return result;233}234235IplImage * CvCapture_Unicap::retrieveFrame(int) {236if (convert_rgb) {237ucil_convert_buffer(&buffer, &raw_buffer);238return frame;239}240return raw_frame;241}242243double CvCapture_Unicap::getProperty(int id) const244{245switch (id) {246case CV_CAP_PROP_POS_MSEC: break;247case CV_CAP_PROP_POS_FRAMES: break;248case CV_CAP_PROP_POS_AVI_RATIO: break;249case CV_CAP_PROP_FRAME_WIDTH:250return desired_size.width;251case CV_CAP_PROP_FRAME_HEIGHT:252return desired_size.height;253case CV_CAP_PROP_FPS: break;254case CV_CAP_PROP_FOURCC: break;255case CV_CAP_PROP_FRAME_COUNT: break;256case CV_CAP_PROP_FORMAT:257return desired_format;258case CV_CAP_PROP_MODE: break;259case CV_CAP_PROP_BRIGHTNESS: break;260case CV_CAP_PROP_CONTRAST: break;261case CV_CAP_PROP_SATURATION: break;262case CV_CAP_PROP_HUE: break;263case CV_CAP_PROP_GAIN: break;264case CV_CAP_PROP_CONVERT_RGB:265return convert_rgb;266}267268return 0;269}270271bool CvCapture_Unicap::setProperty(int id, double value) {272bool reinit = false;273274switch (id) {275case CV_CAP_PROP_POS_MSEC: break;276case CV_CAP_PROP_POS_FRAMES: break;277case CV_CAP_PROP_POS_AVI_RATIO: break;278case CV_CAP_PROP_FRAME_WIDTH:279desired_size.width = (int)value;280reinit = true;281break;282case CV_CAP_PROP_FRAME_HEIGHT:283desired_size.height = (int)value;284reinit = true;285break;286case CV_CAP_PROP_FPS: break;287case CV_CAP_PROP_FOURCC: break;288case CV_CAP_PROP_FRAME_COUNT: break;289case CV_CAP_PROP_FORMAT:290desired_format = id;291reinit = true;292break;293case CV_CAP_PROP_MODE: break;294case CV_CAP_PROP_BRIGHTNESS: break;295case CV_CAP_PROP_CONTRAST: break;296case CV_CAP_PROP_SATURATION: break;297case CV_CAP_PROP_HUE: break;298case CV_CAP_PROP_GAIN: break;299case CV_CAP_PROP_CONVERT_RGB:300convert_rgb = value != 0;301break;302}303304if (reinit && !initDevice())305return false;306307return true;308}309310bool CvCapture_Unicap::open(int index)311{312close();313device_initialized = false;314315desired_device = index < 0 ? 0 : index;316desired_format = 0;317desired_size = cvSize(320, 240);318convert_rgb = true;319320return initDevice();321}322323324CvCapture * cvCreateCameraCapture_Unicap(const int index)325{326CvCapture_Unicap *cap = new CvCapture_Unicap;327if( cap->open(index) )328return cap;329delete cap;330return 0;331}332333334