Loading camogm.c +50 −1 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <linux/limits.h> #include <linux/fs.h> //#include <ctype.h> //#include <getopt.h> #include <time.h> Loading Loading @@ -230,6 +231,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d); void camogm_set_max_frames(camogm_state *state, int d); void camogm_set_frames_per_chunk(camogm_state *state, int d); uint64_t get_disk_size(const char *name); //!====================================================================================================== void put_uint16(void *buf, u_int16_t val) Loading Loading @@ -323,6 +325,11 @@ void camogm_init(camogm_state *state, unsigned int port, char *pipe_name) state->port_num = port; state->pipe_name = pipe_name; state->rawdev.start_pos = RAWDEV_START_OFFSET; state->rawdev.end_pos = state->rawdev.start_pos; state->rawdev.curr_pos = state->rawdev.start_pos; state->rawdev.overrun = 0; state->rawdev_op = 0; } Loading Loading @@ -732,7 +739,7 @@ int camogm_stop(camogm_state *state) switch (state->format) { case CAMOGM_FORMAT_NONE: rslt = 0; break; case CAMOGM_FORMAT_OGM: rslt = camogm_end_ogm(state); break; case CAMOGM_FORMAT_JPEG: rslt = camogm_end_jpeg(); break; case CAMOGM_FORMAT_JPEG: rslt = camogm_end_jpeg(state); break; case CAMOGM_FORMAT_MOV: rslt = camogm_end_mov(state); break; /// default: return 0; // do nothing } Loading Loading @@ -838,6 +845,23 @@ void camogm_set_prefix(camogm_state *state, const char * p) { strncpy(state->path_prefix, p, sizeof(state->path_prefix) - 1); state->path_prefix[sizeof(state->path_prefix) - 1] = '\0'; // check if we are going to write to raw device if (strncmp("/dev/", state->path_prefix, 5) == 0) { state->rawdev.end_pos = get_disk_size(state->path_prefix); if (state->rawdev.end_pos == 0) { state->rawdev_op = 0; state->rawdev.end_pos = state->rawdev.start_pos; state->path_prefix[0] = '\0'; printf("ERROR: unable to initiate raw device operation\n"); } else { printf("WARNING: raw device write initiated\n"); state->rawdev_op = 1; /* debug code follows */ state->rawdev.end_pos = state->rawdev.start_pos + 10485760; // 10Mib size } } else { state->rawdev_op = 0; } } void camogm_set_timescale(camogm_state *state, double d) //! set timescale, default=1,000,000 Loading Loading @@ -1511,6 +1535,31 @@ int listener_loop(camogm_state *state) return EXIT_SUCCESS; } /** * @brief Return disk size in bytes * * This function reads disk size using ioctl call. * @param name pointer to disk name string * @return disk size in bytes if it was read correctly and 0 otherwise */ uint64_t get_disk_size(const char *name) { int fd; uint64_t dev_sz; if ((fd = open(name, O_RDONLY)) < 0) { perror(__func__); return 0; } if (ioctl(fd, BLKGETSIZE64, &dev_sz) < 0) { perror(__func__); return 0; } close(fd); return dev_sz; } int main(int argc, char *argv[]) { const char usage[] = "This program allows recording of the video/images acquired by Elphel camera to the storage media.\n" \ Loading camogm.h +15 −1 Original line number Diff line number Diff line Loading @@ -72,6 +72,18 @@ #define Exif_GPSInfo_CompassRoll_Index 0x10 #define ExifKmlNumber 0x11 */ /** @brief Offset from the beginning of raw device buffer. Must be aligned to physical sector size */ #define RAWDEV_START_OFFSET 1024 typedef struct { int rawdev_fd; uint64_t start_pos; uint64_t end_pos; uint64_t curr_pos; uint32_t overrun; } rawdev_buffer; typedef struct { int segment_duration; int segment_length; Loading Loading @@ -158,8 +170,10 @@ typedef struct { int kml_last_uts; //! last generated kml file timestamp, microseconds struct exif_dir_table_t kml_exif[ExifKmlNumber]; //! store locations of the fields needed for KML generations in the Exif block unsigned int port_num; // sensor port this state assigned to unsigned int port_num; // sensor port this state is assigned to char *pipe_name; // command pipe name for this sensor port int rawdev_op; // flag indicating writing to raw device rawdev_buffer rawdev; // contains pointers to raw device buffer } camogm_state; extern int debug_level; Loading camogm_jpeg.c +136 −42 Original line number Diff line number Diff line Loading @@ -34,35 +34,54 @@ *! Initial release of camogm - program to record video/image to the camera hard drive (or other storage) *! */ #define LARGEFILES64_SOURCE //!Not all are needed, just copied from the camogm.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> //#include <signal.h> #include <fcntl.h> #include <sys/uio.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> //#include <sys/socket.h> //#include <sys/stat.h> //#include <ctype.h> //#include <getopt.h> #include <time.h> //#include <time.h> #include <string.h> #include <netinet/in.h> /*little <-> big endian ?*/ #include <sys/mman.h> /* mmap */ #include <sys/ioctl.h> //#include <sys/mman.h> /* mmap */ //#include <sys/ioctl.h> #include <c313a.h> #include <asm/byteorder.h> #include <assert.h> #include <ogg/ogg.h> // has to be before ogmstreams.h #include "ogmstreams.h" // move it to <>? #include "camogm_jpeg.h" /** @brief Size of iovec structures holding data to be written */ #define IOVEC_SIZE 10 /** @brief Start of file marker, contains "elphelst" string in ASCII symbols */ const unsigned char elphelst[] = {0x65, 0x6c, 0x70, 0x68, 0x65, 0x6c, 0x73, 0x74}; /** @brief End of file marker, contains "elphelen" string in ASCII symbols */ const unsigned char elphelen[] = {0x65, 0x6c, 0x70, 0x68, 0x65, 0x6c, 0x65, 0x6e}; static struct iovec start_marker = { .iov_base = elphelst, .iov_len = sizeof(elphelst) }; static struct iovec end_marker = { .iov_base = elphelen, .iov_len = sizeof(elphelen) }; //! may add something - called first time format is changed to this one (only once) recording is stopped int camogm_init_jpeg(void) { Loading @@ -78,6 +97,7 @@ int camogm_start_jpeg(camogm_state *state) char * slash; int rslt; if (!state->rawdev_op) { strcpy(state->path, state->path_prefix); //!make state->path a directory name (will be replaced when the frames will be written) slash = strrchr(state->path, '/'); D2(fprintf(debug_file, "camogm_start_jpeg\n")); Loading @@ -92,16 +112,32 @@ int camogm_start_jpeg(camogm_state *state) return -CAMOGM_FRAME_FILE_ERR; } } } else { state->ivf = open(state->path_prefix, O_RDWR); if (state->ivf < 0) { D0(perror(__func__)); D0(fprintf(debug_file, "Error opening raw device %s\n", state->path)); return -CAMOGM_FRAME_FILE_ERR; } D0(fprintf(debug_file, "Open raw device %s; start_pos = %llu, end_pos = %llu, curr_pos = %llu\n", state->path, state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos)); lseek64(state->ivf, state->rawdev.curr_pos, SEEK_SET); } return 0; } int camogm_frame_jpeg(camogm_state *state) { int i, j; // int fd; int i, j, split_index; int chunks_used = state->chunk_index - 1; ssize_t iovlen, l; struct iovec chunks_iovec[7]; struct iovec chunks_iovec[8]; unsigned char *split_ptr = NULL; long split_cntr; long total_len; const uint64_t storage_sz = state->rawdev.end_pos - state->rawdev.start_pos; if (!state->rawdev_op) { l = 0; for (i = 0; i < (state->chunk_index) - 1; i++) { chunks_iovec[i].iov_base = state->packetchunks[i + 1].chunk; Loading @@ -110,14 +146,10 @@ int camogm_frame_jpeg(camogm_state *state) } sprintf(state->path, "%s%010ld_%06ld.jpeg", state->path_prefix, state->this_frame_params.timestamp_sec, state->this_frame_params.timestamp_usec); // if ((devfd = open("/dev/fpgaio", O_RDWR))<0) {printf("error opening /dev/fpgaio\r\n"); return -1;} //_1__12_Error opening /tmp/z/video1195147018_273452.jpeg for writing if (((state->ivf = open(state->path, O_RDWR | O_CREAT, 0777))) < 0) { D0(fprintf(debug_file, "Error opening %s for writing, returned %d, errno=%d\n", state->path, state->ivf, errno)); return -CAMOGM_FRAME_FILE_ERR; } iovlen = writev(state->ivf, chunks_iovec, (state->chunk_index) - 1); if (iovlen < l) { j = errno; Loading @@ -126,10 +158,72 @@ int camogm_frame_jpeg(camogm_state *state) return -CAMOGM_FRAME_FILE_ERR; } close(state->ivf); } else { D0(fprintf(debug_file, "\n%s: current pointers start_pos = %llu, end_pos = %llu, curr_pos = %llu, data in buffer %d\n", __func__, state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos, l)); l = 0; split_index = -1; for (int i = 0, total_len = 0; i < state->chunk_index - 1; i++) { total_len += state->packetchunks[i + 1].bytes; if (total_len + state->rawdev.curr_pos > state->rawdev.end_pos) { split_index = i; chunks_used++; D0(fprintf(debug_file, "\n>>> raw storage roll over detected\n")); break; } } chunks_iovec[0] = start_marker; for (int i = 1; i < chunks_used; i++) { if (i == split_index) { // one of the chunks rolls over the end of the raw storage, split it into two segments and // use additional chunk in chunks_iovec for this additional segment split_cntr = state->rawdev.end_pos - (l + state->rawdev.curr_pos); split_ptr = state->packetchunks[i].chunk + split_cntr; // be careful with indexes here chunks_iovec[i].iov_base = state->packetchunks[i].chunk; chunks_iovec[i].iov_len = split_cntr; l += chunks_iovec[i].iov_len; chunks_iovec[++i].iov_base = split_ptr + 1; chunks_iovec[i].iov_len = state->packetchunks[i].bytes - split_cntr; l += chunks_iovec[i].iov_len; } else { chunks_iovec[i].iov_base = state->packetchunks[i].chunk; chunks_iovec[i].iov_len = state->packetchunks[i].bytes; l += chunks_iovec[i].iov_len; } } assert(chunks_used < IOVEC_SIZE); // consider start_marker here and increment chunks_used chunks_iovec[chunks_used++] = end_marker; /* debug code follows */ fprintf(debug_file, "\n=== raw device write, iovec dump ===\n"); fprintf(debug_file, "split_cntr = %ld; split_ptr = %p; split_index = %d\n", split_cntr, split_ptr, split_index); for (int i = 0; i < chunks_used; i++) { fprintf(debug_file, "i = %d; iov_base = %p; iov_len = %u\n", i, chunks_iovec[i].iov_base, chunks_iovec[i].iov_len); } fprintf(debug_file, "total len = %d\n======\n", l); /* end of debug code */ iovlen = writev(state->ivf, chunks_iovec, chunks_used); if (iovlen < l) { j = errno; D0(fprintf(debug_file, "writev error %d (returned %d, expected %d)\n", j, iovlen, l)); return -CAMOGM_FRAME_FILE_ERR; } state->rawdev.curr_pos += l; if (state->rawdev.curr_pos > state->rawdev.end_pos) state->rawdev.curr_pos = state->rawdev.curr_pos - state->rawdev.end_pos + state->rawdev.start_pos; D0(fprintf(debug_file, "%d bytes written, curr_pos = %llu\n", l, state->rawdev.curr_pos)); } return 0; } int camogm_end_jpeg(void) int camogm_end_jpeg(camogm_state *state) { close(state->ivf); D0(fprintf(debug_file, "Closing raw device %s\n", state->path_prefix)); return 0; } camogm_jpeg.h +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ int camogm_init_jpeg(void); int camogm_start_jpeg(camogm_state *state); int camogm_frame_jpeg(camogm_state *state); int camogm_end_jpeg(void); int camogm_end_jpeg(camogm_state *state); void camogm_free_jpeg(void); #endif /* _CAMOGM_JPEG_H */ Loading
camogm.c +50 −1 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <linux/limits.h> #include <linux/fs.h> //#include <ctype.h> //#include <getopt.h> #include <time.h> Loading Loading @@ -230,6 +231,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d); void camogm_set_max_frames(camogm_state *state, int d); void camogm_set_frames_per_chunk(camogm_state *state, int d); uint64_t get_disk_size(const char *name); //!====================================================================================================== void put_uint16(void *buf, u_int16_t val) Loading Loading @@ -323,6 +325,11 @@ void camogm_init(camogm_state *state, unsigned int port, char *pipe_name) state->port_num = port; state->pipe_name = pipe_name; state->rawdev.start_pos = RAWDEV_START_OFFSET; state->rawdev.end_pos = state->rawdev.start_pos; state->rawdev.curr_pos = state->rawdev.start_pos; state->rawdev.overrun = 0; state->rawdev_op = 0; } Loading Loading @@ -732,7 +739,7 @@ int camogm_stop(camogm_state *state) switch (state->format) { case CAMOGM_FORMAT_NONE: rslt = 0; break; case CAMOGM_FORMAT_OGM: rslt = camogm_end_ogm(state); break; case CAMOGM_FORMAT_JPEG: rslt = camogm_end_jpeg(); break; case CAMOGM_FORMAT_JPEG: rslt = camogm_end_jpeg(state); break; case CAMOGM_FORMAT_MOV: rslt = camogm_end_mov(state); break; /// default: return 0; // do nothing } Loading Loading @@ -838,6 +845,23 @@ void camogm_set_prefix(camogm_state *state, const char * p) { strncpy(state->path_prefix, p, sizeof(state->path_prefix) - 1); state->path_prefix[sizeof(state->path_prefix) - 1] = '\0'; // check if we are going to write to raw device if (strncmp("/dev/", state->path_prefix, 5) == 0) { state->rawdev.end_pos = get_disk_size(state->path_prefix); if (state->rawdev.end_pos == 0) { state->rawdev_op = 0; state->rawdev.end_pos = state->rawdev.start_pos; state->path_prefix[0] = '\0'; printf("ERROR: unable to initiate raw device operation\n"); } else { printf("WARNING: raw device write initiated\n"); state->rawdev_op = 1; /* debug code follows */ state->rawdev.end_pos = state->rawdev.start_pos + 10485760; // 10Mib size } } else { state->rawdev_op = 0; } } void camogm_set_timescale(camogm_state *state, double d) //! set timescale, default=1,000,000 Loading Loading @@ -1511,6 +1535,31 @@ int listener_loop(camogm_state *state) return EXIT_SUCCESS; } /** * @brief Return disk size in bytes * * This function reads disk size using ioctl call. * @param name pointer to disk name string * @return disk size in bytes if it was read correctly and 0 otherwise */ uint64_t get_disk_size(const char *name) { int fd; uint64_t dev_sz; if ((fd = open(name, O_RDONLY)) < 0) { perror(__func__); return 0; } if (ioctl(fd, BLKGETSIZE64, &dev_sz) < 0) { perror(__func__); return 0; } close(fd); return dev_sz; } int main(int argc, char *argv[]) { const char usage[] = "This program allows recording of the video/images acquired by Elphel camera to the storage media.\n" \ Loading
camogm.h +15 −1 Original line number Diff line number Diff line Loading @@ -72,6 +72,18 @@ #define Exif_GPSInfo_CompassRoll_Index 0x10 #define ExifKmlNumber 0x11 */ /** @brief Offset from the beginning of raw device buffer. Must be aligned to physical sector size */ #define RAWDEV_START_OFFSET 1024 typedef struct { int rawdev_fd; uint64_t start_pos; uint64_t end_pos; uint64_t curr_pos; uint32_t overrun; } rawdev_buffer; typedef struct { int segment_duration; int segment_length; Loading Loading @@ -158,8 +170,10 @@ typedef struct { int kml_last_uts; //! last generated kml file timestamp, microseconds struct exif_dir_table_t kml_exif[ExifKmlNumber]; //! store locations of the fields needed for KML generations in the Exif block unsigned int port_num; // sensor port this state assigned to unsigned int port_num; // sensor port this state is assigned to char *pipe_name; // command pipe name for this sensor port int rawdev_op; // flag indicating writing to raw device rawdev_buffer rawdev; // contains pointers to raw device buffer } camogm_state; extern int debug_level; Loading
camogm_jpeg.c +136 −42 Original line number Diff line number Diff line Loading @@ -34,35 +34,54 @@ *! Initial release of camogm - program to record video/image to the camera hard drive (or other storage) *! */ #define LARGEFILES64_SOURCE //!Not all are needed, just copied from the camogm.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> //#include <signal.h> #include <fcntl.h> #include <sys/uio.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> //#include <sys/socket.h> //#include <sys/stat.h> //#include <ctype.h> //#include <getopt.h> #include <time.h> //#include <time.h> #include <string.h> #include <netinet/in.h> /*little <-> big endian ?*/ #include <sys/mman.h> /* mmap */ #include <sys/ioctl.h> //#include <sys/mman.h> /* mmap */ //#include <sys/ioctl.h> #include <c313a.h> #include <asm/byteorder.h> #include <assert.h> #include <ogg/ogg.h> // has to be before ogmstreams.h #include "ogmstreams.h" // move it to <>? #include "camogm_jpeg.h" /** @brief Size of iovec structures holding data to be written */ #define IOVEC_SIZE 10 /** @brief Start of file marker, contains "elphelst" string in ASCII symbols */ const unsigned char elphelst[] = {0x65, 0x6c, 0x70, 0x68, 0x65, 0x6c, 0x73, 0x74}; /** @brief End of file marker, contains "elphelen" string in ASCII symbols */ const unsigned char elphelen[] = {0x65, 0x6c, 0x70, 0x68, 0x65, 0x6c, 0x65, 0x6e}; static struct iovec start_marker = { .iov_base = elphelst, .iov_len = sizeof(elphelst) }; static struct iovec end_marker = { .iov_base = elphelen, .iov_len = sizeof(elphelen) }; //! may add something - called first time format is changed to this one (only once) recording is stopped int camogm_init_jpeg(void) { Loading @@ -78,6 +97,7 @@ int camogm_start_jpeg(camogm_state *state) char * slash; int rslt; if (!state->rawdev_op) { strcpy(state->path, state->path_prefix); //!make state->path a directory name (will be replaced when the frames will be written) slash = strrchr(state->path, '/'); D2(fprintf(debug_file, "camogm_start_jpeg\n")); Loading @@ -92,16 +112,32 @@ int camogm_start_jpeg(camogm_state *state) return -CAMOGM_FRAME_FILE_ERR; } } } else { state->ivf = open(state->path_prefix, O_RDWR); if (state->ivf < 0) { D0(perror(__func__)); D0(fprintf(debug_file, "Error opening raw device %s\n", state->path)); return -CAMOGM_FRAME_FILE_ERR; } D0(fprintf(debug_file, "Open raw device %s; start_pos = %llu, end_pos = %llu, curr_pos = %llu\n", state->path, state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos)); lseek64(state->ivf, state->rawdev.curr_pos, SEEK_SET); } return 0; } int camogm_frame_jpeg(camogm_state *state) { int i, j; // int fd; int i, j, split_index; int chunks_used = state->chunk_index - 1; ssize_t iovlen, l; struct iovec chunks_iovec[7]; struct iovec chunks_iovec[8]; unsigned char *split_ptr = NULL; long split_cntr; long total_len; const uint64_t storage_sz = state->rawdev.end_pos - state->rawdev.start_pos; if (!state->rawdev_op) { l = 0; for (i = 0; i < (state->chunk_index) - 1; i++) { chunks_iovec[i].iov_base = state->packetchunks[i + 1].chunk; Loading @@ -110,14 +146,10 @@ int camogm_frame_jpeg(camogm_state *state) } sprintf(state->path, "%s%010ld_%06ld.jpeg", state->path_prefix, state->this_frame_params.timestamp_sec, state->this_frame_params.timestamp_usec); // if ((devfd = open("/dev/fpgaio", O_RDWR))<0) {printf("error opening /dev/fpgaio\r\n"); return -1;} //_1__12_Error opening /tmp/z/video1195147018_273452.jpeg for writing if (((state->ivf = open(state->path, O_RDWR | O_CREAT, 0777))) < 0) { D0(fprintf(debug_file, "Error opening %s for writing, returned %d, errno=%d\n", state->path, state->ivf, errno)); return -CAMOGM_FRAME_FILE_ERR; } iovlen = writev(state->ivf, chunks_iovec, (state->chunk_index) - 1); if (iovlen < l) { j = errno; Loading @@ -126,10 +158,72 @@ int camogm_frame_jpeg(camogm_state *state) return -CAMOGM_FRAME_FILE_ERR; } close(state->ivf); } else { D0(fprintf(debug_file, "\n%s: current pointers start_pos = %llu, end_pos = %llu, curr_pos = %llu, data in buffer %d\n", __func__, state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos, l)); l = 0; split_index = -1; for (int i = 0, total_len = 0; i < state->chunk_index - 1; i++) { total_len += state->packetchunks[i + 1].bytes; if (total_len + state->rawdev.curr_pos > state->rawdev.end_pos) { split_index = i; chunks_used++; D0(fprintf(debug_file, "\n>>> raw storage roll over detected\n")); break; } } chunks_iovec[0] = start_marker; for (int i = 1; i < chunks_used; i++) { if (i == split_index) { // one of the chunks rolls over the end of the raw storage, split it into two segments and // use additional chunk in chunks_iovec for this additional segment split_cntr = state->rawdev.end_pos - (l + state->rawdev.curr_pos); split_ptr = state->packetchunks[i].chunk + split_cntr; // be careful with indexes here chunks_iovec[i].iov_base = state->packetchunks[i].chunk; chunks_iovec[i].iov_len = split_cntr; l += chunks_iovec[i].iov_len; chunks_iovec[++i].iov_base = split_ptr + 1; chunks_iovec[i].iov_len = state->packetchunks[i].bytes - split_cntr; l += chunks_iovec[i].iov_len; } else { chunks_iovec[i].iov_base = state->packetchunks[i].chunk; chunks_iovec[i].iov_len = state->packetchunks[i].bytes; l += chunks_iovec[i].iov_len; } } assert(chunks_used < IOVEC_SIZE); // consider start_marker here and increment chunks_used chunks_iovec[chunks_used++] = end_marker; /* debug code follows */ fprintf(debug_file, "\n=== raw device write, iovec dump ===\n"); fprintf(debug_file, "split_cntr = %ld; split_ptr = %p; split_index = %d\n", split_cntr, split_ptr, split_index); for (int i = 0; i < chunks_used; i++) { fprintf(debug_file, "i = %d; iov_base = %p; iov_len = %u\n", i, chunks_iovec[i].iov_base, chunks_iovec[i].iov_len); } fprintf(debug_file, "total len = %d\n======\n", l); /* end of debug code */ iovlen = writev(state->ivf, chunks_iovec, chunks_used); if (iovlen < l) { j = errno; D0(fprintf(debug_file, "writev error %d (returned %d, expected %d)\n", j, iovlen, l)); return -CAMOGM_FRAME_FILE_ERR; } state->rawdev.curr_pos += l; if (state->rawdev.curr_pos > state->rawdev.end_pos) state->rawdev.curr_pos = state->rawdev.curr_pos - state->rawdev.end_pos + state->rawdev.start_pos; D0(fprintf(debug_file, "%d bytes written, curr_pos = %llu\n", l, state->rawdev.curr_pos)); } return 0; } int camogm_end_jpeg(void) int camogm_end_jpeg(camogm_state *state) { close(state->ivf); D0(fprintf(debug_file, "Closing raw device %s\n", state->path_prefix)); return 0; }
camogm_jpeg.h +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ int camogm_init_jpeg(void); int camogm_start_jpeg(camogm_state *state); int camogm_frame_jpeg(camogm_state *state); int camogm_end_jpeg(void); int camogm_end_jpeg(camogm_state *state); void camogm_free_jpeg(void); #endif /* _CAMOGM_JPEG_H */