Commit dcb01432 authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

Add JPEG header stuffing and time measurement

The JPEG header is stuffed with APP15 markers up to nearest 32 byte long
value.
parent c64a4de9
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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];
+26 −3
Original line number Diff line number Diff line
@@ -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;
}