From fb65e9ca59fbdf6a33c4bda16b70e6bfabf2ebf4 Mon Sep 17 00:00:00 2001 From: Jaromil Date: Wed, 8 Apr 2009 20:34:33 +0200 Subject: [PATCH] unicap layer enhancements also parameters implemented still wondering why the eeepc cam doesn't works it used to work... mmm... --- src/freej.cpp | 6 +- src/include/parameter.h | 1 + src/include/unicap_layer.h | 18 ++- src/parameter.cpp | 7 +- src/unicap_layer.cpp | 242 +++++++++++++++++++++++++++---------- 5 files changed, 202 insertions(+), 72 deletions(-) diff --git a/src/freej.cpp b/src/freej.cpp index 3e8e934e..bc636de8 100644 --- a/src/freej.cpp +++ b/src/freej.cpp @@ -346,10 +346,10 @@ int main (int argc, char **argv) { func("creating layer for file %s",pp); - lay = create_layer(freej, pp); // hey, this already init and open the layer !! + lay = freej->open(pp); // hey, this already init and open the layer !! if(lay) { - lay->start(); - freej->add_layer(lay); + freej.add_layer(lay); + lay->start(); lay->fps.set(fps); if (startstate) diff --git a/src/include/parameter.h b/src/include/parameter.h index eb1741e2..c337d463 100644 --- a/src/include/parameter.h +++ b/src/include/parameter.h @@ -65,6 +65,7 @@ class Parameter : public Entry { filter_param_f *filter_get_f; filter_param_f *filter_set_f; + bool changed; ///< can be used externally by application caller }; #endif diff --git a/src/include/unicap_layer.h b/src/include/unicap_layer.h index 78b848d4..964f40f6 100644 --- a/src/include/unicap_layer.h +++ b/src/include/unicap_layer.h @@ -26,6 +26,9 @@ #include +#define UNICAP_SYSTEM_CAPTURE 1 +#define UNICAP_USER_CAPTURE 2 + class UnicapLayer: public Layer { @@ -42,14 +45,25 @@ class UnicapLayer: public Layer { void *feed_ready; void *rgba[2]; int swap; + int detected; + + int capture_type; + + Linklist parameters; private: unicap_device_t m_device; - + unicap_device_t m_device_spec; + unicap_handle_t m_handle; - + unicap_data_buffer_t m_buffer; + + unicap_format_t m_format; + + unicap_property_t m_property; + unicap_property_t m_property_spec; }; #endif diff --git a/src/parameter.cpp b/src/parameter.cpp index c0104912..edbbe322 100644 --- a/src/parameter.cpp +++ b/src/parameter.cpp @@ -49,6 +49,8 @@ Parameter::Parameter(Parameter::Type param_type) error("parameter initialized with unknown type: %u", param_type); } + changed = false; + type = param_type; layer_set_f = NULL; @@ -65,13 +67,11 @@ bool Parameter::set(void *val) { //////////////////////////////////////// if(type == Parameter::NUMBER) { - func("set_parameter number"); *(float*)value = *(float*)val; ////////////////////////////////////// } else if(type == Parameter::BOOL) { - func("set_parameter bool"); *(bool*)value = *(bool*)val; // act("filter %s parameter %s set to: %e", name, param->name, (double*)value); @@ -97,7 +97,8 @@ bool Parameter::set(void *val) { error("attempt to set value for a parameter of unknown type: %u", type); return false; } - + + changed = true; return true; } diff --git a/src/unicap_layer.cpp b/src/unicap_layer.cpp index 4f28af56..d99a9f57 100644 --- a/src/unicap_layer.cpp +++ b/src/unicap_layer.cpp @@ -1,5 +1,5 @@ /* FreeJ - * (c) Copyright 2008 Denis Roio aka jaromil + * (c) Copyright 2008 - 2009 Denis Roio * * This source code is free software; you can redistribute it and/or * modify it under the terms of the GNU Public License as published @@ -30,21 +30,21 @@ UnicapLayer::UnicapLayer() :Layer() { - unicap_device_t device; - int i=0; - m_handle = NULL; - - notice("Unicap layer initialized, devices detected:"); - while( SUCCESS(unicap_enumerate_devices( NULL, &device, i++))) - act("%u - %s",i,device.identifier); - + m_handle = NULL; + m_buffer.data = NULL; + swap = 0; rgba[0] = NULL; rgba[1] = NULL; feed_ready = NULL; + set_name("CAM"); + + // change this to UNICAP_USER_CAPTURE + // to switch the way unicap captures.. + capture_type = UNICAP_SYSTEM_CAPTURE; } UnicapLayer::~UnicapLayer() { @@ -70,6 +70,7 @@ static void new_frame_yuyv_cb (unicap_event_t event, unicap_handle_t handle, unicap_data_buffer_t * buffer, void *usr_data) { UnicapLayer *lay = (UnicapLayer*)usr_data; + func("cam callback"); ccvt_yuyv_bgr32(lay->geo.w, lay->geo.h, buffer->data, lay->rgba[lay->swap]); lay->feed_ready = lay->rgba[lay->swap]; @@ -81,30 +82,39 @@ bool UnicapLayer::open(const char *devfile) { bool res = false; int i = 0; int fourcc, bpp; - unicap_device_t device; - unicap_format_t format, format_spec; + + unicap_format_t format_spec; + Parameter *p; + + if(!detected) { + error("no video devices found"); + return(false); + } - while( unicap_enumerate_devices( NULL, &device, i++) + while( unicap_enumerate_devices( &m_device_spec, &m_device, i++) == STATUS_SUCCESS) { - if(strcmp(devfile,device.device)==0) { // found + func("checking device match \"%s\" == \"%s\"", m_device.device, devfile); - m_device = device; + if(strcasecmp(devfile,m_device.device)==0) { // found if( unicap_open(&m_handle, &m_device ) == STATUS_SUCCESS ) { res = true; break; + } else { + error("error opening device %s", m_device.identifier); + return(false); } - - } + + } else continue; } if(!res) { - error("Unicap device %s is not found", m_device.identifier); - return(false); + error("Unicap device %s is not found", devfile); + return(false); } - + notice("Unicap device opened: %s",m_device.identifier); act("available video formats:"); @@ -112,17 +122,20 @@ bool UnicapLayer::open(const char *devfile) { i=0; fourcc=0; - while(SUCCESS(unicap_enumerate_formats( m_handle, &format_spec, &format, i++))) { - act("%u - %s - 0x%x - %u bpp",i, format.identifier, format.fourcc, format.bpp); - switch(format.fourcc) { + while(SUCCESS(unicap_enumerate_formats( m_handle, &format_spec, &m_format, i++))) { + act("%u - %s - 0x%x - %u bpp",i, m_format.identifier, m_format.fourcc, m_format.bpp); + switch(m_format.fourcc) { case 0x33524742: // BGR24 - fourcc = format.fourcc; + fourcc = m_format.fourcc; bpp = 24; - unicap_register_callback (m_handle, - UNICAP_EVENT_NEW_FRAME, - (unicap_callback_t) new_frame_bgr24_cb, - (void*)this); + if(capture_type==UNICAP_SYSTEM_CAPTURE) { + unicap_register_callback (m_handle, + UNICAP_EVENT_NEW_FRAME, + (unicap_callback_t) new_frame_bgr24_cb, + (void*)this); + func("registered conversion callback BGR24"); + } break; /* @@ -137,26 +150,28 @@ bool UnicapLayer::open(const char *devfile) { case 0x56595559: // YUYV and equivalents case 0x32595559: - if(!fourcc) { - fourcc = format.fourcc; + fourcc = m_format.fourcc; + if(capture_type==UNICAP_SYSTEM_CAPTURE) { unicap_register_callback (m_handle, UNICAP_EVENT_NEW_FRAME, (unicap_callback_t) new_frame_yuyv_cb, (void*)this); + func("registered conversion callback YUYV"); } break; case 0x30323449: case 0x56555949: - if(!fourcc) { - fourcc = format.fourcc; + fourcc = m_format.fourcc; + if(capture_type==UNICAP_SYSTEM_CAPTURE) { unicap_register_callback (m_handle, UNICAP_EVENT_NEW_FRAME, (unicap_callback_t) new_frame_yuyv_cb, (void*)this); + func("registered conversion callback YUYV"); } break; - + default: break; } @@ -167,50 +182,111 @@ bool UnicapLayer::open(const char *devfile) { fourcc = 0x56595559; } - if( ! SUCCESS( unicap_get_format (m_handle, &format) )) + if( ! SUCCESS( unicap_get_format (m_handle, &m_format) )) error("format get failed on capture device"); // list sizes - act("%u supported sizes:", format.size_count); + act("%u supported sizes:", m_format.size_count); act("min %ux%u - max %ux%u - stepping %ux%u", - format.min_size.width, format.min_size.height, - format.max_size.width, format.max_size.height, - format.h_stepping, format.v_stepping); - for(i=0; i RGBA transform + rgba[0] = jalloc(m_format.size.width * m_format.size.height * 4); +// rgba[1] = jalloc(format.size.width * format.size.height * 4); +// feed_ready = rgba[0]; + // properties + // Initialize a property specifier structure + unicap_void_property( &m_property_spec ); + + i=0; + while(SUCCESS(unicap_enumerate_properties( m_handle, &m_property_spec, &m_property, i++))) { + + char tmp[512]; + + unicap_get_property(m_handle, &m_property); + + sprintf(tmp,"%i - %s", i, m_property.identifier); + switch( m_property.type ) { + case UNICAP_PROPERTY_TYPE_RANGE: + case UNICAP_PROPERTY_TYPE_VALUE_LIST: + sprintf(tmp,"%s = %.2f", tmp, m_property.value ); + p = new Parameter(Parameter::NUMBER); + p->set_name(m_property.identifier); + p->description = " "; + p->set((void*)&m_property.value); + parameters.append(p); + break; + + case UNICAP_PROPERTY_TYPE_MENU: + sprintf(tmp,"%s = %s", tmp, m_property.menu_item ); + break; + case UNICAP_PROPERTY_TYPE_FLAGS: + { + sprintf(tmp,"%s =",tmp); + unsigned int j; + const char *flags[] = + { "MANUAL", "AUTO", "ONE_PUSH", "READ_OUT", + "ON_OFF", "READ_ONLY", "FORMAT_CHANGE" }; + for( j = 0; j < ( sizeof( flags ) / sizeof( char* ) ); j++ ) { + if( ( (unsigned int)m_property.flags & ( 1<changed) + unicap_set_property_value( m_handle, p->name, *(double*)p->value); + p->changed = false; + p = (Parameter*)p->next; + } + + if(capture_type==UNICAP_USER_CAPTURE) { + unicap_data_buffer_t *res; + unicap_wait_buffer(m_handle,&res); + ccvt_yuyv_bgr32(geo.w, geo.h, res->data, rgba[0]); + unicap_queue_buffer(m_handle,res); + } + return rgba[0]; } @@ -238,16 +349,19 @@ void UnicapLayer::close() { if(unicap_is_stream_locked(&m_device)) unicap_unlock_stream(m_handle); - status = unicap_stop_capture(m_handle); - if( ! SUCCESS( status ) ) { - error("unicap reports error in stop_capture: 0x%x", status); - unicap_stop_capture(m_handle); + if(m_handle) { + status = unicap_stop_capture(m_handle); + if( ! SUCCESS( status ) ) { + error("unicap reports error in stop_capture: 0x%x", status); + unicap_stop_capture(m_handle); + } + unicap_close(m_handle); } - - unicap_close(m_handle); - jfree(rgba[0]); - jfree(rgba[1]); + if(m_buffer.data) jfree(m_buffer.data); + + if(rgba[0]) jfree(rgba[0]); +// if(rgba[1]) jfree(rgba[1]); opened = false; }