aboutsummaryrefslogtreecommitdiff
path: root/gphoto
diff options
context:
space:
mode:
authorB. Bogart <bbogart@users.sourceforge.net>2009-03-29 04:40:00 +0000
committerB. Bogart <bbogart@users.sourceforge.net>2009-03-29 04:40:00 +0000
commitac294f862525f3d573b9de6a98ae249454e8b716 (patch)
treef48c814b14fa9ac133bf0d546800a8c1e7c2bf1a /gphoto
parentb6d7291115368ab2381f75abaf3b73d4cc109084 (diff)
The captureimages method worked a lot betterl, 10,000 iterations.
Unfortunatly PD only got 2,000 bangs and died. Need to figure that out. svn path=/trunk/externals/bbogart/; revision=10926
Diffstat (limited to 'gphoto')
-rw-r--r--gphoto/gphoto-help.pd8
-rw-r--r--gphoto/gphoto.c121
2 files changed, 127 insertions, 2 deletions
diff --git a/gphoto/gphoto-help.pd b/gphoto/gphoto-help.pd
index 2eacadc..5772ff6 100644
--- a/gphoto/gphoto-help.pd
+++ b/gphoto/gphoto-help.pd
@@ -1,4 +1,4 @@
-#N canvas 479 0 638 746 10;
+#N canvas 577 0 638 746 10;
#X msg 83 48 getconfig model;
#X msg 142 83 getconfig capture;
#X msg 167 116 getconfig zoom;
@@ -21,6 +21,9 @@
#X msg 18 158 reset;
#X msg 208 154 setconfig iso \$1;
#X symbolatom 320 153 10 0 0 0 - - -;
+#X msg 135 473 captureimages stop;
+#X msg 45 508 captureimages /store/stills/image-%d;
+#X msg 135 453 captureimages /store/stills/image-%05d.jpg 2;
#X connect 0 0 16 0;
#X connect 1 0 16 0;
#X connect 2 0 16 0;
@@ -39,3 +42,6 @@
#X connect 18 0 16 0;
#X connect 19 0 16 0;
#X connect 20 0 19 0;
+#X connect 21 0 16 0;
+#X connect 22 0 16 0;
+#X connect 23 0 16 0;
diff --git a/gphoto/gphoto.c b/gphoto/gphoto.c
index 5eb982a..407c761 100644
--- a/gphoto/gphoto.c
+++ b/gphoto/gphoto.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <string.h>
#include <m_pd.h>
#include <fcntl.h>
@@ -35,7 +36,7 @@ typedef struct gphoto_struct {
t_outlet *doneOutlet;
int busy;
pthread_attr_t threadAttr; //thread attributes
-
+ int capturing;
} gphoto_struct;
// Struct to store A_GIMME data passed to thread.
@@ -630,6 +631,123 @@ static void reset(gphoto_struct *gphoto) {
return;
}
+void *captureImages(void *threadArgs) {
+ int gp_ret, fd;
+ Camera *camera;
+ CameraFile *camerafile;
+ CameraFilePath camera_file_path;
+ t_symbol *format;
+ char filename[MAXPDSTRING];
+ int count;
+ int sleepTime;
+
+ sys_lock();
+ format = atom_getsymbol( ((gphoto_gimme_struct *)threadArgs)->argv ); // destination filename
+ sleepTime = atom_getint ( ((gphoto_gimme_struct *)threadArgs)->argv+1 ); // loop sleep delay
+ post("format: %s", format->s_name);
+ post("sleeptime: %d", sleepTime);
+ sys_unlock();
+
+ gp_ret = gp_camera_new (&camera);
+ if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(camera); return(NULL);}
+
+ // INIT camera (without context)
+ gp_ret = gp_camera_init (camera, NULL);
+ if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); }
+ if (gp_ret == -105) {
+ sys_lock();
+ error("gphoto: Are you sure the camera is supported, connected and powered on?");
+ sys_unlock();
+ gp_camera_unref(camera);
+ ((gphoto_gimme_struct *)threadArgs)->gphoto->busy = 0; // no longer busy if we got an error.
+ return(NULL);
+ }
+
+ count = 0;
+ while (((gphoto_gimme_struct *)threadArgs)->gphoto->capturing) {
+
+ // Create filename from format. This does not check if the format string is suitable.
+ sprintf(&filename, format->s_name, count);
+
+ gp_ret = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, NULL);
+ if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(camera); return(NULL);}
+
+ fd = open( filename, O_CREAT | O_WRONLY, 0644); // create file descriptor
+
+ gp_ret = gp_file_new_from_fd(&camerafile, fd); // create gphoto file from descriptor
+ if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(camera); return(NULL);}
+
+ gp_ret = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name, GP_FILE_TYPE_NORMAL, camerafile, NULL); // get file from camera
+ if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(camera); return(NULL);}
+
+ gp_ret = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name, NULL);
+ if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(camera); return(NULL);}
+
+ close(fd); // close file descriptor
+
+ // Send bang out 2nd outlet for each iteration.
+ sys_lock();
+ outlet_bang(((gphoto_gimme_struct *)threadArgs)->gphoto->doneOutlet);
+ sys_unlock();
+
+ sleep(sleepTime);
+ count++;
+ }
+
+ // Free memory
+ gp_camera_free(camera);
+
+ // We are done and other messsages can now be sent.
+ ((gphoto_gimme_struct *)threadArgs)->gphoto->busy = 0;
+
+ pthread_exit(NULL);
+}
+
+// Wrap captureImage
+// TODO is there a way to have one wrapper for all funcs?
+static void wrapCaptureImages(gphoto_struct *gphoto, t_symbol *s, int argc, t_atom *argv) {
+ int ret;
+ pthread_t thread1;
+
+ if (strcmp(atom_getsymbol(argv)->s_name, "stop") == 0) {
+
+ gphoto->capturing = 0; // Stop Capturing.
+ gphoto->busy = 0; // No longer busy
+ post("cap stop");
+
+ } else if (!gphoto->busy) {
+
+ if (argc != 2) {
+ error("gphoto: ERROR: usage: captureimages [filename-format] [sleeptime (seconds)]");
+ } else {
+
+ post("cap start");
+ gphoto->capturing = 1; // Now capturing.
+
+ // instance of structure
+ gphoto_gimme_struct *threadArgs = (gphoto_gimme_struct *)malloc(sizeof(gphoto_gimme_struct));
+
+ // packaging arguments into structure
+ threadArgs->gphoto = gphoto;
+ threadArgs->s = s;
+ threadArgs->argc = argc;
+ threadArgs->argv = argv;
+
+ // We're busy
+ gphoto->busy = 1;
+
+ // Create thread
+ ret = pthread_create( &thread1, &gphoto->threadAttr, captureImages, threadArgs);
+ }
+
+ } else {
+
+ error("gphoto: ERROR: Already executing a command, try again later.");
+ }
+
+ return;
+}
+
static void *gphoto_new(void) {
gphoto_struct *gphoto = (gphoto_struct *) pd_new(gphoto_class);
outlet_new(&gphoto->x_obj, NULL);
@@ -656,6 +774,7 @@ void gphoto_setup(void) {
class_addmethod(gphoto_class, (t_method) wrapGetConfig, gensym("getconfig"), A_GIMME, 0);
class_addmethod(gphoto_class, (t_method) wrapGetConfigDetail, gensym("configdetail"), A_GIMME, 0);
class_addmethod(gphoto_class, (t_method) wrapCaptureImage, gensym("captureimage"), A_GIMME, 0);
+ class_addmethod(gphoto_class, (t_method) wrapCaptureImages, gensym("captureimages"), A_GIMME, 0);
class_addmethod(gphoto_class, (t_method) wrapSetConfig, gensym("setconfig"), A_GIMME, 0);
class_addmethod(gphoto_class, (t_method) wrapListConfig, gensym("listconfig"), 0);
class_addmethod(gphoto_class, (t_method) reset, gensym("reset"), 0);