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) ...@@ -479,6 +479,9 @@ int sendImageFrame(camogm_state *state)
int * ifp_this = (int*)&(state->this_frame_params[state->port_num]); int * ifp_this = (int*)&(state->this_frame_params[state->port_num]);
int fp; int fp;
int port = state->port_num; 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) // This is probably needed only for Quicktime (not to exceed already allocated frame index)
if (state->frameno >= (state->max_frames)) { if (state->frameno >= (state->max_frames)) {
...@@ -571,7 +574,7 @@ int sendImageFrame(camogm_state *state) ...@@ -571,7 +574,7 @@ int sendImageFrame(camogm_state *state)
D3(fprintf(debug_file, "_5_")); D3(fprintf(debug_file, "_5_"));
// update the Exif header with the current frame metadata // 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 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 //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) 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]); rslt = read(state->fd_exif[port], state->ed[port], state->exifSize[port]);
...@@ -592,15 +595,28 @@ int sendImageFrame(camogm_state *state) ...@@ -592,15 +595,28 @@ int sendImageFrame(camogm_state *state)
state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port]; state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port];
state->packetchunks[state->chunk_index ].bytes = state->exifSize[port]; state->packetchunks[state->chunk_index ].bytes = state->exifSize[port];
state->packetchunks[state->chunk_index++].chunk = state->ed[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 ].bytes = state->head_size[port] - 2;
state->packetchunks[state->chunk_index++].chunk = &(state->jpegHeader[port][2]); state->packetchunks[state->chunk_index++].chunk = &(state->jpegHeader[port][2]);
stuffing = 32 - (2 + state->exifSize[port] + state->head_size[port]) % 32;
} else { } else {
D3(fprintf(debug_file, "_8_")); 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 ].bytes = state->head_size[port];
state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port]; state->packetchunks[state->chunk_index++].chunk = state->jpegHeader[port];
stuffing = 32 - (state->head_size[port] % 32);
} }
D3(fprintf(debug_file, "_9_")); 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 */ /* 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 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 */ /* copy from the beginning of the frame to the end of the buffer */
...@@ -1566,6 +1582,7 @@ unsigned int select_port(camogm_state *state) ...@@ -1566,6 +1582,7 @@ unsigned int select_port(camogm_state *state)
} }
} }
} }
return chn; return chn;
} }
......
...@@ -186,7 +186,7 @@ typedef struct { ...@@ -186,7 +186,7 @@ typedef struct {
int formats; ///< bitmask of used (initialized) formats int formats; ///< bitmask of used (initialized) formats
int format; ///< output file format int format; ///< output file format
int set_format; ///< output format to set (will be updated after stop) 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 chunk_index;
int buf_overruns[SENSOR_PORTS]; int buf_overruns[SENSOR_PORTS];
int buf_min[SENSOR_PORTS]; int buf_min[SENSOR_PORTS];
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include <c313a.h>
#include "camogm_jpeg.h" #include "camogm_jpeg.h"
...@@ -81,6 +82,9 @@ int camogm_start_jpeg(camogm_state *state) ...@@ -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; return 0;
} }
...@@ -100,7 +104,10 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -100,7 +104,10 @@ int camogm_frame_jpeg(camogm_state *state)
unsigned char *split_ptr = NULL; unsigned char *split_ptr = NULL;
long split_cntr = 0; long split_cntr = 0;
int port = state->port_num; 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) { if (!state->rawdev_op) {
l = 0; l = 0;
for (i = 0; i < (state->chunk_index) - 1; i++) { for (i = 0; i < (state->chunk_index) - 1; i++) {
...@@ -122,7 +129,7 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -122,7 +129,7 @@ int camogm_frame_jpeg(camogm_state *state)
} }
close(state->ivf); close(state->ivf);
} else { } 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)); state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos_w, l));
split_index = -1; split_index = -1;
for (int i = 0, total_len = 0; i < state->chunk_index - 1; i++) { for (int i = 0, total_len = 0; i < state->chunk_index - 1; i++) {
...@@ -130,7 +137,7 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -130,7 +137,7 @@ int camogm_frame_jpeg(camogm_state *state)
if (total_len + state->rawdev.curr_pos_w > state->rawdev.end_pos) { if (total_len + state->rawdev.curr_pos_w > state->rawdev.end_pos) {
split_index = i; split_index = i;
chunks_used++; 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; break;
} }
} }
...@@ -185,8 +192,24 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -185,8 +192,24 @@ int camogm_frame_jpeg(camogm_state *state)
state->rawdev.curr_pos_w += l; state->rawdev.curr_pos_w += l;
if (state->rawdev.curr_pos_w > state->rawdev.end_pos) 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; 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; 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