aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessio Treglia <quadrispro@ubuntu.com>2018-08-01 11:02:51 (GMT)
committerGitHub <noreply@github.com>2018-08-01 11:02:51 (GMT)
commitd73d6c58d392dfbd11f5b384ab8c4ee948d2dfb7 (patch)
tree51580318fbcd908b972f1fb74f90655afad41e81
parent00dca626855904e955ec4c164505a0bc34db671d (diff)
parentcbc8d0905488d9efe5c9ecb2e97076e27049c6b3 (diff)
Merge pull request #12 from mchehab/resolution_improvement
Resolution improvement
-rw-r--r--data/camorama.glade24
-rw-r--r--src/callbacks.c37
-rw-r--r--src/camorama-window.c63
-rw-r--r--src/main.c2
-rw-r--r--src/v4l.c84
-rw-r--r--src/v4l.h9
6 files changed, 174 insertions, 45 deletions
diff --git a/data/camorama.glade b/data/camorama.glade
index 196d5d7..317757d 100644
--- a/data/camorama.glade
+++ b/data/camorama.glade
@@ -1878,29 +1878,7 @@
<property name="label" translatable="yes">Small</property>
<property name="use_underline">True</property>
<property name="active">False</property>
- <signal name="activate" handler="on_small_activate" last_modification_time="Tue, 26 Aug 2003 03:09:34 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkRadioMenuItem" id="medium">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Medium</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="group">small</property>
- <signal name="activate" handler="on_medium_activate" last_modification_time="Tue, 26 Aug 2003 03:09:42 GMT"/>
- </widget>
- </child>
-
- <child>
- <widget class="GtkRadioMenuItem" id="large">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Large</property>
- <property name="use_underline">True</property>
- <property name="active">False</property>
- <property name="group">small</property>
- <signal name="activate" handler="on_large_activate" last_modification_time="Tue, 26 Aug 2003 03:09:55 GMT"/>
+ <signal name="activate" handler="activate" last_modification_time="Tue, 26 Aug 2003 03:09:34 GMT"/>
</widget>
</child>
</widget>
diff --git a/src/callbacks.c b/src/callbacks.c
index 0b193c8..0b7aaa1 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -364,29 +364,34 @@ void on_change_size_activate (GtkWidget * widget, cam * cam)
{
gchar const *name;
gchar *title;
+ int width = 0, height = 0;
name = gtk_widget_get_name (widget);
- printf("name = %s\n",name);
+
if (strcmp (name, "small") == 0) {
- cam->width = cam->min_width;
- cam->height = cam->min_height;
- if (cam->debug) {
- printf ("\nsmall\n");
- }
+ width = cam->min_width;
+ height = cam->min_height;
} else if (strcmp (name, "medium") == 0) {
- cam->width = cam->max_width / 2;
- cam->height = cam->max_height / 2;
- if (cam->debug) {
- printf ("\nmed\n");
- }
+ width = cam->max_width / 2;
+ height = cam->max_height / 2;
+ } else if (strcmp (name, "large") == 0) {
+ width = cam->max_width;
+ height = cam->max_height;
} else {
- cam->width = cam->max_width;
- cam->height = cam->max_height;
- if (cam->debug) {
- printf ("\nlarge\n");
- }
+ sscanf(name, "%dx%d", &width, &height);
}
+ try_set_win_info(cam, &width, &height);
+
+ /* Nothing to do, so just return */
+ if (width == cam->width && height == cam->height)
+ return;
+
+ cam->width = width;
+ cam->height = height;
+
+ printf("name = %s\n",name);
+
if (cam->read == FALSE)
stop_streaming(cam);
set_win_info (cam);
diff --git a/src/camorama-window.c b/src/camorama-window.c
index 44cdfc0..3018e1a 100644
--- a/src/camorama-window.c
+++ b/src/camorama-window.c
@@ -183,12 +183,16 @@ tray_clicked_callback (GtkStatusIcon* status, guint button, guint activate_time,
}
}
+static guint resolution_signals[8] = { 0 };
+
+
void
load_interface(cam* cam) {
gchar *title;
GdkPixbuf *logo = NULL;
GtkTreeView* treeview = GTK_TREE_VIEW(glade_xml_get_widget(cam->xml, "treeview_effects"));
GtkCellRenderer* cell;
+ GtkWidget *small_res, *new_res;
menu_item_filter_type = g_quark_from_static_string("camorama-menu-item-filter-type");
@@ -269,12 +273,59 @@ load_interface(cam* cam) {
G_CALLBACK
(on_show_adjustments_activate), cam);
- glade_xml_signal_connect_data (cam->xml, "on_large_activate",
- G_CALLBACK (on_change_size_activate), cam);
- glade_xml_signal_connect_data (cam->xml, "on_medium_activate",
- G_CALLBACK (on_change_size_activate), cam);
- glade_xml_signal_connect_data (cam->xml, "on_small_activate",
- G_CALLBACK (on_change_size_activate), cam);
+
+ /*
+ * Dynamically generate the resolutions based on what the camera
+ * actually supports. Provide a fallback method, if the camera driver
+ * is too old and doesn't support formats enumeration.
+ */
+
+ small_res = glade_xml_get_widget (cam->xml, "small");
+
+ /* Get all supported resolutions by cam->pixformat */
+ get_supported_resolutions(cam);
+
+ if (cam->n_res > 0) {
+ int i;
+
+ for (i = 0; i < cam->n_res; i++) {
+ char name[32];
+
+ sprintf(name, "%dx%d", cam->res[i].x, cam->res[i].y);
+
+ new_res = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(small_res), name);
+ gtk_menu_append(GTK_MENU(glade_xml_get_widget (cam->xml, "menuitem4_menu")), new_res);
+ gtk_widget_show (new_res);
+ g_signal_connect(new_res, "activate",
+ G_CALLBACK (on_change_size_activate), cam);
+ gtk_widget_set_name(new_res, name);
+
+ if (cam->width == cam->res[i].x && cam->height == cam->res[i].y)
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_res), TRUE);
+ else
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_res), FALSE);
+ }
+
+ /* We won't actually use the small res */
+ gtk_widget_hide (small_res);
+ } else {
+ glade_xml_signal_connect_data (cam->xml, "activate",
+ G_CALLBACK (on_change_size_activate), cam);
+
+ new_res = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(small_res), "Medium");
+ gtk_menu_append(GTK_MENU(glade_xml_get_widget (cam->xml, "menuitem4_menu")), new_res);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_res), FALSE);
+ gtk_widget_show (new_res);
+ g_signal_connect(new_res, "activate", G_CALLBACK (on_change_size_activate), cam);
+ gtk_widget_set_name(new_res, "medium");
+
+ new_res = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(small_res), "Large");
+ gtk_menu_append(GTK_MENU(glade_xml_get_widget (cam->xml, "menuitem4_menu")), new_res);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_res), FALSE);
+ gtk_widget_show (new_res);
+ g_signal_connect(new_res, "activate", G_CALLBACK (on_change_size_activate), cam);
+ gtk_widget_set_name(new_res, "large");
+ }
//glade_xml_signal_connect_data(cam->xml, "capture_func", G_CALLBACK(on_change_size_activate), cam);
glade_xml_signal_connect_data (cam->xml, "capture_func",
diff --git a/src/main.c b/src/main.c
index 2a2bf90..6e9f175 100644
--- a/src/main.c
+++ b/src/main.c
@@ -106,6 +106,8 @@ main(int argc, char *argv[]) {
cam->read = FALSE;
cam->width = 0;
cam->height = 0;
+ cam->res = NULL;
+ cam->n_res = 0;
bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
diff --git a/src/v4l.c b/src/v4l.c
index 47c0fe6..5a00b13 100644
--- a/src/v4l.c
+++ b/src/v4l.c
@@ -2,6 +2,7 @@
#include<time.h>
#include<errno.h>
#include<gnome.h>
+#include<stdlib.h>
#include <sys/select.h>
#include "support.h"
@@ -20,6 +21,73 @@ void print_cam(cam *cam){
}
+void insert_resolution(cam * cam, int x, int y)
+{
+ int i;
+
+ try_set_win_info(cam, &x, &y);
+ for (i = 0; i++; i < cam->n_res) {
+ if (cam->res[i].x == x && cam->res[i].y == y)
+ return;
+ }
+
+ cam->res = realloc(cam->res, (cam->n_res + 1) * sizeof(struct resolutions));
+
+ cam->res[cam->n_res].x = x;
+ cam->res[cam->n_res].y = y;
+ cam->n_res++;
+}
+
+static int sort_func(const void *__b,
+ const void *__a)
+{
+ const struct resolutions *a = __a;
+ const struct resolutions *b = __b;
+ int r;
+
+ r = b->x - a->x;
+ if (!r)
+ r = b->y - a->y;
+
+ return r;
+}
+
+void get_supported_resolutions(cam * cam)
+{
+ struct v4l2_fmtdesc fmt;
+ struct v4l2_frmsizeenum frmsize;
+ struct v4l2_frmivalenum frmival;
+ int i, x, y;
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ for (fmt.index = 0;
+ !v4l2_ioctl(cam->dev, VIDIOC_ENUM_FMT, &fmt);
+ fmt.index++) {
+ if (cam->pixformat != fmt.pixelformat)
+ continue;
+
+ frmsize.pixel_format = fmt.pixelformat;
+ frmsize.index = 0;
+ while (!v4l2_ioctl(cam->dev, VIDIOC_ENUM_FRAMESIZES, &frmsize)) {
+ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+ insert_resolution(cam, frmsize.discrete.width,
+ frmsize.discrete.height);
+ } else if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
+ for (i = 0; i < 4; i++) {
+ x = frmsize.stepwise.min_width +
+ i * (frmsize.stepwise.max_width - frmsize.stepwise.min_width) / 4;
+ y = frmsize.stepwise.min_height +
+ i * (frmsize.stepwise.max_height - frmsize.stepwise.min_height) / 4;
+ insert_resolution(cam, x, y);
+ }
+ }
+ frmsize.index++;
+ }
+ }
+ qsort(cam->res, cam->n_res, sizeof(struct resolutions), sort_func);
+}
+
void camera_cap(cam * cam)
{
char *msg;
@@ -258,6 +326,22 @@ void get_win_info(cam * cam)
}
}
+void try_set_win_info(cam * cam, int *x, int *y)
+{
+ gchar *msg;
+ struct v4l2_format fmt;
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.pixelformat = cam->pixformat;
+ fmt.fmt.pix.width = *x;
+ fmt.fmt.pix.height = *y;
+ if (!v4l2_ioctl(cam->dev, VIDIOC_TRY_FMT, &fmt)) {
+ *x = fmt.fmt.pix.width;
+ *y = fmt.fmt.pix.height;
+ }
+}
+
void set_win_info(cam * cam)
{
gchar *msg;
diff --git a/src/v4l.h b/src/v4l.h
index 1c07641..1469b5d 100644
--- a/src/v4l.h
+++ b/src/v4l.h
@@ -39,6 +39,10 @@ struct buffer_start_len {
size_t length;
};
+struct resolutions {
+ int x, y;
+};
+
typedef struct camera {
int dev;
int width;
@@ -53,6 +57,9 @@ typedef struct camera {
int min_width, min_height, max_width, max_height;
+ int n_res;
+ struct resolutions *res;
+
char *video_dev;
unsigned char *image;
gchar *capturefile, *rcapturefile;
@@ -86,9 +93,11 @@ typedef struct camera {
} cam;
void camera_cap (cam *);
+void try_set_win_info(cam * cam, int *x, int *y);
void set_win_info (cam * cam);
void get_pic_info (cam *);
void get_win_info (cam *);
+void get_supported_resolutions(cam * cam);
void start_streaming(cam * cam);
void capture_buffers(cam * cam, unsigned char *outbuf, int len);
void stop_streaming(cam * cam);

Privacy Policy