Loading src/camogm.c +79 −53 Original line number Diff line number Diff line Loading @@ -387,6 +387,7 @@ int camogm_start(camogm_state *state) D3(fprintf(debug_file, "1a: compressed frame number = %li\n", lseek(state->fd_circ[chn], LSEEK_CIRC_GETFRAME, SEEK_END))); if ((state->cirbuf_rp[chn] < 0) || (lseek(state->fd_circ[chn], state->cirbuf_rp[chn], SEEK_SET) < 0) || (lseek(state->fd_circ[chn], LSEEK_CIRC_VALID, SEEK_END) < 0 )) { D3(fprintf(debug_file, "2: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn])); D3(fprintf(debug_file, "2.1: state->greedy=%d\n", state->greedy)); /* In "greedy" mode try to save as many frames from the circbuf as possible */ state->cirbuf_rp[chn] = lseek(state->fd_circ[chn], state->greedy ? LSEEK_CIRC_SCND : LSEEK_CIRC_LAST, SEEK_END); if (!state->ignore_fps) { // don't even try in ignore mode Loading Loading @@ -505,6 +506,7 @@ int camogm_start(camogm_state *state) read(state->fd_head[chn], state->jpegHeader[chn], state->head_size[chn]); // Restore read pointer to the original (now there may be no frame ready there yet) lseek(state->fd_circ[chn], state->cirbuf_rp[chn], SEEK_SET); state->image_size[chn] = 0; } } Loading Loading @@ -547,7 +549,10 @@ int sendImageFrame(camogm_state *state) int fd_exif_tiff; // switching between TIFF and Exif depending on coloe mode int port = state->port_num; struct timeval start_time, end_time; if (port < 0) { D3(fprintf(debug_file, "sendImageFrame:0: port < 0!\n")); return -CAMOGM_FRAME_BROKEN; } // start_time = get_fpga_time(state->fd_fparmsall[port], port); // This is probably needed only for Quicktime (not to exceed already allocated frame index) Loading Loading @@ -579,7 +584,8 @@ int sendImageFrame(camogm_state *state) } // is the frame ready? if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) { D3(fprintf(debug_file, "?6,fp=0x%x\n", fp)); //frame not ready, frame pointer seems valid, but not ready D4(fprintf(debug_file, "?6")) ; //frame not ready, frame pointer seems valid, but not ready D6(fprintf(debug_file, ",fp=0x%x\n", fp)); //frame not ready, frame pointer seems valid, but not ready return -CAMOGM_FRAME_NOT_READY; // frame pointer valid, but no frames yet } Loading @@ -594,7 +600,7 @@ int sendImageFrame(camogm_state *state) } // Get metadata D3(fprintf(debug_file, "_1_")); D4(fprintf(debug_file, "_1_")); state->metadata_start = state->cirbuf_rp[port] - 32; if (state->metadata_start < 0) state->metadata_start += state->circ_buff_size[port]; memcpy(&(state->this_frame_params[port]), (unsigned long* )&ccam_dma_buf[state->port_num][state->metadata_start >> 2], 32); Loading @@ -607,11 +613,11 @@ int sendImageFrame(camogm_state *state) D3(fprintf(debug_file, "sendImageFrame:8: frame broken\n")); return -CAMOGM_FRAME_BROKEN; } D3(fprintf(debug_file, "_2_")); D4(fprintf(debug_file, "_2_")); // find location of the timestamp and copy it to the frame_params structure timestamp_start = state->cirbuf_rp[port] + ((state->jpeg_len + CCAM_MMAP_META + 3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC; // magic shift - should index first byte of the time stamp if (timestamp_start >= state->circ_buff_size[port]) timestamp_start -= state->circ_buff_size[port]; D3(fprintf(debug_file, "_3_")); D4(fprintf(debug_file, "_3_")); memcpy(&(state->this_frame_params[port].timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8); // verify that the essential current frame params did not change, if they did - return an error (need new file header) if (!state->ignore_fps && ((state->frame_params[port].width != state->this_frame_params[port].width) || Loading @@ -635,9 +641,9 @@ int sendImageFrame(camogm_state *state) } D3(fprintf(debug_file, "_4_")); D4(fprintf(debug_file, "_4_")); if (state->exif) { D3(fprintf(debug_file, "_5_")); D4(fprintf(debug_file, "_5_")); fd_exif_tiff = (state->this_frame_params[port].color == COLORMODE_RAW)? state->fd_tiff[port] : state->fd_exif[port]; // update the Exif header with the current frame metadata state->exifSize[port] = lseek(fd_exif_tiff, 1, SEEK_END); // at the beginning of page 1 - position == page length Loading @@ -650,21 +656,21 @@ int sendImageFrame(camogm_state *state) } else state->exifSize[port] = 0; } else state->exifSize[port] = 0; D3(fprintf(debug_file, "_6_")); D4(fprintf(debug_file, "_6_")); // prepare a packet to be sent (a lst of memory chunks) state->chunk_index = 0; state->packetchunks[state->chunk_index ].bytes = 1; state->packetchunks[state->chunk_index++].chunk = &frame_packet_type; if (state->exif > 0) { // insert Exif/Tiff D3(fprintf(debug_file, "_7_")); D4(fprintf(debug_file, "_7_")); if (state->this_frame_params[port].color == COLORMODE_RAW) { // Tiff D3(fprintf(debug_file, "_8a_")); D4(fprintf(debug_file, "_8a_")); state->packetchunks[state->chunk_index ].bytes = state->exifSize[port]; // Tiff Header length state->packetchunks[state->chunk_index++].chunk = state->ed[port]; // Tiff Header } else { // JPEG/JP4 D3(fprintf(debug_file, "_8b_")); D4(fprintf(debug_file, "_8b_")); state->packetchunks[state->chunk_index ].bytes = 2; state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port]; state->packetchunks[state->chunk_index ].bytes = state->exifSize[port]; Loading @@ -673,16 +679,16 @@ int sendImageFrame(camogm_state *state) state->packetchunks[state->chunk_index++].chunk = &(state->jpegHeader[port][2]); } } else { D3(fprintf(debug_file, "_8_")); D4(fprintf(debug_file, "_8_")); state->packetchunks[state->chunk_index ].bytes = state->head_size[port]; state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port]; } D3(fprintf(debug_file, "_9_")); D4(fprintf(debug_file, "_9_")); /* Jpeg/Tiff image data may be split in two segments (rolled over buffer end) - process both variants */ if ((state->cirbuf_rp[port] + state->jpeg_len) > state->circ_buff_size[port]) { // two segments /* copy from the beginning of the frame to the end of the buffer */ D3(fprintf(debug_file, "_10_")); D4(fprintf(debug_file, "_10_")); state->packetchunks[state->chunk_index ].bytes = state->circ_buff_size[port] - state->cirbuf_rp[port]; state->packetchunks[state->chunk_index++].chunk = (unsigned char*)&ccam_dma_buf[state->port_num][state->cirbuf_rp[port] >> 2]; /* copy from the beginning of the buffer to the end of the frame */ Loading @@ -690,15 +696,15 @@ int sendImageFrame(camogm_state *state) state->packetchunks[state->chunk_index++].chunk = (unsigned char*)&ccam_dma_buf[state->port_num][0]; state->writer_params.segments = 2; } else { // single segment D3(fprintf(debug_file, "_11_")); D4(fprintf(debug_file, "_11_")); /* copy from the beginning of the frame to the end of the frame (no buffer rollovers) */ state->packetchunks[state->chunk_index ].bytes = state->jpeg_len; state->packetchunks[state->chunk_index++].chunk = (unsigned char*)&ccam_dma_buf[state->port_num][state->cirbuf_rp[port] >> 2]; state->writer_params.segments = 1; } D3(fprintf(debug_file, "\tcirbuf_rp[%d] = 0x%x\t", port, state->cirbuf_rp[port])); D3(fprintf(debug_file, "_12_\n")); D4(fprintf(debug_file, "\tcirbuf_rp[%d] = 0x%x\t", port, state->cirbuf_rp[port])); D5(fprintf(debug_file, "_12_\n")); if (state->this_frame_params[port].color != COLORMODE_RAW) { // Tiff state->packetchunks[state->chunk_index ].bytes = 2; state->packetchunks[state->chunk_index++].chunk = (unsigned char*)trailer; Loading @@ -717,20 +723,25 @@ int sendImageFrame(camogm_state *state) default: rslt = 0; // do nothing } if (rslt) { D3(fprintf(debug_file, "sendImageFrame:12: camogm_frame_***() returned %d\n", rslt)); D4(fprintf(debug_file, "sendImageFrame:12: camogm_frame_***() returned %d\n", rslt)); return rslt; } if (state->kml_used) rslt = camogm_frame_kml(state); // will turn on state->kml_used if it can if (rslt) return rslt; D3(fprintf(debug_file, "_14_")); D4(fprintf(debug_file, "_14_")); // advance frame pointer state->frameno++; state->cirbuf_rp[port] = lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END); D3(fprintf(debug_file, "\tcompressed frame number: %li\t", lseek(state->fd_circ[port], LSEEK_CIRC_GETFRAME, SEEK_END))); if (state->cirbuf_rp[port] < 0) { D2(fprintf(debug_file, "_14a_: sendImageFrame(): frame broken - buffer overrun\n")); return -CAMOGM_FRAME_BROKEN; } D3(fprintf(debug_file, "\tcompressed frame number: %li\n", lseek(state->fd_circ[port], LSEEK_CIRC_GETFRAME, SEEK_END))); // optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers") if (state->save_gp) lseek(state->fd_circ[port], LSEEK_CIRC_SETP, SEEK_END); D3(fprintf(debug_file, "_15_\n")); D4(fprintf(debug_file, "_15_\n")); if (state->frames_skip > 0) { state->frames_skip_left[port] = state->frames_skip; } else if (state->frames_skip < 0) { Loading @@ -749,6 +760,7 @@ int sendImageFrame(camogm_state *state) // state->rawdev.last_jpeg_size)); // D6(fprintf(debug_file, "Write speed: %d MB/s\n", mbps)); D6(fprintf(debug_file, "Exit sendImageFrame() OK @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0))); return 0; } Loading Loading @@ -1389,15 +1401,17 @@ int parse_cmd(camogm_state *state, FILE* npipe) char * argse; int d; double dd; int port = state->port_num; //skip empty commands while (((cmd = getLineFromPipe(npipe))) && !cmd[0]) ; if (!cmd) return 0; // nothing in the pipe D2(fprintf(debug_file, "Got command: '%s' @ %06d -> ", cmd, get_fpga_usec(state->fd_fparmsall[0], 0))); D2(fprintf(debug_file, "Got command (state->port_num=%d): '%s' @ %06d -> ", port, cmd, get_fpga_usec(state->fd_fparmsall[0], 0))); if (port >= 0) { D3(fprintf(debug_file, "Acknowledge received command for port=%d\n", port)); // Acknowledge received command by copying frame number to per-daemon parameter // GLOBALPARS(state->port_num, G_DAEMON_ERR + lastDaemonBit[state->port_num]) = GLOBALPARS(state->port_num, G_THIS_FRAME); setGValue(state->port_num, G_DAEMON_ERR + lastDaemonBit[state->port_num], getGPValue(state->port_num, G_THIS_FRAME)); setGValue(port, G_DAEMON_ERR + lastDaemonBit[port], getGPValue(port, G_THIS_FRAME)); } args = strpbrk(cmd, "= \t"); // is it just a single word command or does it have parameters? if (args) { Loading Loading @@ -1687,7 +1701,11 @@ int listener_loop(camogm_state *state) } if (state->prog_state == STATE_RUNNING) { // no commands in queue, started D6(fprintf(debug_file, "state->prog_state == STATE_RUNNING ")); if (curr_port < 0) { rslt = CAMOGM_FRAME_BROKEN; } else { rslt = -sendImageFrame(state); } D6(fprintf(debug_file, " ==> %d @ %06d\n",rslt,get_fpga_usec(state->fd_fparmsall[0], 0))); switch (rslt) { case 0: Loading Loading @@ -1995,7 +2013,7 @@ unsigned int select_port(camogm_state *state) } if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "Selecting sensor port, buffer free size: ")); D3(fprintf(debug_file, "Selecting sensor port, buffer free size: ")); for (int i = 0; i < SENSOR_PORTS; i++) { if (is_chn_active(state, i)) { file_pos = lseek(state->fd_circ[i], 0, SEEK_CUR); Loading @@ -2003,24 +2021,32 @@ unsigned int select_port(camogm_state *state) free_sz = lseek(state->fd_circ[i], LSEEK_CIRC_FREE, SEEK_END); lseek(state->fd_circ[i], file_pos, SEEK_SET); if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "port %i = %li, ", i, free_sz)); D3(fprintf(debug_file, "port %i = %li, ", i, free_sz)); if (free_sz < CAMOGM_MIN_BUF_FRAMES * state->image_size[i]) { D3(fprintf(debug_file, "port %i has too little free space (<CAMOGM_MIN_BUF_FRAMES * %d), considered BROKEN", i, state->image_size[i])); chn = -1; // i; break; } if ((free_sz < min_sz && free_sz >= 0) || min_sz == -1) { min_sz = free_sz; chn = i; } } else { if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D3(fprintf(debug_file, "port %i BROKEN FRAME, ", i)); // current frame pointer is possibly overwritten (buffer overflow), select // this channel which will force sendImageFrame() to take recovery actions chn = i; // Did not work - mMaybe use -1? Make susre at least one extra frame is OK? chn = -1; // i; break; } } else { if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "port %i is inactive, ", i)); D3(fprintf(debug_file, "port %i is inactive, ", i)); } } if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "selected port: %i\n", chn)); D3(fprintf(debug_file, "selected port: %i @ %06d\n", chn, get_fpga_usec(state->fd_fparmsall[0], 0))); return chn; } Loading src/camogm.h +8 −6 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #define CAMOGM_FORMAT_OGM 1 ///< output as Ogg Media file #define CAMOGM_FORMAT_JPEG 2 ///< output as individual JPEG files #define CAMOGM_FORMAT_MOV 3 ///< output as Apple Quicktime #define CAMOGM_MIN_BUF_FRAMES 2 ///< buffer should accomodate at list this number of frames #define D(x) { if (debug_file && debug_level) { x; fflush(debug_file); } } #define D0(x) { if (debug_file) { pthread_mutex_lock(&print_mutex); x; fflush(debug_file); pthread_mutex_unlock(&print_mutex); } } Loading Loading @@ -194,6 +195,7 @@ typedef struct { int fd_exif[SENSOR_PORTS]; ///< file descriptor for Exif data int fd_tiff[SENSOR_PORTS]; ///< file descriptor for Tiff data int head_size[SENSOR_PORTS]; ///< JPEG header size int image_size[SENSOR_PORTS]; ///< last image size in bytes unsigned char jpegHeader[SENSOR_PORTS][JPEG_HEADER_MAXSIZE]; int metadata_start; struct interframe_params_t frame_params[SENSOR_PORTS]; Loading src/camogm_align.c +7 −5 Original line number Diff line number Diff line Loading @@ -368,6 +368,8 @@ void align_frame(camogm_state *state) // total_sz = get_size_from(chunks, 0, 0, INCLUDE_REM) + rbuff->iov_len; total_sz = get_size_from_paged(state, 0, INCLUDE_REM) + rbuff->iov_len; //port_num state->image_size[state->port_num] = total_sz; D4(fprintf(debug_file, "total_sz = %d, rbuff->iov_len=%d\n", total_sz, (int)(rbuff->iov_len))); if (total_sz < PHY_BLOCK_SIZE) { /* the frame length is less than sector size, delay this frame */ Loading src/camogm_jpeg.c +21 −19 Original line number Diff line number Diff line Loading @@ -319,6 +319,7 @@ int camogm_frame_jpeg(camogm_state *state) state->rawdev.last_jpeg_size = l; close(state->ivf); } else { D3(fprintf(debug_file, "_12.7_ camogm_frame_jpeg(): %ld.%06ld:%d @ %06d\n",state->this_frame_params[port].timestamp_sec, state->this_frame_params[port].timestamp_usec, port, get_fpga_usec(state->fd_fparmsall[0], 0))); D6(fprintf(debug_file, "\ndump iovect array for port %u\n", state->port_num)); for (int i = 0; i < state->chunk_index - 1; i++) { D6(fprintf(debug_file, "ptr: %p, length: %ld\n", state->packetchunks[i + 1].chunk, state->packetchunks[i + 1].bytes)); Loading Loading @@ -495,13 +496,14 @@ void *jpeg_writer(void *thread_args) if (state->writer_params.lba_current + blocks_write <= state->writer_params.lba_end) { // almost always - single write state->writer_params.lba_current += blocks_write; // D6(fprintf(debug_file, "_w02_: starting writev @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0))); D6(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w02_: starting writev @ %06d\n",dbg_us1)); D3(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0)); D6(fprintf(debug_file, "_w02_: starting writev @ %06d\n",dbg_us1)); state->writer_params.writev_run = true; pthread_cond_signal(¶ms->main_cond); iovlen = writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], chunk_index); state->writer_params.writev_run = false; // D6(fprintf(debug_file, "_w03_: finished writev @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0))); D6(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished writev @ %06d (+ %06d, +%06d)\n",dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)); dbg_us2=dbg_us); D3(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished writev @ %06d (+ %06d, +%06d)\n",dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)); dbg_us2=dbg_us); if (iovlen < l) { D0(fprintf(debug_file, "writev error: %s (returned %i, expected %i)\n", strerror(errno), iovlen, l)); state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR; Loading Loading
src/camogm.c +79 −53 Original line number Diff line number Diff line Loading @@ -387,6 +387,7 @@ int camogm_start(camogm_state *state) D3(fprintf(debug_file, "1a: compressed frame number = %li\n", lseek(state->fd_circ[chn], LSEEK_CIRC_GETFRAME, SEEK_END))); if ((state->cirbuf_rp[chn] < 0) || (lseek(state->fd_circ[chn], state->cirbuf_rp[chn], SEEK_SET) < 0) || (lseek(state->fd_circ[chn], LSEEK_CIRC_VALID, SEEK_END) < 0 )) { D3(fprintf(debug_file, "2: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn])); D3(fprintf(debug_file, "2.1: state->greedy=%d\n", state->greedy)); /* In "greedy" mode try to save as many frames from the circbuf as possible */ state->cirbuf_rp[chn] = lseek(state->fd_circ[chn], state->greedy ? LSEEK_CIRC_SCND : LSEEK_CIRC_LAST, SEEK_END); if (!state->ignore_fps) { // don't even try in ignore mode Loading Loading @@ -505,6 +506,7 @@ int camogm_start(camogm_state *state) read(state->fd_head[chn], state->jpegHeader[chn], state->head_size[chn]); // Restore read pointer to the original (now there may be no frame ready there yet) lseek(state->fd_circ[chn], state->cirbuf_rp[chn], SEEK_SET); state->image_size[chn] = 0; } } Loading Loading @@ -547,7 +549,10 @@ int sendImageFrame(camogm_state *state) int fd_exif_tiff; // switching between TIFF and Exif depending on coloe mode int port = state->port_num; struct timeval start_time, end_time; if (port < 0) { D3(fprintf(debug_file, "sendImageFrame:0: port < 0!\n")); return -CAMOGM_FRAME_BROKEN; } // start_time = get_fpga_time(state->fd_fparmsall[port], port); // This is probably needed only for Quicktime (not to exceed already allocated frame index) Loading Loading @@ -579,7 +584,8 @@ int sendImageFrame(camogm_state *state) } // is the frame ready? if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) { D3(fprintf(debug_file, "?6,fp=0x%x\n", fp)); //frame not ready, frame pointer seems valid, but not ready D4(fprintf(debug_file, "?6")) ; //frame not ready, frame pointer seems valid, but not ready D6(fprintf(debug_file, ",fp=0x%x\n", fp)); //frame not ready, frame pointer seems valid, but not ready return -CAMOGM_FRAME_NOT_READY; // frame pointer valid, but no frames yet } Loading @@ -594,7 +600,7 @@ int sendImageFrame(camogm_state *state) } // Get metadata D3(fprintf(debug_file, "_1_")); D4(fprintf(debug_file, "_1_")); state->metadata_start = state->cirbuf_rp[port] - 32; if (state->metadata_start < 0) state->metadata_start += state->circ_buff_size[port]; memcpy(&(state->this_frame_params[port]), (unsigned long* )&ccam_dma_buf[state->port_num][state->metadata_start >> 2], 32); Loading @@ -607,11 +613,11 @@ int sendImageFrame(camogm_state *state) D3(fprintf(debug_file, "sendImageFrame:8: frame broken\n")); return -CAMOGM_FRAME_BROKEN; } D3(fprintf(debug_file, "_2_")); D4(fprintf(debug_file, "_2_")); // find location of the timestamp and copy it to the frame_params structure timestamp_start = state->cirbuf_rp[port] + ((state->jpeg_len + CCAM_MMAP_META + 3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC; // magic shift - should index first byte of the time stamp if (timestamp_start >= state->circ_buff_size[port]) timestamp_start -= state->circ_buff_size[port]; D3(fprintf(debug_file, "_3_")); D4(fprintf(debug_file, "_3_")); memcpy(&(state->this_frame_params[port].timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8); // verify that the essential current frame params did not change, if they did - return an error (need new file header) if (!state->ignore_fps && ((state->frame_params[port].width != state->this_frame_params[port].width) || Loading @@ -635,9 +641,9 @@ int sendImageFrame(camogm_state *state) } D3(fprintf(debug_file, "_4_")); D4(fprintf(debug_file, "_4_")); if (state->exif) { D3(fprintf(debug_file, "_5_")); D4(fprintf(debug_file, "_5_")); fd_exif_tiff = (state->this_frame_params[port].color == COLORMODE_RAW)? state->fd_tiff[port] : state->fd_exif[port]; // update the Exif header with the current frame metadata state->exifSize[port] = lseek(fd_exif_tiff, 1, SEEK_END); // at the beginning of page 1 - position == page length Loading @@ -650,21 +656,21 @@ int sendImageFrame(camogm_state *state) } else state->exifSize[port] = 0; } else state->exifSize[port] = 0; D3(fprintf(debug_file, "_6_")); D4(fprintf(debug_file, "_6_")); // prepare a packet to be sent (a lst of memory chunks) state->chunk_index = 0; state->packetchunks[state->chunk_index ].bytes = 1; state->packetchunks[state->chunk_index++].chunk = &frame_packet_type; if (state->exif > 0) { // insert Exif/Tiff D3(fprintf(debug_file, "_7_")); D4(fprintf(debug_file, "_7_")); if (state->this_frame_params[port].color == COLORMODE_RAW) { // Tiff D3(fprintf(debug_file, "_8a_")); D4(fprintf(debug_file, "_8a_")); state->packetchunks[state->chunk_index ].bytes = state->exifSize[port]; // Tiff Header length state->packetchunks[state->chunk_index++].chunk = state->ed[port]; // Tiff Header } else { // JPEG/JP4 D3(fprintf(debug_file, "_8b_")); D4(fprintf(debug_file, "_8b_")); state->packetchunks[state->chunk_index ].bytes = 2; state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port]; state->packetchunks[state->chunk_index ].bytes = state->exifSize[port]; Loading @@ -673,16 +679,16 @@ int sendImageFrame(camogm_state *state) state->packetchunks[state->chunk_index++].chunk = &(state->jpegHeader[port][2]); } } else { D3(fprintf(debug_file, "_8_")); D4(fprintf(debug_file, "_8_")); state->packetchunks[state->chunk_index ].bytes = state->head_size[port]; state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port]; } D3(fprintf(debug_file, "_9_")); D4(fprintf(debug_file, "_9_")); /* Jpeg/Tiff image data may be split in two segments (rolled over buffer end) - process both variants */ if ((state->cirbuf_rp[port] + state->jpeg_len) > state->circ_buff_size[port]) { // two segments /* copy from the beginning of the frame to the end of the buffer */ D3(fprintf(debug_file, "_10_")); D4(fprintf(debug_file, "_10_")); state->packetchunks[state->chunk_index ].bytes = state->circ_buff_size[port] - state->cirbuf_rp[port]; state->packetchunks[state->chunk_index++].chunk = (unsigned char*)&ccam_dma_buf[state->port_num][state->cirbuf_rp[port] >> 2]; /* copy from the beginning of the buffer to the end of the frame */ Loading @@ -690,15 +696,15 @@ int sendImageFrame(camogm_state *state) state->packetchunks[state->chunk_index++].chunk = (unsigned char*)&ccam_dma_buf[state->port_num][0]; state->writer_params.segments = 2; } else { // single segment D3(fprintf(debug_file, "_11_")); D4(fprintf(debug_file, "_11_")); /* copy from the beginning of the frame to the end of the frame (no buffer rollovers) */ state->packetchunks[state->chunk_index ].bytes = state->jpeg_len; state->packetchunks[state->chunk_index++].chunk = (unsigned char*)&ccam_dma_buf[state->port_num][state->cirbuf_rp[port] >> 2]; state->writer_params.segments = 1; } D3(fprintf(debug_file, "\tcirbuf_rp[%d] = 0x%x\t", port, state->cirbuf_rp[port])); D3(fprintf(debug_file, "_12_\n")); D4(fprintf(debug_file, "\tcirbuf_rp[%d] = 0x%x\t", port, state->cirbuf_rp[port])); D5(fprintf(debug_file, "_12_\n")); if (state->this_frame_params[port].color != COLORMODE_RAW) { // Tiff state->packetchunks[state->chunk_index ].bytes = 2; state->packetchunks[state->chunk_index++].chunk = (unsigned char*)trailer; Loading @@ -717,20 +723,25 @@ int sendImageFrame(camogm_state *state) default: rslt = 0; // do nothing } if (rslt) { D3(fprintf(debug_file, "sendImageFrame:12: camogm_frame_***() returned %d\n", rslt)); D4(fprintf(debug_file, "sendImageFrame:12: camogm_frame_***() returned %d\n", rslt)); return rslt; } if (state->kml_used) rslt = camogm_frame_kml(state); // will turn on state->kml_used if it can if (rslt) return rslt; D3(fprintf(debug_file, "_14_")); D4(fprintf(debug_file, "_14_")); // advance frame pointer state->frameno++; state->cirbuf_rp[port] = lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END); D3(fprintf(debug_file, "\tcompressed frame number: %li\t", lseek(state->fd_circ[port], LSEEK_CIRC_GETFRAME, SEEK_END))); if (state->cirbuf_rp[port] < 0) { D2(fprintf(debug_file, "_14a_: sendImageFrame(): frame broken - buffer overrun\n")); return -CAMOGM_FRAME_BROKEN; } D3(fprintf(debug_file, "\tcompressed frame number: %li\n", lseek(state->fd_circ[port], LSEEK_CIRC_GETFRAME, SEEK_END))); // optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers") if (state->save_gp) lseek(state->fd_circ[port], LSEEK_CIRC_SETP, SEEK_END); D3(fprintf(debug_file, "_15_\n")); D4(fprintf(debug_file, "_15_\n")); if (state->frames_skip > 0) { state->frames_skip_left[port] = state->frames_skip; } else if (state->frames_skip < 0) { Loading @@ -749,6 +760,7 @@ int sendImageFrame(camogm_state *state) // state->rawdev.last_jpeg_size)); // D6(fprintf(debug_file, "Write speed: %d MB/s\n", mbps)); D6(fprintf(debug_file, "Exit sendImageFrame() OK @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0))); return 0; } Loading Loading @@ -1389,15 +1401,17 @@ int parse_cmd(camogm_state *state, FILE* npipe) char * argse; int d; double dd; int port = state->port_num; //skip empty commands while (((cmd = getLineFromPipe(npipe))) && !cmd[0]) ; if (!cmd) return 0; // nothing in the pipe D2(fprintf(debug_file, "Got command: '%s' @ %06d -> ", cmd, get_fpga_usec(state->fd_fparmsall[0], 0))); D2(fprintf(debug_file, "Got command (state->port_num=%d): '%s' @ %06d -> ", port, cmd, get_fpga_usec(state->fd_fparmsall[0], 0))); if (port >= 0) { D3(fprintf(debug_file, "Acknowledge received command for port=%d\n", port)); // Acknowledge received command by copying frame number to per-daemon parameter // GLOBALPARS(state->port_num, G_DAEMON_ERR + lastDaemonBit[state->port_num]) = GLOBALPARS(state->port_num, G_THIS_FRAME); setGValue(state->port_num, G_DAEMON_ERR + lastDaemonBit[state->port_num], getGPValue(state->port_num, G_THIS_FRAME)); setGValue(port, G_DAEMON_ERR + lastDaemonBit[port], getGPValue(port, G_THIS_FRAME)); } args = strpbrk(cmd, "= \t"); // is it just a single word command or does it have parameters? if (args) { Loading Loading @@ -1687,7 +1701,11 @@ int listener_loop(camogm_state *state) } if (state->prog_state == STATE_RUNNING) { // no commands in queue, started D6(fprintf(debug_file, "state->prog_state == STATE_RUNNING ")); if (curr_port < 0) { rslt = CAMOGM_FRAME_BROKEN; } else { rslt = -sendImageFrame(state); } D6(fprintf(debug_file, " ==> %d @ %06d\n",rslt,get_fpga_usec(state->fd_fparmsall[0], 0))); switch (rslt) { case 0: Loading Loading @@ -1995,7 +2013,7 @@ unsigned int select_port(camogm_state *state) } if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "Selecting sensor port, buffer free size: ")); D3(fprintf(debug_file, "Selecting sensor port, buffer free size: ")); for (int i = 0; i < SENSOR_PORTS; i++) { if (is_chn_active(state, i)) { file_pos = lseek(state->fd_circ[i], 0, SEEK_CUR); Loading @@ -2003,24 +2021,32 @@ unsigned int select_port(camogm_state *state) free_sz = lseek(state->fd_circ[i], LSEEK_CIRC_FREE, SEEK_END); lseek(state->fd_circ[i], file_pos, SEEK_SET); if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "port %i = %li, ", i, free_sz)); D3(fprintf(debug_file, "port %i = %li, ", i, free_sz)); if (free_sz < CAMOGM_MIN_BUF_FRAMES * state->image_size[i]) { D3(fprintf(debug_file, "port %i has too little free space (<CAMOGM_MIN_BUF_FRAMES * %d), considered BROKEN", i, state->image_size[i])); chn = -1; // i; break; } if ((free_sz < min_sz && free_sz >= 0) || min_sz == -1) { min_sz = free_sz; chn = i; } } else { if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D3(fprintf(debug_file, "port %i BROKEN FRAME, ", i)); // current frame pointer is possibly overwritten (buffer overflow), select // this channel which will force sendImageFrame() to take recovery actions chn = i; // Did not work - mMaybe use -1? Make susre at least one extra frame is OK? chn = -1; // i; break; } } else { if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "port %i is inactive, ", i)); D3(fprintf(debug_file, "port %i is inactive, ", i)); } } if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING) D6(fprintf(debug_file, "selected port: %i\n", chn)); D3(fprintf(debug_file, "selected port: %i @ %06d\n", chn, get_fpga_usec(state->fd_fparmsall[0], 0))); return chn; } Loading
src/camogm.h +8 −6 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #define CAMOGM_FORMAT_OGM 1 ///< output as Ogg Media file #define CAMOGM_FORMAT_JPEG 2 ///< output as individual JPEG files #define CAMOGM_FORMAT_MOV 3 ///< output as Apple Quicktime #define CAMOGM_MIN_BUF_FRAMES 2 ///< buffer should accomodate at list this number of frames #define D(x) { if (debug_file && debug_level) { x; fflush(debug_file); } } #define D0(x) { if (debug_file) { pthread_mutex_lock(&print_mutex); x; fflush(debug_file); pthread_mutex_unlock(&print_mutex); } } Loading Loading @@ -194,6 +195,7 @@ typedef struct { int fd_exif[SENSOR_PORTS]; ///< file descriptor for Exif data int fd_tiff[SENSOR_PORTS]; ///< file descriptor for Tiff data int head_size[SENSOR_PORTS]; ///< JPEG header size int image_size[SENSOR_PORTS]; ///< last image size in bytes unsigned char jpegHeader[SENSOR_PORTS][JPEG_HEADER_MAXSIZE]; int metadata_start; struct interframe_params_t frame_params[SENSOR_PORTS]; Loading
src/camogm_align.c +7 −5 Original line number Diff line number Diff line Loading @@ -368,6 +368,8 @@ void align_frame(camogm_state *state) // total_sz = get_size_from(chunks, 0, 0, INCLUDE_REM) + rbuff->iov_len; total_sz = get_size_from_paged(state, 0, INCLUDE_REM) + rbuff->iov_len; //port_num state->image_size[state->port_num] = total_sz; D4(fprintf(debug_file, "total_sz = %d, rbuff->iov_len=%d\n", total_sz, (int)(rbuff->iov_len))); if (total_sz < PHY_BLOCK_SIZE) { /* the frame length is less than sector size, delay this frame */ Loading
src/camogm_jpeg.c +21 −19 Original line number Diff line number Diff line Loading @@ -319,6 +319,7 @@ int camogm_frame_jpeg(camogm_state *state) state->rawdev.last_jpeg_size = l; close(state->ivf); } else { D3(fprintf(debug_file, "_12.7_ camogm_frame_jpeg(): %ld.%06ld:%d @ %06d\n",state->this_frame_params[port].timestamp_sec, state->this_frame_params[port].timestamp_usec, port, get_fpga_usec(state->fd_fparmsall[0], 0))); D6(fprintf(debug_file, "\ndump iovect array for port %u\n", state->port_num)); for (int i = 0; i < state->chunk_index - 1; i++) { D6(fprintf(debug_file, "ptr: %p, length: %ld\n", state->packetchunks[i + 1].chunk, state->packetchunks[i + 1].bytes)); Loading Loading @@ -495,13 +496,14 @@ void *jpeg_writer(void *thread_args) if (state->writer_params.lba_current + blocks_write <= state->writer_params.lba_end) { // almost always - single write state->writer_params.lba_current += blocks_write; // D6(fprintf(debug_file, "_w02_: starting writev @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0))); D6(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w02_: starting writev @ %06d\n",dbg_us1)); D3(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0)); D6(fprintf(debug_file, "_w02_: starting writev @ %06d\n",dbg_us1)); state->writer_params.writev_run = true; pthread_cond_signal(¶ms->main_cond); iovlen = writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], chunk_index); state->writer_params.writev_run = false; // D6(fprintf(debug_file, "_w03_: finished writev @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0))); D6(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished writev @ %06d (+ %06d, +%06d)\n",dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)); dbg_us2=dbg_us); D3(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished writev @ %06d (+ %06d, +%06d)\n",dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)); dbg_us2=dbg_us); if (iovlen < l) { D0(fprintf(debug_file, "writev error: %s (returned %i, expected %i)\n", strerror(errno), iovlen, l)); state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR; Loading