|
|
|
@ -6,6 +6,7 @@
|
|
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "gui.h"
|
|
|
|
|
#include "video.h"
|
|
|
|
|
|
|
|
|
@ -15,6 +16,30 @@ GdkPixbuf *video_pixbuf = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gboolean videoctrl_update(gpointer data) {
|
|
|
|
|
GtkWidget *grid = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vidctrl-grid"));
|
|
|
|
|
GtkWidget *scale = NULL;
|
|
|
|
|
GtkWidget *entry = NULL;
|
|
|
|
|
GtkWidget *label = NULL;
|
|
|
|
|
|
|
|
|
|
int value;
|
|
|
|
|
int min;
|
|
|
|
|
int max;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; (label = gtk_grid_get_child_at(GTK_GRID(grid), 0, i)) != NULL; i++) {
|
|
|
|
|
if (videodev.GetCtrlMinMaxValue(gtk_label_get_text(GTK_LABEL(label)), &min, &max, &value) == VDEV_STATUS_OK) {
|
|
|
|
|
scale = gtk_grid_get_child_at(GTK_GRID(grid), 1, i);
|
|
|
|
|
gtk_range_set_value(GTK_RANGE(scale), value);
|
|
|
|
|
entry = gtk_grid_get_child_at(GTK_GRID(grid), 2, i);
|
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entry), std::to_string(value).c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void videoframe_to_pixbuf(GdkPixbuf* dest, VideoFrame *src) {
|
|
|
|
|
int destw, desth;
|
|
|
|
|
unsigned char *destpixel;
|
|
|
|
@ -33,21 +58,43 @@ void videoframe_to_pixbuf(GdkPixbuf* dest, VideoFrame *src) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cb_videoda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) {
|
|
|
|
|
if (video_da == NULL) return;
|
|
|
|
|
int clientw, clienth, pixbufw, pixbufh;
|
|
|
|
|
float clientar, pixbufar;
|
|
|
|
|
|
|
|
|
|
GdkPixbuf *pixbuf = NULL;
|
|
|
|
|
|
|
|
|
|
if (video_da == NULL) return;
|
|
|
|
|
|
|
|
|
|
clienth = gtk_widget_get_allocated_height(video_da);
|
|
|
|
|
clientw = gtk_widget_get_allocated_width(video_da);
|
|
|
|
|
clientar = (float)clientw/(float)clienth;
|
|
|
|
|
pixbufh = gdk_pixbuf_get_height(video_pixbuf);
|
|
|
|
|
pixbufw = gdk_pixbuf_get_width(video_pixbuf);
|
|
|
|
|
pixbufar = (float)pixbufw/(float)pixbufh;
|
|
|
|
|
|
|
|
|
|
if (pixbufar < clientar) {
|
|
|
|
|
clientw = (pixbufar * (float) clienth);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
clienth = ((float) clientw / pixbufar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pixbuf = gdk_pixbuf_scale_simple (video_pixbuf, clientw, clienth, GDK_INTERP_NEAREST);
|
|
|
|
|
|
|
|
|
|
//cairo_move_to(cr, 30, 30);
|
|
|
|
|
//cairo_set_font_size(cr,15);
|
|
|
|
|
//cairo_show_text(cr, "hello world");
|
|
|
|
|
|
|
|
|
|
gdk_cairo_set_source_pixbuf(cr, video_pixbuf, 0, 0);
|
|
|
|
|
gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
|
|
|
|
|
cairo_paint(cr);
|
|
|
|
|
cairo_fill (cr);
|
|
|
|
|
g_object_unref (pixbuf);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void video_draw_image (VideoFrame *vf) {
|
|
|
|
|
int pix_w;
|
|
|
|
|
int pix_h;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
if (video_da == NULL) {
|
|
|
|
|
video_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "video-da"));
|
|
|
|
@ -67,7 +114,6 @@ void video_draw_image (VideoFrame *vf) {
|
|
|
|
|
// display error screen?
|
|
|
|
|
if (vf == NULL) {
|
|
|
|
|
unsigned char *pixels;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
// need to allocate?
|
|
|
|
|
if (video_pixbuf == NULL) {
|
|
|
|
@ -94,6 +140,7 @@ void video_draw_image (VideoFrame *vf) {
|
|
|
|
|
else {
|
|
|
|
|
//
|
|
|
|
|
// changes in resolution?
|
|
|
|
|
|
|
|
|
|
if (video_pixbuf == NULL || pix_h != vf->h || pix_w != vf->w) {
|
|
|
|
|
if (video_pixbuf != NULL) g_object_unref (video_pixbuf);
|
|
|
|
|
|
|
|
|
@ -138,12 +185,19 @@ void cb_video_btnrefreshlist (GtkWidget *widget, gpointer data) {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// start recording from the videodev (will start a new thread)
|
|
|
|
|
// load list of controls from the video device and create the GtkGrid
|
|
|
|
|
// with all elements. Also connect the signals to the callback functions.
|
|
|
|
|
void cb_video_btnrec (GtkWidget *widget, gpointer data) {
|
|
|
|
|
std::list<std::string> list;
|
|
|
|
|
std::list<std::string>::iterator iter;
|
|
|
|
|
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videodev"));
|
|
|
|
|
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"));
|
|
|
|
|
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
|
|
|
|
|
GtkWidget *grid = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vidctrl-grid"));
|
|
|
|
|
GtkWidget *gridchild = NULL;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
|
|
|
|
|
std::string device = gtk_entry_get_text(GTK_ENTRY(cbdevice));
|
|
|
|
|
device = device.substr (0, device.find(' '));
|
|
|
|
|
|
|
|
|
@ -152,6 +206,54 @@ void cb_video_btnrec (GtkWidget *widget, gpointer data) {
|
|
|
|
|
gtk_widget_set_sensitive(btnstop, true);
|
|
|
|
|
|
|
|
|
|
videodev.Start(device, cb_thread_video);
|
|
|
|
|
videodev.GetCtrlList(&list);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// clear grid
|
|
|
|
|
while ((gridchild = gtk_grid_get_child_at(GTK_GRID(grid), 0, 0)) != NULL) {
|
|
|
|
|
gtk_grid_remove_row (GTK_GRID(grid), 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// add elements
|
|
|
|
|
for (i = 0, iter = list.begin(); iter != list.end(); iter++, i++) {
|
|
|
|
|
int min = 0;
|
|
|
|
|
int max = 100;
|
|
|
|
|
int value = 50;
|
|
|
|
|
|
|
|
|
|
videodev.GetCtrlMinMaxValue((*iter), &min, &max, &value);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// label
|
|
|
|
|
GtkWidget *label = gtk_label_new(iter->c_str());
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// scale/range
|
|
|
|
|
GtkWidget *scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, 1);
|
|
|
|
|
gtk_range_set_value(GTK_RANGE(scale),value);
|
|
|
|
|
gtk_widget_set_hexpand (scale,true);
|
|
|
|
|
gtk_scale_set_draw_value(GTK_SCALE(scale), false);
|
|
|
|
|
g_signal_connect (GTK_RANGE(scale), "value-changed", G_CALLBACK(cb_vidctrl_scale_change), (void*)(long int)i);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// entry field
|
|
|
|
|
GtkWidget *entry = gtk_entry_new();
|
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entry), std::to_string(value).c_str());
|
|
|
|
|
g_signal_connect (entry, "activate", G_CALLBACK(cb_vidctrl_entry_change), (void*)(long int)i);
|
|
|
|
|
|
|
|
|
|
gtk_grid_insert_row(GTK_GRID(grid), i);
|
|
|
|
|
if (i == 0) {
|
|
|
|
|
gtk_grid_insert_column(GTK_GRID(grid), 0);
|
|
|
|
|
gtk_grid_insert_column(GTK_GRID(grid), 0);
|
|
|
|
|
gtk_grid_insert_column(GTK_GRID(grid), 0);
|
|
|
|
|
}
|
|
|
|
|
gtk_grid_attach(GTK_GRID(grid), label, 0, i, 1, 1);
|
|
|
|
|
gtk_grid_attach(GTK_GRID(grid), scale, 1, i, 1, 1);
|
|
|
|
|
gtk_grid_attach(GTK_GRID(grid), entry, 2, i, 1, 1);
|
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
gtk_widget_show (scale);
|
|
|
|
|
gtk_widget_show (entry);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -170,6 +272,9 @@ void cb_video_btnstop (GtkWidget *widget, gpointer data) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// callback from videodev thread. data will point to the latest VideoFrame.
|
|
|
|
|
// Access to this data must be Locked before use.
|
|
|
|
|
gboolean cb_thread_video (gpointer data) {
|
|
|
|
|
GtkWidget *btnstart;
|
|
|
|
|
GtkWidget *btnstop;
|
|
|
|
@ -192,3 +297,45 @@ gboolean cb_thread_video (gpointer data) {
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// set ctrl on the device
|
|
|
|
|
void videoctrl_set(std::string name, int value) {
|
|
|
|
|
videodev.SetCtrlValue(name, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// callback video control scale change
|
|
|
|
|
void cb_vidctrl_scale_change (GtkRange *range, gpointer data) {
|
|
|
|
|
GtkWidget *grid = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vidctrl-grid"));
|
|
|
|
|
GtkWidget *scale = NULL;
|
|
|
|
|
GtkWidget *label = NULL;
|
|
|
|
|
int idx = (long int)data;
|
|
|
|
|
double value;
|
|
|
|
|
|
|
|
|
|
label = gtk_grid_get_child_at(GTK_GRID(grid), 0, idx);
|
|
|
|
|
scale = gtk_grid_get_child_at(GTK_GRID(grid), 1, idx);
|
|
|
|
|
if (scale == NULL) return;
|
|
|
|
|
|
|
|
|
|
value = gtk_range_get_value(GTK_RANGE(scale));
|
|
|
|
|
videoctrl_set((std::string)gtk_label_get_text(GTK_LABEL(label)), (int)value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// callback video control entry change
|
|
|
|
|
void cb_vidctrl_entry_change (GtkWidget *widget, gpointer data) {
|
|
|
|
|
GtkWidget *grid = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vidctrl-grid"));
|
|
|
|
|
GtkWidget *label = NULL;
|
|
|
|
|
GtkWidget *entry = NULL;
|
|
|
|
|
int idx = (long int)data;
|
|
|
|
|
int value;
|
|
|
|
|
|
|
|
|
|
label = gtk_grid_get_child_at(GTK_GRID(grid), 0, idx);
|
|
|
|
|
entry = gtk_grid_get_child_at(GTK_GRID(grid), 2, idx);
|
|
|
|
|
if (entry == NULL) return;
|
|
|
|
|
|
|
|
|
|
value = atoi(gtk_entry_get_text(GTK_ENTRY(entry)));
|
|
|
|
|
videoctrl_set((std::string)gtk_label_get_text(GTK_LABEL(label)), (int)value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|