Commit dcb01432 authored by Mikhail Karpenko's avatar Mikhail Karpenko

Add JPEG header stuffing and time measurement

The JPEG header is stuffed with APP15 markers up to nearest 32 byte long
value.
parent c64a4de9
......@@ -479,6 +479,9 @@ int sendImageFrame(camogm_state *state)
int * ifp_this = (int*)&(state->this_frame_params[state->port_num]);
int fp;
int port = state->port_num;
unsigned char app15[64] = {0xff, 0xef};
int app15_pos = 0;
int stuffing;
// This is probably needed only for Quicktime (not to exceed already allocated frame index)
if (state->frameno >= (state->max_frames)) {
......@@ -571,7 +574,7 @@ int sendImageFrame(camogm_state *state)
D3(fprintf(debug_file, "_5_"));
// update the Exif header with the current frame metadata
state->exifSize[port] = lseek(state->fd_exif[port], 1, SEEK_END); // at the beginning of page 1 - position == page length
if (state->exifSize > 0) {
if (state->exifSize[port] > 0) {
//state->this_frame_params.meta_index
lseek(state->fd_exif[port], state->this_frame_params[port].meta_index, SEEK_END); // select meta page to use (matching frame)
rslt = read(state->fd_exif[port], state->ed[port], state->exifSize[port]);
......@@ -592,15 +595,28 @@ int sendImageFrame(camogm_state *state)
state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port];
state->packetchunks[state->chunk_index ].bytes = state->exifSize[port];
state->packetchunks[state->chunk_index++].chunk = state->ed[port];
app15_pos = state->chunk_index++;
state->packetchunks[state->chunk_index ].bytes = state->head_size[port] - 2;
state->packetchunks[state->chunk_index++].chunk = &(state->jpegHeader[port][2]);
stuffing = 32 - (2 + state->exifSize[port] + state->head_size[port]) % 32;
} else {
D3(fprintf(debug_file, "_8_"));
app15_pos = state->chunk_index++;
state->packetchunks[state->chunk_index ].bytes = state->head_size[port];
state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port];
stuffing = 32 - (state->head_size[port] % 32);
}
D3(fprintf(debug_file, "_9_"));
// align JPEG (+ Exif) header to 32 bytes by adding APP15 marker
if (stuffing < 4) {
stuffing += 32;
}
app15[3] = stuffing - 2;
state->packetchunks[app15_pos].bytes = stuffing;
state->packetchunks[app15_pos].chunk = app15;
fprintf(debug_file, "\nadd %d stuffing bytes as APP15\n", stuffing);
/* JPEG image data may be split in two segments (rolled over buffer end) - process both variants */
if ((state->cirbuf_rp[port] + state->jpeg_len) > state->circ_buff_size[port]) { // two segments
/* copy from the beginning of the frame to the end of the buffer */
......@@ -1566,6 +1582,7 @@ unsigned int select_port(camogm_state *state)
}
}
}
return chn;
}
......
......@@ -186,7 +186,7 @@ typedef struct {
int formats; ///< bitmask of used (initialized) formats
int format; ///< output file format
int set_format; ///< output format to set (will be updated after stop)
elph_packet_chunk packetchunks[7];
elph_packet_chunk packetchunks[8];
int chunk_index;
int buf_overruns[SENSOR_PORTS];
int buf_min[SENSOR_PORTS];
......
......@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <c313a.h>
#include "camogm_jpeg.h"
......@@ -81,6 +82,9 @@ int camogm_start_jpeg(camogm_state *state)
}
}
fprintf(debug_file, "Start recording buffer usage statistics\n");
fprintf(debug_file, "\"JPEG write time, us\",\"free buff, %\",\"free buff, %\",\"free buff, %\",\"free buff, %\"\n");
return 0;
}
......@@ -100,7 +104,10 @@ int camogm_frame_jpeg(camogm_state *state)
unsigned char *split_ptr = NULL;
long split_cntr = 0;
int port = state->port_num;
uint32_t start_time, end_time;
off_t free_space;
start_time = lseek(state->fd_circ[0], LSEEK_CIRC_UTIME, SEEK_END);
if (!state->rawdev_op) {
l = 0;
for (i = 0; i < (state->chunk_index) - 1; i++) {
......@@ -122,7 +129,7 @@ int camogm_frame_jpeg(camogm_state *state)
}
close(state->ivf);
} else {
D0(fprintf(debug_file, "\n%s: current pointers start_pos = %llu, end_pos = %llu, curr_pos = %llu, data in buffer %d\n", __func__,
D3(fprintf(debug_file, "\n%s: current pointers start_pos = %llu, end_pos = %llu, curr_pos = %llu, data in buffer %d\n", __func__,
state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos_w, l));
split_index = -1;
for (int i = 0, total_len = 0; i < state->chunk_index - 1; i++) {
......@@ -130,7 +137,7 @@ int camogm_frame_jpeg(camogm_state *state)
if (total_len + state->rawdev.curr_pos_w > state->rawdev.end_pos) {
split_index = i;
chunks_used++;
D0(fprintf(debug_file, "\n>>> raw storage roll over detected\n"));
D3(fprintf(debug_file, "\n>>> raw storage roll over detected\n"));
break;
}
}
......@@ -185,8 +192,24 @@ int camogm_frame_jpeg(camogm_state *state)
state->rawdev.curr_pos_w += l;
if (state->rawdev.curr_pos_w > state->rawdev.end_pos)
state->rawdev.curr_pos_w = state->rawdev.curr_pos_w - state->rawdev.end_pos + state->rawdev.start_pos;
D0(fprintf(debug_file, "%d bytes written, curr_pos = %llu\n", l, state->rawdev.curr_pos_w));
D6(fprintf(debug_file, "%d bytes written, curr_pos = %llu\n", l, state->rawdev.curr_pos_w));
}
end_time = lseek(state->fd_circ[0], LSEEK_CIRC_UTIME, SEEK_END);
// fprintf(debug_file, "JPEG write time = %u us\n", end_time - start_time);
fprintf(debug_file, "%u,", end_time - start_time);
// fprintf(debug_file, "Free space in buffers: ");
for (int i = 0; i < SENSOR_PORTS; i++) {
int buff_size, jpeg_pos;
jpeg_pos = lseek(state->fd_circ[i], 0 , SEEK_CUR);
free_space = lseek(state->fd_circ[i], LSEEK_CIRC_FREE, SEEK_END);
buff_size = lseek(state->fd_circ[i], 0, SEEK_END);
lseek(state->fd_circ[i], jpeg_pos, SEEK_SET);
// fprintf(debug_file, "chn %d = %ld ",
fprintf(debug_file, "%ld,",
// i,
(int)(100 * (float)free_space / (float)buff_size));
}
fprintf(debug_file, "\b\n");
return 0;
}
......
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