Commit 5459227b authored by Andrey Filippov's avatar Andrey Filippov
Browse files

trying to record tiff files

parent cd9c687b
Loading
Loading
Loading
Loading
+48 −21
Original line number Diff line number Diff line
@@ -29,9 +29,9 @@
#include <getopt.h>
#include <ctype.h>
#include <elphel/ahci_cmd.h>

#ifdef USE_POLL
   #include <poll.h>

#endif
#include "camogm_ogm.h"
#include "camogm_jpeg.h"
#include "camogm_mov.h"
@@ -169,6 +169,9 @@ void clean_up(camogm_state *state);
static void camogm_err_stat(const camogm_state *state, int port, FILE *f, bool xml);
static void camogm_set_dummy_read(camogm_state *state, int d);

static void dbg_show_packetchunks(camogm_state *state);


void put_uint16(void *buf, u_int16_t val)
{
	unsigned char  *tmp;
@@ -651,6 +654,7 @@ int sendImageFrame(camogm_state *state)
			state->packetchunks[state->chunk_index++].chunk = state->ed[port];       // Tiff Header

		} else { // JPEG/JP4
			D3(fprintf(debug_file, "_8b_"));
			state->packetchunks[state->chunk_index  ].bytes = 2;
			state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port];
			state->packetchunks[state->chunk_index  ].bytes = state->exifSize[port];
@@ -685,8 +689,14 @@ int sendImageFrame(camogm_state *state)
	}
	D3(fprintf(debug_file, "\tcirbuf_rp = 0x%x\t", state->cirbuf_rp[port]));
	D3(fprintf(debug_file, "_12_"));
	if (state->this_frame_params[port].color != COLORMODE_RAW) { // Tiff
		state->packetchunks[state->chunk_index  ].bytes = 2;
		state->packetchunks[state->chunk_index++].chunk = (unsigned char*)trailer;
	}

	dbg_show_packetchunks(state);



	switch (state->format) {
	case CAMOGM_FORMAT_NONE: rslt = 0; break;
@@ -731,6 +741,16 @@ int sendImageFrame(camogm_state *state)
	return 0;
}

static void dbg_show_packetchunks(camogm_state *state)
{
	int i;
	for (i = 0; i < FILE_CHUNKS_NUM; i++) {
		D4(fprintf(debug_file, "packetchunk[%d]: ptr = %p, size = %d\n", i, state->packetchunks[i].chunk, state->packetchunks[i].bytes));
	}
}



/**
 * @brief Stop current recording. If recording was not started, this function has no effect. This function
 * calls @e camogm_end_* for the current file format.
@@ -1319,7 +1339,11 @@ char * getLineFromPipe(FILE* npipe)
	if (!nlp) { //no complete string, try to read more
		// 2019/01/16: this change is related to switching to poll()
		//fl = fread(&cmdbuf[cmdbufp], 1, sizeof(cmdbuf) - cmdbufp - 1, npipe);
#ifdef USE_POLL
		fl = read(npipe, &cmdbuf[cmdbufp], sizeof(cmdbuf) - cmdbufp - 1);
#else
		fl = fread(&cmdbuf[cmdbufp], 1, sizeof(cmdbuf) - cmdbufp - 1, npipe);
#endif
		cmdbuf[cmdbufp + fl] = 0;
// is there any complete string in a buffer after reading?
		nlp = strpbrk(&cmdbuf[cmdbufp], ";\n"); // there were no new lines before cmdbufp
@@ -1567,9 +1591,9 @@ int listener_loop(camogm_state *state)
	int process = 1;
	int curr_port = 0;
	const char *pipe_name = state->pipe_name;

#ifdef USE_POLL
	struct pollfd pfd;

#endif
	// create a named pipe
	// always delete the pipe if it existed, start a fresh one
	f_ok = access(pipe_name, F_OK);
@@ -1589,17 +1613,7 @@ int listener_loop(camogm_state *state)
		}
	}

	/* old */
	/*
	// now open the pipe - will block until something will be written (or just open for writing,
	// reads themselves will not block)
	if (!((cmd_file = fopen(pipe_name, "r")))) {
		D0(fprintf(debug_file, "Can not open command file %s\n", pipe_name));
		clean_up(state);
		return -5;
	}
	*/

#ifdef USE_POLL
	/* new: 2019/01/16 */

	// Adding poll() because supposedly read calls (read, fread)
@@ -1618,7 +1632,16 @@ int listener_loop(camogm_state *state)
	// ready to read
	pfd.events = POLLIN;
	pfd.fd     = cmd_file;

	/* old */
#else
	// now open the pipe - will block until something will be written (or just open for writing,
	// reads themselves will not block)
	if (!((cmd_file = fopen(pipe_name, "r")))) {
		D0(fprintf(debug_file, "Can not open command file %s\n", pipe_name));
		clean_up(state);
		return -5;
	}
#endif
	D0(fprintf(debug_file, "Pipe %s open for reading\n", pipe_name)); // to make sure something is sent out

	// enter main processing loop
@@ -1627,17 +1650,19 @@ int listener_loop(camogm_state *state)
		state->port_num = curr_port;
		// look at command queue first

#ifdef USE_POLL
		ret = poll(&pfd,1,DEFAULT_POLL_TIMEOUT);

		if (ret==0){
			D6(fprintf(debug_file, "Waiting for commands..., state->prog_state = %d, pfd.revents=%d\n",state->prog_state, (int) pfd.revents));
		}

		if (pfd.revents & POLLIN){
#endif
			cmd = parse_cmd(state, cmd_file);
			if (cmd) {
				if (cmd < 0) D0(fprintf(debug_file, "Unrecognized command\n"));
#ifdef USE_POLL
			}
#endif
		} else if (state->prog_state == STATE_RUNNING) { // no commands in queue, started

			D6(fprintf(debug_file, "state->prog_state == STATE_RUNNING "));
@@ -1731,7 +1756,9 @@ int listener_loop(camogm_state *state)
			state->rawdev.thread_state = STATE_RUNNING;
			usleep(COMMAND_LOOP_DELAY);     // make it longer but interruptible by signals?
		}
#ifdef USE_POLL
//		} // if pfd.revents & POLLIN
#endif
	} // while (process)

	// normally, we should not be here
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@

#ifndef _CAMOGM_H
#define _CAMOGM_H

//#define  USE_POLL
#include <pthread.h>
#include <stdbool.h>
#include <ogg/ogg.h>
+98 −42
Original line number Diff line number Diff line
@@ -32,12 +32,15 @@ static inline size_t get_size_from(const struct iovec *vects, int index, size_t
static inline size_t align_bytes_num(size_t data_len, size_t align_len);
static inline void vectcpy(struct iovec *dest, void *src, size_t len);
static inline void vectshrink(struct iovec *vec, size_t len);
static inline void vectshrinkhead(struct iovec *vec, size_t len);
static inline unsigned char *vectrpos(struct iovec *vec, size_t offset);
static void dev_dbg(const char *prefix, const char *format, ...);
//static void dev_dbg(const char *prefix, const char *format, ...);
static void remap_vectors(camogm_state *state, struct iovec *chunks);
static size_t get_blocks_num(struct iovec *sgl, size_t n_elem);
/* debug functions */
static int check_chunks(struct iovec *vects);
static void dev_dbg(const char *prefix, const char *format, ...);


/** Replace debug function with the same name from driver code with debug macro to reduce changes */
static void dev_dbg(const char *prefix, const char *format, ...)
@@ -66,6 +69,17 @@ static inline void vectshrink(struct iovec *vec, size_t len)
	}
}

/** Shrink vector length by @len bytes from the head */
static inline void vectshrinkhead(struct iovec *vec, size_t len)
{
	if (vec->iov_len >= len) {
		vec->iov_len -= len;
		unsigned char * p = (unsigned char * ) vec->iov_base; // += len;
		vec->iov_base = p + len;
	}
}


/** This helper function is used to position a pointer @e offset bytes from the end
 * of a buffer. */
static inline unsigned char *vectrpos(struct iovec *vec, size_t offset)
@@ -110,28 +124,49 @@ static inline size_t align_bytes_num(size_t data_len, size_t align_len)
static void remap_vectors(camogm_state *state, struct iovec *chunks)
{
	int chunk_index = 1;

    int is_tiff = state->this_frame_params[state->port_num].color == COLORMODE_RAW;
	if (state->exif > 0) {
		if (is_tiff) { // Tiff
			chunks[CHUNK_EXIF].iov_base =   (void *)state->packetchunks[chunk_index].chunk;
			chunks[CHUNK_EXIF].iov_len =            state->packetchunks[chunk_index++].bytes;
			// set length of unused chunks to zero, and pointer to any valid pointer
			chunks[CHUNK_LEADER].iov_base = chunks[CHUNK_EXIF].iov_base;
			chunks[CHUNK_LEADER].iov_len = 0;
			chunks[CHUNK_HEADER].iov_base = chunks[CHUNK_EXIF].iov_base;
			chunks[CHUNK_HEADER].iov_len = 0;
		} else { // JPEG/JP4
			chunks[CHUNK_LEADER].iov_base = (void *)state->packetchunks[chunk_index].chunk;
			chunks[CHUNK_LEADER].iov_len =          state->packetchunks[chunk_index++].bytes;
			chunks[CHUNK_EXIF].iov_base =   (void *)state->packetchunks[chunk_index].chunk;
			chunks[CHUNK_EXIF].iov_len =            state->packetchunks[chunk_index++].bytes;
			chunks[CHUNK_HEADER].iov_base = (void *)state->packetchunks[chunk_index].chunk;
			chunks[CHUNK_HEADER].iov_len =          state->packetchunks[chunk_index++].bytes;
		}
	} else {
		chunks[CHUNK_LEADER].iov_base = (void *)state->packetchunks[chunk_index].chunk;
		chunks[CHUNK_LEADER].iov_len  =          JPEG_MARKER_LEN;
		chunks[CHUNK_HEADER].iov_base = (void *)(state->packetchunks[chunk_index].chunk + JPEG_MARKER_LEN);
		chunks[CHUNK_HEADER].iov_len  =          state->packetchunks[chunk_index++].bytes - JPEG_MARKER_LEN;
		// set to zero length and valid pointer
		chunks[CHUNK_EXIF].iov_base   = chunks[CHUNK_HEADER].iov_base;
		chunks[CHUNK_EXIF].iov_len    = 0;
	}
	chunks[CHUNK_DATA_0].iov_base = (void *)state->packetchunks[chunk_index].chunk;
	chunks[CHUNK_DATA_0].iov_len = state->packetchunks[chunk_index++].bytes;
	if (state->writer_params.segments == 2) {
		chunks[CHUNK_DATA_1].iov_base = (void *)state->packetchunks[chunk_index].chunk;
		chunks[CHUNK_DATA_1].iov_len = state->packetchunks[chunk_index++].bytes;
	} else{
		chunks[CHUNK_DATA_1].iov_base = chunks[CHUNK_DATA_0].iov_base;
		chunks[CHUNK_DATA_1].iov_len =  0;
	}
	chunks[CHUNK_TRAILER].iov_base = (void *)state->packetchunks[chunk_index].chunk;
	if (is_tiff) { // Tiff
		chunks[CHUNK_TRAILER].iov_len = 0;
	} else {
		chunks[CHUNK_TRAILER].iov_len = state->packetchunks[chunk_index].bytes;
	}


	/* some data may be left from previous frame, copy it to special buffer */
	if (chunks[CHUNK_REM].iov_len != 0) {
@@ -165,6 +200,10 @@ static int check_chunks(struct iovec *vects)
	return ret;
}





/** Calculate the number of blocks this frame will occupy. The frame must be aligned to block size */
static size_t get_blocks_num(struct iovec *sgl, size_t n_elem)
{
@@ -249,12 +288,14 @@ void align_frame(camogm_state *state)
	remap_vectors(state, chunks);

	total_sz = get_size_from(chunks, 0, 0, INCLUDE_REM) + rbuff->iov_len;
	D4(fprintf(debug_file, "total_sz = %d\n", total_sz));
	if (total_sz < PHY_BLOCK_SIZE) {
		/* the frame length is less than sector size, delay this frame */
		if (rbuff->iov_len != 0) {
			/* some data may be left from previous frame */
			vectcpy(&chunks[CHUNK_REM], rbuff->iov_base, rbuff->iov_len);
			vectshrink(rbuff, rbuff->iov_len);
			D4(fprintf(debug_file, "copied rbuff->iov_len = %d\n", rbuff->iov_len));
		}
		dev_dbg(dev, "frame size is less than sector size: %u bytes; delay recording\n", total_sz);
		vectcpy    (&chunks[CHUNK_REM],     chunks[CHUNK_LEADER].iov_base,  chunks[CHUNK_LEADER].iov_len);
@@ -280,11 +321,13 @@ void align_frame(camogm_state *state)
		vectshrink(rbuff, rbuff->iov_len);
	}

	/* copy JPEG marker */
	/* copy JPEG marker if present */
	if (chunks[CHUNK_LEADER].iov_len != 0) {
		len = chunks[CHUNK_LEADER].iov_len;
		dev_dbg(dev, "copy %u bytes from LEADER to common buffer\n", len);
		vectcpy(cbuff, chunks[CHUNK_LEADER].iov_base, len);
		vectshrink(&chunks[CHUNK_LEADER], chunks[CHUNK_LEADER].iov_len);

	}
	/* copy Exif if present */
	if (chunks[CHUNK_EXIF].iov_len != 0) {
		len = chunks[CHUNK_EXIF].iov_len;
@@ -293,8 +336,11 @@ void align_frame(camogm_state *state)
		vectshrink(&chunks[CHUNK_EXIF], chunks[CHUNK_EXIF].iov_len);
	}


	if (chunks[CHUNK_LEADER].iov_len != 0){ // only if it is not TIFF
		/* align common buffer to ALIGNMENT boundary, APP15 marker should be placed before header data */
		data_len = cbuff->iov_len + chunks[CHUNK_HEADER].iov_len;

		len = align_bytes_num(data_len, ALIGNMENT_SIZE);
		if (len < (JPEG_MARKER_LEN + JPEG_SIZE_LEN) && len != 0) {
			/* the number of bytes needed for alignment is less than the length of the marker itself, increase the number of stuffing bytes */
@@ -303,12 +349,21 @@ void align_frame(camogm_state *state)
		dev_dbg(dev, "total number of stuffing bytes in APP15 marker: %u\n", len);
		app15[3] = len - JPEG_MARKER_LEN;
		vectcpy(cbuff, app15, len);

		/* copy JPEG header */
		len = chunks[CHUNK_HEADER].iov_len;
		dev_dbg(dev, "copy %u bytes from HEADER to common buffer\n", len);
		vectcpy(cbuff, chunks[CHUNK_HEADER].iov_base, len);
		vectshrink(&chunks[CHUNK_HEADER], chunks[CHUNK_HEADER].iov_len);
	} else { // for Tiff (may be the same for Jpeg too - borrow data from the image data, copy up to 31 bytes to the end of the common buffer,
		// move start of the data_0 accordingly
		data_len = cbuff->iov_len;
		len = align_bytes_num(data_len, ALIGNMENT_SIZE);
		if (len){ // assuming image data > 32 bits
			vectcpy(cbuff, chunks[CHUNK_DATA_0].iov_base, len);
			vectshrinkhead(&chunks[CHUNK_DATA_0],len);
		}
	}


	/* check if there is enough data to continue - JPEG data length can be too short */
	len = get_size_from(chunks, CHUNK_DATA_0, 0, EXCLUDE_REM);
@@ -514,6 +569,7 @@ int prep_last_block(camogm_state *state)

/** Convert LBA to byte offset used for lseek */
off64_t lba_to_offset(uint64_t lba)
//uint64_t lba_to_offset(uint64_t lba)
{
	return lba * PHY_BLOCK_SIZE;
}
+3 −0
Original line number Diff line number Diff line
@@ -79,4 +79,7 @@ int get_data_buffers(camogm_state *state, struct iovec *mapped, size_t all_sz);
int prep_last_block(camogm_state *state);
off64_t lba_to_offset(uint64_t lba);


//uint64_t lba_to_offset(uint64_t lba);

#endif /* _CAMOGM_ALIGN_H */