adding automatic format detection, fixing control display. Adding rudimentary support for controls to SVBONY driver

test16bit
Steffen Pohle 3 years ago
parent 27d0d9bbe7
commit c635975500

@ -1,3 +1,8 @@
2022-10-30:
- fixing many bugs check change log.
controls are back working, automatic format detection.
adding alot FIXMEs to the code.
2021-11-17:
- adding basic support for SBVcams like SV-305

@ -7,10 +7,12 @@ APP = simpleskycam
OBJECTS := $(OBJECTS) gui.oo main.oo video.oo videoframe.oo videodev.oo videodev-v4l2.oo convert.oo filter.oo detect.oo json.oo configuration.oo
DISTNAME=simpleskycam-$(VERSION)
ifeq ($(TARGET),)
noconfig: help
noconfig: configlinux help
endif
all: Makefile.rules $(TARGET)
help:
@ -34,6 +36,7 @@ config: Makefile.rules
echo "#define _CONFIG_H_" >> config.h
echo "" >> config.h
echo "#define VERSION \"$(VERSION)\"" >> config.h
echo "#define USE_SVBONY" >> config.h
echo "" >> config.h
echo "#endif" >> config.h
@ -53,6 +56,8 @@ clean:
rm -rf *.dll
rm -rf *.exe
rm -rf Makefile.rules
rm -rf U2SM200C-AST_Cfg_A.bin
rm -rf U2SM200C-AST_Cfg_SAVE.bin
dist: clean
rm -rf $(DISTNAME)

@ -12,9 +12,9 @@ OBJECTS =
#
# Uncomment to enable support for SVBONY Cammeras.
#
# CPPFLAGS := $(CPPFLAGS) -DUSE_SVBONY -I/usr/local/include
# LDFLAGS := $(LDFLAGS) -lSVBCameraSDK -L/usr/local/lib
# OBJECTS := $(OBJECTS) videodev-svbcam.oo
CPPFLAGS := $(CPPFLAGS) -I/usr/local/include
LDFLAGS := $(LDFLAGS) -lSVBCameraSDK -L/usr/local/lib
OBJECTS := $(OBJECTS) videodev-svbcam.oo
#

@ -143,7 +143,6 @@ void Configuration::LoadConfig(std::string filename) {
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videodev"));
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
gtk_entry_set_text(GTK_ENTRY(cbdevice), vstr.c_str());
cb_video_btnrec (NULL, NULL);
}
//

@ -4,6 +4,17 @@
#include "gui.h"
#include "video.h"
uint32_t convert_pixelformats [] = {
V4L2_PIX_FMT_MJPEG,
V4L2_PIX_FMT_YUYV,
V4L2_PIX_FMT_RGB32,
V4L2_PIX_FMT_RGB24,
V4L2_PIX_FMT_BGR32,
V4L2_PIX_FMT_UYVY,
0
};
/*
* helper part for converting different video types
@ -243,6 +254,8 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
break;
default:
printf ("%s:%d Error no default possible, need to finish\n", __FILE__, __LINE__);
exit (-1);
break;
}
@ -251,3 +264,21 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
std::string convert_from_pixelformat (uint32_t fmt) {
char txt[5];
snprintf (txt, 5, "%c%c%c%c", ((char*)&fmt)[0], ((char*)&fmt)[1], ((char*)&fmt)[2], ((char*)&fmt)[3]);
return txt;
};
uint32_t convert_to_pixelformat(std::string s) {
uint32_t u = 0;
u = ((unsigned char) s[0]) + ((unsigned char) s[1] << 8) +
((unsigned char) s[2] << 16) + ((unsigned char) s[3] << 24);
return u;
};

@ -21,4 +21,9 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr
int ConvertStart(ConvertData *cdata, uint32_t pixelformat);
int ConvertStop(ConvertData *cdata, uint32_t pixelformat);
extern uint32_t convert_pixelformats[];
std::string convert_from_pixelformat (uint32_t fmt);
uint32_t convert_to_pixelformat(std::string s);
#endif

@ -57,6 +57,8 @@ G_MODULE_EXPORT gboolean cb_window_delete_event (GtkWidget *widget,
//
// video and video devices
G_MODULE_EXPORT void cb_video_cbox_videodev (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_video_btnrefreshlist (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_video_btnrec (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_video_btnstop (GtkWidget *widget, gpointer data);
@ -69,6 +71,7 @@ G_MODULE_EXPORT void cb_vidctrl_entry_change (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_vidctrl_scale_change (GtkRange *range, gpointer data);
gboolean videoctrl_update(gpointer data);
// preset buttons
G_MODULE_EXPORT void cb_video_pre_click (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_video_pre_pressed (GtkWidget *widget, gpointer data);
gboolean video_pre_long(gpointer data);

@ -11,6 +11,7 @@
#include "gui.h"
#include "filter.h"
#include "detect.h"
#include "convert.h"
/**************************************************************************
* global variables

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.18"/>
<object class="GtkAdjustment" id="detect-pos-adjbright">
@ -82,6 +82,7 @@
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="has-entry">True</property>
<signal name="changed" handler="cb_video_cbox_videodev" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can-focus">False</property>

@ -34,6 +34,49 @@ extern position_2d video_enterdata_pos;
extern detect_movement detectedpos_data;
extern Configuration config;
/*
* stop video recording
*/
void video_stoprecord() {
GtkWidget *btnstart = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-rec"));
GtkWidget *btnstop = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-stop"));
if (videodev == NULL) return;
videodev->Stop();
gtk_widget_set_sensitive(btnstart, true);
gtk_widget_set_sensitive(btnstop, false);
if (videodev_thread != NULL) g_thread_join (videodev_thread);
videodev_thread = NULL;
delete videodev;
videodev = NULL;
}
/*
* return selected driver and device from GUI
*/
void video_get_driverdevice(std::string *driver, std::string *device) {
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videodev"));
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
if (driver == NULL || device == NULL) return;
// read values from GUI elements, and start videodev with the correct driver
int i;
*device = gtk_entry_get_text(GTK_ENTRY(cbdevice));
i = device->find(' ');
*driver = device->substr (0, i);
*device = device->substr (i+1, std::string::npos);
*device = device->substr (0, device->find(' '));
}
gboolean videoctrl_update(gpointer data) {
GtkWidget *grid = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vidctrl-grid"));
GtkWidget *scale = NULL;
@ -242,6 +285,7 @@ void cb_videoda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data)
// fixme: refresh format list.
/*
* refresh the possible devices
*/
@ -291,43 +335,25 @@ gpointer videodev_threadprocess_wrapper (gpointer data) {
* with all elements. Also connect the signals to the callback functions.
*/
void cb_video_btnrec (GtkWidget *widget, gpointer data) {
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videodev"));
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
GtkWidget *cbres = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videores"));
GtkWidget *cbresentry = gtk_bin_get_child(GTK_BIN(cbres));
GtkWidget *cbfmt = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videofmt"));
GtkWidget *cbfmtentry = gtk_bin_get_child(GTK_BIN(cbfmt));
GtkWidget *btnstart = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-rec"));
GtkWidget *btnstop = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-stop"));
int i, w, h;
int w, h;
//
// read values from GUI elements, and start videodev with the correct driver
std::string device = gtk_entry_get_text(GTK_ENTRY(cbdevice));
std::string driver;
// get device and driver information
std::string device, driver;
std::string parameter;
video_get_driverdevice(&driver, &device);
i = device.find(' ');
driver = device.substr (0, i);
device = device.substr (i+1, std::string::npos);
device = device.substr (0, device.find(' '));
if (videodev != NULL) {
//
// before we can delete this object we must stop the thread.
//
videodev->Stop();
if (videodev_thread != NULL) g_thread_join (videodev_thread);
videodev_thread = NULL;
delete videodev;
videodev = NULL;
}
// stop recording
video_stoprecord();
//
// load the selected driver
if (driver.compare("V4L2") == 0) videodev = new VideoDev_V4L2;
#ifdef USE_SVBONY
else if (driver.compare("SVBCAM") == 0) videodev = new VideoDev_SVBCam;
#endif
@ -431,21 +457,8 @@ void video_refreshctrls () {
* we need to wait for the thread to complete and then we can delete this object.
*/
void cb_video_btnstop (GtkWidget *widget, gpointer data) {
GtkWidget *btnstart = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-rec"));
GtkWidget *btnstop = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-stop"));
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
if (videodev == NULL) return;
videodev->Stop();
gtk_widget_set_sensitive(btnstart, true);
gtk_widget_set_sensitive(btnstop, false);
if (videodev_thread != NULL) g_thread_join (videodev_thread);
videodev_thread = NULL;
delete videodev;
videodev = NULL;
video_stoprecord();
};
@ -459,9 +472,14 @@ gboolean cb_thread_video (gpointer data) {
VideoDevThreadData *cbdata = (VideoDevThreadData*) data;
VideoFrame *vf = NULL;
// printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
if (cbdata != NULL) {
vf = &cbdata->vf;
if (cbdata->running == 1) video_refreshctrls();
if (cbdata->running == 1) {
video_refreshctrls();
cbdata->running = 2;
}
if (vf->w <= 0 || vf->h <= 0 || vf->data == NULL) vf = NULL;
}
if (videodev == NULL) return false;
@ -616,6 +634,7 @@ struct {
struct timeval tv;
guint timer;
} presetbtn;
void cb_video_pre_click (GtkWidget *widget, gpointer data) {
float pushtime = get_cycletime(&presetbtn.tv);
std::string s;
@ -702,3 +721,63 @@ gboolean video_pre_long(gpointer data) {
};
/*
* videodevice changed
*/
void cb_video_cbox_videodev (GtkWidget *widget, gpointer data) {
// GtkWidget *cbres = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videores"));
// GtkWidget *cbresentry = gtk_bin_get_child(GTK_BIN(cbres));
GtkWidget *cbfmt = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videofmt"));
GtkWidget *cbfmtentry = gtk_bin_get_child(GTK_BIN(cbfmt));
GtkListStore *model;
std::list<string> lst_format;
std::list<string> lst_resolution;
std::list<string>::iterator iter;
std::string device, driver;
std::string parameter;
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
video_stoprecord();
//
// open device
video_get_driverdevice(&driver, &device);
//
// load the selected driver
if (driver.compare("V4L2") == 0) videodev = new VideoDev_V4L2;
#ifdef USE_SVBONY
else if (driver.compare("SVBCAM") == 0) videodev = new VideoDev_SVBCam;
#endif
else if (driver.compare("DUMMY") == 0) videodev = new VideoDev;
else videodev = new VideoDev;
videodev->GetDeviceFormats(device, &lst_format);
model = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(cbfmt)));
gtk_list_store_clear(GTK_LIST_STORE(model));
gtk_entry_set_text (GTK_ENTRY(cbfmtentry), "");
for (iter = lst_format.begin(); iter != lst_format.end(); iter++) {
gtk_list_store_insert_with_values(GTK_LIST_STORE(model), NULL, -1,
0, iter->c_str(),
-1);
}
videodev->GetDeviceResolutions(device, &lst_format);
//
// get resolution
//
// get controls
//
// close device
delete videodev;
videodev = NULL;
};

@ -49,6 +49,8 @@ public:
VideoDev_Dummy();
~VideoDev_Dummy();
int GetDeviceList(std::list<std::string> *list);
int GetDeviceFormats(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
};
#endif

@ -4,6 +4,8 @@
* SUBSYSTEMS=="usb", ATTRS{idVendor}=="f266", ATTRS{idProduct}=="9a0a", GROUP="plugdev", MODE="0660"
*/
#include "config.h"
#ifdef USE_SVBONY
#include <stdlib.h>
@ -56,7 +58,6 @@ void VideoDev_SVBCam::print_error(int err) {
printf ("unknown %d\n", err);
break;
}
exit (0);
};
@ -113,7 +114,7 @@ int VideoDev_SVBCam::Open() {
}
printf ("%s:%d %s height: %ld width: %ld\n", __FILE__, __LINE__, __FUNCTION__, camprop.MaxHeight, camprop.MaxWidth);
for(int i=0; i < 8 && camprop.SupportedVideoFormat[i] == SVB_IMG_END; i++) {
for(int i=0; i < 8 && camprop.SupportedVideoFormat[i] != SVB_IMG_END; i++) {
printf ("%s:%d %s VideoFormat Index:%d ", __FILE__, __LINE__, __FUNCTION__, i);
switch (camprop.SupportedVideoFormat[i]) {
case SVB_IMG_RAW8:
@ -172,8 +173,8 @@ int VideoDev_SVBCam::Open() {
print_error(err);
return VDEV_STATUS_ERROR;
}
printf ("%s:%d %s Got Control idx: %d name:%s desc:%s\n", __FILE__, __LINE__, __FUNCTION__,
i, camcontrols[i].Name, camcontrols[i].Description);
printf ("%s:%d %s Got Control idx: %d name:%s desc:%s [%ld - %ld]\n", __FILE__, __LINE__, __FUNCTION__,
i, camcontrols[i].Name, camcontrols[i].Description, (long)camcontrols[i].MinValue, (long)camcontrols[i].MaxValue);
vctl.name = (char*)camcontrols[i].Name;
vctl.id = i;
vctl.min = camcontrols[i].MinValue;
@ -194,11 +195,30 @@ int VideoDev_SVBCam::Open() {
print_error(err);
return VDEV_STATUS_ERROR;
}
if ((err = SVBSetOutputImageType(camid, SVB_IMG_RGB24)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
switch (convert_to_pixelformat(conf_format)) {
case (V4L2_PIX_FMT_RGB32):
if ((err = SVBSetOutputImageType(camid, SVB_IMG_RGB32)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
break;
case (V4L2_PIX_FMT_RGB24):
if ((err = SVBSetOutputImageType(camid, SVB_IMG_RGB24)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
break;
default:
conf_format = convert_from_pixelformat(V4L2_PIX_FMT_RGB24);
if ((err = SVBSetOutputImageType(camid, SVB_IMG_RGB24)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
break;
}
//
// preprare buffer
LockMutex();
@ -266,6 +286,7 @@ int VideoDev_SVBCam::CaptureStop() {
* If something goes wrong return an error code.
* Return code VDEV_STATUS_AGAIN is not an error. There was no video image ready to read.
*/
// FIXME: SVBGetVideoData needs to be outside of Lock/UnLockMutex - using inside thread inbuffer
int VideoDev_SVBCam::Grab(VideoFrame *vf) {
int err;
@ -283,6 +304,96 @@ int VideoDev_SVBCam::Grab(VideoFrame *vf) {
}
int VideoDev_SVBCam::GetDeviceFormats(string device, std::list<string> *formats) {
int camid_;
std::string result = "";
int err;
SVB_CAMERA_PROPERTY camprop;
VideoDevCtrl vctl;
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
LockMutex();
if (camid == -1) {
camid_ = atoi (device.c_str());
printf ("%s:%d %s opening cam %d\n", __FILE__, __LINE__, __FUNCTION__, camid_);
if ((err = SVBOpenCamera(camid_)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
}
else camid_ = camid;
//
// get cam property
if ((err = SVBGetCameraProperty(camid_, &camprop)) != SVB_SUCCESS) {
print_error(err);
Close();
return VDEV_STATUS_ERROR;
}
printf ("%s:%d %s height: %ld width: %ld\n", __FILE__, __LINE__, __FUNCTION__, camprop.MaxHeight, camprop.MaxWidth);
for(int i=0; i < 8 && camprop.SupportedVideoFormat[i] != SVB_IMG_END; i++) {
printf ("%s:%d %s VideoFormat Index:%d ", __FILE__, __LINE__, __FUNCTION__, i);
switch (camprop.SupportedVideoFormat[i]) {
case SVB_IMG_RAW8:
printf("\t\tSVB_IMG_RAW8\n");
break;
case SVB_IMG_RAW10:
printf("\t\tSVB_IMG_RAW10\n");
break;
case SVB_IMG_RAW12:
printf("\t\tSVB_IMG_RAW12\n");
break;
case SVB_IMG_RAW14:
printf("\t\tSVB_IMG_RAW14\n");
break;
case SVB_IMG_RAW16:
printf("\t\tSVB_IMG_RAW16\n");
break;
case SVB_IMG_Y8:
printf("\t\tSVB_IMG_Y8\n");
break;
case SVB_IMG_Y10:
printf("\t\tSVB_IMG_Y10\n");
break;
case SVB_IMG_Y12:
printf("\t\tSVB_IMG_Y12\n");
break;
case SVB_IMG_Y14:
printf("\t\tSVB_IMG_Y14\n");
break;
case SVB_IMG_Y16:
printf("\t\tSVB_IMG_Y16\n");
break;
case SVB_IMG_RGB24:
printf("\t\tSVB_IMG_RGB24\n");
formats->push_back(convert_from_pixelformat(V4L2_PIX_FMT_RGB24));
break;
case SVB_IMG_RGB32:
printf("\t\tSVB_IMG_RGB32\n");
formats->push_back(convert_from_pixelformat(V4L2_PIX_FMT_RGB32));
break;
case SVB_IMG_END:
printf("\t\tSVB_IMG_END\n");
break;
default:
printf ("\t\tunbekannt\n");
break;
}
}
if (camid == -1) {
if ((err = SVBCloseCamera(camid_)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
}
UnLockMutex();
return VDEV_STATUS_OK;
}
@ -294,6 +405,23 @@ int VideoDev_SVBCam::Grab(VideoFrame *vf) {
* set video control identified by id
*/
int VideoDev_SVBCam::SetDevCtrl(unsigned int id, int value) {
int err;
int oldv;
if (value < 0) { // enable auto
GetDevCtrl (id, &oldv);
if ((err = SVBSetControlValue(camid, static_cast<SVB_CONTROL_TYPE>(id), oldv, SVB_TRUE)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
}
else {
if ((err = SVBSetControlValue(camid, static_cast<SVB_CONTROL_TYPE>(id), value, SVB_FALSE)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
}
return VDEV_STATUS_OK;
};
@ -302,7 +430,15 @@ int VideoDev_SVBCam::SetDevCtrl(unsigned int id, int value) {
* get video control identified by id
*/
int VideoDev_SVBCam::GetDevCtrl(unsigned int id, int *value) {
*value = 0;
int err;
long pvalue;
SVB_BOOL ctlauto;
if ((err = SVBGetControlValue(camid, static_cast<SVB_CONTROL_TYPE>(id), &pvalue, &ctlauto)) != SVB_SUCCESS) {
print_error(err);
return VDEV_STATUS_ERROR;
}
*value = (int) pvalue;
return VDEV_STATUS_OK;
};

@ -47,6 +47,8 @@ public:
VideoDev_SVBCam();
~VideoDev_SVBCam();
int GetDeviceList(std::list<std::string> *list);
int GetDeviceFormats(string device, std::list<string> *formats);
int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
};
#endif

@ -108,10 +108,10 @@ void VideoDev_V4L2::PrintFmt(struct v4l2_format *f) {
printf (" type : %u\n", f->type);
printf (" fmt.pix.width : %d\n", f->fmt.pix.width);
printf (" fmt.pix.height : %d\n", f->fmt.pix.height);
printf (" fmt.fmt.pix.pixelformat : %c%c%c%c\n", ((char*)&fmt.fmt.pix.pixelformat)[0],
((char*)&fmt.fmt.pix.pixelformat)[1],
((char*)&fmt.fmt.pix.pixelformat)[2],
((char*)&fmt.fmt.pix.pixelformat)[3]);
printf (" fmt.fmt.pix.pixelformat : %c%c%c%c\n", ((char*)&f->fmt.pix.pixelformat)[0],
((char*)&f->fmt.pix.pixelformat)[1],
((char*)&f->fmt.pix.pixelformat)[2],
((char*)&f->fmt.pix.pixelformat)[3]);
printf (" fmt.pix.field : %d\n", f->fmt.pix.field);
printf (" fmt.pix.bytesperline : %d\n", f->fmt.pix.bytesperline);
printf (" fmt.pix.sizeimage : %d\n", f->fmt.pix.sizeimage);
@ -199,16 +199,8 @@ int VideoDev_V4L2::Open() {
fmt.fmt.pix.height = 1080;
}
if (conf_format.length() > 0) { // pixelformat
if (conf_format.compare("MJPG") == 0) fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
else if (conf_format.compare("YUYV") == 0) fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
else if (conf_format.compare("RGB4") == 0) fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
else fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
}
else {
// fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
}
// fixme: hardcoded video format?????
fmt.fmt.pix.pixelformat = convert_to_pixelformat(conf_format);
fmt.fmt.pix.field = V4L2_FIELD_NONE;
if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) {
fprintf (stderr, "%s:%d VIDIOC_S_FMT : %s\n", __FILE__, __LINE__, strerror (errno));
@ -500,6 +492,47 @@ int VideoDev_V4L2::Grab(VideoFrame *vf) {
}
int VideoDev_V4L2::GetDeviceFormats(string device, std::list<string> *formats) {
int i, fd_;
struct v4l2_format format = {0};
std::string result = "";
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
LockMutex();
if (fd == -1){
//
// open device and get device name and capabilities | O_NONBLOCK
if((fd_ = open(device.c_str(), O_RDWR)) == -1) {
printf ("%s could not open device %s: %s\n", __FUNCTION__, device.c_str(), strerror(errno));
return VDEV_STATUS_ERROR;
}
}
else fd_ = fd;
for(i = 0; convert_pixelformats[i] != 0; i++){
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = -1;
format.fmt.pix.height = -1;
format.fmt.pix.pixelformat = convert_pixelformats[i];
if(xioctl(fd_, VIDIOC_S_FMT, &format) != -1) {
if (format.fmt.pix.pixelformat == convert_pixelformats[i]) {
formats->push_back(convert_from_pixelformat(format.fmt.pix.pixelformat));
}
}
else {
printf ("error: %s\n", strerror(errno));
}
}
if (fd == -1) {
close (fd_);
}
UnLockMutex();
return VDEV_STATUS_OK;
}

@ -66,6 +66,8 @@ public:
VideoDev_V4L2();
~VideoDev_V4L2();
int GetDeviceList(std::list<std::string> *list);
int GetDeviceFormats(string device, std::list<string> *formats);
int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
};
#endif

@ -163,9 +163,11 @@ void VideoDev::ThreadProcess() {
Close();
running = 0;
}
threaddata.running = 1;
threaddata.running = 1; // prevent reading all controlls every time.
// will be set to 2 in callback function
if (callback) gdk_threads_add_idle(callback, &threaddata);
threaddata.running = 2;
// threaddata.running = 2;
while (running) {
i = Grab(&threaddata.vf);

@ -16,6 +16,7 @@
#include "video.h"
#include "videoframe.h"
enum {
VDEV_STATUS_UNKNOWN,
VDEV_STATUS_OK,
@ -141,6 +142,8 @@ public:
/* fills the list with all found device */
virtual int GetDeviceList(std::list<std::string> *list) { return VDEV_STATUS_OK; };
virtual int GetDeviceFormats(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
virtual int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
int GetCtrlList(std::list<std::string> *list);

Loading…
Cancel
Save