Loading src/camogm.c +48 −21 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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; Loading Loading @@ -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]; Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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) Loading @@ -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 Loading @@ -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 ")); Loading Loading @@ -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 Loading src/camogm.h +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ #ifndef _CAMOGM_H #define _CAMOGM_H //#define USE_POLL #include <pthread.h> #include <stdbool.h> #include <ogg/ogg.h> Loading src/camogm_align.c +98 −42 Original line number Diff line number Diff line Loading @@ -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, ...) Loading Loading @@ -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) Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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); Loading @@ -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; Loading @@ -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 */ Loading @@ -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); Loading Loading @@ -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; } src/camogm_align.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
src/camogm.c +48 −21 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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; Loading Loading @@ -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]; Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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) Loading @@ -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 Loading @@ -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 ")); Loading Loading @@ -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 Loading
src/camogm.h +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ #ifndef _CAMOGM_H #define _CAMOGM_H //#define USE_POLL #include <pthread.h> #include <stdbool.h> #include <ogg/ogg.h> Loading
src/camogm_align.c +98 −42 Original line number Diff line number Diff line Loading @@ -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, ...) Loading Loading @@ -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) Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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); Loading @@ -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; Loading @@ -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 */ Loading @@ -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); Loading Loading @@ -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; }
src/camogm_align.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 */