static VideoPhonePlugin * _video_init(PhonePluginHelper * helper) { VideoPhonePlugin * video; char const * device; char const * p; if((video = object_new(sizeof(*video))) == NULL) return NULL; video->helper = helper; if((device = helper->config_get(helper->phone, "video", "device")) == NULL) device = VIDEO_DEVICE; p = helper->config_get(helper->phone, "video", "hflip"); video->hflip = (p != NULL && p[0] != '\0' && strtol(p, NULL, 10) > 0) ? TRUE : FALSE; p = helper->config_get(helper->phone, "video", "vflip"); video->vflip = (p != NULL && p[0] != '\0' && strtol(p, NULL, 10) > 0) ? TRUE : FALSE; p = helper->config_get(helper->phone, "video", "ratio"); video->ratio = (p == NULL || p[0] == '\0' || strtol(p, NULL, 10) != 0) ? TRUE : FALSE; video->interp = GDK_INTERP_BILINEAR; video->source = 0; video->fd = -1; memset(&video->cap, 0, sizeof(video->cap)); video->channel = NULL; video->buffers = NULL; video->buffers_cnt = 0; video->raw_buffer = NULL; video->raw_buffer_cnt = 0; video->rgb_buffer = NULL; video->rgb_buffer_cnt = 0; video->yuv_amp = 255; video->window = NULL; #if !GTK_CHECK_VERSION(3, 0, 0) video->gc = NULL; #endif /* check for errors */ if((video->device = string_new(device)) == NULL) { helper->error(helper->phone, "Could not initialize the video capture device", 1); _video_destroy(video); return NULL; } /* create the window */ video->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(video->window), "Phone - Video"); gtk_widget_realize(video->window); #if !GTK_CHECK_VERSION(3, 0, 0) video->gc = gdk_gc_new(video->window->window); /* XXX */ #endif g_signal_connect_swapped(video->window, "delete-event", G_CALLBACK( _init_on_closex), video); video->area = gtk_drawing_area_new(); video->pixbuf = NULL; #if !GTK_CHECK_VERSION(3, 0, 0) video->pixmap = NULL; #endif #if GTK_CHECK_VERSION(3, 0, 0) g_signal_connect(video->area, "draw", G_CALLBACK( _video_on_drawing_area_draw), video); g_signal_connect(video->area, "size-allocate", G_CALLBACK( _video_on_drawing_area_size_allocate), video); #else g_signal_connect(video->area, "configure-event", G_CALLBACK( _video_on_drawing_area_configure), video); g_signal_connect(video->area, "expose-event", G_CALLBACK( _video_on_drawing_area_expose), video); #endif gtk_widget_set_size_request(video->area, video->format.fmt.pix.width, video->format.fmt.pix.height); gtk_container_add(GTK_CONTAINER(video->window), video->area); gtk_widget_show_all(video->window); _video_start(video); return video; }
/* video_init */ static VideoPhonePlugin * _video_init(PhonePluginHelper * helper) { VideoPhonePlugin * video; struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format format; if((video = object_new(sizeof(*video))) == NULL) return NULL; video->helper = helper; /* FIXME let this be configurable */ video->fd = open("/dev/video0", O_RDWR); video->buffer = buffer_new(0, NULL); video->source = 0; video->window = NULL; /* check for errors */ if(video->buffer == NULL || video->fd < 0 || _video_ioctl(video, VIDIOC_QUERYCAP, &cap) == -1 || (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0 /* FIXME also implement mmap() and streaming */ || (cap.capabilities & V4L2_CAP_READWRITE) == 0) { helper->error(helper->phone, "Could not open the video capture device", 1); _video_destroy(video); return NULL; } /* reset cropping */ memset(&cropcap, 0, sizeof(cropcap)); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(_video_ioctl(video, VIDIOC_CROPCAP, &cropcap) == 0) { /* reset to default */ crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; if(_video_ioctl(video, VIDIOC_S_CROP, &crop) == -1 && errno == EINVAL) helper->error(helper->phone, "Cropping not supported", 0); } /* obtain the current format */ if(_video_ioctl(video, VIDIOC_G_FMT, &format) == -1 || buffer_set_size(video->buffer, format.fmt.pix.sizeimage) != 0) { _video_destroy(video); return NULL; } /* create the window */ video->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable(GTK_WINDOW(video->window), FALSE); gtk_window_set_title(GTK_WINDOW(video->window), "Phone - Video"); g_signal_connect_swapped(video->window, "delete-event", G_CALLBACK( _video_on_closex), video); video->area = gtk_drawing_area_new(); gtk_widget_set_size_request(video->area, format.fmt.pix.width, format.fmt.pix.height); gtk_container_add(GTK_CONTAINER(video->window), video->area); gtk_widget_show_all(video->window); if(_video_on_refresh(video) == TRUE) video->source = g_timeout_add(1000, _video_on_refresh, video); return video; }