Implemented camera switching
This commit is contained in:
parent
e41b090090
commit
dae8aafacf
131
main.c
131
main.c
|
@ -55,14 +55,17 @@ static char *media_drv_name;
|
||||||
static int *interface_entity_id;
|
static int *interface_entity_id;
|
||||||
static char *dev_name[20];
|
static char *dev_name[20];
|
||||||
static int media_fd;
|
static int media_fd;
|
||||||
|
static int video_fd;
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
static int ready = 0;
|
||||||
static int current_width = -1;
|
static int current_width = -1;
|
||||||
static int current_height = -1;
|
static int current_height = -1;
|
||||||
static int current_fmt = 0;
|
static int current_fmt = 0;
|
||||||
static int current_rotate = 0;
|
static int current_rotate = 0;
|
||||||
static int current_fd;
|
static int current_fd;
|
||||||
static int capture = 0;
|
static int capture = 0;
|
||||||
|
static int current_is_rear = 1;
|
||||||
static cairo_surface_t *surface = NULL;
|
static cairo_surface_t *surface = NULL;
|
||||||
static int preview_width = -1;
|
static int preview_width = -1;
|
||||||
static int preview_height = -1;
|
static int preview_height = -1;
|
||||||
|
@ -91,49 +94,43 @@ static void
|
||||||
start_capturing(int fd)
|
start_capturing(int fd)
|
||||||
{
|
{
|
||||||
enum v4l2_buf_type type;
|
enum v4l2_buf_type type;
|
||||||
switch (io) {
|
|
||||||
case IO_METHOD_READ:
|
|
||||||
/* Nothing to do. */
|
|
||||||
break;
|
|
||||||
case IO_METHOD_MMAP:
|
|
||||||
for (int i = 0; i < n_buffers; ++i) {
|
|
||||||
struct v4l2_buffer buf = {
|
|
||||||
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
||||||
.memory = V4L2_MEMORY_MMAP,
|
|
||||||
.index = i,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
for (int i = 0; i < n_buffers; ++i) {
|
||||||
errno_exit("VIDIOC_QBUF");
|
struct v4l2_buffer buf = {
|
||||||
}
|
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||||
}
|
.memory = V4L2_MEMORY_MMAP,
|
||||||
|
.index = i,
|
||||||
|
};
|
||||||
|
|
||||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
||||||
if (xioctl(fd, VIDIOC_STREAMON, &type) == -1) {
|
errno_exit("VIDIOC_QBUF");
|
||||||
errno_exit("VIDIOC_STREAMON");
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IO_METHOD_USERPTR:
|
|
||||||
for (int i = 0; i < n_buffers; ++i) {
|
|
||||||
struct v4l2_buffer buf = {
|
|
||||||
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
||||||
.memory = V4L2_MEMORY_USERPTR,
|
|
||||||
.index = i,
|
|
||||||
};
|
|
||||||
buf.m.userptr = (unsigned long) buffers[i].start;
|
|
||||||
buf.length = buffers[i].length;
|
|
||||||
|
|
||||||
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
|
||||||
errno_exit("VIDIOC_QBUF");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
||||||
if (xioctl(fd, VIDIOC_STREAMON, &type) == -1) {
|
|
||||||
errno_exit("VIDIOC_STREAMON");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
if (xioctl(fd, VIDIOC_STREAMON, &type) == -1) {
|
||||||
|
errno_exit("VIDIOC_STREAMON");
|
||||||
|
}
|
||||||
|
|
||||||
|
ready = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_capturing(int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ready = 0;
|
||||||
|
printf("Stopping capture\n");
|
||||||
|
|
||||||
|
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
if(xioctl(fd, VIDIOC_STREAMOFF, &type) == -1) {
|
||||||
|
errno_exit("VIDIOC_STREAMOFF");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<n_buffers;++i){
|
||||||
|
munmap(buffers[i].start, buffers[i].length);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -199,7 +196,7 @@ v4l2_ctrl_set(int fd, uint32_t id, int val)
|
||||||
ctrl.value = val;
|
ctrl.value = val;
|
||||||
|
|
||||||
if(xioctl(fd, VIDIOC_S_CTRL, &ctrl) == -1){
|
if(xioctl(fd, VIDIOC_S_CTRL, &ctrl) == -1){
|
||||||
g_printerr("Failed to set control %d to %d", id, val);
|
g_printerr("Failed to set control %d to %d\n", id, val);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -229,7 +226,8 @@ init_sensor(char* fn, int width, int height, int mbus)
|
||||||
fmt.format.width, fmt.format.height,
|
fmt.format.width, fmt.format.height,
|
||||||
fmt.format.code);
|
fmt.format.code);
|
||||||
|
|
||||||
v4l2_ctrl_set(fd, V4L2_CID_AUTOGAIN, 0);
|
// Placeholder, default is also 1
|
||||||
|
//v4l2_ctrl_set(fd, V4L2_CID_AUTOGAIN, 1);
|
||||||
close(current_fd);
|
close(current_fd);
|
||||||
current_fd = fd;
|
current_fd = fd;
|
||||||
}
|
}
|
||||||
|
@ -342,19 +340,7 @@ init_device(int fd)
|
||||||
fmt.fmt.pix.sizeimage = min;
|
fmt.fmt.pix.sizeimage = min;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (io) {
|
init_mmap(fd);
|
||||||
case IO_METHOD_READ:
|
|
||||||
//init_read(fmt.fmt.pix.sizeimage);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IO_METHOD_MMAP:
|
|
||||||
init_mmap(fd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IO_METHOD_USERPTR:
|
|
||||||
//init_userp(fmt.fmt.pix.sizeimage);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -412,8 +398,8 @@ process_image(const int *p, int size)
|
||||||
cr = cairo_create(surface);
|
cr = cairo_create(surface);
|
||||||
cairo_set_source_rgb(cr, 0,0,0);
|
cairo_set_source_rgb(cr, 0,0,0);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
gdk_cairo_set_source_pixbuf(cr, pixbufrot, 0, 0);
|
|
||||||
cairo_scale(cr, scale, scale);
|
cairo_scale(cr, scale, scale);
|
||||||
|
gdk_cairo_set_source_pixbuf(cr, pixbufrot, 0, 0);
|
||||||
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_NONE);
|
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_NONE);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
gtk_widget_queue_draw_area(preview, 0, 0, preview_width, preview_height);
|
gtk_widget_queue_draw_area(preview, 0, 0, preview_width, preview_height);
|
||||||
|
@ -538,6 +524,8 @@ read_frame(int fd)
|
||||||
static gboolean
|
static gboolean
|
||||||
get_frame(int fd)
|
get_frame(int fd)
|
||||||
{
|
{
|
||||||
|
if (ready == 0)
|
||||||
|
return TRUE;
|
||||||
while (1) {
|
while (1) {
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -751,7 +739,7 @@ setup_front()
|
||||||
link.sink.index = 0;
|
link.sink.index = 0;
|
||||||
|
|
||||||
if(xioctl(media_fd, MEDIA_IOC_SETUP_LINK, &link) < 0){
|
if(xioctl(media_fd, MEDIA_IOC_SETUP_LINK, &link) < 0){
|
||||||
g_printerr("Could not disable front camera link\n");
|
g_printerr("Could not disable rear camera link\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +751,7 @@ setup_front()
|
||||||
link.sink.index = 0;
|
link.sink.index = 0;
|
||||||
|
|
||||||
if(xioctl(media_fd, MEDIA_IOC_SETUP_LINK, &link) < 0){
|
if(xioctl(media_fd, MEDIA_IOC_SETUP_LINK, &link) < 0){
|
||||||
g_printerr("Could not enable rear camera link\n");
|
g_printerr("Could not enable front camera link\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
current_width = front_width;
|
current_width = front_width;
|
||||||
|
@ -846,6 +834,29 @@ on_shutter_clicked(GtkWidget *widget, gpointer user_data)
|
||||||
capture = 1;
|
capture = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
on_camera_switch_clicked(GtkWidget *widget, gpointer user_data)
|
||||||
|
{
|
||||||
|
stop_capturing(video_fd);
|
||||||
|
close(current_fd);
|
||||||
|
if(current_is_rear == 1){
|
||||||
|
setup_front();
|
||||||
|
current_is_rear = 0;
|
||||||
|
}else{
|
||||||
|
setup_rear();
|
||||||
|
current_is_rear = 1;
|
||||||
|
}
|
||||||
|
printf("close() = %d\n", close(video_fd));
|
||||||
|
printf("Opening %s again\n", dev_name);
|
||||||
|
video_fd = open(dev_name, O_RDWR);
|
||||||
|
if (video_fd == -1) {
|
||||||
|
g_printerr("Error opening video device: %s\n", dev_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
init_device(video_fd);
|
||||||
|
start_capturing(video_fd);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -871,10 +882,12 @@ main(int argc, char *argv[])
|
||||||
GObject *window = gtk_builder_get_object(builder, "window");
|
GObject *window = gtk_builder_get_object(builder, "window");
|
||||||
GObject *preview_box = gtk_builder_get_object(builder, "preview_box");
|
GObject *preview_box = gtk_builder_get_object(builder, "preview_box");
|
||||||
GObject *shutter = gtk_builder_get_object(builder, "shutter");
|
GObject *shutter = gtk_builder_get_object(builder, "shutter");
|
||||||
|
GObject *switch_btn = gtk_builder_get_object(builder, "switch_camera");
|
||||||
GObject *settings_btn = gtk_builder_get_object(builder, "settings");
|
GObject *settings_btn = gtk_builder_get_object(builder, "settings");
|
||||||
preview = gtk_builder_get_object(builder, "preview");
|
preview = gtk_builder_get_object(builder, "preview");
|
||||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
g_signal_connect(shutter, "clicked", G_CALLBACK(on_shutter_clicked), NULL);
|
g_signal_connect(shutter, "clicked", G_CALLBACK(on_shutter_clicked), NULL);
|
||||||
|
g_signal_connect(switch_btn, "clicked", G_CALLBACK(on_camera_switch_clicked), NULL);
|
||||||
g_signal_connect(preview, "draw", G_CALLBACK(preview_draw), NULL);
|
g_signal_connect(preview, "draw", G_CALLBACK(preview_draw), NULL);
|
||||||
g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure), NULL);
|
g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure), NULL);
|
||||||
|
|
||||||
|
@ -917,6 +930,8 @@ main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
video_fd = fd;
|
||||||
|
|
||||||
init_device(fd);
|
init_device(fd);
|
||||||
start_capturing(fd);
|
start_capturing(fd);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ rotate=270
|
||||||
|
|
||||||
[front]
|
[front]
|
||||||
driver=gc2145
|
driver=gc2145
|
||||||
width=1280
|
width=800
|
||||||
height=720
|
height=600
|
||||||
fmt=BGGR8
|
fmt=BGGR8
|
||||||
rotate=90
|
rotate=90
|
||||||
|
|
Loading…
Reference in New Issue