Commit e4468ac7 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging fast raw recording

parent a54d1b82
Loading
Loading
Loading
Loading
+34 −29
Original line number Original line Diff line number Diff line
@@ -713,7 +713,7 @@ int sendImageFrame(camogm_state *state)
	dbg_show_packetchunks(state);
	dbg_show_packetchunks(state);




	D6(fprintf(debug_file, "_12.5_ before CAMOGM_FORMAT_XXX @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
	D6(fprintf(debug_file, "_12.5_ before CAMOGM_FORMAT_XXX @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));


	switch (state->format) {
	switch (state->format) {
	case CAMOGM_FORMAT_NONE: rslt = 0; break;
	case CAMOGM_FORMAT_NONE: rslt = 0; break;
@@ -759,7 +759,7 @@ int sendImageFrame(camogm_state *state)
//			end_time.tv_sec, end_time.tv_usec,
//			end_time.tv_sec, end_time.tv_usec,
//			state->rawdev.last_jpeg_size));
//			state->rawdev.last_jpeg_size));
//	D6(fprintf(debug_file, "Write speed: %d MB/s\n", mbps));
//	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)));
	D6(fprintf(debug_file, "Exit sendImageFrame() OK @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));


	return 0;
	return 0;
}
}
@@ -1405,7 +1405,9 @@ int parse_cmd(camogm_state *state, FILE* npipe)
//skip empty commands
//skip empty commands
        while (((cmd = getLineFromPipe(npipe))) && !cmd[0]) ;
        while (((cmd = getLineFromPipe(npipe))) && !cmd[0]) ;
        if (!cmd) return 0;  // nothing in the pipe
        if (!cmd) return 0;  // nothing in the pipe
        D2(fprintf(debug_file, "Got command (state->port_num=%d): '%s' @ %06d -> ", port, cmd, get_fpga_usec(state->fd_fparmsall[0], 0)));
        D2(fprintf(debug_file, "Got command (state->port_num=%d): '%s' @ %07d -> ", port, cmd, get_fpga_usec(state->fd_fparmsall[0], 0)));
        D3(syslog (LOG_INFO,   "Got command (state->port_num=%d): '%s' @ %07d -> ", port, cmd, get_fpga_usec(state->fd_fparmsall[0], 0)));

        if (port >= 0) {
        if (port >= 0) {
                D3(fprintf(debug_file, "Acknowledge received command for port=%d\n", port));
                D3(fprintf(debug_file, "Acknowledge received command for port=%d\n", port));
// Acknowledge received command by copying frame number to per-daemon parameter
// Acknowledge received command by copying frame number to per-daemon parameter
@@ -1676,7 +1678,7 @@ int listener_loop(camogm_state *state)


	// enter main processing loop
	// enter main processing loop
	while (process) {
	while (process) {
		D6(fprintf(debug_file, "--------------- Listener loop @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
		D6(fprintf(debug_file, "--------------- Listener loop @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
		curr_port = select_port(state);
		curr_port = select_port(state);
		state->port_num = curr_port;
		state->port_num = curr_port;
		// look at command queue first
		// look at command queue first
@@ -1690,7 +1692,7 @@ int listener_loop(camogm_state *state)
#endif
#endif
		cmd = parse_cmd(state, cmd_file);
		cmd = parse_cmd(state, cmd_file);
		if (cmd) {
		if (cmd) {
			D2(fprintf(debug_file, "DONE command @ %06d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
			D2(fprintf(debug_file, "DONE command @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));


				if (cmd < 0) D0(fprintf(debug_file, "Unrecognized command\n"));
				if (cmd < 0) D0(fprintf(debug_file, "Unrecognized command\n"));
#ifdef USE_POLL
#ifdef USE_POLL
@@ -1706,7 +1708,7 @@ int listener_loop(camogm_state *state)
			} else {
			} else {
				rslt = -sendImageFrame(state);
				rslt = -sendImageFrame(state);
			}
			}
			D6(fprintf(debug_file, " ==> %d @ %06d\n",rslt,get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, " ==> %d @ %07d\n",rslt,get_fpga_usec(state->fd_fparmsall[0], 0)));
			switch (rslt) {
			switch (rslt) {
			case 0:
			case 0:
				break;                      // frame sent OK, nothing to do (TODO: check file length/duration)
				break;                      // frame sent OK, nothing to do (TODO: check file length/duration)
@@ -1714,7 +1716,7 @@ int listener_loop(camogm_state *state)
				// we'll wait for a frame, not to waste resources. But if the compressor is stopped this program will not respond to any commands
				// we'll wait for a frame, not to waste resources. But if the compressor is stopped this program will not respond to any commands
				// TODO - add another wait with (short) timeout?
				// TODO - add another wait with (short) timeout?
				wait_frame_sync(state->fd_fparmsall[curr_port]);
				wait_frame_sync(state->fd_fparmsall[curr_port]);
				D6(fprintf(debug_file, "No compressed frame ready, waited for the next frame sync for port %d @ %06d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "No compressed frame ready, waited for the next frame sync for port %d @ %07d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
				break;
				break;
				// do not analyze next frame (may be non-existing), will do that next time
				// do not analyze next frame (may be non-existing), will do that next time
				/*
				/*
@@ -1728,7 +1730,7 @@ int listener_loop(camogm_state *state)
						D0(fprintf(debug_file, "%s:line %d got broken frame (%d) while waiting for ready. Before that fp0=0x%x\n", __FILE__, __LINE__, fp1, fp0));
						D0(fprintf(debug_file, "%s:line %d got broken frame (%d) while waiting for ready. Before that fp0=0x%x\n", __FILE__, __LINE__, fp1, fp0));
						rslt = CAMOGM_FRAME_BROKEN;
						rslt = CAMOGM_FRAME_BROKEN;
					} else {
					} else {
						D6(fprintf(debug_file, "No compressed frame ready, skipped 1 frame sync for port %d @ %06d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
						D6(fprintf(debug_file, "No compressed frame ready, skipped 1 frame sync for port %d @ %07d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
						break;
						break;
					}
					}
				}
				}
@@ -1798,14 +1800,14 @@ int listener_loop(camogm_state *state)
				// add port number to error code to facilitate debugging
				// add port number to error code to facilitate debugging
				state->last_error_code = rslt + 100 * state->port_num;
				state->last_error_code = rslt + 100 * state->port_num;
		} else if (state->prog_state == STATE_READING) {
		} else if (state->prog_state == STATE_READING) {
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY start for STATE_READING@ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY start for STATE_READING@ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
			usleep(COMMAND_LOOP_DELAY);
			usleep(COMMAND_LOOP_DELAY);
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY end   for STATE_READING@ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY end   for STATE_READING@ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
		} else {                            // not running, not starting
		} else {                            // not running, not starting
			state->rawdev.thread_state = STATE_RUNNING;
			state->rawdev.thread_state = STATE_RUNNING;
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY start for STATE_RUNNING@ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY start for STATE_RUNNING@ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
			usleep(COMMAND_LOOP_DELAY);     // make it longer but interruptible by signals?
			usleep(COMMAND_LOOP_DELAY);     // make it longer but interruptible by signals?
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY end   for STATE_RUNNING@ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "COMMAND_LOOP_DELAY end   for STATE_RUNNING@ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
		}
		}
#ifdef USE_POLL
#ifdef USE_POLL
//		} // if pfd.revents & POLLIN
//		} // if pfd.revents & POLLIN
@@ -2011,9 +2013,8 @@ unsigned int select_port(camogm_state *state)
			break;
			break;
		}
		}
	}
	}

	if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
	if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
		D3(fprintf(debug_file, "Selecting sensor port, buffer free size: "));
		D6(fprintf(debug_file, "Selecting sensor port, buffer free size: "));
	for (int i = 0; i < SENSOR_PORTS; i++) {
	for (int i = 0; i < SENSOR_PORTS; i++) {
		if (is_chn_active(state, i)) {
		if (is_chn_active(state, i)) {
			file_pos = lseek(state->fd_circ[i], 0, SEEK_CUR);
			file_pos = lseek(state->fd_circ[i], 0, SEEK_CUR);
@@ -2021,7 +2022,7 @@ unsigned int select_port(camogm_state *state)
				free_sz = lseek(state->fd_circ[i], LSEEK_CIRC_FREE, SEEK_END);
				free_sz = lseek(state->fd_circ[i], LSEEK_CIRC_FREE, SEEK_END);
				lseek(state->fd_circ[i], file_pos, SEEK_SET);
				lseek(state->fd_circ[i], file_pos, SEEK_SET);
				if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
				if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
                                        D3(fprintf(debug_file, "port %i = %li, ", i, free_sz));
					D6(fprintf(debug_file, "port %i = %li, ", i, free_sz));
				if (free_sz < CAMOGM_MIN_BUF_FRAMES * state->image_size[i]) {
				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]));
					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;
					chn = -1; // i;
@@ -2042,11 +2043,15 @@ unsigned int select_port(camogm_state *state)
			}
			}
		} else {
		} else {
			if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
			if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
				D3(fprintf(debug_file, "port %i is inactive, ", i));
				D6(fprintf(debug_file, "port %i is inactive, ", i));
		}
		}
	}
	}
	if (state->prog_state == STATE_STARTING || state->prog_state == STATE_RUNNING)
	if ((state->prog_state == STATE_STARTING) || (state->prog_state == STATE_RUNNING)) {
		D3(fprintf(debug_file, "selected port: %i @ %06d\n", chn, get_fpga_usec(state->fd_fparmsall[0], 0)));
//		if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) {
		D3(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0)) \
				fprintf(debug_file, "selected port: %i, min free size = %d @ %07d\n", chn, min_sz, get_fpga_usec(state->fd_fparmsall[0], 0)); \
				else if (debug_level >= 6) fprintf(debug_file,"no port is ready @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
	}


	return chn;
	return chn;
}
}
@@ -2324,7 +2329,7 @@ inline int get_fpga_usec(const int fd_fparsall, unsigned int port)
{
{
	lseek(fd_fparsall, LSEEK_GET_FPGA_TIME, SEEK_END);
	lseek(fd_fparsall, LSEEK_GET_FPGA_TIME, SEEK_END);
//	return (int) getGPValue(port, G_MICROSECONDS);
//	return (int) getGPValue(port, G_MICROSECONDS);
	return (int) GLOBALPARS(port, G_MICROSECONDS);
	return (int) GLOBALPARS(port, G_MICROSECONDS) + 1000000*(GLOBALPARS(port, G_SECONDS) % 10);
}
}


/**
/**
+1 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@
#include <elphel/exifa.h>
#include <elphel/exifa.h>
#include <elphel/c313a.h>
#include <elphel/c313a.h>
#include <elphel/x393_devices.h>
#include <elphel/x393_devices.h>
#include <syslog.h>


#define CAMOGM_FRAME_NOT_READY    1        ///< frame pointer valid, but not yet acquired
#define CAMOGM_FRAME_NOT_READY    1        ///< frame pointer valid, but not yet acquired
#define CAMOGM_FRAME_INVALID      2        ///< invalid frame pointer
#define CAMOGM_FRAME_INVALID      2        ///< invalid frame pointer
+7 −7
Original line number Original line Diff line number Diff line
@@ -548,7 +548,7 @@ void align_frame(camogm_state *state)
		if (len >= (chunks[paged_CHUNK_DATA_1].iov_len + chunks[paged_CHUNK_TRAILER].iov_len)) {
		if (len >= (chunks[paged_CHUNK_DATA_1].iov_len + chunks[paged_CHUNK_TRAILER].iov_len)) {
			/* current frame is not split or the second part of JPEG data is too short */
			/* current frame is not split or the second part of JPEG data is too short */
			data_len = len - chunks[paged_CHUNK_DATA_1].iov_len - chunks[paged_CHUNK_TRAILER].iov_len;
			data_len = len - chunks[paged_CHUNK_DATA_1].iov_len - chunks[paged_CHUNK_TRAILER].iov_len;
			D6(fprintf(debug_file, "_algn002:  data_len=%d, copy %d short JPEG @ %06d\n", data_len, chunks[paged_CHUNK_DATA_1].iov_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "_algn002:  data_len=%d, copy %d short JPEG @ %07d\n", data_len, chunks[paged_CHUNK_DATA_1].iov_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			src = vectrpos(&chunks[paged_CHUNK_DATA_0], data_len);
			src = vectrpos(&chunks[paged_CHUNK_DATA_0], data_len);
			vectcpy(chunk_rem, src, data_len);
			vectcpy(chunk_rem, src, data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_0], data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_0], data_len);
@@ -559,7 +559,7 @@ void align_frame(camogm_state *state)
		} else if (len >= chunks[paged_CHUNK_TRAILER].iov_len) {
		} else if (len >= chunks[paged_CHUNK_TRAILER].iov_len) {
			/* there is enough data in second part to align the frame */
			/* there is enough data in second part to align the frame */
			data_len = len - chunks[paged_CHUNK_TRAILER].iov_len;
			data_len = len - chunks[paged_CHUNK_TRAILER].iov_len;
			D6(fprintf(debug_file, "_algn003:  data_len=%d, copy %d short JPEG @ %06d\n", data_len, chunks[paged_CHUNK_DATA_1].iov_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "_algn003:  data_len=%d, copy %d short JPEG @ %07d\n", data_len, chunks[paged_CHUNK_DATA_1].iov_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			src = vectrpos(&chunks[paged_CHUNK_DATA_1], data_len);
			src = vectrpos(&chunks[paged_CHUNK_DATA_1], data_len);
			vectcpy(chunk_rem, src, data_len);
			vectcpy(chunk_rem, src, data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_1], data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_1], data_len);
@@ -571,7 +571,7 @@ void align_frame(camogm_state *state)
			data_len = PHY_BLOCK_SIZE - (chunks[paged_CHUNK_TRAILER].iov_len - len);
			data_len = PHY_BLOCK_SIZE - (chunks[paged_CHUNK_TRAILER].iov_len - len);
			if (data_len >= chunks[paged_CHUNK_DATA_1].iov_len) {
			if (data_len >= chunks[paged_CHUNK_DATA_1].iov_len) {
				size_t cut_len = data_len - chunks[paged_CHUNK_DATA_1].iov_len;
				size_t cut_len = data_len - chunks[paged_CHUNK_DATA_1].iov_len;
				D6(fprintf(debug_file, "_algn004:  cut_len=%d, copy %d short JPEG @ %06d\n", cut_len, chunks[paged_CHUNK_DATA_1].iov_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "_algn004:  cut_len=%d, copy %d short JPEG @ %07d\n", cut_len, chunks[paged_CHUNK_DATA_1].iov_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
				src = vectrpos(&chunks[paged_CHUNK_DATA_0], cut_len);
				src = vectrpos(&chunks[paged_CHUNK_DATA_0], cut_len);
				vectcpy(chunk_rem, src, cut_len);
				vectcpy(chunk_rem, src, cut_len);
				vectshrink(&chunks[paged_CHUNK_DATA_0], cut_len);
				vectshrink(&chunks[paged_CHUNK_DATA_0], cut_len);
@@ -580,7 +580,7 @@ void align_frame(camogm_state *state)
				vectcpy(chunk_rem, chunks[paged_CHUNK_TRAILER].iov_base, chunks[paged_CHUNK_TRAILER].iov_len);
				vectcpy(chunk_rem, chunks[paged_CHUNK_TRAILER].iov_base, chunks[paged_CHUNK_TRAILER].iov_len);
				vectshrink(&chunks[paged_CHUNK_TRAILER], chunks[paged_CHUNK_TRAILER].iov_len);
				vectshrink(&chunks[paged_CHUNK_TRAILER], chunks[paged_CHUNK_TRAILER].iov_len);
			} else {
			} else {
				D6(fprintf(debug_file, "_algn005:  data_len=%d, @ %06d\n", data_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "_algn005:  data_len=%d, @ %07d\n", data_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
				src = vectrpos(&chunks[paged_CHUNK_DATA_1], data_len);
				src = vectrpos(&chunks[paged_CHUNK_DATA_1], data_len);
				vectcpy(chunk_rem, src, data_len);
				vectcpy(chunk_rem, src, data_len);
				vectshrink(&chunks[paged_CHUNK_DATA_1], data_len);
				vectshrink(&chunks[paged_CHUNK_DATA_1], data_len);
@@ -594,13 +594,13 @@ void align_frame(camogm_state *state)
		chunks[paged_CHUNK_ALIGN].iov_len = 0;
		chunks[paged_CHUNK_ALIGN].iov_len = 0;
		if (chunks[paged_CHUNK_DATA_1].iov_len == 0) {
		if (chunks[paged_CHUNK_DATA_1].iov_len == 0) {
			data_len = chunks[paged_CHUNK_DATA_0].iov_len % ALIGNMENT_SIZE;
			data_len = chunks[paged_CHUNK_DATA_0].iov_len % ALIGNMENT_SIZE;
			D6(fprintf(debug_file, "_algn006:  data_len=%d, @ %06d\n", data_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "_algn006:  data_len=%d, @ %07d\n", data_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			src = vectrpos(&chunks[CHUNK_DATA_0], data_len);
			src = vectrpos(&chunks[CHUNK_DATA_0], data_len);
			vectcpy(&chunks[paged_CHUNK_ALIGN], src, data_len);
			vectcpy(&chunks[paged_CHUNK_ALIGN], src, data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_0], data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_0], data_len);
		} else {
		} else {
			data_len = chunks[paged_CHUNK_DATA_1].iov_len % ALIGNMENT_SIZE;
			data_len = chunks[paged_CHUNK_DATA_1].iov_len % ALIGNMENT_SIZE;
			D6(fprintf(debug_file, "_algn007:  data_len=%d, @ %06d\n", data_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "_algn007:  data_len=%d, @ %07d\n", data_len, get_fpga_usec(state->fd_fparmsall[0], 0)));
			src = vectrpos(&chunks[paged_CHUNK_DATA_1], data_len);
			src = vectrpos(&chunks[paged_CHUNK_DATA_1], data_len);
			vectcpy(&chunks[paged_CHUNK_ALIGN], src, data_len);
			vectcpy(&chunks[paged_CHUNK_ALIGN], src, data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_1], data_len);
			vectshrink(&chunks[paged_CHUNK_DATA_1], data_len);
@@ -614,7 +614,7 @@ void align_frame(camogm_state *state)
		dev_dbg(NULL, "ERROR: the number of bytes copied to common buffer exceeds its size\n");
		dev_dbg(NULL, "ERROR: the number of bytes copied to common buffer exceeds its size\n");
	}
	}
	check_chunks(chunks, page);
	check_chunks(chunks, page);
	D6(fprintf(debug_file, "align_frame() DONE @ %06d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
	D6(fprintf(debug_file, "align_frame() DONE @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));


}
}


+3 −3
Original line number Original line Diff line number Diff line
@@ -22,9 +22,9 @@
#include <sys/types.h>
#include <sys/types.h>


#include "camogm.h"
#include "camogm.h"
// TODO: Change PHY_BLOCK_SIZE to 4096 as it is 4096!
// TODO: Change PHY_BLOCK_SIZE to 4096 as it is 4096 - no, most SSDs are still 512
//#define PHY_BLOCK_SIZE            512            ///< Physical disk block size
#define PHY_BLOCK_SIZE            512            ///< Physical disk block size - still 512 even for the OS with 4096
#define PHY_BLOCK_SIZE            4096           ///< Physical disk block size
//#define PHY_BLOCK_SIZE            4096           ///< Physical disk block size
#define JPEG_MARKER_LEN           2              ///< The size in bytes of JPEG marker
#define JPEG_MARKER_LEN           2              ///< The size in bytes of JPEG marker
#define JPEG_SIZE_LEN             2              ///< The size in bytes of JPEG marker length field
#define JPEG_SIZE_LEN             2              ///< The size in bytes of JPEG marker length field
#define INCLUDE_REM               1              ///< Include REM buffer to total size calculation
#define INCLUDE_REM               1              ///< Include REM buffer to total size calculation
+94 −89
Original line number Original line Diff line number Diff line
@@ -319,36 +319,36 @@ int camogm_frame_jpeg(camogm_state *state)
    	state->rawdev.last_jpeg_size = l;
    	state->rawdev.last_jpeg_size = l;
    	close(state->ivf);
    	close(state->ivf);
    } else {
    } 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)));
    	D3(fprintf(debug_file, "_12.7_ camogm_frame_jpeg(): %ld.%06ld:%d @ %07d\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));
    	D6(fprintf(debug_file, "\ndump iovect array for port %u\n", state->port_num));
    	for (int i = 0; i < state->chunk_index - 1; i++) {
    	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));
    		D6(fprintf(debug_file, "ptr: %p, length: %ld\n", state->packetchunks[i + 1].chunk, state->packetchunks[i + 1].bytes));
    	}
    	}
    	// next frame is ready for recording, signal this to the writer thread
    	// next frame is ready for recording, signal this to the writer thread
		D6(fprintf(debug_file, "_13__: Yielding thread before getting a lock (%d, %d):%d @ %06d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	D6(fprintf(debug_file, "_13__: Yielding thread before getting a lock (%d, %d):%d @ %07d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	pthread_yield();
    	pthread_yield();
    	pthread_mutex_lock(&state->writer_params.writer_mutex);
    	pthread_mutex_lock(&state->writer_params.writer_mutex);
		D6(fprintf(debug_file, "_13a_: waiting for empty buffer (%d, %d):%d @ %06d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	D6(fprintf(debug_file, "_13a_: waiting for empty buffer (%d, %d):%d @ %07d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	// do not run ahead by >= FILE_CHUNKS_PAGES (0 or 1 for just FILE_CHUNKS_PAGES == 2)
    	// do not run ahead by >= FILE_CHUNKS_PAGES (0 or 1 for just FILE_CHUNKS_PAGES == 2)
    	// either buffer is completely empty (state->writer_params->chunk_page_prep == state->writer_params->chunk_page_write)
    	// either buffer is completely empty (state->writer_params->chunk_page_prep == state->writer_params->chunk_page_write)
    	// or it is not full and writev_run is active
    	// or it is not full and writev_run is active
    	while (((state->writer_params.chunk_page_prep - state->writer_params.chunk_page_write + (2 * FILE_CHUNKS_PAGES))
    	while (((state->writer_params.chunk_page_prep - state->writer_params.chunk_page_write + (2 * FILE_CHUNKS_PAGES))
    			% (2 * FILE_CHUNKS_PAGES) >= FILE_CHUNKS_PAGES) ||
    			% (2 * FILE_CHUNKS_PAGES) >= FILE_CHUNKS_PAGES) ||
    			(!state->writer_params.writev_run && (state->writer_params.chunk_page_prep != state->writer_params.chunk_page_write))) {
    			(!state->writer_params.writev_run && (state->writer_params.chunk_page_prep != state->writer_params.chunk_page_write))) {
			D6(fprintf(debug_file, "_13b_: waiting for empty buffer (%d, %d):%d @ %06d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    		D6(fprintf(debug_file, "_13b_: waiting for empty buffer (%d, %d):%d @ %07d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    		pthread_cond_wait(&state->writer_params.main_cond, &state->writer_params.writer_mutex);
    		pthread_cond_wait(&state->writer_params.main_cond, &state->writer_params.writer_mutex);
    	}
    	}
    	pthread_mutex_unlock(&state->writer_params.writer_mutex);
    	pthread_mutex_unlock(&state->writer_params.writer_mutex);
		D6(fprintf(debug_file, "_13c_: got empty buffer         (%d, %d):%d @ %06d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	D6(fprintf(debug_file, "_13c_: got empty buffer         (%d, %d):%d @ %07d\n", state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, state->writer_params.writev_run, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	align_frame(state);
    	align_frame(state);
    	// proceed if last frame was recorded without errors
    	// proceed if last frame was recorded without errors
		D6(fprintf(debug_file, "_13d_:frame aligned @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
    	D6(fprintf(debug_file, "_13d_:frame aligned @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
    	pthread_mutex_lock(&state->writer_params.writer_mutex);
    	pthread_mutex_lock(&state->writer_params.writer_mutex);
    	if (state->writer_params.last_ret_val == 0) {
    	if (state->writer_params.last_ret_val == 0) {
    		state->writer_params.chunk_page_prep = (state->writer_params.chunk_page_prep + 1) % (2 * FILE_CHUNKS_PAGES);
    		state->writer_params.chunk_page_prep = (state->writer_params.chunk_page_prep + 1) % (2 * FILE_CHUNKS_PAGES);
    		//			state->writer_params.data_ready = true;
    		//			state->writer_params.data_ready = true;
    		pthread_cond_signal(&state->writer_params.writer_cond);
    		pthread_cond_signal(&state->writer_params.writer_cond);
			D6(fprintf(debug_file, "_13e_: chunk_page_prep = %d (%d), signal writer_cond @ %06d\n",state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, get_fpga_usec(state->fd_fparmsall[0], 0)));
    		D6(fprintf(debug_file, "_13e_: chunk_page_prep = %d (%d), signal writer_cond @ %07d\n",state->writer_params.chunk_page_prep, state->writer_params.chunk_page_write, get_fpga_usec(state->fd_fparmsall[0], 0)));
    	}
    	}
    	pthread_mutex_unlock(&state->writer_params.writer_mutex);
    	pthread_mutex_unlock(&state->writer_params.writer_mutex);
    	if (state->writer_params.last_ret_val != 0) {
    	if (state->writer_params.last_ret_val != 0) {
@@ -358,7 +358,7 @@ int camogm_frame_jpeg(camogm_state *state)
    	curr_time = time(NULL);
    	curr_time = time(NULL);
    	if (difftime(curr_time, state->writer_params.stat_update) > STAT_UPDATE_PERIOD) {
    	if (difftime(curr_time, state->writer_params.stat_update) > STAT_UPDATE_PERIOD) {
    		save_state_file(state);
    		save_state_file(state);
			D6(fprintf(debug_file, "_13f_: saved state file @ %06d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
    		D6(fprintf(debug_file, "_13f_: saved state file @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
    	}
    	}
    }
    }


@@ -426,6 +426,7 @@ int camogm_end_jpeg(camogm_state *state) // TODO: Resolve multippage !
void *jpeg_writer(void *thread_args)
void *jpeg_writer(void *thread_args)
{
{
	int dbg_us1, dbg_us2, dbg_us; // save usec for difference
	int dbg_us1, dbg_us2, dbg_us; // save usec for difference
	long dbg_pos;
	int reset_rem;
	int reset_rem;
	int chunk_index, i0, i1;
	int chunk_index, i0, i1;
	ssize_t iovlen, l, ll, l0, l1, blocks_write, wpage;
	ssize_t iovlen, l, ll, l0, l1, blocks_write, wpage;
@@ -441,7 +442,7 @@ void *jpeg_writer(void *thread_args)
	// lock, will only allow main thread while a) waiting for write buffer, and b) waiting for writev
	// lock, will only allow main thread while a) waiting for write buffer, and b) waiting for writev
////	pthread_mutex_lock(&params->writer_mutex);
////	pthread_mutex_lock(&params->writer_mutex);
	params->state = STATE_RUNNING;
	params->state = STATE_RUNNING;
	D6(fprintf(debug_file, "_w000_:  Before jpeg_writer loop @ %06d\n", get_fpga_usec(state->fd_fparmsall[0], 0))); // before the debug file is set !
	D6(fprintf(debug_file, "_w000_:  Before jpeg_writer loop @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0))); // before the debug file is set !
	while (process) {
	while (process) {
		/*
		/*
		while (!params->data_ready && !params->exit_thread) {
		while (!params->data_ready && !params->exit_thread) {
@@ -449,7 +450,7 @@ void *jpeg_writer(void *thread_args)
		} // get rid of params->data_ready
		} // get rid of params->data_ready
		*/
		*/
		pthread_mutex_lock(&params->writer_mutex);  // first time before the debug file is set !
		pthread_mutex_lock(&params->writer_mutex);  // first time before the debug file is set !
		D6(fprintf(debug_file, "_w00_: (%d, %d) @ %06d\n", params->chunk_page_prep, params->chunk_page_write, get_fpga_usec(state->fd_fparmsall[0], 0)));
		D6(fprintf(debug_file, "_w00_: (%d, %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write, get_fpga_usec(state->fd_fparmsall[0], 0)));
		while ((params->chunk_page_prep == params->chunk_page_write) && !params->exit_thread) {
		while ((params->chunk_page_prep == params->chunk_page_write) && !params->exit_thread) {
			pthread_cond_wait(&params->writer_cond, &params->writer_mutex);
			pthread_cond_wait(&params->writer_cond, &params->writer_mutex);
		}
		}
@@ -459,10 +460,10 @@ void *jpeg_writer(void *thread_args)
		}
		}
		has_data_to_write = params->chunk_page_prep != params->chunk_page_write;
		has_data_to_write = params->chunk_page_prep != params->chunk_page_write;
		pthread_mutex_unlock(&params->writer_mutex);
		pthread_mutex_unlock(&params->writer_mutex);
		D6(fprintf(debug_file, "_w00.5_: (%d, %d) @ %06d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
		D6(fprintf(debug_file, "_w00.5_: (%d, %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
//		if (params->data_ready) {
//		if (params->data_ready) {
		if (has_data_to_write) {
		if (has_data_to_write) {
			D6(fprintf(debug_file, "_w01_: got write data (%d > %d) @ %06d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "_w01_: got write data (%d > %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
			/* dummy read cycle from (approximately) the beginning of previous frame;
			/* dummy read cycle from (approximately) the beginning of previous frame;
			 * this is a debug feature used to find disk errors */
			 * this is a debug feature used to find disk errors */
			/*//temporary disable for simplicity 05/21/2023
			/*//temporary disable for simplicity 05/21/2023
@@ -495,15 +496,19 @@ void *jpeg_writer(void *thread_args)
				blocks_write = l / PHY_BLOCK_SIZE;
				blocks_write = l / PHY_BLOCK_SIZE;
				if (state->writer_params.lba_current + blocks_write <= state->writer_params.lba_end) { // almost always - single write
				if (state->writer_params.lba_current + blocks_write <= state->writer_params.lba_end) { // almost always - single write
					state->writer_params.lba_current += blocks_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(fprintf(debug_file, "_w02_: starting writev @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
//					D3(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0); dbg_pos = lseek(state->writer_params.blockdev_fd, 0, SEEK_CUR));
					D3(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0));
					D3(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0));
                                        D6(fprintf(debug_file, "_w02_: starting writev @ %06d\n",dbg_us1));
					D6(dbg_pos = lseek(state->writer_params.blockdev_fd, 0, SEEK_CUR));
					D6(fprintf(debug_file, "_w02_: starting writev@ %07d\n", dbg_us1));
					state->writer_params.writev_run = true;
					state->writer_params.writev_run = true;
					pthread_cond_signal(&params->main_cond);
					pthread_cond_signal(&params->main_cond);
					iovlen = writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], chunk_index);
					iovlen = writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], chunk_index);
					state->writer_params.writev_run = false;
					state->writer_params.writev_run = false;
//                                      D6(fprintf(debug_file, "_w03_: finished writev @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
					//                                      D6(fprintf(debug_file, "_w03_: finished writev @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
                                        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);
					D3(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished writev, pos%%block = %ld, pos= %ld  @ %07d (+ %07d, +%07d)\n",dbg_pos % PHY_BLOCK_SIZE, dbg_pos,dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D3(syslog (LOG_INFO, "_w03_: finished writev, pos= %ld  @ %07d (+ %07d, +%07d)", dbg_pos, dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D3(dbg_us2=dbg_us);
					if (iovlen < l) {
					if (iovlen < l) {
						D0(fprintf(debug_file, "writev error: %s (returned %i, expected %i)\n", strerror(errno), 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;
						state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR;
@@ -549,7 +554,7 @@ void *jpeg_writer(void *thread_args)
							state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR;
							state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR;
							reset_rem = 1;
							reset_rem = 1;
						} else {
						} else {
							// do not update statistic after the first writed, do it after the second
							// do not update statistic after the first writev(), do it after the second
							D6(fprintf(debug_file, "(1 of 2) Current position in block device: %lld\n", lseek64(state->writer_params.blockdev_fd, 0, SEEK_CUR)));
							D6(fprintf(debug_file, "(1 of 2) Current position in block device: %lld\n", lseek64(state->writer_params.blockdev_fd, 0, SEEK_CUR)));
							// update split chunk to use its second part, shift chunks
							// update split chunk to use its second part, shift chunks
							if (l1 > 0) { // length to be written after rollover
							if (l1 > 0) { // length to be written after rollover
@@ -582,7 +587,7 @@ void *jpeg_writer(void *thread_args)
						}
						}
					}
					}
				}
				}
				D6(fprintf(debug_file, "_w04: wrote data @ %06d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "_w04: wrote data @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "_w05_: Block device positions: start = %llu, current = %llu, end = %llu\n",
				D6(fprintf(debug_file, "_w05_: Block device positions: start = %llu, current = %llu, end = %llu\n",
						state->writer_params.lba_start, state->writer_params.lba_current, state->writer_params.lba_end));
						state->writer_params.lba_start, state->writer_params.lba_current, state->writer_params.lba_end));
			} else {
			} else {
@@ -600,9 +605,9 @@ void *jpeg_writer(void *thread_args)
//			params->data_ready = false;
//			params->data_ready = false;
			if (params->chunk_page_prep == params->chunk_page_write) {
			if (params->chunk_page_prep == params->chunk_page_write) {
				pthread_cond_signal(&params->main_cond); // **********  Do not signal if can write more !
				pthread_cond_signal(&params->main_cond); // **********  Do not signal if can write more !
				D6(fprintf(debug_file, "_w06_: wrote data (%d , %d), buffer empty, signal main thread @ %06d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "_w06_: wrote data (%d , %d), buffer empty, signal main thread @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
			} else {
			} else {
				D6(fprintf(debug_file, "_w06a_: wrote data (%d , %d), has more to write, do not signal! @ %06d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "_w06a_: wrote data (%d , %d), has more to write, do not signal! @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));


			}
			}
			pthread_mutex_unlock(&params->writer_mutex); // do not release untill waiting for writev() or waiting for data to write
			pthread_mutex_unlock(&params->writer_mutex); // do not release untill waiting for writev() or waiting for data to write
Loading