diff options
author | Marcus Meissner <marcus@jet.franken.de> | 2010-04-01 21:28:56 +0000 |
---|---|---|
committer | Marcus Meissner <marcus@jet.franken.de> | 2010-04-01 21:28:56 +0000 |
commit | 1f9373e7719ffc877cb22e352e4ecb82f3c211eb (patch) | |
tree | 244fede6d241892accaec75d3ced2fbdfad86ad7 /examples | |
parent | 53f6d9cd6f295675960c0761d56dcbd7e7d1ebdc (diff) | |
download | libgphoto2-1f9373e7719ffc877cb22e352e4ecb82f3c211eb.tar.gz |
added new trigger capture sample program (not fully working yet)
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@12885 67ed7778-7388-44ab-90cf-0a291f65f57c
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Makefile.am | 8 | ||||
-rw-r--r-- | examples/README | 2 | ||||
-rw-r--r-- | examples/sample-trigger-capture.c | 230 |
3 files changed, 239 insertions, 1 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am index 4da77511a..2b4adb623 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -21,13 +21,19 @@ INSTALL_TESTS_ENVIRONMENT = env \ CLEANFILES = $(check_SCRIPTS) -noinst_PROGRAMS += sample-autodetect sample-multi-detect lunkwill-canon-capture sample-owner sample-preview sample-capture +noinst_PROGRAMS += \ + sample-autodetect sample-multi-detect \ + lunkwill-canon-capture \ + sample-owner \ + sample-preview \ + sample-capture sample-trigger-capture sample_autodetect_SOURCES = sample-autodetect.c samples.h context.c config.c sample_owner_SOURCES = sample-owner.c samples.h context.c config.c sample_multi_detect_SOURCES = sample-multi-detect.c samples.h autodetect.c context.c config.c lunkwill_canon_capture_SOURCES = lunkwill-canon-capture.c context.c samples.h config.c sample_capture_SOURCES = sample-capture.c context.c samples.h config.c +sample_trigger_capture_SOURCES = sample-trigger-capture.c context.c samples.h config.c sample_preview_SOURCES = preview.c samples.h context.c config.c LDADD = $(top_builddir)/libgphoto2/libgphoto2.la \ diff --git a/examples/README b/examples/README index cd1b673a7..4b68f9ebd 100644 --- a/examples/README +++ b/examples/README @@ -25,6 +25,8 @@ Files with samples: sample-capture.c: Minimalistic remote capture sample. + sample-trigger-capture.c: New capture trigger and then loop example. + lunkwill-canon-capture.c: A simple capture program that captures a single image, retrieves it to disk, and removes it from the camera. diff --git a/examples/sample-trigger-capture.c b/examples/sample-trigger-capture.c new file mode 100644 index 000000000..d893ea288 --- /dev/null +++ b/examples/sample-trigger-capture.c @@ -0,0 +1,230 @@ +/* + */ + +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <gphoto2/gphoto2.h> + +#include "samples.h" + +static void +errordumper(GPLogLevel level, const char *domain, const char *str, void *data) { + fprintf(stderr, "%s\n", str); +} + +static void +capture_to_memory(Camera *camera, GPContext *context, const char **ptr, unsigned long int *size) { + int retval; + CameraFile *file; + CameraFilePath camera_file_path; + + printf("Capturing.\n"); + + /* NOP: This gets overridden in the library to /capt0000.jpg */ + strcpy(camera_file_path.folder, "/"); + strcpy(camera_file_path.name, "foo.jpg"); + + retval = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context); + printf(" Retval: %d\n", retval); + + printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name); + + retval = gp_file_new(&file); + printf(" Retval: %d\n", retval); + retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name, + GP_FILE_TYPE_NORMAL, file, context); + printf(" Retval: %d\n", retval); + + gp_file_get_data_and_size (file, ptr, size); + + printf("Deleting.\n"); + retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name, + context); + printf(" Retval: %d\n", retval); + + gp_file_free(file); +} + +static void +capture_to_file(Camera *camera, GPContext *context, char *fn) { + int fd, retval; + CameraFile *file; + CameraFilePath camera_file_path; + + printf("Capturing.\n"); + + /* NOP: This gets overridden in the library to /capt0000.jpg */ + strcpy(camera_file_path.folder, "/"); + strcpy(camera_file_path.name, "foo.jpg"); + + retval = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context); + printf(" Retval: %d\n", retval); + + printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name); + + fd = open(fn, O_CREAT | O_WRONLY, 0644); + retval = gp_file_new_from_fd(&file, fd); + printf(" Retval: %d\n", retval); + retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name, + GP_FILE_TYPE_NORMAL, file, context); + printf(" Retval: %d\n", retval); + + printf("Deleting.\n"); + retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name, + context); + printf(" Retval: %d\n", retval); + + gp_file_free(file); +} + +static struct queue_entry { + CameraFilePath path; + int offset; +} *queue = NULL; +static int nrofqueue=0; +static int nrdownloads=0; + +static char *buffer; +static int buffersize = 256*1024; + +static int +wait_event_and_download (Camera *camera, int waittime, GPContext *context) { + CameraEventType evtype; + CameraFilePath *path; + void *data; + int retval; + + data = NULL; + if (nrofqueue) + waittime = 10; /* just drain the event queue */ + retval = gp_camera_wait_for_event(camera, waittime, &evtype, &data, context); + if (retval != GP_OK) { + fprintf (stderr, "return from waitevent in trigger sample with %d\n", retval); + return retval; + } + path = data; + switch (evtype) { + case GP_EVENT_CAPTURE_COMPLETE: + fprintf (stderr, "wait for event CAPTURE_COMPLETE\n"); + break; + case GP_EVENT_UNKNOWN: + case GP_EVENT_TIMEOUT: + break; + case GP_EVENT_FOLDER_ADDED: + fprintf (stderr, "wait for event FOLDER_ADDED\n"); + break; + case GP_EVENT_FILE_ADDED: + fprintf (stderr, "File %s / %s added to queue.\n", path->folder, path->name); + if (nrofqueue) { + struct queue_entry *q; + q = realloc(queue, sizeof(struct queue_entry)*(nrofqueue+1)); + if (!q) return GP_ERROR_NO_MEMORY; + queue = q; + } else { + queue = malloc (sizeof(struct queue_entry)); + if (!queue) return GP_ERROR_NO_MEMORY; + } + memcpy (&queue[nrofqueue].path, path, sizeof(CameraFilePath)); + queue[nrofqueue].offset = 0; + nrofqueue++; + break; + } + if (nrofqueue) { + uint64_t size = buffersize; + int fd; + struct stat stbuf; + + if (queue[0].offset == 0) + fprintf(stderr,"starting download %d\n", ++nrdownloads); + fprintf(stderr,"camera readfile of %s / %s at offset %d\n", + queue[0].path.folder, + queue[0].path.name, + queue[0].offset + ); + retval = gp_camera_file_read (camera, + queue[0].path.folder, + queue[0].path.name, + GP_FILE_TYPE_NORMAL, + queue[0].offset, + buffer, + &size, + context + ); + fprintf(stderr,"done camera readfile size was %d\n", size); + if (retval != GP_OK) { + fprintf (stderr,"gp_camera_file_read failed: %d\n", retval); + return retval; + } + if (-1 == stat(queue[0].path.name, &stbuf)) + fd = creat(queue[0].path.name, 0644); + else + fd = open(queue[0].path.name, O_RDWR, 0644); + if (fd == -1) perror(queue[0].path.name); + if (-1 == lseek(fd, queue[0].offset, SEEK_SET)) + perror("lseek"); + if (-1 == write (fd, buffer, size)) + perror("write"); + close (fd); + queue[0].offset += size; + if (size != buffersize) { + fprintf(stderr, "%s/%s is at end of file (read %d of %d bytes)\n", + queue[0].path.folder, queue[0].path.name, + (int)size, buffersize + ); + fprintf(stderr,"ending download %d, deleting file.\n", nrdownloads); + retval = gp_camera_file_delete(camera, queue[0].path.folder, queue[0].path.name, context); + memmove(&queue[0],&queue[1],sizeof(queue[0])*(nrofqueue-1)); + nrofqueue--; + } + } + return GP_OK; +} + +int +main(int argc, char **argv) { + Camera *camera; + int retval, nrcapture = 0; + time_t lastsec; + GPContext *context = sample_create_context(); + + buffer = malloc(buffersize); + if (!buffer) exit(1); + + gp_log_add_func(GP_LOG_ERROR, errordumper, NULL); + //gp_log_add_func(GP_LOG_DEBUG, errordumper, NULL); + gp_camera_new(&camera); + + lastsec = time(NULL); + + /* When I set GP_LOG_DEBUG instead of GP_LOG_ERROR above, I noticed that the + * init function seems to traverse the entire filesystem on the camera. This + * is partly why it takes so long. + * (Marcus: the ptp2 driver does this by default currently.) + */ + retval = gp_camera_init(camera, context); + if (retval != GP_OK) { + printf("gp_camera_init: %d\n", retval); + exit (1); + } + while (1) { + if (lastsec + 3 <= time(NULL)) { + lastsec = time(NULL); + //fprintf(stderr,"triggering capture %d\n", ++nrcapture); + retval = gp_camera_trigger_capture (camera, context); + if (retval != GP_OK) + break; + //fprintf (stderr, "done triggering\n"); + } + //fprintf(stderr,"waiting for events\n"); + wait_event_and_download(camera, 100, context); + //fprintf(stderr,"end waiting for events\n"); + } + gp_camera_exit(camera, context); + return 0; +} |