Commit 01b565e2 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

edited for EO, restored write camogm.disk to /dev/sda1

parent a7ffbc6d
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -618,27 +618,27 @@ int sendImageFrame(camogm_state *state)
	//   D3(fprintf (debug_file,"sendImageFrame: format=%d, set_format=%d\n", state->format, state->set_format));

	if (state->format != state->set_format) {
		D2(fprintf(debug_file, "sendImageFrame:2: state->format(0x%x) != state->set_format(0x%x)\n", state->format, state->set_format));
		D1(fprintf(debug_file, "sendImageFrame:2: state->format(0x%x) != state->set_format(0x%x)\n", state->format, state->set_format));
		return -CAMOGM_FRAME_CHANGED;
	}
	//   check if file size is exceeded (assuming fopen),-CAMOGM_FRAME_CHANGED will trigger a new segment
	if (!state->rawdev_op && (state->vf) && (state->segment_length >= 0) && (ftell(state->vf) > state->segment_length)) {
		D2(fprintf(debug_file, "sendImageFrame:3: segment length exceeded\n"));
		D1(fprintf(debug_file, "sendImageFrame:3: segment length exceeded\n"));
		return -CAMOGM_FRAME_NEXTFILE;
	}
	//same for open
	if (!state->rawdev_op && ((state->ivf) >= 0) && (state->segment_length >= 0) && (lseek(state->ivf, 0, SEEK_CUR) > state->segment_length)) {
		D3(fprintf(debug_file, "sendImageFrame:4: segment length exceeded\n"));
		D1(fprintf(debug_file, "sendImageFrame:4: segment length exceeded\n"));
		return -CAMOGM_FRAME_NEXTFILE;
	}
	// check the frame pointer is valid
	if ((fp = lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET)) < 0) {
		D2(fprintf(debug_file, "sendImageFrame:5: invalid frame\n"));
		D1(fprintf(debug_file, "sendImageFrame:5: invalid frame\n"));
		return -CAMOGM_FRAME_INVALID; //it will probably be that allready
	}
	// is the frame ready?
	if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) {
		D3(fprintf(debug_file, "?6")) ;     //frame not ready, frame pointer seems valid, but not ready
		D1(fprintf(debug_file, "?6")) ;     //frame not ready, frame pointer seems valid, but not ready
		D6(fprintf(debug_file, ",FRAME NOT READY 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
	}
@@ -658,7 +658,7 @@ int sendImageFrame(camogm_state *state)
		//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);
		state->frames_skip_left[port]--;
		D2(fprintf(debug_file, "?7\n")); //frame not ready
		D1(fprintf(debug_file, "?7\n")); //frame not ready
		return -CAMOGM_FRAME_NOT_READY; // the required frame is not ready
	}

@@ -689,6 +689,8 @@ int sendImageFrame(camogm_state *state)
	if (timestamp_start >= state->circ_buff_size[port]) timestamp_start -= state->circ_buff_size[port];
	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);
	D1(fprintf(debug_file, "%ld.%06ld ",state->this_frame_params[port].timestamp_sec,state->this_frame_params[port].timestamp_usec); \
	if (debug_level < 2) fprintf(debug_file,"\n"););
	// 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) ||
			(state->frame_params[port].height != state->this_frame_params[port].height))) {
@@ -2216,8 +2218,10 @@ unsigned int select_port(camogm_state *state)
						state->writer_params.circbuf_many, get_num_empty(&state->writer_params), get_num_busy(&state->writer_params), \
						params->chunk_page_state[0],params->chunk_page_state[1],params->chunk_page_state[2],params->chunk_page_state[3], \
						params->chunk_page_state[4],params->chunk_page_state[5],params->chunk_page_state[6],params->chunk_page_state[7], \
						get_fpga_usec(state->fd_fparmsall[0], 0)); if (debug_level < 2) fprintf(debug_file,"\n");}\
						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)));

		//if (debug_level < 2) fprintf(debug_file,"\n");}
#else

		D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0)) {\
+46 −18
Original line number Diff line number Diff line
@@ -679,7 +679,8 @@ void *jpeg_writer(void *thread_args)
{
	int dbg_start_wait = 0, dbg_wait, dbg_time;
	char * dbg_pref;
	struct iovec write_segments[SEGMENTS_NUMBER];// 3
#define MAX_SEGM_NUMBER 16 // temporary, debugging
	struct iovec write_segments[MAX_SEGM_NUMBER]; // SEGMENTS_NUMBER];// 3
	int num_write_segments, seg_len;
	int dbg_us1=0, dbg_us2=0, dbg_us; // save usec for difference
	pthread_t this_thread = pthread_self();
@@ -688,10 +689,12 @@ void *jpeg_writer(void *thread_args)
	int reset_rem;
	long long dbg_pos64;
	int i, i0, i1, wpage;
	char * bufp;

//	int32_t res32;
//	int64_t res64;
//	int errno32, errno64;
	ssize_t iovlen, l, ll, l0, l1, blocks_write; // , wpage;
	ssize_t iovlen, image_len_padded, ll, l0, l1, blocks_write; // , wpage;
	ssize_t writev_wlen;
	struct iovec split_chunk;
	int blockdev_fd;   ///< file descriptor for open block device where frame will be recorded, local for the thread
@@ -808,26 +811,45 @@ void *jpeg_writer(void *thread_args)
		if (wpage >= 0) {
			D6(fprintf(debug_file, "%s_w01_: got write segment page %d (preparing %d) @ %07d\n", dbg_pref,\
					wpage, params->chunk_page_prep, get_fpga_usec(state->fd_fparmsall[0], 0)));
			l = 0;
			image_len_padded = 0;
			reset_rem = 0;
			params->last_ret_val = 0;
			// inputs from params->data_chunks, returns number of result chunks
#define MAX_SEGM_PAGES  0xa0
#define MAX_SEGM_LENGTH	(MAX_SEGM_PAGES * PAGE_PHYS) // 0xa0000 // multiple of
			// Seems that I introduced a bug into kernel - it can not handle too longsegments

			num_write_segments = 0;
			for (i = 0; i < SEGMENTS_NUMBER; i++){
				seg_len = params->data_segments[wpage][i].iov_len;
				image_len_padded+=seg_len;
				if (seg_len > 0){
					if (seg_len <= MAX_SEGM_LENGTH) {
						write_segments[num_write_segments++] = params->data_segments[wpage][i];
					l+=seg_len;
					} else {
						bufp = (char *) params->data_segments[wpage][i].iov_base;
						while (seg_len >= MAX_SEGM_LENGTH){
							write_segments[num_write_segments  ].iov_base = bufp;
							write_segments[num_write_segments++].iov_len = MAX_SEGM_LENGTH;
							bufp += MAX_SEGM_LENGTH;
							seg_len -= MAX_SEGM_LENGTH;
						}
						if (seg_len > 0){
							write_segments[num_write_segments  ].iov_base = bufp;
							write_segments[num_write_segments++].iov_len =  seg_len;
						}
					}
				}
			}
			// l is correct here
			// chunk_index = get_data_buffers(state, chunks_iovec[wpage], FILE_CHUNKS_NUM, wpage);
			// assuming write is block-aligned
			if (num_write_segments > 0) {
				// Moved rollover here
				blocks_write = l / PHY_BLOCK_SIZE; // here LBA, 512
				blocks_write = image_len_padded / PHY_BLOCK_SIZE; // here LBA, 512
				if (get_lba_next(params) + blocks_write <= params->lba_end) { // almost always - single write
					D2(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0));
					D2(dbg_pos = lseek64(blockdev_fd, 0, SEEK_CUR);  if (dbg_pos < 0) fprintf( \
					D3(dbg_pos = lseek64(blockdev_fd, 0, SEEK_CUR);  if (dbg_pos < 0) fprintf( \
							debug_file,"%slseek64()->-1, errno=%d(%s)",  dbg_pref,errno, strerror(errno)));

					D6(fprintf(debug_file, "%s_w02_: starting emul_writev@ %07d\n",  dbg_pref, dbg_us1));
@@ -882,7 +904,7 @@ void *jpeg_writer(void *thread_args)

							writev_wlen = write (blockdev_fd, write_segments[i].iov_base, write_segments[i].iov_len);
//							if (i == 1) { // only for segment 1, if other write thread also is writing second (large) segment
								D2(fprintf(debug_file, \
								D3(fprintf(debug_file, \
										"%s_w02x_: i=%d start =0x%08x, len=0x%08x\n", dbg_pref, i, (int)write_segments[i].iov_base, (int)write_segments[i].iov_len));
//							}
							if (writev_wlen < 0) {
@@ -906,19 +928,19 @@ void *jpeg_writer(void *thread_args)
					D4(syslog (LOG_INFO, "%s_w03_: finished emul_writev, pos= %lld, len = %d(0x%x) thread ID = %ld @ %07d (+ %07d, +%07d)", dbg_pref,\
							dbg_pos, iovlen, iovlen, pthread_self(),  dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D2(dbg_us2=dbg_us);
					if (iovlen < l) {
						D0(fprintf(debug_file, "%semul_writev error: %s (returned %i, expected %i)\n", dbg_pref, strerror(errno), iovlen, l));
					if (iovlen < image_len_padded) {
						D0(fprintf(debug_file, "%semul_writev error: %s (returned %i, expected %i)\n", dbg_pref, strerror(errno), iovlen, image_len_padded));
						params->last_ret_val = -CAMOGM_FRAME_FILE_ERR;
						reset_rem = 1;
					} else {
						// update statistic
						state->rawdev.last_jpeg_size = l;
						state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
//						state->rawdev.last_jpeg_size = l;
//						state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
						D6(fprintf(debug_file, "%sCurrent position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));
					}
				} else { // Split into two writes: to the end of partition and startion from the beginning
					l0 = get_lba_next(params) * PHY_BLOCK_SIZE; // remaining to be written before rollover
					l1 = l - l0; // remaining to be written after rollover
					l1 = image_len_padded - l0; // remaining to be written after rollover
					i1 = 0; // start of the second write
					if (l0 > 0) { // should be always
						ll = 0;
@@ -975,10 +997,10 @@ void *jpeg_writer(void *thread_args)
									params->last_ret_val = -CAMOGM_FRAME_FILE_ERR;
									reset_rem = 1;
								} else {
									// update statistic (for both parts of the split write)
									state->rawdev.last_jpeg_size = l;
									state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
									D6(fprintf(debug_file, "%s(1 of 2) Current position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));
///									// update statistic (for both parts of the split write)
///									state->rawdev.last_jpeg_size = l;
///									state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
									D6(fprintf(debug_file, "%s(2 of 2) Current position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));
								}
							}
						}
@@ -1000,6 +1022,12 @@ void *jpeg_writer(void *thread_args)
			reset_segments(state, reset_rem, wpage);
			pthread_mutex_lock(&params->writer_mutex);
			params->chunk_page_state[wpage] = SEGPAGE_EMPTY;
// update statistics right here !
		    state->rawdev.last_jpeg_size = image_len_padded;
		    state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
		    D3(fprintf(debug_file, "%sl=%d, total_rec_len=%lld\n",dbg_pref, image_len_padded, state->rawdev.total_rec_len));
//		    D6(fprintf(debug_file, "%sCurrent position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));

// moved to while waiting
//			pthread_cond_signal(&params->main_cond); // signal to main thread that prepares data
			pthread_cond_broadcast(&params->writer_cond); // signal to other writer thread  waiting for this one to finish writing