Commit 67643efd authored by Andrey Filippov's avatar Andrey Filippov

Start/restart behavior, more of relevant status output

parent eb2f643e
......@@ -363,8 +363,13 @@ int camogm_start(camogm_state *state, bool restart)
D1(syslog (LOG_INFO, "Starting raw data recording, marked %s", get_state_path(state)));
next_state_path(state); // increment path so next time will use different one.
} else {
D1(fprintf(debug_file, "Re-starting raw data recording, using the same state file, text will be %s, state->path='%s'\n", get_state_path(state), state->path));
D1(syslog (LOG_INFO, "Re-starting raw data recording, next will be %s", get_state_path(state)));
if (state->prog_state == STATE_STARTING) {
D1(fprintf(debug_file, "Continue starting, state->path='%s'\n", state->path));
D1(syslog (LOG_INFO, "Continue starting, state->path='%s'\n", state->path));
} else {
D1(fprintf(debug_file, "Re-starting raw data recording, using the same state file, next will be %s, state->path='%s'\n", get_state_path(state), state->path));
D1(syslog (LOG_INFO, "Re-starting raw data recording, next will be %s", get_state_path(state)));
}
}
} else {
D1(fprintf(debug_file, "Starting file system recording to %s\n", state->path));
......@@ -375,10 +380,11 @@ int camogm_start(camogm_state *state, bool restart)
state->frameno = 0;
// do not trigger overrun alert on successfull (from GUI) restarts
#if ERRORS_FROM_START == 0
if (state->prog_state != STATE_RESTARTING)
for (int p = 0; p < SENSOR_PORTS; p++)
state->buf_overruns[p] = -1;
#endif
state->timescale = state->set_timescale; // current timescale, default 1
// debug
int * ifp = (int*)&(state->frame_params[port]);
......@@ -431,12 +437,36 @@ int camogm_start(camogm_state *state, bool restart)
if (!state->ignore_fps) { // don't even try in ignore mode
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
}
#if ERRORS_FROM_START == 0
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);
state->buf_min[chn] = getGPValue(chn, G_FREECIRCBUF);
#endif
} else {
if (state->buf_min[chn] > getGPValue(chn, G_FREECIRCBUF)) state->buf_min[chn] = getGPValue(chn, G_FREECIRCBUF);
#if ERRORS_FROM_START == 0
if (state->buf_min[chn] > getGPValue(chn, G_FREECIRCBUF)) {
state->buf_min[chn] = getGPValue(chn, G_FREECIRCBUF);
}
#endif
}
#if ERRORS_FROM_START
if (!restart) { // only reset errors and minimal buffer size during slient-initiated start (not after buffer overrun)
state->buf_mmin = state->circ_buff_size[0] - MIN_USED_SIZE;;
FOR_EACH_PORT(int, chn) {
state->buf_overruns[chn] = 0;
state->buf_min[chn] = state->circ_buff_size[chn] - MIN_USED_SIZE;
if (state->buf_min[chn] < state->buf_mmin){ // will never happed with the same buffers
state->buf_mmin = state->buf_min[chn];
}
}
state->last_error_code = 0; // Reset error
state->error_restarts = 0;
} else { // restart only after buffer overrun
if (state->prog_state != STATE_STARTING) { // during STATE_STARTING it continuously gets here if
state->error_restarts ++;
}
}
#endif
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)=0x%x\n",\
(int)lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END)));
......@@ -1160,14 +1190,15 @@ void camogm_status(camogm_state *state, char * fn, int xml)
int _dur = 0, _udur = 0, _dur_raw, _udur_raw;
FILE* f;
char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS];
int _b_free[SENSOR_PORTS], _b_used[SENSOR_PORTS], _b_size[SENSOR_PORTS];
// int _b_free[SENSOR_PORTS], _b_used[SENSOR_PORTS], _b_size[SENSOR_PORTS];
int _b_size[SENSOR_PORTS];
int _frames_remain[SENSOR_PORTS] = {0};
int _sec_remain[SENSOR_PORTS] = {0};
int _frames_skip = 0;
int _sec_skip = 0;
char *_kml_enable, *_kml_used, *_kml_height_mode;
unsigned int _percent_done;
off_t save_p;
// off_t save_p;
_kml_enable = state->kml_enable ? "yes" : "no";
_kml_used = state->kml_used ? "yes" : "no";
......@@ -1175,11 +1206,11 @@ void camogm_status(camogm_state *state, char * fn, int xml)
for (int chn = 0; chn < SENSOR_PORTS; chn++) {
_b_size[chn] = getGPValue(chn, G_FRAME_SIZE);
save_p = lseek(state->fd_circ[chn], 0, SEEK_CUR);
_b_free[chn] = lseek(state->fd_circ[chn], LSEEK_CIRC_FREE, SEEK_END);
lseek(state->fd_circ[chn], save_p, SEEK_SET);
_b_used[chn] = lseek(state->fd_circ[chn], LSEEK_CIRC_USED, SEEK_END);
lseek(state->fd_circ[chn], save_p, SEEK_SET);
// save_p = lseek(state->fd_circ[chn], 0, SEEK_CUR);
// _b_free[chn] = lseek(state->fd_circ[chn], LSEEK_CIRC_FREE, SEEK_END);
// lseek(state->fd_circ[chn], save_p, SEEK_SET);
// _b_used[chn] = lseek(state->fd_circ[chn], LSEEK_CIRC_USED, SEEK_END);
// lseek(state->fd_circ[chn], save_p, SEEK_SET);
_compressor_state[chn] = (getGPValue(chn, P_COMPRESSOR_RUN) == 2) ? "running" : "stopped";
if (state->frames_skip > 0)
_frames_remain[chn] = state->frames_skip_left[chn];
......@@ -1252,6 +1283,8 @@ void camogm_status(camogm_state *state, char * fn, int xml)
fprintf(f, "<?xml version=\"1.0\"?>\n" \
"<camogm_state>\n" \
" <state>\"%s\"</state>\n" \
" <buf_mfree>\"%d\"</buf_mfree>\n" \
" <buf_mmin>\"%d\"</buf_mmin>\n" \
" <file_name>\"%s\"</file_name>\n" \
" <frame_number>%d</frame_number>\n" \
" <start_after_timestamp>%f</start_after_timestamp>\n" \
......@@ -1270,6 +1303,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
" <timescale>%f</timescale>\n" \
" <frames_per_chunk>%d</frames_per_chunk>\n" \
" <last_error_code>%d</last_error_code>\n" \
" <error_restarts>%d</error_restarts>\n" \
" <debug_output>\"%s\"</debug_output>\n" \
" <debug_level>%d</debug_level>\n" \
" <use_global_rp>\"%s\"</use_global_rp>\n" \
......@@ -1292,11 +1326,11 @@ void camogm_status(camogm_state *state, char * fn, int xml)
" <lba_start>%llu</lba_start>\n" \
" <lba_current>%llu</lba_current>\n" \
" <lba_end>%llu</lba_end>\n",
_state, state->path, state->frameno, state->start_after_timestamp, _dur, _udur, _len, \
_state, state->buf_mfree, state->buf_mmin, state->path, state->frameno, state->start_after_timestamp, _dur, _udur, _len, \
_frames_skip, _sec_skip, \
state->width, state->height, _output_format, _using_exif, \
state->path_prefix, state->segment_duration, state->segment_length, state->max_frames, state->timescale, \
state->frames_per_chunk, state->last_error_code, \
state->frames_per_chunk, state->last_error_code, state->error_restarts, \
state->debug_name, debug_level, _using_global_pointer, \
_kml_enable, _kml_used, state->kml_path, state->kml_horHalfFov, state->kml_vertHalfFov, state->kml_near, \
_kml_height_mode, state->kml_height, state->kml_period, state->kml_last_ts, state->kml_last_uts, \
......@@ -1328,8 +1362,8 @@ void camogm_status(camogm_state *state, char * fn, int xml)
state->buf_overruns[chn],
state->buf_min[chn],
state->frame_period[chn],
_b_free[chn],
_b_used[chn],
state->buf_free[chn], // _b_free[chn],
state->circ_buff_size[chn] - state->buf_free[chn], // _b_used[chn],
state->cirbuf_rp[chn]
);
camogm_err_stat(state, chn, f, true);
......@@ -1338,6 +1372,8 @@ void camogm_status(camogm_state *state, char * fn, int xml)
fprintf(f, "</camogm_state>\n");
} else {
fprintf(f, "state \t%s\n", _state);
fprintf(f, "buf_mfree \t%d\n", state->buf_mfree); // minimal of all ports
fprintf(f, "buf_mmin \t%d\n", state->buf_mmin); // minimal of all ports
fprintf(f, "file \t%s\n", state->path);
fprintf(f, "frame \t%d\n", state->frameno);
fprintf(f, "start_after_timestamp \t%f\n", state->start_after_timestamp);
......@@ -1363,6 +1399,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
fprintf(f, "ignore fps \t%s\n", state->ignore_fps ? "yes" : "no");
fprintf(f, "\n");
fprintf(f, "last error code \t%d\n", state->last_error_code);
fprintf(f, "error_restarts \t%d\n", state->error_restarts);
fprintf(f, "\n");
fprintf(f, "debug output to \t%s\n", state->debug_name);
fprintf(f, "debug level \t%d\n", debug_level);
......@@ -1396,17 +1433,20 @@ void camogm_status(camogm_state *state, char * fn, int xml)
fprintf(f, "buffer overruns \t%d\n", state->buf_overruns[chn]);
fprintf(f, "buffer minimal \t%d\n", state->buf_min[chn]);
fprintf(f, "frame period \t%d (0x%x)\n", state->frame_period[chn], state->frame_period[chn]);
fprintf(f, "buffer free \t%d\n", _b_free[chn]);
fprintf(f, "buffer used \t%d\n", _b_used[chn]);
fprintf(f, "buffer free \t%d\n", state->buf_free[chn]); // _b_free[chn]);
fprintf(f, "buffer used \t%d\n", state->circ_buff_size[chn] - state->buf_free[chn]); //_b_used[chn]);
fprintf(f, "circbuf_rp \t%d (0x%x)\n", state->cirbuf_rp[chn], state->cirbuf_rp[chn]);
camogm_err_stat(state, chn, f, false);
fprintf(f, "\n");
}
}
if ((f != stdout) && (f != stderr)) fclose(f);
#if ERRORS_FROM_START == 0
FOR_EACH_PORT(int, chn) {if (state->buf_overruns[chn] >= 0) state->buf_overruns[chn] = 0;} // resets overruns after reading status , so "overruns" means since last reading status
state->last_error_code = 0; // Reset error
FOR_EACH_PORT(int, chn) {state->buf_min[chn] = _b_free[chn];}
#endif
}
/**
......@@ -1877,7 +1917,8 @@ int listener_loop(camogm_state *state)
case CAMOGM_FRAME_INVALID: // invalid frame pointer
case CAMOGM_FRAME_BROKEN: // frame broken (buffer overrun)
// restart the file
D0(fprintf(debug_file,"%s:line %d - sendImageFrame() returned -%d\n", __FILE__, __LINE__, rslt));
D0(fprintf(debug_file,"%s:line %d - *** sendImageFrame() returned -%d, restarting\n", __FILE__, __LINE__, rslt));
D0(syslog (LOG_INFO,"%s:line %d - *** sendImageFrame() returned -%d, restarting", __FILE__, __LINE__, rslt));
camogm_stop(state);
state->prog_state = STATE_RESTARTING;
D6(fprintf(debug_file, "camogm_start() from %s:%d: @ %07d\n", \
......@@ -1920,7 +1961,6 @@ int listener_loop(camogm_state *state)
//next_segment_pos
}
} else if (state->prog_state == STATE_STARTING) { // no commands in queue,starting (but not started yet)
// retry starting
D2(fprintf(debug_file, "camogm_start() from %s:%d: @ %07d\n", __FILE__, __LINE__,get_fpga_usec(state->fd_fparmsall[0], 0)));
switch ((rslt = -camogm_start(state, true))) {
......@@ -2213,20 +2253,32 @@ unsigned int select_port(camogm_state *state)
port,state->cirbuf_rp[port]); for (i=0; i< 16; i++) { \
fprintf(debug_file," 0x%08lx", ((unsigned long* )&ccam_dma_buf[port][dbg_meta >> 2])[i]); \
if ((i & 7) == 7) fprintf(debug_file,"\n"); });
#if ERRORS_FROM_START
state ->buf_overruns[port]++;
#endif
chn = -1; // port;
break;
}
D6(fprintf(debug_file, "port %i = %li, ", port, free_sz));
}
if ((free_sz < min_sz && free_sz >= 0) || min_sz == -1) {
#if ERRORS_FROM_START
if (free_sz >= 0) {
state-> buf_free[port] = free_sz;
if (free_sz < state-> buf_min[port]){
state-> buf_min[port] = free_sz;
}
}
#endif
if (((free_sz < min_sz) && (free_sz >= 0)) || min_sz == -1) {
if (free_sz < CAMOGM_MIN_BUF_FRAMES * state->image_size[port]) {
if ((state->prog_state == STATE_STARTING) || (state->prog_state == STATE_RUNNING)) {
D1(fprintf(debug_file, "port %i has too little free space (%ld <CAMOGM_MIN_BUF_FRAMES * %d), considered BROKEN, state=%d\n", \
port, free_sz, state->image_size[port], state->prog_state));
}
#if ERRORS_FROM_START
state ->buf_overruns[port]++;
#endif
chn = -1; // port;
break;
}
......@@ -2248,6 +2300,10 @@ unsigned int select_port(camogm_state *state)
}
}
if ((state->prog_state == STATE_STARTING) || (state->prog_state == STATE_RUNNING)) {
state->buf_mfree = min_sz;
if (state->buf_mfree < state->buf_mmin){
state->buf_mmin = state->buf_mfree;
}
#ifdef MIN_USED_SIZE
D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0) && \
(lseek(state->fd_circ[chn], LSEEK_CIRC_USED, SEEK_END) >= MIN_USED_SIZE)) {\
......
......@@ -35,6 +35,7 @@
#define NUM_NEED_NEMPTY (NUM_WRITER_THREADS + 0) // wake up main thread if there are at least this number of empty pages
#define NUM_FREE_MANY (NUM_WRITER_THREADS + 1) // Set many if get_num_empty() < NUM_FREE_MANY
#define ERRORS_FROM_START 1 ///< Reset errors only when starting recording, not after reading status
//#define NODEBUG
#define CAMOGM_FRAME_NOT_READY 1 ///< frame pointer valid, but not yet acquired
#define CAMOGM_FRAME_INVALID 2 ///< invalid frame pointer
......@@ -172,7 +173,7 @@ enum state_flags {
STATE_STARTING,
STATE_RUNNING,
STATE_READING,
STATE_RESTARTING,
STATE_RESTARTING, // after errors, until started
STATE_CANCEL
};
......@@ -337,6 +338,10 @@ typedef struct {
int data_segments; ///< the number of segments in frame
int buf_overruns[SENSOR_PORTS];
int buf_min[SENSOR_PORTS];
int buf_free[SENSOR_PORTS]; ///< free buffer size last measured, per port
int buf_mfree; ///< free buffer size - minimal for all ports
int buf_mmin; ///< minimum of buf_min[port]
int error_restarts; ///< number of restarts due to errors;
int set_frames_skip; ///< will be copied to frames_skip if stopped or at start
int frames_skip; ///< number of frames to skip after the one recorded (for time lapse)
///< if negative - -(interval between frames in seconds)
......
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