Commit 2e89b4c0 authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: single threaded app

Record jpegs from all channels
parent c4ef6af1
...@@ -226,6 +226,7 @@ unsigned long getGPValue(unsigned int port, unsigned long GPNumber); ...@@ -226,6 +226,7 @@ unsigned long getGPValue(unsigned int port, unsigned long GPNumber);
void setGValue(unsigned int port, unsigned long GNumber, unsigned long value); void setGValue(unsigned int port, unsigned long GNumber, unsigned long value);
unsigned int select_port(camogm_state *states); unsigned int select_port(camogm_state *states);
inline void set_chn_state(camogm_state *s, unsigned int port, unsigned int new_state); inline void set_chn_state(camogm_state *s, unsigned int port, unsigned int new_state);
inline int is_chn_active(camogm_state *s, unsigned int port);
//!====================================================================================================== //!======================================================================================================
void put_uint16(void *buf, u_int16_t val) void put_uint16(void *buf, u_int16_t val)
...@@ -368,8 +369,8 @@ int camogm_start(camogm_state *state) ...@@ -368,8 +369,8 @@ int camogm_start(camogm_state *state)
state->frameno = 0; state->frameno = 0;
state->timescale = state->set_timescale; //! current timescale, default 1 state->timescale = state->set_timescale; //! current timescale, default 1
///debug ///debug
int * ifp = (int*)&(state->frame_params); int * ifp = (int*)&(state->frame_params[port]);
int * ifp_this = (int*)&(state->this_frame_params); int * ifp_this = (int*)&(state->this_frame_params[port]);
if (state->kml_enable) camogm_init_kml(); // do nothing if (state->kml_enable) camogm_init_kml(); // do nothing
if (state->format != state->set_format) { if (state->format != state->set_format) {
...@@ -386,127 +387,132 @@ int camogm_start(camogm_state *state) ...@@ -386,127 +387,132 @@ int camogm_start(camogm_state *state)
state->max_frames = state->set_max_frames; state->max_frames = state->set_max_frames;
state->frames_per_chunk = state->set_frames_per_chunk; state->frames_per_chunk = state->set_frames_per_chunk;
state->starting = 1; //!may be already set state->starting = 1; //!may be already set
//! Check/set circbuf read pointer FOR_EACH_PORT(int, chn) {
D3(fprintf(debug_file, "1: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); printf("Checking channel %d\n", chn);
if ((state->cirbuf_rp[port] < 0) || (lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET) < 0) || (lseek(state->fd_circ[port], LSEEK_CIRC_VALID, SEEK_END) < 0 )) { //! Check/set circbuf read pointer
D3(fprintf(debug_file, "2: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); D3(fprintf(debug_file, "1: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
/* In "greedy" mode try to save as many frames from the circbuf as possible */ 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 )) {
state->cirbuf_rp[port] = lseek(state->fd_circ[port], state->greedy ? LSEEK_CIRC_SCND : LSEEK_CIRC_LAST, SEEK_END); D3(fprintf(debug_file, "2: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
/* 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 if (!state->ignore_fps) { // don't even try in ignore mode
if (((fp = lseek(state->fd_circ[port], LSEEK_CIRC_PREV, SEEK_END))) >= 0) state->cirbuf_rp[port] = fp; //!try to have 2 frames available for fps if (((fp = lseek(state->fd_circ[chn], LSEEK_CIRC_PREV, SEEK_END))) >= 0) state->cirbuf_rp[chn] = fp; //!try to have 2 frames available for fps
} }
state->buf_overruns[port]++; state->buf_overruns[chn]++;
//! file pointer here should match state->rp; so no need to do lseek(state->fd_circ,state->cirbuf_rp,SEEK_SET); //! file pointer here should match state->rp; so no need to do lseek(state->fd_circ,state->cirbuf_rp,SEEK_SET);
state->buf_min[port] = getGPValue(state->port_num, G_FREECIRCBUF); state->buf_min[chn] = getGPValue(chn, G_FREECIRCBUF);
} else { } else {
if (state->buf_min[port] > getGPValue(state->port_num, G_FREECIRCBUF)) state->buf_min[port] = getGPValue(state->port_num, G_FREECIRCBUF); if (state->buf_min[chn] > getGPValue(chn, G_FREECIRCBUF)) state->buf_min[chn] = getGPValue(chn, G_FREECIRCBUF);
} }
D3(fprintf(debug_file, "3: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); D3(fprintf(debug_file, "3: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
D3(fprintf(debug_file, "4:lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END)=%d\n", (int)lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END))); D3(fprintf(debug_file, "4:lseek(state->fd_circ,LSEEK_CIRC_READY,SEEK_END)=%d\n", (int)lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END)));
//! is this frame ready? //! is this frame ready?
if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) return -CAMOGM_FRAME_NOT_READY; //! frame pointer valid, but no frames yet if (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) < 0) return -CAMOGM_FRAME_NOT_READY; //! frame pointer valid, but no frames yet
D3(fprintf(debug_file, "5: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); D3(fprintf(debug_file, "5: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
state->metadata_start = (state->cirbuf_rp[port]) - 32; state->metadata_start = (state->cirbuf_rp[chn]) - 32;
if (state->metadata_start < 0) state->metadata_start += state->circ_buff_size[port]; if (state->metadata_start < 0) state->metadata_start += state->circ_buff_size[chn];
///================================== ///==================================
memcpy(&(state->frame_params), (unsigned long* )&ccam_dma_buf[state->port_num][state->metadata_start >> 2], 32); memcpy(&(state->frame_params[chn]), (unsigned long* )&ccam_dma_buf[chn][state->metadata_start >> 2], 32);
state->jpeg_len = state->frame_params.frame_length; //! frame_params.frame_length are now the length of bitstream state->jpeg_len = state->frame_params[chn].frame_length; //! frame_params.frame_length are now the length of bitstream
if (state->frame_params.signffff != 0xffff) { if (state->frame_params[chn].signffff != 0xffff) {
D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->frame_params.signffff)); D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->frame_params[chn].signffff));
state->cirbuf_rp[port] = -1; state->cirbuf_rp[chn] = -1;
D1(fprintf(debug_file, "state->cirbuf_rp=0x%x\r\n", (int)state->cirbuf_rp[port])); ifp = (int *) &state->frame_params[chn];
D1(fprintf(debug_file, "state->cirbuf_rp=0x%x\r\n", (int)state->cirbuf_rp[chn]));
D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n", ifp[0], ifp[1], ifp[2], ifp[3], ifp[4], ifp[5], ifp[6], ifp[7])); D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n", ifp[0], ifp[1], ifp[2], ifp[3], ifp[4], ifp[5], ifp[6], ifp[7]));
return -CAMOGM_FRAME_BROKEN; return -CAMOGM_FRAME_BROKEN;
} }
//! find location of the timestamp and copy it to the frame_params structure //! 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 timestamp_start = (state->cirbuf_rp[chn]) + ((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]; if (timestamp_start >= state->circ_buff_size[chn]) timestamp_start -= state->circ_buff_size[chn];
memcpy(&(state->frame_params.timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8); memcpy(&(state->frame_params[chn].timestamp_sec), (unsigned long* )&ccam_dma_buf[chn][timestamp_start >> 2], 8);
/// New - see if current timestamp is later than start one, if not return "CAMOGM_TOO_EARLY" reset read pointer and buffer read pointer /// New - see if current timestamp is later than start one, if not return "CAMOGM_TOO_EARLY" reset read pointer and buffer read pointer
if (state->start_after_timestamp > 0.0) { /// don't bother if it is 0 if (state->start_after_timestamp > 0.0) { /// don't bother if it is 0
dtime_stamp = 0.000001 * state->frame_params.timestamp_usec + state->frame_params.timestamp_sec; dtime_stamp = 0.000001 * state->frame_params[chn].timestamp_usec + state->frame_params[chn].timestamp_sec;
if (dtime_stamp < state->start_after_timestamp) { if (dtime_stamp < state->start_after_timestamp) {
state->cirbuf_rp[port] = -1; state->cirbuf_rp[chn] = -1;
D3(fprintf(debug_file, "Too early to start, %f < %f\n", dtime_stamp, state->start_after_timestamp)); D3(fprintf(debug_file, "Too early to start, %f < %f\n", dtime_stamp, state->start_after_timestamp));
return -CAMOGM_TOO_EARLY; return -CAMOGM_TOO_EARLY;
} }
} }
D3(fprintf(debug_file, "6: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); D3(fprintf(debug_file, "6: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
//! see if next frame is available //! see if next frame is available
if ((lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END) < 0 ) || if ((lseek(state->fd_circ[chn], LSEEK_CIRC_NEXT, SEEK_END) < 0 ) ||
//! is that next frame ready? //! is that next frame ready?
(((fp = lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END))) < 0)) { (((fp = lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END))) < 0)) {
D3(fprintf(debug_file, "6a:lseek(state->fd_circ,LSEEK_CIRC_NEXT,SEEK_END)=0x%x, fp=0x%x\n", (int)lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END), (int)lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END))); D3(fprintf(debug_file, "6a:lseek(state->fd_circ,LSEEK_CIRC_NEXT,SEEK_END)=0x%x, fp=0x%x\n", (int)lseek(state->fd_circ[chn], LSEEK_CIRC_NEXT, SEEK_END), (int)lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END)));
lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET); //!just in case - restore pointer lseek(state->fd_circ[chn], state->cirbuf_rp[chn], SEEK_SET); //!just in case - restore pointer
return -CAMOGM_FRAME_NOT_READY; //! frame pointer valid, but no frames yet return -CAMOGM_FRAME_NOT_READY; //! frame pointer valid, but no frames yet
} }
next_metadata_start = fp - 32; next_metadata_start = fp - 32;
if (next_metadata_start < 0) next_metadata_start += state->circ_buff_size[port]; if (next_metadata_start < 0) next_metadata_start += state->circ_buff_size[chn];
memcpy(&(state->this_frame_params), (unsigned long* )&ccam_dma_buf[state->port_num][next_metadata_start >> 2], 32); memcpy(&(state->this_frame_params[chn]), (unsigned long* )&ccam_dma_buf[chn][next_metadata_start >> 2], 32);
next_jpeg_len = state->this_frame_params.frame_length; //! frame_params.frame_length are now the length of bitstream next_jpeg_len = state->this_frame_params[chn].frame_length; //! frame_params.frame_length are now the length of bitstream
if (state->this_frame_params.signffff != 0xffff) { //! should not happen ever if (state->this_frame_params[chn].signffff != 0xffff) { //! should not happen ever
D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->this_frame_params.signffff)); D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->this_frame_params[chn].signffff));
ifp_this = (int *) &state->this_frame_params[chn];
D1(fprintf(debug_file, "fp=0x%x\r\n", (int)fp)); D1(fprintf(debug_file, "fp=0x%x\r\n", (int)fp));
D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n", ifp_this[0], ifp_this[1], ifp_this[2], ifp_this[3], ifp_this[4], ifp_this[5], ifp_this[6], ifp_this[7])); D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n", ifp_this[0], ifp_this[1], ifp_this[2], ifp_this[3], ifp_this[4], ifp_this[5], ifp_this[6], ifp_this[7]));
state->cirbuf_rp[port] = -1; state->cirbuf_rp[chn] = -1;
return -CAMOGM_FRAME_BROKEN; return -CAMOGM_FRAME_BROKEN;
} }
D3(fprintf(debug_file, "7: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); D3(fprintf(debug_file, "7: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
//! find location of the timestamp and copy it to the frame_params structure //! find location of the timestamp and copy it to the frame_params structure
timestamp_start = fp + ((next_jpeg_len + CCAM_MMAP_META + 3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC; //! magic shift - should index first byte of the time stamp timestamp_start = fp + ((next_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]; if (timestamp_start >= state->circ_buff_size[chn]) timestamp_start -= state->circ_buff_size[chn];
memcpy(&(state->this_frame_params.timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8); memcpy(&(state->this_frame_params[chn].timestamp_sec), (unsigned long* )&ccam_dma_buf[chn][timestamp_start >> 2], 8);
//! verify that the essential current frame params did not change, if they did - return an error (need new file header) //! 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.width != state->this_frame_params.width) || if (!state->ignore_fps && ((state->frame_params[chn].width != state->this_frame_params[chn].width) ||
(state->frame_params.height != state->this_frame_params.height))) { (state->frame_params[chn].height != state->this_frame_params[chn].height))) {
//! Advance frame pointer to the next (caller should try again) //! Advance frame pointer to the next (caller should try again)
state->cirbuf_rp[port] = fp; state->cirbuf_rp[chn] = fp;
return -CAMOGM_FRAME_CHANGED; // no yet checking for the FPS return -CAMOGM_FRAME_CHANGED; // no yet checking for the FPS
} }
D3(fprintf(debug_file, "8: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[port])); D3(fprintf(debug_file, "8: state->cirbuf_rp=0x%x\n", state->cirbuf_rp[chn]));
//! calcualte the frame period - time difference (in microseconds) //! calcualte the frame period - time difference (in microseconds)
state->frame_period[port] = (state->this_frame_params.timestamp_usec - state->frame_params.timestamp_usec) + state->frame_period[chn] = (state->this_frame_params[chn].timestamp_usec - state->frame_params[chn].timestamp_usec) +
1000000 * (state->this_frame_params.timestamp_sec - state->frame_params.timestamp_sec); 1000000 * (state->this_frame_params[chn].timestamp_sec - state->frame_params[chn].timestamp_sec);
//! correct for timelapse modes: //! correct for timelapse modes:
state->frames_skip = state->set_frames_skip; state->frames_skip = state->set_frames_skip;
if (state->frames_skip > 0) { if (state->frames_skip > 0) {
state->frames_skip_left[port] = 0; state->frames_skip_left[chn] = 0;
state->frame_period[port] *= (state->frames_skip + 1); state->frame_period[chn] *= (state->frames_skip + 1);
} else if (state->frames_skip < 0) { } else if (state->frames_skip < 0) {
state->frame_period[port] = -(state->frames_skip); //! actual frame period will fluctuate to the nearest frame acquired (free running) state->frame_period[chn] = -(state->frames_skip); //! actual frame period will fluctuate to the nearest frame acquired (free running)
state->frames_skip_left[port] = state->frame_params.timestamp_sec; state->frames_skip_left[chn] = state->frame_params[chn].timestamp_sec;
} }
D3(fprintf(debug_file, "9: state->frame_period=0x%x\n", state->frame_period[port])); D3(fprintf(debug_file, "9: state->frame_period=0x%x\n", state->frame_period[chn]));
state->time_unit = (ogg_int64_t)(((double)state->frame_period[port]) * ((double)10) / ((double)state->timescale)); state->time_unit = (ogg_int64_t)(((double)state->frame_period[chn]) * ((double)10) / ((double)state->timescale));
state->width = state->frame_params.width; state->width = state->frame_params[chn].width;
state->height = state->frame_params.height; state->height = state->frame_params[chn].height;
//!read JPEG header - it should stay the same for the whole file (restart new file if any parameters changed) //!read JPEG header - it should stay the same for the whole file (restart new file if any parameters changed)
//!rebuild JPEG header: //!rebuild JPEG header:
lseek(state->fd_head[port], state->cirbuf_rp[port] + 1, SEEK_END); //!+1 to avoid condition when jpeg_start==0. overloaded lseek will ignore 5 LSBs when SEEK_END lseek(state->fd_head[chn], state->cirbuf_rp[chn] + 1, SEEK_END); //!+1 to avoid condition when jpeg_start==0. overloaded lseek will ignore 5 LSBs when SEEK_END
state->head_size[port] = lseek(state->fd_head[port], 0, SEEK_END); /// In 8.0 the header size might change for some jp4 modes state->head_size[chn] = lseek(state->fd_head[chn], 0, SEEK_END); /// In 8.0 the header size might change for some jp4 modes
if (state->head_size[port] > JPEG_HEADER_MAXSIZE) { if (state->head_size[chn] > JPEG_HEADER_MAXSIZE) {
D0(fprintf(debug_file, "%s:%d: Too big JPEG header (%d > %d)", __FILE__, __LINE__, state->head_size[port], JPEG_HEADER_MAXSIZE )); D0(fprintf(debug_file, "%s:%d: Too big JPEG header (%d > %d)", __FILE__, __LINE__, state->head_size[chn], JPEG_HEADER_MAXSIZE ));
return -2; return -2;
} }
//! and read it //! and read it
lseek(state->fd_head[port], 0, 0); lseek(state->fd_head[chn], 0, 0);
read(state->fd_head[port], state->jpegHeader[port], state->head_size[port]); 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) //! Restore read pointer to the original (now there may be no frame ready there yet)
lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET); lseek(state->fd_circ[chn], state->cirbuf_rp[chn], SEEK_SET);
}
//!here we are ready to initialize Ogm (or other) file //!here we are ready to initialize Ogm (or other) file
switch (state->format) { switch (state->format) {
...@@ -533,7 +539,7 @@ int sendImageFrame(camogm_state *state) ...@@ -533,7 +539,7 @@ int sendImageFrame(camogm_state *state)
int rslt; int rslt;
unsigned char frame_packet_type = PACKET_IS_SYNCPOINT; unsigned char frame_packet_type = PACKET_IS_SYNCPOINT;
int timestamp_start; int timestamp_start;
int * ifp_this = (int*)&(state->this_frame_params); int * ifp_this = (int*)&(state->this_frame_params[state->port_num]);
int fp; int fp;
int port = state->port_num; int port = state->port_num;
...@@ -585,10 +591,10 @@ int sendImageFrame(camogm_state *state) ...@@ -585,10 +591,10 @@ int sendImageFrame(camogm_state *state)
D3(fprintf(debug_file, "_1_")); D3(fprintf(debug_file, "_1_"));
state->metadata_start = state->cirbuf_rp[port] - 32; state->metadata_start = state->cirbuf_rp[port] - 32;
if (state->metadata_start < 0) state->metadata_start += state->circ_buff_size[port]; if (state->metadata_start < 0) state->metadata_start += state->circ_buff_size[port];
memcpy(&(state->this_frame_params), (unsigned long* )&ccam_dma_buf[state->port_num][state->metadata_start >> 2], 32); memcpy(&(state->this_frame_params[port]), (unsigned long* )&ccam_dma_buf[state->port_num][state->metadata_start >> 2], 32);
state->jpeg_len = state->this_frame_params.frame_length; //! frame_params.frame_length are now the length of bitstream state->jpeg_len = state->this_frame_params[port].frame_length; //! frame_params.frame_length are now the length of bitstream
if (state->this_frame_params.signffff != 0xffff) { if (state->this_frame_params[port].signffff != 0xffff) {
D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->this_frame_params.signffff)); D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->this_frame_params[port].signffff));
D1(fprintf(debug_file, "state->cirbuf_rp=0x%x\r\n", (int)state->cirbuf_rp[port])); D1(fprintf(debug_file, "state->cirbuf_rp=0x%x\r\n", (int)state->cirbuf_rp[port]));
D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n", ifp_this[0], ifp_this[1], ifp_this[2], ifp_this[3], ifp_this[4], ifp_this[5], ifp_this[6], ifp_this[7])); D1(fprintf(debug_file, "%08x %08x %08x %08x %08x %08x %08x %08x\r\n", ifp_this[0], ifp_this[1], ifp_this[2], ifp_this[3], ifp_this[4], ifp_this[5], ifp_this[6], ifp_this[7]));
...@@ -600,21 +606,21 @@ int sendImageFrame(camogm_state *state) ...@@ -600,21 +606,21 @@ int sendImageFrame(camogm_state *state)
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 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]; if (timestamp_start >= state->circ_buff_size[port]) timestamp_start -= state->circ_buff_size[port];
D3(fprintf(debug_file, "_3_")); D3(fprintf(debug_file, "_3_"));
memcpy(&(state->this_frame_params.timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8); 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) //! 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.width != state->this_frame_params.width) || if (!state->ignore_fps && ((state->frame_params[port].width != state->this_frame_params[port].width) ||
(state->frame_params.height != state->this_frame_params.height))) { (state->frame_params[port].height != state->this_frame_params[port].height))) {
D3(fprintf(debug_file, "sendImageFrame:9: WOI changed\n")); D3(fprintf(debug_file, "sendImageFrame:9: WOI changed\n"));
return -CAMOGM_FRAME_CHANGED; //! not yet checking for the FPS return -CAMOGM_FRAME_CHANGED; //! not yet checking for the FPS
} }
//! check if file duration (in seconds) exceeded ,-CAMOGM_FRAME_CHANGED will trigger a new segment //! check if file duration (in seconds) exceeded ,-CAMOGM_FRAME_CHANGED will trigger a new segment
if ((state->segment_duration > 0) && if ((state->segment_duration > 0) &&
((state->this_frame_params.timestamp_sec - state->frame_params.timestamp_sec) > state->segment_duration)) { ((state->this_frame_params[port].timestamp_sec - state->frame_params[port].timestamp_sec) > state->segment_duration)) {
D3(fprintf(debug_file, "sendImageFrame:10: segment duration in seconds exceeded\n")); D3(fprintf(debug_file, "sendImageFrame:10: segment duration in seconds exceeded\n"));
return -CAMOGM_FRAME_CHANGED; return -CAMOGM_FRAME_CHANGED;
} }
//! check if (in timelapse mode) it is too early for the frame to be stored //! check if (in timelapse mode) it is too early for the frame to be stored
if ((state->frames_skip < 0) && (state->frames_skip_left[port] > state->this_frame_params.timestamp_sec) ) { if ((state->frames_skip < 0) && (state->frames_skip_left[port] > state->this_frame_params[port].timestamp_sec) ) {
state->cirbuf_rp[port] = lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END); state->cirbuf_rp[port] = lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END);
//!optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers") //!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); if (state->save_gp) lseek(state->fd_circ[port], LSEEK_CIRC_SETP, SEEK_END);
...@@ -630,7 +636,7 @@ int sendImageFrame(camogm_state *state) ...@@ -630,7 +636,7 @@ int sendImageFrame(camogm_state *state)
state->exifSize[port] = lseek(state->fd_exif[port], 1, SEEK_END); // at the beginning of page 1 - position == page length state->exifSize[port] = lseek(state->fd_exif[port], 1, SEEK_END); // at the beginning of page 1 - position == page length
if (state->exifSize > 0) { if (state->exifSize > 0) {
//state->this_frame_params.meta_index //state->this_frame_params.meta_index
lseek(state->fd_exif[port], state->this_frame_params.meta_index, SEEK_END); //! select meta page to use (matching frame) lseek(state->fd_exif[port], state->this_frame_params[port].meta_index, SEEK_END); //! select meta page to use (matching frame)
rslt = read(state->fd_exif[port], state->ed[port], state->exifSize[port]); rslt = read(state->fd_exif[port], state->ed[port], state->exifSize[port]);
if (rslt < 0) rslt = 0; if (rslt < 0) rslt = 0;
state->exifSize[port] = rslt; state->exifSize[port] = rslt;
...@@ -909,7 +915,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d) ...@@ -909,7 +915,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d)
void camogm_status(camogm_state *state, char * fn, int xml) void camogm_status(camogm_state *state, char * fn, int xml)
{ {
int _len = 0; int _len = 0;
int _dur, _udur; int _dur[SENSOR_PORTS], _udur[SENSOR_PORTS];
//TODO:make it XML file //TODO:make it XML file
FILE* f; FILE* f;
char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS]; char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS];
...@@ -940,14 +946,16 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -940,14 +946,16 @@ void camogm_status(camogm_state *state, char * fn, int xml)
} }
if (state->vf) _len = ftell(state->vf); //! for ogm if (state->vf) _len = ftell(state->vf); //! for ogm
else if ((state->ivf) >= 0) _len = lseek(state->ivf, 0, SEEK_CUR); //!for mov else if ((state->ivf) >= 0) _len = lseek(state->ivf, 0, SEEK_CUR); //!for mov
_dur = state->this_frame_params.timestamp_sec - state->frame_params.timestamp_sec; FOR_EACH_PORT(int, chn) {
_udur = state->this_frame_params.timestamp_usec - state->frame_params.timestamp_usec; _dur[chn] = state->this_frame_params[chn].timestamp_sec - state->frame_params[chn].timestamp_sec;
if (_udur < 0) { _udur[chn] = state->this_frame_params[chn].timestamp_usec - state->frame_params[chn].timestamp_usec;
_dur -= 1; if (_udur[chn] < 0) {
_udur += 1000000; _dur[chn] -= 1;
} else if (_udur >= 1000000) { _udur[chn] += 1000000;
_dur += 1; } else if (_udur[chn] >= 1000000) {
_udur -= 1000000; _dur[chn] += 1;
_udur[chn] -= 1000000;
}
} }
_state = state->running ? "running" : (state->starting ? "starting" : "stopped"); _state = state->running ? "running" : (state->starting ? "starting" : "stopped");
_output_format = state->format ? ((state->format == CAMOGM_FORMAT_OGM) ? "ogm" : _output_format = state->format ? ((state->format == CAMOGM_FORMAT_OGM) ? "ogm" :
...@@ -961,7 +969,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -961,7 +969,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
FOR_EACH_PORT(int, chn) {_frames_remain[chn] = state->frames_skip_left[chn];} FOR_EACH_PORT(int, chn) {_frames_remain[chn] = state->frames_skip_left[chn];}
_frames_skip = state->frames_skip; _frames_skip = state->frames_skip;
} else if ( state->frames_skip < 0 ) { } else if ( state->frames_skip < 0 ) {
FOR_EACH_PORT(int, chn) {_sec_remain[chn] = (state->frames_skip_left[chn] - state->this_frame_params.timestamp_sec);} FOR_EACH_PORT(int, chn) {_sec_remain[chn] = (state->frames_skip_left[chn] - state->this_frame_params[chn].timestamp_sec);}
_sec_skip = -(state->frames_skip); _sec_skip = -(state->frames_skip);
} }
...@@ -1014,7 +1022,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -1014,7 +1022,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
" <greedy>\"%s\"</greedy>\n" \ " <greedy>\"%s\"</greedy>\n" \
" <ignore_fps>\"%s\"</ignore_fps>\n" \ " <ignore_fps>\"%s\"</ignore_fps>\n" \
"</camogm_state>\n", "</camogm_state>\n",
_state, _compressor_state[0], state->path, state->frameno, _b_size, state->start_after_timestamp, _dur, _udur, _len, state->frame_period[0], \ _state, _compressor_state[0], state->path, state->frameno, _b_size, state->start_after_timestamp, _dur[0], _udur[0], _len, state->frame_period[0], \
_frames_skip, _sec_skip, _frames_remain[0], _sec_remain[0], \ _frames_skip, _sec_skip, _frames_remain[0], _sec_remain[0], \
state->width, state->height, _output_format, _using_exif, \ state->width, state->height, _output_format, _using_exif, \
state->path_prefix, state->segment_duration, state->segment_length, state->max_frames, state->timescale, \ state->path_prefix, state->segment_duration, state->segment_length, state->max_frames, state->timescale, \
...@@ -1030,7 +1038,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -1030,7 +1038,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
fprintf(f, "frame %d\n", state->frameno); fprintf(f, "frame %d\n", state->frameno);
fprintf(f, "frame size %d\n", _b_size); fprintf(f, "frame size %d\n", _b_size);
fprintf(f, "start_after_timestamp %f\n", state->start_after_timestamp); fprintf(f, "start_after_timestamp %f\n", state->start_after_timestamp);
fprintf(f, "file duration %d.%06d sec\n", _dur, _udur); FOR_EACH_PORT(int, chn) {fprintf(f, "file duration %d.%06d sec\n", _dur[chn], _udur[chn]);}
fprintf(f, "file length %d B\n", _len); fprintf(f, "file length %d B\n", _len);
FOR_EACH_PORT(int, chn) {fprintf(f, "frame period %d (0x%x)\n", state->frame_period[chn], state->frame_period[chn]);} FOR_EACH_PORT(int, chn) {fprintf(f, "frame period %d (0x%x)\n", state->frame_period[chn], state->frame_period[chn]);}
if ( _frames_skip > 0 ) { if ( _frames_skip > 0 ) {
...@@ -1470,10 +1478,10 @@ unsigned int select_port(camogm_state *state) ...@@ -1470,10 +1478,10 @@ unsigned int select_port(camogm_state *state)
} }
} }
for (int i = 1; i < SENSOR_PORTS; i++) { for (int i = 1; i < SENSOR_PORTS; i++) {
if (free_sz[i - 1] < free_sz[i]) if (free_sz[i] < free_sz[i - 1])
chn = i; chn = i;
} }
printf("free sizes: %x, %x, %x, %x\n", free_sz[0], free_sz[1], free_sz[2], free_sz[3]); printf("free sizes: %lx, %lx, %lx, %lx\n", free_sz[0], free_sz[1], free_sz[2], free_sz[3]);
return chn; return chn;
} }
......
...@@ -100,8 +100,8 @@ typedef struct { ...@@ -100,8 +100,8 @@ typedef struct {
int head_size[SENSOR_PORTS]; //! JPEG header size int head_size[SENSOR_PORTS]; //! JPEG header size
unsigned char jpegHeader[SENSOR_PORTS][JPEG_HEADER_MAXSIZE]; unsigned char jpegHeader[SENSOR_PORTS][JPEG_HEADER_MAXSIZE];
int metadata_start; int metadata_start;
struct interframe_params_t frame_params; struct interframe_params_t frame_params[SENSOR_PORTS];
struct interframe_params_t this_frame_params; struct interframe_params_t this_frame_params[SENSOR_PORTS];
int jpeg_len; int jpeg_len;
int frame_period[SENSOR_PORTS]; //!in microseconds (1/10 of what is needed for the Ogm header) int frame_period[SENSOR_PORTS]; //!in microseconds (1/10 of what is needed for the Ogm header)
int width; int width;
......
...@@ -134,6 +134,7 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -134,6 +134,7 @@ int camogm_frame_jpeg(camogm_state *state)
struct iovec chunks_iovec[8]; struct iovec chunks_iovec[8];
unsigned char *split_ptr = NULL; unsigned char *split_ptr = NULL;
long split_cntr = 0; long split_cntr = 0;
int port = state->port_num;
if (!state->rawdev_op) { if (!state->rawdev_op) {
l = 0; l = 0;
...@@ -143,7 +144,7 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -143,7 +144,7 @@ int camogm_frame_jpeg(camogm_state *state)
l += chunks_iovec[i].iov_len; l += chunks_iovec[i].iov_len;
} }
sprintf(state->path, "%s%010ld_%06ld.jpeg", state->path_prefix, state->this_frame_params.timestamp_sec, state->this_frame_params.timestamp_usec); sprintf(state->path, "%s%010ld_%06ld.jpeg", state->path_prefix, state->this_frame_params[port].timestamp_sec, state->this_frame_params[port].timestamp_usec);
if (((state->ivf = open(state->path, O_RDWR | O_CREAT, 0777))) < 0) { 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)); D0(fprintf(debug_file, "Error opening %s for writing, returned %d, errno=%d\n", state->path, state->ivf, errno));
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
......
...@@ -139,7 +139,7 @@ int camogm_start_kml(camogm_state *state) ...@@ -139,7 +139,7 @@ int camogm_start_kml(camogm_state *state)
} }
} }
close(fd_ExifDir); close(fd_ExifDir);
sprintf(state->kml_path, "%s%010ld_%06ld.kml", state->path_prefix, state->this_frame_params.timestamp_sec, state->this_frame_params.timestamp_usec); sprintf(state->kml_path, "%s%010ld_%06ld.kml", state->path_prefix, state->this_frame_params[state->port_num].timestamp_sec, state->this_frame_params[state->port_num].timestamp_usec);
if (!((state->kml_file = fopen(state->kml_path, "w+"))) ) { if (!((state->kml_file = fopen(state->kml_path, "w+"))) ) {
D0(fprintf(debug_file, "Error opening %s for writing\n", state->kml_path)); D0(fprintf(debug_file, "Error opening %s for writing\n", state->kml_path));
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
...@@ -168,15 +168,15 @@ int camogm_frame_kml(camogm_state *state) ...@@ -168,15 +168,15 @@ int camogm_frame_kml(camogm_state *state)
int port = state->port_num; int port = state->port_num;
if (state->kml_file) { // probably not needed if (state->kml_file) { // probably not needed
i = state->this_frame_params.timestamp_sec - (state->kml_last_ts + state->kml_period); i = state->this_frame_params[state->port_num].timestamp_sec - (state->kml_last_ts + state->kml_period);
if ((i > 1) || ((i == 0) && ( state->this_frame_params.timestamp_usec > state->kml_last_uts ))) { if ((i > 1) || ((i == 0) && ( state->this_frame_params[state->port_num].timestamp_usec > state->kml_last_uts ))) {
// if (state->this_frame_params.timestamp_sec > (state->kml_last_ts + state->kml_period)) { // this way it is safe to put kml_period=1000, then kml_period=1 // if (state->this_frame_params.timestamp_sec > (state->kml_last_ts + state->kml_period)) { // this way it is safe to put kml_period=1000, then kml_period=1
state->kml_last_ts = state->this_frame_params.timestamp_sec; state->kml_last_ts = state->this_frame_params[state->port_num].timestamp_sec;
state->kml_last_uts = state->this_frame_params.timestamp_usec; state->kml_last_uts = state->this_frame_params[state->port_num].timestamp_usec;
if (state->format == CAMOGM_FORMAT_JPEG) { if (state->format == CAMOGM_FORMAT_JPEG) {
strcpy(JPEGFileName, state->path); strcpy(JPEGFileName, state->path);
} else { } else {
sprintf(JPEGFileName, "%s%010ld_%06ld.jpeg", state->path_prefix, state->this_frame_params.timestamp_sec, state->this_frame_params.timestamp_usec); sprintf(JPEGFileName, "%s%010ld_%06ld.jpeg", state->path_prefix, state->this_frame_params[state->port_num].timestamp_sec, state->this_frame_params[state->port_num].timestamp_usec);
if (((fd_JPEG = open(JPEGFileName, O_RDWR | O_CREAT, 0777))) >= 0) { if (((fd_JPEG = open(JPEGFileName, O_RDWR | O_CREAT, 0777))) >= 0) {
l = 0; l = 0;
for (i = 0; i < (state->chunk_index) - 1; i++) { for (i = 0; i < (state->chunk_index) - 1; i++) {
......
...@@ -153,7 +153,7 @@ int camogm_start_mov(camogm_state *state) ...@@ -153,7 +153,7 @@ int camogm_start_mov(camogm_state *state)
//! allocate memory for the frame index table //! allocate memory for the frame index table
if (!((state->frame_lengths = malloc(4 * state->max_frames)))) return -CAMOGM_FRAME_MALLOC; if (!((state->frame_lengths = malloc(4 * state->max_frames)))) return -CAMOGM_FRAME_MALLOC;
//! open file for writing //! open file for writing
sprintf(state->path, "%s%010ld_%06ld.mov", state->path_prefix, state->frame_params.timestamp_sec, state->frame_params.timestamp_usec); sprintf(state->path, "%s%010ld_%06ld.mov", state->path_prefix, state->frame_params[state->port_num].timestamp_sec, state->frame_params[state->port_num].timestamp_usec);
if (((state->ivf = open(state->path, O_RDWR | O_CREAT, 0777))) < 0) { 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)); D0(fprintf(debug_file, "Error opening %s for writing, returned %d, errno=%d\n", state->path, state->ivf, errno));
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
......
...@@ -73,10 +73,10 @@ int camogm_start_ogm(camogm_state *state) ...@@ -73,10 +73,10 @@ int camogm_start_ogm(camogm_state *state)
char vendor[] = "ElphelOgm v 0.1"; char vendor[] = "ElphelOgm v 0.1";
int pos; int pos;
stream_header sh; stream_header sh;
char hdbuf[sizeof(sh) + 1]; unsigned char hdbuf[sizeof(sh) + 1];
ogg_packet ogg_header; ogg_packet ogg_header;
sprintf(state->path, "%s%010ld_%06ld.ogm", state->path_prefix, state->frame_params.timestamp_sec, state->frame_params.timestamp_usec); sprintf(state->path, "%s%010ld_%06ld.ogm", state->path_prefix, state->frame_params[state->port_num].timestamp_sec, state->frame_params[state->port_num].timestamp_usec);
if (!((state->vf = fopen(state->path, "w+"))) ) { if (!((state->vf = fopen(state->path, "w+"))) ) {
D0(fprintf(debug_file, "Error opening %s for writing\n", state->path)); D0(fprintf(debug_file, "Error opening %s for writing\n", state->path));
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
...@@ -153,8 +153,8 @@ int camogm_start_ogm(camogm_state *state) ...@@ -153,8 +153,8 @@ int camogm_start_ogm(camogm_state *state)
*/ */
//! calculate initial absolute granulepos (from 1970), then increment with each frame. Later try calculating granulepos of each frame //! calculate initial absolute granulepos (from 1970), then increment with each frame. Later try calculating granulepos of each frame
//! from the absolute time (actual timestamp) //! from the absolute time (actual timestamp)
state->granulepos = (ogg_int64_t)( (((double)state->frame_params.timestamp_usec) + state->granulepos = (ogg_int64_t)( (((double)state->frame_params[state->port_num].timestamp_usec) +
(((double)1000000) * ((double)state->frame_params.timestamp_sec))) * (((double)1000000) * ((double)state->frame_params[state->port_num].timestamp_sec))) *
((double)10) / ((double)10) /
((double)state->time_unit) * ((double)state->time_unit) *
((double)state->timescale)); ((double)state->timescale));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment