move photo capture into thread
This commit is contained in:
parent
1ce8391fa4
commit
f54dcb4785
2 changed files with 85 additions and 66 deletions
111
photobooth.c
111
photobooth.c
|
@ -59,12 +59,14 @@ static void photo_booth_window_destroyed_signal (PhotoBoothWindow *win, GMainLoo
|
||||||
static void photo_booth_setup_window (PhotoBooth *pb);
|
static void photo_booth_setup_window (PhotoBooth *pb);
|
||||||
static void photo_booth_preview (PhotoBooth *pb);
|
static void photo_booth_preview (PhotoBooth *pb);
|
||||||
static void photo_booth_snapshot (PhotoBooth *pb);
|
static void photo_booth_snapshot (PhotoBooth *pb);
|
||||||
|
static gboolean photo_booth_snapshot_taken (PhotoBooth *pb);
|
||||||
|
|
||||||
/* libgphoto2 */
|
/* libgphoto2 */
|
||||||
static gboolean photo_booth_cam_init (CameraInfo **cam_info);
|
static gboolean photo_booth_cam_init (CameraInfo **cam_info);
|
||||||
static gboolean photo_booth_cam_close (CameraInfo **cam_info);
|
static gboolean photo_booth_cam_close (CameraInfo **cam_info);
|
||||||
|
static gboolean photo_booth_take_photo (CameraInfo *cam_info);
|
||||||
static void photo_booth_flush_pipe (int fd);
|
static void photo_booth_flush_pipe (int fd);
|
||||||
static void photo_booth_video_capture_thread_func (PhotoBooth *pb);
|
static void photo_booth_capture_thread_func (PhotoBooth *pb);
|
||||||
|
|
||||||
/* gstreamer functions */
|
/* gstreamer functions */
|
||||||
static gboolean photo_booth_setup_gstreamer (PhotoBooth *pb);
|
static gboolean photo_booth_setup_gstreamer (PhotoBooth *pb);
|
||||||
|
@ -105,8 +107,8 @@ static void photo_booth_init (PhotoBooth *pb)
|
||||||
pb->video_block_id = 0;
|
pb->video_block_id = 0;
|
||||||
pb->photo_block_id = 0;
|
pb->photo_block_id = 0;
|
||||||
|
|
||||||
pb->video_capture_thread = NULL;
|
pb->capture_thread = NULL;
|
||||||
pb->video_capture_thread = g_thread_try_new ("video-capture", (GThreadFunc) photo_booth_video_capture_thread_func, pb, NULL);
|
pb->capture_thread = g_thread_try_new ("gphoto-capture", (GThreadFunc) photo_booth_capture_thread_func, pb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void photo_booth_setup_window (PhotoBooth *pb)
|
static void photo_booth_setup_window (PhotoBooth *pb)
|
||||||
|
@ -141,7 +143,7 @@ static void photo_booth_finalize (GObject *object)
|
||||||
GST_INFO_OBJECT (pb, "finalize server");
|
GST_INFO_OBJECT (pb, "finalize server");
|
||||||
SEND_COMMAND (pb, CONTROL_STOP);
|
SEND_COMMAND (pb, CONTROL_STOP);
|
||||||
photo_booth_flush_pipe (pb->video_fd);
|
photo_booth_flush_pipe (pb->video_fd);
|
||||||
g_thread_join (pb->video_capture_thread);
|
g_thread_join (pb->capture_thread);
|
||||||
if (pb->cam_info)
|
if (pb->cam_info)
|
||||||
photo_booth_cam_close (&pb->cam_info);
|
photo_booth_cam_close (&pb->cam_info);
|
||||||
}
|
}
|
||||||
|
@ -183,6 +185,8 @@ static gboolean photo_booth_cam_init (CameraInfo **cam_info)
|
||||||
g_mutex_init (&(*cam_info)->mutex);
|
g_mutex_init (&(*cam_info)->mutex);
|
||||||
g_mutex_lock (&(*cam_info)->mutex);
|
g_mutex_lock (&(*cam_info)->mutex);
|
||||||
(*cam_info)->preview_capture_count = 0;
|
(*cam_info)->preview_capture_count = 0;
|
||||||
|
(*cam_info)->size = 0;
|
||||||
|
(*cam_info)->data = NULL;
|
||||||
(*cam_info)->context = gp_context_new();
|
(*cam_info)->context = gp_context_new();
|
||||||
gp_log_add_func(GP_LOG_ERROR, _gphoto_err, NULL);
|
gp_log_add_func(GP_LOG_ERROR, _gphoto_err, NULL);
|
||||||
gp_camera_new(&(*cam_info)->camera);
|
gp_camera_new(&(*cam_info)->camera);
|
||||||
|
@ -232,26 +236,26 @@ static void photo_booth_window_destroyed_signal (PhotoBoothWindow *win, GMainLoo
|
||||||
g_main_loop_quit (loop);
|
g_main_loop_quit (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
static void photo_booth_capture_thread_func (PhotoBooth *pb)
|
||||||
{
|
{
|
||||||
PhotoboothReadthreadState state = CAPTURETHREAD_NONE;
|
PhotoboothCaptureThreadState state = CAPTURE_NONE;
|
||||||
|
|
||||||
mkfifo("moviepipe", 0666);
|
mkfifo("moviepipe", 0666);
|
||||||
pb->video_fd = open("moviepipe", O_RDWR);
|
pb->video_fd = open("moviepipe", O_RDWR);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pb, "enter video capture thread fd = %d cam_info@%p", pb->video_fd, pb->cam_info);
|
GST_DEBUG_OBJECT (pb, "enter capture thread fd = %d cam_info@%p", pb->video_fd, pb->cam_info);
|
||||||
|
|
||||||
CameraFile *gp_file = NULL;
|
CameraFile *gp_file = NULL;
|
||||||
int gpret, captured_frames = 0;
|
int gpret, captured_frames = 0;
|
||||||
|
|
||||||
if (gp_file_new_from_fd (&gp_file, pb->video_fd) != GP_OK)
|
if (gp_file_new_from_fd (&gp_file, pb->video_fd) != GP_OK)
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (pb, "couldn't start video capture thread because gp_file_new_from_fd (%d) failed!", pb->video_fd);
|
GST_ERROR_OBJECT (pb, "couldn't start capture thread because gp_file_new_from_fd (%d) failed!", pb->video_fd);
|
||||||
goto stop_running;
|
goto stop_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
if (state == CAPTURETHREAD_STOP)
|
if (state == CAPTURE_STOP)
|
||||||
goto stop_running;
|
goto stop_running;
|
||||||
|
|
||||||
struct pollfd rfd[2];
|
struct pollfd rfd[2];
|
||||||
|
@ -267,7 +271,7 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
}
|
}
|
||||||
else if (pb->state == PB_STATE_NONE)
|
else if (pb->state == PB_STATE_NONE)
|
||||||
pb->state = PB_STATE_PREVIEW;
|
pb->state = PB_STATE_PREVIEW;
|
||||||
else if (state == CAPTURETHREAD_PAUSED)
|
else if (state == CAPTURE_PAUSED)
|
||||||
timeout = 1000;
|
timeout = 1000;
|
||||||
else
|
else
|
||||||
timeout = 1000 / PREVIEW_FPS;
|
timeout = 1000 / PREVIEW_FPS;
|
||||||
|
@ -278,8 +282,9 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
GST_ERROR_OBJECT (pb, "SELECT ERROR!");
|
GST_ERROR_OBJECT (pb, "SELECT ERROR!");
|
||||||
goto stop_running;
|
goto stop_running;
|
||||||
}
|
}
|
||||||
else if (ret == 0 && state >= CAPTURETHREAD_RUN)
|
else if (ret == 0 && state == CAPTURE_VIDEO)
|
||||||
{
|
{
|
||||||
|
GST_DEBUG_OBJECT (pb, "STATE == CAPTURE_VIDEO");
|
||||||
const char *mime;
|
const char *mime;
|
||||||
if (pb->cam_info)
|
if (pb->cam_info)
|
||||||
{
|
{
|
||||||
|
@ -288,7 +293,7 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
g_mutex_unlock (&pb->cam_info->mutex);
|
g_mutex_unlock (&pb->cam_info->mutex);
|
||||||
if (gpret < 0) {
|
if (gpret < 0) {
|
||||||
GST_ERROR_OBJECT (pb, "Movie capture error %d", gpret);
|
GST_ERROR_OBJECT (pb, "Movie capture error %d", gpret);
|
||||||
state = CAPTURETHREAD_STOP;
|
state = CAPTURE_STOP;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -297,7 +302,7 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
g_mutex_unlock (&pb->cam_info->mutex);
|
g_mutex_unlock (&pb->cam_info->mutex);
|
||||||
if (strcmp (mime, GP_MIME_JPEG)) {
|
if (strcmp (mime, GP_MIME_JPEG)) {
|
||||||
GST_ERROR_OBJECT ("Movie capture error... Unhandled MIME type '%s'.", mime);
|
GST_ERROR_OBJECT ("Movie capture error... Unhandled MIME type '%s'.", mime);
|
||||||
state = CAPTURETHREAD_STOP;
|
state = CAPTURE_STOP;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
captured_frames++;
|
captured_frames++;
|
||||||
|
@ -305,6 +310,21 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ret == 0 && state == CAPTURE_PHOTO)
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (pb, "STATE == CAPTURE_PHOTO");
|
||||||
|
if (pb->cam_info)
|
||||||
|
{
|
||||||
|
ret = photo_booth_take_photo (pb->cam_info);
|
||||||
|
if (ret)
|
||||||
|
g_main_context_invoke (NULL, (GSourceFunc) photo_booth_snapshot_taken, pb);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (pb, "taking photo failed!");
|
||||||
|
state = CAPTURE_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (rfd[0].revents)
|
else if (rfd[0].revents)
|
||||||
{
|
{
|
||||||
char command;
|
char command;
|
||||||
|
@ -312,22 +332,27 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case CONTROL_STOP:
|
case CONTROL_STOP:
|
||||||
GST_DEBUG_OBJECT (pb, "CONTROL_STOP!");
|
GST_DEBUG_OBJECT (pb, "CONTROL_STOP!");
|
||||||
state = CAPTURETHREAD_STOP;
|
state = CAPTURE_STOP;
|
||||||
break;
|
break;
|
||||||
case CONTROL_PAUSE:
|
case CONTROL_PAUSE:
|
||||||
GST_DEBUG_OBJECT (pb, "CONTROL_PAUSE!");
|
GST_DEBUG_OBJECT (pb, "CONTROL_PAUSE!");
|
||||||
state = CAPTURETHREAD_PAUSED;
|
state = CAPTURE_PAUSED;
|
||||||
break;
|
break;
|
||||||
case CONTROL_RUN:
|
case CONTROL_VIDEO:
|
||||||
GST_DEBUG_OBJECT (pb, "CONTROL_RUN");
|
GST_DEBUG_OBJECT (pb, "CONTROL_VIDEO");
|
||||||
state = CAPTURETHREAD_RUN;
|
state = CAPTURE_VIDEO;
|
||||||
|
break;
|
||||||
|
case CONTROL_PHOTO:
|
||||||
|
GST_DEBUG_OBJECT (pb, "CONTROL_PHOTO");
|
||||||
|
state = CAPTURE_PHOTO;
|
||||||
|
// photo_booth_flush_pipe (pb->video_fd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_ERROR_OBJECT (pb, "illegal control socket command %c received!", command);
|
GST_ERROR_OBJECT (pb, "illegal control socket command %c received!", command);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (state == CAPTURETHREAD_PAUSED)
|
else if (state == CAPTURE_PAUSED)
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (pb, "captured thread paused... timeout");
|
GST_DEBUG_OBJECT (pb, "captured thread paused... timeout");
|
||||||
}
|
}
|
||||||
|
@ -345,7 +370,6 @@ static void photo_booth_video_capture_thread_func (PhotoBooth *pb)
|
||||||
GST_DEBUG ("stop running, exit thread, %d frames captured", captured_frames);
|
GST_DEBUG ("stop running, exit thread, %d frames captured", captured_frames);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstElement *build_video_bin (PhotoBooth *pb)
|
static GstElement *build_video_bin (PhotoBooth *pb)
|
||||||
|
@ -548,16 +572,16 @@ static gboolean photo_booth_bus_callback (GstBus *bus, GstMessage *message, Phot
|
||||||
GST_DEBUG ("%" GST_PTR_FORMAT " state transition %s -> %s", src, gst_element_state_get_name(GST_STATE_TRANSITION_CURRENT(transition)), gst_element_state_get_name(GST_STATE_TRANSITION_NEXT(transition)));
|
GST_DEBUG ("%" GST_PTR_FORMAT " state transition %s -> %s", src, gst_element_state_get_name(GST_STATE_TRANSITION_CURRENT(transition)), gst_element_state_get_name(GST_STATE_TRANSITION_NEXT(transition)));
|
||||||
if (src == pb->video_bin && transition == GST_STATE_CHANGE_PAUSED_TO_PLAYING)
|
if (src == pb->video_bin && transition == GST_STATE_CHANGE_PAUSED_TO_PLAYING)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("video_bin GST_STATE_CHANGE_READY_TO_PAUSED -> RUN CAPTURE!");
|
GST_DEBUG ("video_bin GST_STATE_CHANGE_READY_TO_PAUSED -> CAPTURE VIDEO!");
|
||||||
SEND_COMMAND (pb, CONTROL_RUN);
|
SEND_COMMAND (pb, CONTROL_VIDEO);
|
||||||
// priv = photo_booth_get_instance_private (pb);
|
// priv = photo_booth_get_instance_private (pb);
|
||||||
// photo_booth_window_set_spinner (priv->win, FALSE);
|
// photo_booth_window_set_spinner (priv->win, FALSE);
|
||||||
}
|
}
|
||||||
else if (src == pb->video_bin && transition == GST_STATE_CHANGE_PLAYING_TO_PAUSED)
|
// else if (src == pb->video_bin && transition == GST_STATE_CHANGE_PLAYING_TO_PAUSED)
|
||||||
{
|
// {
|
||||||
GST_DEBUG ("video_bin GST_STATE_CHANGE_PLAYING_TO_PAUSED -> PAUSE CAPTURE!");
|
// GST_DEBUG ("video_bin GST_STATE_CHANGE_PLAYING_TO_PAUSED -> PAUSE CAPTURE!");
|
||||||
SEND_COMMAND (pb, CONTROL_PAUSE);
|
// SEND_COMMAND (pb, CONTROL_PAUSE);
|
||||||
}
|
// }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_MESSAGE_STREAM_START:
|
case GST_MESSAGE_STREAM_START:
|
||||||
|
@ -617,7 +641,7 @@ static gboolean photo_booth_focus (CameraInfo *cam_info)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean photo_booth_take_photo (CameraInfo *cam_info, const char **ptr, unsigned long int *size)
|
static gboolean photo_booth_take_photo (CameraInfo *cam_info)
|
||||||
{
|
{
|
||||||
int gpret;
|
int gpret;
|
||||||
CameraFile *file;
|
CameraFile *file;
|
||||||
|
@ -639,8 +663,7 @@ static gboolean photo_booth_take_photo (CameraInfo *cam_info, const char **ptr,
|
||||||
GST_DEBUG ("gp_camera_file_get gpret=%i", gpret);
|
GST_DEBUG ("gp_camera_file_get gpret=%i", gpret);
|
||||||
if (gpret < 0)
|
if (gpret < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
gp_file_get_data_and_size (file, (const char**)&(cam_info->data), &(cam_info->size));
|
||||||
gp_file_get_data_and_size (file, ptr, size);
|
|
||||||
if (gpret < 0)
|
if (gpret < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -690,7 +713,6 @@ static void photo_booth_preview (PhotoBooth *pb)
|
||||||
int ret = gst_element_link (pb->video_bin, pb->pixoverlay);
|
int ret = gst_element_link (pb->video_bin, pb->pixoverlay);
|
||||||
GST_DEBUG_OBJECT (pb, "linking %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT " ret=%i", pb->video_bin, pb->pixoverlay, ret);
|
GST_DEBUG_OBJECT (pb, "linking %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT " ret=%i", pb->video_bin, pb->pixoverlay, ret);
|
||||||
gst_element_set_state (pb->video_bin, GST_STATE_PLAYING);
|
gst_element_set_state (pb->video_bin, GST_STATE_PLAYING);
|
||||||
// SEND_COMMAND (pb, CONTROL_RUN);
|
|
||||||
GST_DEBUG_OBJECT (pb, "photo_booth_preview done");
|
GST_DEBUG_OBJECT (pb, "photo_booth_preview done");
|
||||||
pb->state = PB_STATE_PREVIEW;
|
pb->state = PB_STATE_PREVIEW;
|
||||||
}
|
}
|
||||||
|
@ -710,12 +732,7 @@ static void photo_booth_snapshot (PhotoBooth *pb)
|
||||||
priv = photo_booth_get_instance_private (pb);
|
priv = photo_booth_get_instance_private (pb);
|
||||||
photo_booth_window_set_spinner (priv->win, TRUE);
|
photo_booth_window_set_spinner (priv->win, TRUE);
|
||||||
|
|
||||||
if (!photo_booth_focus (pb->cam_info))
|
SEND_COMMAND (pb, CONTROL_PHOTO);
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (pb, "OUT OF FOCUS!");
|
|
||||||
pb->state = PB_STATE_PREVIEW;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_element_set_state (pb->video_bin, GST_STATE_READY);
|
gst_element_set_state (pb->video_bin, GST_STATE_READY);
|
||||||
GST_DEBUG_OBJECT (pb, "photo_booth_preview! halt video_bin...");
|
GST_DEBUG_OBJECT (pb, "photo_booth_preview! halt video_bin...");
|
||||||
|
@ -735,30 +752,28 @@ static void photo_booth_snapshot (PhotoBooth *pb)
|
||||||
ret = gst_element_link (pb->photo_bin, pb->pixoverlay);
|
ret = gst_element_link (pb->photo_bin, pb->pixoverlay);
|
||||||
GST_DEBUG_OBJECT (pb, "linking %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT " ret=%i", pb->photo_bin, pb->pixoverlay, ret);
|
GST_DEBUG_OBJECT (pb, "linking %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT " ret=%i", pb->photo_bin, pb->pixoverlay, ret);
|
||||||
gst_element_set_state (pb->photo_bin, GST_STATE_PLAYING);
|
gst_element_set_state (pb->photo_bin, GST_STATE_PLAYING);
|
||||||
|
}
|
||||||
|
|
||||||
char *data;
|
static gboolean photo_booth_snapshot_taken (PhotoBooth *pb)
|
||||||
unsigned long size;
|
|
||||||
ret = photo_booth_take_photo (pb->cam_info, (const char**)&data, &size);
|
|
||||||
if (ret)
|
|
||||||
{
|
{
|
||||||
|
GST_INFO_OBJECT (pb, "photo_booth_snapshot_taken size=%lu", pb->cam_info->size);
|
||||||
|
|
||||||
GstElement *appsrc = gst_bin_get_by_name (GST_BIN (pb->photo_bin), "photo-appsrc");
|
GstElement *appsrc = gst_bin_get_by_name (GST_BIN (pb->photo_bin), "photo-appsrc");
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstFlowReturn flowret;
|
GstFlowReturn flowret;
|
||||||
|
|
||||||
buffer = gst_buffer_new_wrapped (data, size);
|
buffer = gst_buffer_new_wrapped (pb->cam_info->data, pb->cam_info->size);
|
||||||
g_signal_emit_by_name (appsrc, "push-buffer", buffer, &flowret);
|
g_signal_emit_by_name (appsrc, "push-buffer", buffer, &flowret);
|
||||||
|
|
||||||
if (flowret != GST_FLOW_OK)
|
if (flowret != GST_FLOW_OK)
|
||||||
GST_ERROR_OBJECT(appsrc, "couldn't push %" GST_PTR_FORMAT " to appsrc", buffer);
|
GST_ERROR_OBJECT(appsrc, "couldn't push %" GST_PTR_FORMAT " to appsrc", buffer);
|
||||||
gst_object_unref (appsrc);
|
gst_object_unref (appsrc);
|
||||||
GST_INFO_OBJECT (pb, "photo_booth_snapshot now waiting for user input... PB_STATE_ASKING");
|
GST_INFO_OBJECT (pb, "photo_booth_snapshot now waiting for user input... PB_STATE_ASKING");
|
||||||
|
|
||||||
|
SEND_COMMAND (pb, CONTROL_PAUSE);
|
||||||
pb->state = PB_STATE_ASKING;
|
pb->state = PB_STATE_ASKING;
|
||||||
return;
|
|
||||||
}
|
return FALSE; // prevent continously re-running
|
||||||
GST_INFO_OBJECT (pb, "photo_booth_take_photo_push_to_appsrc failed!");
|
|
||||||
gst_element_set_state (pb->pipeline, GST_STATE_NULL);
|
|
||||||
g_main_loop_quit (pb->loop);
|
|
||||||
// photo_booth_preview (pb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoBooth *photo_booth_new (void)
|
PhotoBooth *photo_booth_new (void)
|
||||||
|
|
20
photobooth.h
20
photobooth.h
|
@ -23,9 +23,10 @@
|
||||||
#include <gphoto2/gphoto2.h>
|
#include <gphoto2/gphoto2.h>
|
||||||
#include <gphoto2/gphoto2-camera.h>
|
#include <gphoto2/gphoto2-camera.h>
|
||||||
|
|
||||||
#define CONTROL_RUN 'R' /* start movie capture */
|
#define CONTROL_VIDEO 'V' /* start movie capture */
|
||||||
#define CONTROL_PAUSE 'P' /* pause movie capture */
|
#define CONTROL_PHOTO 'T' /* photo capture */
|
||||||
#define CONTROL_STOP 'S' /* stop movie capture */
|
#define CONTROL_PAUSE 'P' /* pause capture */
|
||||||
|
#define CONTROL_STOP 'S' /* stop capture thread */
|
||||||
#define CONTROL_SOCKETS(src) src->control_sock
|
#define CONTROL_SOCKETS(src) src->control_sock
|
||||||
#define WRITE_SOCKET(src) src->control_sock[1]
|
#define WRITE_SOCKET(src) src->control_sock[1]
|
||||||
#define READ_SOCKET(src) src->control_sock[0]
|
#define READ_SOCKET(src) src->control_sock[0]
|
||||||
|
@ -56,15 +57,18 @@ struct _CameraInfo {
|
||||||
GPContext *context;
|
GPContext *context;
|
||||||
GMutex mutex;
|
GMutex mutex;
|
||||||
int preview_capture_count;
|
int preview_capture_count;
|
||||||
|
char *data;
|
||||||
|
unsigned long size;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CAPTURETHREAD_NONE = 0,
|
CAPTURE_NONE = 0,
|
||||||
CAPTURETHREAD_STOP,
|
CAPTURE_VIDEO,
|
||||||
CAPTURETHREAD_PAUSED,
|
CAPTURE_PHOTO,
|
||||||
CAPTURETHREAD_RUN,
|
CAPTURE_PAUSED,
|
||||||
} PhotoboothReadthreadState;
|
CAPTURE_STOP,
|
||||||
|
} PhotoboothCaptureThreadState;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue