mirror of
https://github.com/dyne/FreeJ.git
synced 2026-06-16 12:59:33 +02:00
unicap layer enhancements
also parameters implemented still wondering why the eeepc cam doesn't works it used to work... mmm...
This commit is contained in:
+3
-3
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
#include <context.h>
|
||||
|
||||
#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<Parameter> 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
|
||||
|
||||
+4
-3
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+178
-64
@@ -1,5 +1,5 @@
|
||||
/* FreeJ
|
||||
* (c) Copyright 2008 Denis Roio aka jaromil <jaromil@dyne.org>
|
||||
* (c) Copyright 2008 - 2009 Denis Roio <jaromil@dyne.org>
|
||||
*
|
||||
* 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<format.size_count; i++)
|
||||
m_format.min_size.width, m_format.min_size.height,
|
||||
m_format.max_size.width, m_format.max_size.height,
|
||||
m_format.h_stepping, m_format.v_stepping);
|
||||
for(i=0; i<m_format.size_count; i++)
|
||||
act("%u - %u x %u", i,
|
||||
format.sizes[i].width, format.sizes[i].height);
|
||||
m_format.sizes[i].width, m_format.sizes[i].height);
|
||||
|
||||
// TODO: choose closest available size
|
||||
format.size.width = geo.w;
|
||||
format.size.height = geo.h;
|
||||
|
||||
format.buffer_type = UNICAP_BUFFER_TYPE_SYSTEM;
|
||||
format.fourcc = fourcc;
|
||||
format.bpp = bpp;
|
||||
m_format.size.width = geo.w;
|
||||
m_format.size.height = geo.h;
|
||||
|
||||
act("initializing at %ux%u bpp:%u fourcc:0x%x",
|
||||
format.size.width, format.size.height,
|
||||
format.bpp, format.fourcc);
|
||||
if(capture_type==UNICAP_SYSTEM_CAPTURE) {
|
||||
m_format.buffer_type = UNICAP_BUFFER_TYPE_SYSTEM;
|
||||
} else {
|
||||
m_format.buffer_type = UNICAP_BUFFER_TYPE_USER;
|
||||
}
|
||||
|
||||
if( ! SUCCESS( unicap_set_format(m_handle, &format) )) {
|
||||
m_format.fourcc = fourcc;
|
||||
m_format.bpp = bpp;
|
||||
|
||||
|
||||
act("initializing at %ux%u bpp:%u fourcc:0x%x",
|
||||
m_format.size.width, m_format.size.height,
|
||||
m_format.bpp, m_format.fourcc);
|
||||
|
||||
if( ! SUCCESS( unicap_set_format(m_handle, &m_format) )) {
|
||||
error("format setting failed on capture device");
|
||||
error("maybe the size is not supported by this camera");
|
||||
error("else report your model and format strings");
|
||||
// unicap_close(m_handle);
|
||||
// return(false);
|
||||
return(false);
|
||||
}
|
||||
|
||||
// allocate first yuv buffer for grabbing
|
||||
m_buffer.data = (unsigned char*)jalloc(m_format.buffer_size);
|
||||
m_buffer.buffer_size = m_format.buffer_size;
|
||||
|
||||
rgba[0] = jalloc(format.size.width * format.size.height * 4);
|
||||
rgba[1] = jalloc(format.size.width * format.size.height * 4);
|
||||
feed_ready = rgba[1];
|
||||
// allocate 32bit buffer for YUV -> 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<<j ) ) == ( 1<<j ) ) {
|
||||
sprintf("%s %s",tmp, (char*)flags[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
act("%s",tmp);
|
||||
}
|
||||
act("%u capture device properties found", i-1);
|
||||
|
||||
if( ! SUCCESS( unicap_start_capture( m_handle ) ))
|
||||
error("start capture failed on capture device");
|
||||
else func("capture started for CAM layer");
|
||||
|
||||
set_name(m_device.device);
|
||||
if(capture_type==UNICAP_USER_CAPTURE) {
|
||||
unicap_queue_buffer(m_handle, & m_buffer);
|
||||
}
|
||||
|
||||
// set_name(m_device.device);
|
||||
opened = true;
|
||||
return(res);
|
||||
}
|
||||
@@ -220,13 +296,48 @@ bool UnicapLayer::init(Context *freej) {
|
||||
}
|
||||
|
||||
bool UnicapLayer::init(Context *freej, int width, int height) {
|
||||
func("%s %ux%u",__PRETTY_FUNCTION__,width, height);
|
||||
|
||||
notice("Unicap layer initialized, devices detected:");
|
||||
|
||||
unicap_void_device( &m_device_spec );
|
||||
|
||||
detected = 0;
|
||||
while( SUCCESS(unicap_enumerate_devices( &m_device_spec, &m_device, detected))) {
|
||||
act("%u - %s",detected,m_device.identifier);
|
||||
detected++;
|
||||
}
|
||||
|
||||
|
||||
_init(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void *UnicapLayer::feed() {
|
||||
return feed_ready;
|
||||
Parameter *p;
|
||||
if(!opened) {
|
||||
error("%s : no device opened");
|
||||
return(NULL);
|
||||
}
|
||||
// func("%s",__PRETTY_FUNCTION__);
|
||||
|
||||
// update parameters that changed
|
||||
p = parameters.begin();
|
||||
while(p) {
|
||||
if(p->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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user