Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
unicap.c
Package: unicap-0.2.19.tar.gz [view]
Upload User: shyika
Upload Date: 2017-11-25
Package Size: 1227k
Code Size: 28k
Category:
Video Capture
Development Platform:
Unix_Linux
- /*
- unicap
- Copyright (C) 2004 Arne Caspari
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include "config.h"
- #include <errno.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <fcntl.h>
- #include <dirent.h>
- #include <math.h>
- #if !ENABLE_STATIC_CPI
- #include <dlfcn.h> // dynamic loader
- #else
- #include "static_cpi.h"
- #endif
- #include "unicap.h"
- #include "unicap_version.h"
- #include "unicap_private.h"
- #include "unicap_cpi.h"
- #include "unicap_helpers.h"
- #include "check_match.h"
- #include <unicap_status.h>
- #if UNICAP_DEBUG
- #define DEBUG
- #endif
- #include "debug.h"
- union semun_linux {
- int val; /* Value for SETVAL */
- struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
- unsigned short *array; /* Array for GETALL, SETALL */
- struct seminfo *__buf; /* Buffer for IPC_INFO
- (Linux specific) */
- };
- static unicap_handle_t unicap_copy_handle( unicap_handle_t handle );
- const unsigned int unicap_major_version=UNICAP_MAJOR_VERSION;
- const unsigned int unicap_minor_version=UNICAP_MINOR_VERSION;
- const unsigned int unicap_micro_version=UNICAP_MICRO_VERSION;
- static int g_device_count = 0;
- static unicap_device_t g_devices[128];
- static int g_filter_remote = 0;
- #if ENABLE_STATIC_CPI
- static int g_static_cpi_initialized = 0;
- static void initialize_static_cpis()
- {
- if( !g_static_cpi_initialized )
- {
- int i;
- #if BUILD_DCAM
- unicap_dcam_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_DCAM] );
- #endif
- #if BUILD_VID21394
- unicap_vid21394_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_VID21394] );
- #endif
- #if BUILD_V4L
- unicap_v4l_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_V4L] );
- #endif
- #if BUILD_V4L2
- unicap_v4l2_register_static_cpi( &static_cpis_s[UNICAP_STATIC_CPI_V4L2] );
- #endif
- static_cpis_s[UNICAP_STATIC_CPI_COUNT] = 0;
- }
- g_static_cpi_initialized = 1;
- }
- #endif
- unicap_status_t unicap_set_filter_remote( int do_filter )
- {
- if( do_filter )
- {
- g_filter_remote = 1;
- }
- else
- {
- g_filter_remote = 0;
- }
- return STATUS_SUCCESS;
- }
- static unicap_status_t _unicap_acquire_cpi_lock( int sem_id )
- {
- #ifdef UNICAP_THREAD_LOCKING
- if( sem_id != -1 )
- {
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = SEM_UNDO;
- if( semop( sem_id, &sops, 1 ) < 0 )
- {
- return STATUS_FAILURE;
- }
- }
- #endif
- return STATUS_SUCCESS;
- }
- static unicap_status_t _unicap_release_cpi_lock( int sem_id )
- {
- #ifdef UNICAP_THREAD_LOCKING
- if( sem_id != -1 )
- {
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = 1;
- sops.sem_flg = SEM_UNDO;
- if( semop( sem_id, &sops, 1 ) < 0 )
- {
- return STATUS_FAILURE;
- }
- }
- #endif
- return STATUS_SUCCESS;
- }
- static void unicap_event_callback( unicap_handle_t handle, unicap_event_t event, ... )
- {
- if( !handle->cb_info[event].func )
- {
- return;
- }
- switch( event )
- {
- case UNICAP_EVENT_DEVICE_REMOVED:
- {
- handle->cb_info[event].func( event, handle, handle->cb_info[event].user_ptr );
- }
- break;
- case UNICAP_EVENT_NEW_FRAME:
- {
- va_list ap;
- unicap_data_buffer_t *buffer;
- va_start( ap, event );
- buffer = va_arg(ap, unicap_data_buffer_t *);
- va_end( ap );
- handle->cb_info[event].func( event, handle, buffer, handle->cb_info[event].user_ptr );
- }
- break;
- default:
- {
- handle->cb_info[event].func( event, handle, handle->cb_info[event].user_ptr );
- }
- break;
- }
- }
- unicap_status_t unicap_check_version( unsigned int major, unsigned int minor, unsigned int micro )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( UNICAP_MAJOR_VERSION < major )
- {
- status = STATUS_INCOMPATIBLE_MAJOR_VERSION;
- }
- else if( major == UNICAP_MAJOR_VERSION )
- {
- if( UNICAP_MINOR_VERSION < minor )
- {
- status = STATUS_INCOMPATIBLE_MINOR_VERSION;
- }
- else if( minor == UNICAP_MINOR_VERSION )
- {
- if( UNICAP_MICRO_VERSION < micro )
- {
- status = STATUS_INCOMPATIBLE_MICRO_VERSION;
- }
- }
- }
- return status;
- }
- unicap_status_t unicap_reenumerate_devices( int *_pcount )
- {
- int count = 128;
- unicap_real_enumerate_devices( &count );
- g_device_count = count;
- if( _pcount )
- {
- *_pcount = count;
- }
- return g_device_count ? STATUS_SUCCESS : STATUS_NO_DEVICE;
- }
- unicap_status_t unicap_enumerate_devices( unicap_device_t *specifier, unicap_device_t *device, int index )
- {
- int current_index = -1;
- if( g_device_count != 0)
- {
- int i;
- if( index >= g_device_count )
- {
- return STATUS_NO_MATCH;
- }
- for( i = 0; i < g_device_count; i++ )
- {
- if( _check_device_match( specifier, &g_devices[i] ) )
- {
- current_index++;
- if( current_index == index )
- {
- memcpy( device, &g_devices[i], sizeof( unicap_device_t ) );
- return STATUS_SUCCESS;
- }
- }
- }
- }
- else
- {
- if( SUCCESS( unicap_reenumerate_devices( &g_device_count ) ) )
- {
- if( g_device_count )
- {
- return unicap_enumerate_devices( specifier, device, index );
- }
- }
- }
- return STATUS_NO_MATCH;
- }
- #if !ENABLE_STATIC_CPI
- static unicap_status_t enumerate_devices( int *count )
- {
- void *dlhandle;
- cpi_register_t cpi_register;
- unicap_status_t status = STATUS_SUCCESS;
- struct _unicap_cpi cpi;
- int current_index = 0;
- DIR *cpi_dir;
- struct dirent *cpi_dirent;
- char *dirname;
- char buffer[33000];
- const char suffix[] = ".so";
- #ifdef INSTALL_PREFIX
- strcpy( buffer, INSTALL_PREFIX );
- #else
- strcpy( buffer, "" );
- #endif
- strcat( buffer, "/lib/unicap"PKG_VERSION"/cpi" );
- TRACE( "cpi search path: %s, suffix: %sn", buffer, suffix );
- cpi_dir = opendir( buffer );
- if( !cpi_dir )
- {
- return STATUS_FAILURE;
- }
- dirname = buffer;
- while( ( cpi_dirent = readdir( cpi_dir ) ) > 0 )
- {
- char filename[512];
- int tmp_index = 0;
- sprintf( filename, "%s/%s", dirname, cpi_dirent->d_name );
- if( ( !strstr( filename, suffix ) ) ||
- ( strlen( strstr( filename, suffix ) ) != strlen( suffix ) ) )
- {
- continue;
- }
- TRACE( "open cpi: %sn", filename );
- // load the cpi as a .so
- dlhandle = dlopen( filename, RTLD_NOW );
- if( !dlhandle )
- {
- TRACE( "cpi load: %sn", dlerror() );
- continue;
- }
- cpi_register = dlsym( dlhandle, "cpi_register" );
- if( !cpi_register )
- {
- TRACE( "cpi load: %sn", dlerror() );
- dlclose( dlhandle );
- continue;
- }
- memset( &cpi, 0x0, sizeof( struct _unicap_cpi ) );
- cpi_register( &cpi );
- if( g_filter_remote && ( cpi.cpi_flags & UNICAP_CPI_REMOTE ) )
- {
- TRACE( "cpi load: remote cpi filtered outn" );
- dlclose( dlhandle );
- continue;
- }
- if( CPI_VERSION_HI(cpi.cpi_version) > 2 )
- {
- TRACE( "cpi load: unknown versionn" );
- dlclose( dlhandle );
- continue;
- }
- TRACE( "cpi.cpi_enumerate_devices: %pn", cpi.cpi_enumerate_devices );
- // look at all devices supplied by the cpi
- while( ( current_index < *count ) &&
- ( SUCCESS( status = cpi.cpi_enumerate_devices( &g_devices[current_index], tmp_index ) ) ) )
- {
- TRACE( "current_index: %dn", current_index );
- strcpy( g_devices[current_index].cpi_layer, filename );
- current_index++;
- tmp_index++;
- }
- TRACE( "status: %08xn", status );
- dlclose( dlhandle );
- }
- *count = current_index;
- closedir( cpi_dir );
- return status;
- }
- #else
- static unicap_status_t enumerate_devices( int *count )
- {
- int idx_cpi = 0;
- int idx_device = 0;
- unicap_status_t status = STATUS_SUCCESS;
- initialize_static_cpis();
- while( static_cpis_s[idx_cpi] != 0 )
- {
- struct _unicap_cpi *cpi = static_cpis_s[idx_cpi];
- int idx_tmp = 0;
- while( ( idx_device < *count ) &&
- ( SUCCESS( status = cpi->cpi_enumerate_devices( &g_devices[idx_device], idx_tmp++ ) ) ) )
- {
- TRACE( "current index: %dn", idx_device );
- sprintf( g_devices[idx_device].cpi_layer, "%d", idx_cpi );
- idx_device++;
- }
- TRACE( "status: %08xn", status );
- idx_cpi++;
- }
- *count = idx_device;
- return status;
- }
- #endif //ENABLE_STATIC_CPI
- unicap_status_t unicap_real_enumerate_devices( int *count )
- {
- return enumerate_devices( count );
- }
- #if !ENABLE_STATIC_CPI
- static unicap_status_t open_cpi( unicap_handle_t *unicap_handle, unicap_device_t *device )
- {
- void *dlhandle;
- unicap_handle_t handle;
- unicap_status_t status;
- int i;
- TRACE( "open----------%sn", device->identifier );
- if( !device || !unicap_handle )
- {
- return STATUS_INVALID_PARAMETER;
- }
- *unicap_handle = NULL;
- handle = malloc( sizeof( struct _unicap_handle ) );
- if( !handle )
- {
- return STATUS_NO_MEM;
- }
- // initialize data structure
- memset( handle, 0, sizeof( struct _unicap_handle ) );
- handle->cb_info = malloc( sizeof( struct _unicap_callback_info ) * UNICAP_EVENT_LAST );
- for( i = 0; i < UNICAP_EVENT_LAST; i++ )
- {
- handle->cb_info[ i ].func = NULL;
- handle->cb_info[ i ].user_ptr = NULL;
- }
- sprintf( handle->device_uid, "%s", device->identifier );
- dlhandle = dlopen( device->cpi_layer, RTLD_LAZY );
- if( !dlhandle )
- {
- free( handle );
- return STATUS_CPI_OPEN_FAILED;
- }
- //
- // resolve cpi symbols
- //
- handle->cpi.cpi_register = dlsym( dlhandle, "cpi_register" );
- if( !handle->cpi.cpi_register )
- {
- TRACE( "unicap: cpi %s : INVALID_CPIn", device->cpi_layer );
- free( handle );
- dlclose( dlhandle );
- return STATUS_INVALID_CPI;
- }
- handle->cpi.cpi_register( &handle->cpi );
- if( CPI_VERSION_HI(handle->cpi.cpi_version) > 2 )
- {
- TRACE( "cpi_version hi: %dn", CPI_VERSION_HI(handle->cpi.cpi_version) );
- free( handle );
- dlclose( dlhandle );
- return STATUS_UNSUPPORTED_CPI_VERSION;
- }
- // TODO:: check capabilities
- // if serialized operation is requested, use a semaphore to prevent that more than one thread
- // could enter a cpi function at the time
- if( handle->cpi.cpi_flags & UNICAP_CPI_SERIALIZED )
- {
- struct semid_ds semid;
- union semun_linux semun;
- // serialize per cpi. TODO: serialize per device optionally
- handle->sem_key = ftok( device->cpi_layer, 'a' );
- if( handle->sem_key == -1 )
- {
- free( handle );
- dlclose( dlhandle );
- return STATUS_FAILURE;
- }
- handle->sem_id = semget( handle->sem_key, 1, IPC_CREAT );
- if( handle->sem_id == -1 )
- {
- free( handle );
- dlclose( dlhandle );
- return STATUS_FAILURE;
- }
- semun.buf = &semid;
- // check if the semaphore is used the first time -> initialize it
- semctl( handle->sem_id, 0, IPC_STAT, semun );
- if( semid.sem_otime == 0 )
- {
- semun.val = 1;
- semctl( handle->sem_id, 0, SETVAL, semun );
- }
- }
- else
- {
- handle->sem_key = -1;
- handle->sem_id = -1;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_open( &handle->cpi_data, device );
- if( !SUCCESS( status ) )
- {
- free( handle );
- dlclose( dlhandle );
- return status;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- handle->dlhandle = dlhandle;
- memcpy( &handle->device, device, sizeof( unicap_device_t ) );
- handle->ref_count = malloc( sizeof( int ) );
- *(handle->ref_count) = 1;
- *unicap_handle = handle;
- if( handle->cpi.cpi_set_event_notify )
- {
- handle->cpi.cpi_set_event_notify( handle->cpi_data, unicap_event_callback, unicap_copy_handle( handle ) );
- }
- return STATUS_SUCCESS;
- }
- #else
- static unicap_status_t open_cpi( unicap_handle_t *unicap_handle, unicap_device_t *device )
- {
- unicap_handle_t handle;
- unicap_status_t status;
- int cpi_count;
- int idx_cpi;
- int i;
- TRACE( "open----------%sn", device->identifier );
- initialize_static_cpis();
- if( !device || !unicap_handle )
- {
- return STATUS_INVALID_PARAMETER;
- }
- *unicap_handle = NULL;
- handle = malloc( sizeof( struct _unicap_handle ) );
- if( !handle )
- {
- return STATUS_NO_MEM;
- }
- // initialize data structure
- memset( handle, 0, sizeof( struct _unicap_handle ) );
- handle->cb_info = malloc( sizeof( struct _unicap_callback_info ) * UNICAP_EVENT_LAST );
- for( i = 0; i < UNICAP_EVENT_LAST; i++ )
- {
- handle->cb_info[ i ].func = NULL;
- handle->cb_info[ i ].user_ptr = NULL;
- }
- sprintf( handle->device_uid, "%s", device->identifier );
- sscanf( device->cpi_layer, "%d", &idx_cpi );
- if( ( idx_cpi < 0 ) || ( idx_cpi > UNICAP_STATIC_CPI_COUNT ) )
- {
- free( handle );
- return STATUS_INVALID_PARAMETER;
- }
- memcpy( &handle->cpi, static_cpis_s[idx_cpi], sizeof( struct _unicap_cpi ) );
- handle->sem_key = -1;
- handle->sem_id = -1;
- status = handle->cpi.cpi_open( &handle->cpi_data, device );
- if( !SUCCESS( status ) )
- {
- free( handle );
- return status;
- }
- handle->ref_count = malloc( sizeof( int ) );
- *(handle->ref_count) = 1;
- *unicap_handle = handle;
- if( handle->cpi.cpi_set_event_notify )
- {
- handle->cpi.cpi_set_event_notify( handle->cpi_data, unicap_event_callback, unicap_copy_handle( handle ) );
- }
- return STATUS_SUCCESS;
- }
- #endif //ENABLE_STATIC_CPI
- unicap_status_t unicap_open( unicap_handle_t *unicap_handle, unicap_device_t *device )
- {
- unicap_status_t status = open_cpi( unicap_handle, device );
- return status;
- }
- void unicap_cpi_register_event_notification( void* _func,
- void *data, unicap_handle_t handle )
- {
- cpi_set_event_notify_t func = (cpi_set_event_notify_t)_func;
- func( data, unicap_event_callback, unicap_clone_handle( handle ) );
- }
- /*
- Create a new instance of an unicap handle and increase ref count.
- Input: handle
- Output: A copy of handle; ref count increased
- */
- unicap_handle_t unicap_clone_handle( unicap_handle_t handle )
- {
- unicap_handle_t cloned_handle;
- if( !handle )
- {
- return NULL;
- }
- cloned_handle = malloc( sizeof( struct _unicap_handle ) );
- if( !cloned_handle )
- {
- return NULL;
- }
- memcpy( cloned_handle, handle, sizeof( struct _unicap_handle ) );
- *(handle->ref_count) = *(handle->ref_count) + 1;
- return cloned_handle;
- }
- /**
- * Create a new unicap_handle instance WITHOUT incrementing refcount
- * @handle: handle to copy
- *
- * Returns: copy of handle
- */
- static unicap_handle_t unicap_copy_handle( unicap_handle_t handle )
- {
- unicap_handle_t cloned_handle;
- if( !handle )
- {
- return NULL;
- }
- cloned_handle = malloc( sizeof( struct _unicap_handle ) );
- if( !cloned_handle )
- {
- return NULL;
- }
- memcpy( cloned_handle, handle, sizeof( struct _unicap_handle ) );
- return cloned_handle;
- }
- unicap_status_t unicap_close( unicap_handle_t handle )
- {
- if( *(handle->ref_count) == 0 )
- {
- TRACE( "Tried to close a handle with ref_count == 0!n" );
- return STATUS_FAILURE;
- }
- *(handle->ref_count) = *(handle->ref_count) - 1;
- TRACE( "close: new refcount = %dn", *(handle->ref_count ) );
- if( *(handle->ref_count) == 0 )
- {
- unicap_unlock_properties( handle );
- unicap_unlock_stream( handle );
- // free resources
- _unicap_acquire_cpi_lock( handle->sem_id );
- handle->cpi.cpi_capture_stop( handle->cpi_data );
- handle->cpi.cpi_close( handle->cpi_data );
- if( handle->dlhandle )
- {
- dlclose( handle->dlhandle );
- }
- _unicap_release_cpi_lock( handle->sem_id );
- free( handle->ref_count );
- }
- free( handle );
- return STATUS_SUCCESS;
- }
- unicap_status_t unicap_get_device( unicap_handle_t handle, unicap_device_t *device )
- {
- if( !handle || !device )
- {
- return STATUS_INVALID_PARAMETER;
- }
- memcpy( device, &handle->device, sizeof( unicap_device_t ) );
- return STATUS_SUCCESS;
- }
- unicap_status_t unicap_reenumerate_formats( unicap_handle_t handle, int *count )
- {
- unicap_status_t status;
- status = handle->cpi.cpi_reenumerate_formats( handle->cpi_data, count );
- return status;
- }
- unicap_status_t unicap_enumerate_formats( unicap_handle_t handle,
- unicap_format_t *specifier,
- unicap_format_t *format,
- int index )
- {
- int current_index = -1;
- int tmp_index = 0;
- unicap_status_t status;
- if( !handle )
- {
- TRACE( "handle is NULLn" );
- return STATUS_INVALID_PARAMETER;
- }
- TRACE( "unicap_enumerate_formats, index: %dn", index );
- _unicap_acquire_cpi_lock( handle->sem_id );
- while( ( current_index != index ) &&
- ( ( status = handle->cpi.cpi_enumerate_formats( handle->cpi_data, format, tmp_index ) )
- == STATUS_SUCCESS ) )
- {
- if( _check_format_match( specifier, format ) )
- {
- current_index++;
- }
- tmp_index++;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_set_format( unicap_handle_t handle,
- unicap_format_t *format )
- {
- unicap_status_t status;
- if( !format )
- {
- return STATUS_INVALID_PARAMETER;
- }
- if( !strlen( format->identifier ) )
- {
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_set_format( handle->cpi_data, format );
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_get_format( unicap_handle_t handle,
- unicap_format_t *format )
- {
- unicap_status_t status;
- if( !format )
- {
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_get_format( handle->cpi_data, format );
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_reenumerate_properties( unicap_handle_t handle, int *_pcount )
- {
- unicap_status_t status;
- int count;
- status = handle->cpi.cpi_reenumerate_properties( handle->cpi_data, &count );
- if( _pcount )
- {
- *_pcount = count;
- }
- return status;
- }
- unicap_status_t unicap_enumerate_properties( unicap_handle_t handle, unicap_property_t *specifier, unicap_property_t *property, int index )
- {
- int current_index = -1;
- int tmp_index = 0;
- unicap_status_t status;
- if( !property || !handle || ( index < 0 ) )
- {
- return STATUS_INVALID_PARAMETER;
- }
- TRACE( "enumerate properties: %dn", index );
- _unicap_acquire_cpi_lock( handle->sem_id );
- while( ( current_index != index ) &&
- ( ( status = handle->cpi.cpi_enumerate_properties( handle->cpi_data, property, tmp_index ) ) == STATUS_SUCCESS ) )
- {
- TRACE( "%s <> %s: %dn", specifier->identifier, property->identifier, _check_property_match( specifier, property ) );
- if( _check_property_match( specifier, property ) )
- {
- current_index++;
- }
- tmp_index++;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_set_property( unicap_handle_t handle, unicap_property_t *property )
- {
- unicap_status_t status;
- if( !handle || ! property )
- {
- TRACE( "invalid paramn" );
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_set_property( handle->cpi_data, property );
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_get_property( unicap_handle_t handle, unicap_property_t *property )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( !handle || !property )
- {
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_get_property( handle->cpi_data, property );
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_start_capture( unicap_handle_t handle )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( !handle )
- {
- TRACE( "Invalid parametern" );
- return STATUS_INVALID_PARAMETER;
- }
- if( !handle->have_stream_lock )
- {
- status = unicap_lock_stream( handle );
- if( SUCCESS( status ) )
- {
- handle->temporary_stream_lock = 1;
- }
- }
- if( SUCCESS( status ) )
- {
- TRACE( "Capture start...n" );
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_capture_start( handle->cpi_data );
- _unicap_release_cpi_lock( handle->sem_id );
- }
- else
- {
- TRACE( "FAILED TO GET STREAM LOCKnnnnnn" );
- }
- return status;
- }
- unicap_status_t unicap_stop_capture( unicap_handle_t handle )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( !handle )
- {
- return STATUS_INVALID_PARAMETER;
- }
- if( !handle->have_stream_lock )
- {
- status = STATUS_PERMISSION_DENIED;
- }
- else
- {
- if( handle->temporary_stream_lock )
- {
- handle->temporary_stream_lock = 0;
- unicap_unlock_stream( handle );
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_capture_stop( handle->cpi_data );
- _unicap_release_cpi_lock( handle->sem_id );
- }
- return status;
- }
- unicap_status_t unicap_queue_buffer( unicap_handle_t handle, unicap_data_buffer_t *buffer )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( !handle || !buffer )
- {
- TRACE( "Invalid parametern" );
- return STATUS_INVALID_PARAMETER;
- }
- if( !handle->have_stream_lock )
- {
- status = STATUS_PERMISSION_DENIED;
- }
- else
- {
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_queue_buffer( handle->cpi_data, buffer );
- _unicap_release_cpi_lock( handle->sem_id );
- }
- return status;
- }
- unicap_status_t unicap_dequeue_buffer( unicap_handle_t handle, unicap_data_buffer_t **buffer )
- {
- unicap_status_t status;
- if( !handle || !buffer )
- {
- return STATUS_INVALID_PARAMETER;
- }
- if( !handle->have_stream_lock )
- {
- status = STATUS_PERMISSION_DENIED;
- }
- else
- {
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_dequeue_buffer( handle->cpi_data, buffer );
- _unicap_release_cpi_lock( handle->sem_id );
- }
- return status;
- }
- unicap_status_t unicap_wait_buffer( unicap_handle_t handle, unicap_data_buffer_t **buffer )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( !handle || !buffer )
- {
- TRACE( "!handle || !buffern" );
- return STATUS_INVALID_PARAMETER;
- }
- if( !handle->have_stream_lock )
- {
- status = STATUS_PERMISSION_DENIED;
- }
- else
- {
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_wait_buffer( handle->cpi_data, buffer );
- _unicap_release_cpi_lock( handle->sem_id );
- }
- return status;
- }
- unicap_status_t unicap_poll_buffer( unicap_handle_t handle, int *count )
- {
- unicap_status_t status = STATUS_SUCCESS;
- if( !handle || !count )
- {
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- status = handle->cpi.cpi_poll_buffer( handle->cpi_data, count );
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- static key_t uidtok( char *string )
- {
- int i;
- key_t key = 0x00345678;
- for( i = 0; string[i] != 0; i++ )
- {
- key = key ^ ( string[i] << ( i%3 ) );
- }
- return key;
- }
- int unicap_is_stream_locked( unicap_device_t *device )
- {
- key_t key;
- int sem_id;
- int val;
- #ifndef UNICAP_THREAD_LOCKING
- return 0;
- #endif
- key = uidtok( device->identifier );
- sem_id = semget( key, 1, S_IRWXU | S_IRWXG | S_IRWXO );
- if( sem_id == -1 )
- {
- return 0;
- }
- val = semctl( sem_id, 0, GETVAL );
- TRACE( "STREAM IS LOCKED >>>> %d (%d) key + %dn", val == 0, val, key );
- return val == 0;
- }
- unicap_status_t unicap_lock_stream( unicap_handle_t handle )
- {
- unicap_status_t status = STATUS_SUCCESS;
- key_t key;
- int sem_id;
- #ifndef UNICAP_THREAD_LOCKING
- handle->have_stream_lock = 1;
- return STATUS_SUCCESS;
- #endif
- key = uidtok( handle->device_uid );
- if( !handle->have_stream_lock )
- {
- struct semid_ds semds;
- union semun_linux semun;
- sem_id = semget( key, 1, IPC_CREAT | S_IRWXU | S_IRWXG | S_IRWXO);
- if( sem_id == -1 )
- {
- return STATUS_FAILURE;
- }
- // check if the semaphore is used the first time -> initialize it
- semun.buf = &semds;
- semds.sem_otime = 0;
- semctl( sem_id, 0, IPC_STAT, semun );
- if( semds.sem_otime == 0 )
- {
- struct sembuf sops;
- semun.val = 1;
- semctl( sem_id, 0, SETVAL, semun );
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = SEM_UNDO|IPC_NOWAIT;
- _unicap_acquire_cpi_lock( handle->sem_id );
- if( semop( sem_id, &sops, 1 ) < 0 )
- {
- status = STATUS_PERMISSION_DENIED;
- }
- else
- {
- handle->stream_sem_id = sem_id;
- handle->have_stream_lock = 1;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- }
- else
- {
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = SEM_UNDO|IPC_NOWAIT;
- _unicap_acquire_cpi_lock( handle->sem_id );
- if( semop( sem_id, &sops, 1 ) < 0 )
- {
- status = STATUS_PERMISSION_DENIED;
- }
- else
- {
- handle->stream_sem_id = sem_id;
- handle->have_stream_lock = 1;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- }
- }
- TRACE( "LOCK STREAM >>>> %d key = %dn", handle->have_stream_lock, key );
- return status;
- }
- unicap_status_t unicap_unlock_stream( unicap_handle_t handle )
- {
- unicap_status_t status = STATUS_SUCCESS;
- #ifndef UNICAP_THREAD_LOCKING
- handle->have_stream_lock = 0;
- return STATUS_SUCCESS;
- #endif
- if( handle->have_stream_lock )
- {
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = 1;
- sops.sem_flg = SEM_UNDO;
- if( semop( handle->stream_sem_id, &sops, 1 ) < 0 )
- {
- status = STATUS_FAILURE;
- }
- else
- {
- handle->have_stream_lock = 0;
- }
- }
- else
- {
- status = STATUS_PERMISSION_DENIED;
- }
- TRACE( "UNLOCK STREAM >>>> %dn", handle->have_stream_lock );
- return status;
- }
- unicap_status_t unicap_lock_properties( unicap_handle_t handle )
- {
- unicap_status_t status = STATUS_FAILURE;
- return status;
- }
- unicap_status_t unicap_unlock_properties( unicap_handle_t handle )
- {
- unicap_status_t status = STATUS_SUCCESS;
- return status;
- }
- unicap_status_t unicap_register_callback( unicap_handle_t handle,
- unicap_event_t event,
- unicap_callback_t func,
- void *user_ptr )
- {
- unicap_status_t status = STATUS_FAILURE;
- if( ( event < UNICAP_EVENT_FIRST ) ||
- ( event >= UNICAP_EVENT_LAST ) )
- {
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- if( handle->cb_info[event].func != NULL )
- {
- status = STATUS_FAILURE;
- }
- else
- {
- handle->cb_info[event].func = func;
- handle->cb_info[event].user_ptr = user_ptr;
- status = STATUS_SUCCESS;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }
- unicap_status_t unicap_unregister_callback( unicap_handle_t handle,
- unicap_event_t event,
- unicap_callback_t func,
- void *user_ptr )
- {
- unicap_status_t status = STATUS_FAILURE;
- if( ( event < UNICAP_EVENT_FIRST ) ||
- ( event >= UNICAP_EVENT_LAST ) )
- {
- return STATUS_INVALID_PARAMETER;
- }
- _unicap_acquire_cpi_lock( handle->sem_id );
- if( handle->cb_info[event].func == NULL )
- {
- status = STATUS_FAILURE;
- }
- else
- {
- handle->cb_info[event].func = NULL;
- handle->cb_info[event].user_ptr = NULL;
- status = STATUS_SUCCESS;
- }
- _unicap_release_cpi_lock( handle->sem_id );
- return status;
- }