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

trying to record tiff files

parent cd9c687b
......@@ -29,9 +29,9 @@
#include <getopt.h>
#include <ctype.h>
#include <elphel/ahci_cmd.h>
#include <poll.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_"));
state->packetchunks[state->chunk_index ].bytes = 2;
state->packetchunks[state->chunk_index++].chunk = (unsigned char*)trailer;
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
......
......@@ -18,7 +18,7 @@
#ifndef _CAMOGM_H
#define _CAMOGM_H
//#define USE_POLL
#include <pthread.h>
#include <stdbool.h>
#include <ogg/ogg.h>
......
......@@ -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) {
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;
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_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;
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;
chunks[CHUNK_TRAILER].iov_len = state->packetchunks[chunk_index].bytes;
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,26 +288,28 @@ 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);
vectshrink(&chunks[CHUNK_LEADER], chunks[CHUNK_LEADER].iov_len);
vectcpy(&chunks[CHUNK_REM], chunks[CHUNK_EXIF].iov_base, chunks[CHUNK_EXIF].iov_len);
vectshrink(&chunks[CHUNK_EXIF], chunks[CHUNK_EXIF].iov_len);
vectcpy(&chunks[CHUNK_REM], chunks[CHUNK_HEADER].iov_base, chunks[CHUNK_HEADER].iov_len);
vectshrink(&chunks[CHUNK_HEADER], chunks[CHUNK_HEADER].iov_len);
vectcpy(&chunks[CHUNK_REM], chunks[CHUNK_DATA_0].iov_base, chunks[CHUNK_DATA_0].iov_len);
vectshrink(&chunks[CHUNK_DATA_0], chunks[CHUNK_DATA_0].iov_len);
vectcpy(&chunks[CHUNK_REM], chunks[CHUNK_DATA_1].iov_base, chunks[CHUNK_DATA_1].iov_len);
vectshrink(&chunks[CHUNK_DATA_1], chunks[CHUNK_DATA_1].iov_len);
vectcpy(&chunks[CHUNK_REM], chunks[CHUNK_TRAILER].iov_base, chunks[CHUNK_TRAILER].iov_len);
vectshrink(&chunks[CHUNK_TRAILER], chunks[CHUNK_TRAILER].iov_len);
vectcpy (&chunks[CHUNK_REM], chunks[CHUNK_LEADER].iov_base, chunks[CHUNK_LEADER].iov_len);
vectshrink (&chunks[CHUNK_LEADER], chunks[CHUNK_LEADER].iov_len);
vectcpy (&chunks[CHUNK_REM], chunks[CHUNK_EXIF].iov_base, chunks[CHUNK_EXIF].iov_len);
vectshrink (&chunks[CHUNK_EXIF], chunks[CHUNK_EXIF].iov_len);
vectcpy (&chunks[CHUNK_REM], chunks[CHUNK_HEADER].iov_base, chunks[CHUNK_HEADER].iov_len);
vectshrink (&chunks[CHUNK_HEADER], chunks[CHUNK_HEADER].iov_len);
vectcpy (&chunks[CHUNK_REM], chunks[CHUNK_DATA_0].iov_base, chunks[CHUNK_DATA_0].iov_len);
vectshrink (&chunks[CHUNK_DATA_0], chunks[CHUNK_DATA_0].iov_len);
vectcpy (&chunks[CHUNK_REM], chunks[CHUNK_DATA_1].iov_base, chunks[CHUNK_DATA_1].iov_len);
vectshrink (&chunks[CHUNK_DATA_1], chunks[CHUNK_DATA_1].iov_len);
vectcpy (&chunks[CHUNK_REM], chunks[CHUNK_TRAILER].iov_base, chunks[CHUNK_TRAILER].iov_len);
vectshrink (&chunks[CHUNK_TRAILER], chunks[CHUNK_TRAILER].iov_len);
return;
}
......@@ -280,11 +321,13 @@ void align_frame(camogm_state *state)
vectshrink(rbuff, rbuff->iov_len);
}
/* copy JPEG marker */
len = chunks[CHUNK_LEADER].iov_len;
vectcpy(cbuff, chunks[CHUNK_LEADER].iov_base, len);
vectshrink(&chunks[CHUNK_LEADER], chunks[CHUNK_LEADER].iov_len);
/* 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,22 +336,34 @@ void align_frame(camogm_state *state)
vectshrink(&chunks[CHUNK_EXIF], chunks[CHUNK_EXIF].iov_len);
}
/* 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 */
len += ALIGNMENT_SIZE;
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 */
len += ALIGNMENT_SIZE;
}
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);
}
}
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);
/* 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;
}
......@@ -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 */
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