Commit 09cecd82 authored by Mikhail Karpenko's avatar Mikhail Karpenko

Build file index directory instead of copying files

parent 3e396b5e
...@@ -800,6 +800,9 @@ void camogm_set_prefix(camogm_state *state, const char * p, path_type type) ...@@ -800,6 +800,9 @@ void camogm_set_prefix(camogm_state *state, const char * p, path_type type)
} else { } else {
D0(fprintf(debug_file, "WARNING: raw device write initiated\n")); D0(fprintf(debug_file, "WARNING: raw device write initiated\n"));
state->rawdev_op = 1; state->rawdev_op = 1;
/* debug code follows */
state->rawdev.end_pos = 10485760; // 10 Mib
/* end of debug code */
} }
} }
} }
...@@ -1300,7 +1303,8 @@ int parse_cmd(camogm_state *state, FILE* npipe) ...@@ -1300,7 +1303,8 @@ int parse_cmd(camogm_state *state, FILE* npipe)
return 28; return 28;
} else if (strcmp(cmd, "rawdev_read") == 0) { } else if (strcmp(cmd, "rawdev_read") == 0) {
if (state->rawdev_op) if (state->rawdev_op)
camogm_read(state); // camogm_read(state);
build_index(state);
return 29; return 29;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
/** @brief This define is needed to use lseek64 and should be set before includes */ /** @brief This define is needed to use lseek64 and should be set before includes */
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#define _XOPEN_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
#define TIFF_HDR_OFFSET 12 #define TIFF_HDR_OFFSET 12
/** @brief Separator character between seconds and microseconds in JPEG file name */ /** @brief Separator character between seconds and microseconds in JPEG file name */
#define SUBSEC_SEPARATOR '.' #define SUBSEC_SEPARATOR '.'
#define EXIF_DATE_TIME_FORMAT "%Y:%m:%d %H:%M:%S"
/** @brief The size of read buffer in bytes. The data will be read from disk in blocks of this size */ /** @brief The size of read buffer in bytes. The data will be read from disk in blocks of this size */
#define PHY_BLK_SZ 4096 #define PHY_BLK_SZ 4096
/** @brief Include or exclude file start and stop markers from resulting file. This must be set to 1 for JPEG files */ /** @brief Include or exclude file start and stop markers from resulting file. This must be set to 1 for JPEG files */
...@@ -115,6 +117,11 @@ enum file_ops { ...@@ -115,6 +117,11 @@ enum file_ops {
WRITE_STOP WRITE_STOP
}; };
enum search_state {
SEARCH_SKIP,
SEARCH_FILE_START,
SEARCH_FILE_DATA
};
/** /**
* @brief Exif data format table. * @brief Exif data format table.
* *
...@@ -207,6 +214,117 @@ struct crb_ptrs { ...@@ -207,6 +214,117 @@ struct crb_ptrs {
struct iovec second_buff; struct iovec second_buff;
}; };
void dump_index_dir(const struct disk_idir *idir)
{
struct disk_index *ind = idir->head;
while (ind != NULL) {
fprintf(debug_file, "port number = %d; unix time = %ld; usec time = %06u; offset = 0x%010llx; file size = %u\n",
ind->port, ind->rawtime, ind->usec, ind->f_offset, ind->f_size);
ind = ind->next;
}
}
int create_node(struct disk_index **index)
{
fprintf(debug_file, "Creating new disk node\n");
if (*index != NULL)
return -1;
*index = malloc(sizeof(struct disk_index));
if (*index != NULL) {
memset(*index, 0, sizeof(struct disk_index));
fprintf(debug_file, "New disk node created\n");
return 0;
} else {
fprintf(debug_file, "New disk node NOT created\n");
return -1;
}
}
int add_node(struct disk_idir *idir, struct disk_index *index)
{
fprintf(debug_file, "Adding new disk node\n");
if (idir->head == NULL && idir->tail == NULL) {
idir->head = index;
idir->tail = index;
idir->size = 1;
} else {
index->prev = idir->tail;
idir->tail->next = index;
idir->tail = index;
idir->size++;
}
fprintf(debug_file, "New disk node added\n");
return idir->size;
}
struct disk_index *find_by_offset(const struct disk_idir *idir, uint64_t offset)
{
struct disk_index *index = idir->head;
while (index != NULL) {
if (index->f_offset == offset)
break;
index = index->next;
}
return index;
}
int remove_node(struct disk_idir *idir, struct disk_index *node)
{
if (node == NULL)
return -1;
if (node == idir->head) {
idir->head = node->next;
idir->head->prev = NULL;
} else if (node == idir->tail) {
idir->tail = node->prev;
idir->tail->next = NULL;
} else {
struct disk_index *ind = idir->head;
while (ind != NULL) {
if (ind == node) {
ind->prev->next = ind->next;
ind->next->prev = ind->prev;
break;
}
ind = ind->next;
}
}
free(node);
node = NULL;
idir->size--;
return idir->size;
}
int delete_idir(struct disk_idir *idir)
{
fprintf(debug_file, "Deleting disk index directory\n");
struct disk_index *curr_ind;
struct disk_index *next_ind;
if (idir == NULL || idir->head == NULL)
return -1;
curr_ind = idir->head;
next_ind = curr_ind->next;
while (curr_ind != NULL) {
free(curr_ind);
curr_ind = next_ind;
if (curr_ind != NULL)
next_ind = curr_ind->next;
}
idir->head = idir->tail = NULL;
idir->size = 0;
return 0;
}
/** /**
* @brief Find pattern in a data buffer * @brief Find pattern in a data buffer
* *
...@@ -218,7 +336,8 @@ struct crb_ptrs { ...@@ -218,7 +336,8 @@ struct crb_ptrs {
* @param[in] pt_sz size of the pattern array * @param[in] pt_sz size of the pattern array
* @return the index in data buffer where pattern matches or error code from #match_result if it was not found * @return the index in data buffer where pattern matches or error code from #match_result if it was not found
*/ */
static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz, const unsigned char * restrict pattern, ssize_t pt_sz) static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz, const unsigned char * restrict pattern, ssize_t pt_sz,
int add_pattern)
{ {
int ret = MATCH_NOT_FOUND; int ret = MATCH_NOT_FOUND;
int j = 0; int j = 0;
...@@ -233,7 +352,10 @@ static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz, ...@@ -233,7 +352,10 @@ static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz,
j++; j++;
} else if (buff_ptr[i] == pattern[j] && j == pt_sz - 1) { } else if (buff_ptr[i] == pattern[j] && j == pt_sz - 1) {
// last pattern symbol match // last pattern symbol match
ret = i - j; if (add_pattern)
ret = i;
else
ret = i - j;
j = 0; j = 0;
break; break;
} }
...@@ -281,24 +403,18 @@ static void hdr_byte_order(struct tiff_hdr *hdr) ...@@ -281,24 +403,18 @@ static void hdr_byte_order(struct tiff_hdr *hdr)
* @param[in] ifd Exif image file directory record containing string offset * @param[in] ifd Exif image file directory record containing string offset
* @param[out] buff buffer for the string * @param[out] buff buffer for the string
* @return The number of bytes placed to the read buffer * @return The number of bytes placed to the read buffer
* @todo update description
*/ */
static size_t exif_get_text(camogm_state *state, struct ifd_entry *ifd, char *buff) static size_t exif_get_text(camogm_state *state, struct ifd_entry *tag, char *buff)
{ {
size_t j = 0; size_t bytes = 0;
size_t sz = ifd->len * exif_data_fmt[ifd->format]; size_t str_len = tag->len * exif_data_fmt[tag->format];
uint64_t curr_pos = state->rawdev.file_start + TIFF_HDR_OFFSET + ifd->offset; uint64_t curr_pos = state->rawdev.file_start + TIFF_HDR_OFFSET + tag->offset;
char read_buff[MAX_EXIF_SIZE] = {0};
lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET); lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
read(state->rawdev.rawdev_fd, read_buff, sz); bytes = read(state->rawdev.rawdev_fd, buff, str_len);
for (int i = 0; i < sz; i++) {
if (isdigit(read_buff[i]))
buff[j++] = read_buff[i];
else if (isblank(read_buff[i]))
buff[j++] = '_';
}
return j; return bytes;
} }
/** /**
...@@ -316,26 +432,34 @@ static size_t exif_get_text(camogm_state *state, struct ifd_entry *ifd, char *bu ...@@ -316,26 +432,34 @@ static size_t exif_get_text(camogm_state *state, struct ifd_entry *ifd, char *bu
* @param[in] state a pointer to a structure containing current state * @param[in] state a pointer to a structure containing current state
* @param[out] name resulting file name * @param[out] name resulting file name
* @return 0 if file name was successfully created and negative value otherwise * @return 0 if file name was successfully created and negative value otherwise
* @todo update description
*/ */
static int make_fname(camogm_state *state, char *name) static int save_index(camogm_state *state, struct disk_idir *idir)
{ {
int ret = 0;
int process = 2; int process = 2;
size_t sz = 0;
uint32_t data32; uint32_t data32;
uint16_t num_entries = 0; uint16_t num_entries = 0;
uint64_t curr_pos; uint64_t curr_pos;
uint64_t subifd_offset = 0; uint64_t subifd_offset = 0;
struct tiff_hdr hdr; struct tiff_hdr hdr;
struct ifd_entry ifd; struct ifd_entry ifd;
struct ifd_entry ifd_page_num; struct ifd_entry ifd_page_num = {0};
struct ifd_entry ifd_date_time; struct ifd_entry ifd_date_time = {0};
struct ifd_entry ifd_subsec; struct ifd_entry ifd_subsec = {0};
struct disk_index *node = NULL;
unsigned char read_buff[TIFF_HDR_OFFSET] = {0}; unsigned char read_buff[TIFF_HDR_OFFSET] = {0};
char str_buff[32] = {0};
uint64_t save_pos = lseek64(state->rawdev.rawdev_fd, 0, SEEK_CUR); uint64_t save_pos = lseek64(state->rawdev.rawdev_fd, 0, SEEK_CUR);
if (name == NULL) fprintf(debug_file, "Adding new disk index to index directory\n");
if (idir == NULL)
return -1; return -1;
if (create_node(&node) != 0)
return -1;
fprintf(debug_file, "%s: file start position 0x%llx\n", __func__, state->rawdev.file_start);
curr_pos = state->rawdev.file_start; curr_pos = state->rawdev.file_start;
lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET); lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
if (read(state->rawdev.rawdev_fd, read_buff, sizeof(read_buff)) <= 0) { if (read(state->rawdev.rawdev_fd, read_buff, sizeof(read_buff)) <= 0) {
...@@ -350,6 +474,7 @@ static int make_fname(camogm_state *state, char *name) ...@@ -350,6 +474,7 @@ static int make_fname(camogm_state *state, char *name)
lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET); lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
// process IFD0 and SubIFD fields // process IFD0 and SubIFD fields
do { do {
fprintf(debug_file, "%s: processing IFD\n", __func__);
read(state->rawdev.rawdev_fd, &num_entries, sizeof(num_entries)); read(state->rawdev.rawdev_fd, &num_entries, sizeof(num_entries));
num_entries = __be16_to_cpu(num_entries); num_entries = __be16_to_cpu(num_entries);
for (int i = 0; i < num_entries; i++) { for (int i = 0; i < num_entries; i++) {
...@@ -378,29 +503,46 @@ static int make_fname(camogm_state *state, char *name) ...@@ -378,29 +503,46 @@ static int make_fname(camogm_state *state, char *name)
lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET); lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
} while (process > 0); } while (process > 0);
// assemble file name from collected Exif fields // fill disk index node with Exif data and add it to disk index directory
fprintf(debug_file, "%s: filling node data\n", __func__);
node->f_offset = state->rawdev.file_start;
if (ifd_page_num.len != 0) { if (ifd_page_num.len != 0) {
sz = sprintf(name, "%02lu_", ifd_page_num.offset); fprintf(debug_file, "%s: filling node data, page_num\n", __func__);
node->port = (uint32_t)ifd_page_num.offset;
} }
if (ifd_date_time.len != 0) { if (ifd_date_time.len != 0) {
sz += exif_get_text(state, &ifd_date_time, name + sz); fprintf(debug_file, "%s: filling node data, date_time\n", __func__);
struct tm tm;
exif_get_text(state, &ifd_date_time, str_buff);
strptime(str_buff, EXIF_DATE_TIME_FORMAT, &tm);
node->rawtime = mktime(&tm);
} }
if (ifd_subsec.len != 0) { if (ifd_subsec.len != 0) {
name[sz++] = SUBSEC_SEPARATOR; fprintf(debug_file, "%s: filling node data, subsec\n", __func__);
sz += exif_get_text(state, &ifd_subsec, name + sz); exif_get_text(state, &ifd_subsec, str_buff);
node->usec = strtoul(str_buff, NULL, 10);
} }
sprintf(name + sz, ".jpeg"); fprintf(debug_file, "%s: node data filled\n", __func__);
} else { if (node->rawtime != -1)
// a fallback option in case exif is not found - randomly generate file name add_node(idir, node);
int num; else
srand(time(NULL)); ret = -1;
num = rand();
sprintf(name, "%010d.jpeg", num);
D3(fprintf(debug_file, "Exif marker is not found not found, using randomly generated file name: %s\n", name));
} }
lseek64(state->rawdev.rawdev_fd, save_pos, SEEK_SET); lseek64(state->rawdev.rawdev_fd, save_pos, SEEK_SET);
return 0; return ret;
}
int stop_index(struct disk_idir *idir, uint64_t pos_stop)
{
fprintf(debug_file, "Stop index at position 0x%llx\n", pos_stop);
int ret = 0;
if (idir->tail != NULL) {
idir->tail->f_size = pos_stop - idir->tail->f_offset;
} else {
ret = -1;
}
return ret;
} }
/** /**
...@@ -429,7 +571,7 @@ static int start_new_file(struct file_opts *f_op) ...@@ -429,7 +571,7 @@ static int start_new_file(struct file_opts *f_op)
return -CAMOGM_NO_SPACE; return -CAMOGM_NO_SPACE;
} }
make_fname(f_op->state, file_name); // make_fname(f_op->state, file_name);
sprintf(f_op->state->path, "%s%s", f_op->state->path_prefix, file_name); sprintf(f_op->state->path, "%s%s", f_op->state->path_prefix, file_name);
if ((f_op->fh = fopen(f_op->state->path, "w")) == NULL) { if ((f_op->fh = fopen(f_op->state->path, "w")) == NULL) {
...@@ -560,30 +702,34 @@ static int write_buffer(struct file_opts *f_op, unsigned char *from, unsigned ch ...@@ -560,30 +702,34 @@ static int write_buffer(struct file_opts *f_op, unsigned char *from, unsigned ch
* analyzed for JPEG markers and then the data from buffer is written to a file. * analyzed for JPEG markers and then the data from buffer is written to a file.
* @param[in] state a pointer to a structure containing current state * @param[in] state a pointer to a structure containing current state
* @return 0 if files were extracted successfully and negative error code otherwise * @return 0 if files were extracted successfully and negative error code otherwise
* @todo update description, reorder decision tree
*/ */
int camogm_read(camogm_state *state) int build_index(camogm_state *state)
{ {
const int include_markers = INCLUDE_MARKERS; const int include_markers = INCLUDE_MARKERS;
int process; int process;
int zero_cross; int zero_cross;
int file_op;
int err; int err;
int pos_start, pos_stop; int pos_start, pos_stop;
int buff_processed; int buff_processed;
int file_pos_saved; int search_state;
int idir_result;
ssize_t rd; ssize_t rd;
unsigned char buff[PHY_BLK_SZ]; unsigned char buff[PHY_BLK_SZ];
unsigned char next_buff[PHY_BLK_SZ]; unsigned char next_buff[PHY_BLK_SZ];
unsigned char *active_buff = buff;
unsigned char *save_from = NULL; unsigned char *save_from = NULL;
unsigned char *save_to = NULL; unsigned char *save_to = NULL;
struct file_opts f_opts; // struct file_opts f_opts;
uint64_t dev_curr_pos = 0; uint64_t dev_curr_pos = 0;
uint64_t include_st_marker, include_en_marker; uint64_t include_st_marker, include_en_marker;
struct disk_idir index_dir = {0};
size_t add_stm_len, add_enm_len;
memset(&f_opts, 0, sizeof(struct file_opts)); // memset(&f_opts, 0, sizeof(struct file_opts));
f_opts.file_state = WRITE_STOP; // f_opts.file_state = WRITE_STOP;
f_opts.state = state; // f_opts.state = state;
//
state->rawdev.rawdev_fd = open(state->rawdev.rawdev_path, O_RDONLY); state->rawdev.rawdev_fd = open(state->rawdev.rawdev_path, O_RDONLY);
if (state->rawdev.rawdev_fd < 0) { if (state->rawdev.rawdev_fd < 0) {
D0(perror(__func__)); D0(perror(__func__));
...@@ -592,16 +738,21 @@ int camogm_read(camogm_state *state) ...@@ -592,16 +738,21 @@ int camogm_read(camogm_state *state)
} }
if (include_markers) { if (include_markers) {
include_st_marker = elphel_st.iov_len; include_st_marker = 0;
include_en_marker = elphel_en.iov_len; add_stm_len = elphel_st.iov_len;
include_en_marker = 1;
add_enm_len = 0;
} else { } else {
include_st_marker = 0; include_st_marker = 0;
include_en_marker = 0; add_stm_len = 0;
include_en_marker = 1;
add_enm_len = elphel_en.iov_len;
} }
process = 1; process = 1;
zero_cross = 0; zero_cross = 0;
file_op = FILE_OK; search_state = SEARCH_SKIP;
idir_result = 0;
while (process) { while (process) {
rd = read(state->rawdev.rawdev_fd, buff, sizeof(buff)); rd = read(state->rawdev.rawdev_fd, buff, sizeof(buff));
err = errno; err = errno;
...@@ -629,60 +780,70 @@ int camogm_read(camogm_state *state) ...@@ -629,60 +780,70 @@ int camogm_read(camogm_state *state)
if (process) { if (process) {
save_from = buff; save_from = buff;
save_to = buff + rd; save_to = buff + rd;
active_buff = buff;
buff_processed = 0; buff_processed = 0;
file_pos_saved = 0;
do { do {
// process data in read buffer // process data in read buffer
pos_start = find_marker(save_from, save_to - save_from, elphel_st.iov_base, elphel_st.iov_len); pos_start = find_marker(save_from, save_to - save_from, elphel_st.iov_base, elphel_st.iov_len, include_st_marker);
pos_stop = find_marker(save_from, save_to - save_from, elphel_en.iov_base, elphel_en.iov_len); pos_stop = find_marker(save_from, save_to - save_from, elphel_en.iov_base, elphel_en.iov_len, include_en_marker);
fprintf(debug_file, "pos_start = %d, pos_stop = %d\n", pos_start, pos_stop);
if (pos_start == MATCH_NOT_FOUND && pos_stop == MATCH_NOT_FOUND &&
(f_opts.file_state == WRITE_RUNNING || f_opts.file_state == WRITE_START)) { if (pos_start == MATCH_NOT_FOUND && pos_stop == MATCH_NOT_FOUND) {
// writing in progress, got full buffer of new data // normal condition, search in progress
f_opts.file_state = WRITE_RUNNING; buff_processed = 1;
file_op = write_buffer(&f_opts, save_from, save_to); D6(fprintf(debug_file, "State 'skip data'\n"));
} else if (pos_start >= 0 && pos_stop == MATCH_NOT_FOUND && search_state == SEARCH_SKIP) {
// normal condition, new file found
search_state = SEARCH_FILE_DATA;
state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
idir_result = save_index(state, &index_dir);
buff_processed = 1; buff_processed = 1;
D6(fprintf(debug_file, "State 'writing'\n"));
} else if (pos_start >= 0 /*&& pos_stop == MATCH_NOT_FOUND */ &&
f_opts.file_state == WRITE_STOP) {
// not writing, start marker found - start writing
f_opts.file_state = WRITE_START;
if (file_pos_saved == 0)
state->rawdev.file_start = dev_curr_pos + pos_start;
D6(fprintf(debug_file, "New file found. File start position: %llu\n", state->rawdev.file_start)); D6(fprintf(debug_file, "New file found. File start position: %llu\n", state->rawdev.file_start));
save_from = save_from + pos_start + elphel_st.iov_len; D6(fprintf(debug_file, "State 'starting file'\n"));
file_op = write_buffer(&f_opts, save_from - include_st_marker, save_to); } else if (pos_start >= 0 && pos_stop == MATCH_NOT_FOUND && search_state == SEARCH_FILE_DATA) {
// error condition (normally should not happen), discard current index and start a new one
buff_processed = 1; buff_processed = 1;
f_opts.file_state = WRITE_RUNNING; remove_node(&index_dir, index_dir.tail);
D6(fprintf(debug_file, "State 'starting file', file_op = %d\n", file_op)); if (zero_cross == 0) {
state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
idir_result = save_index(state, &index_dir);
} else {
process = 0;
}
D6(fprintf(debug_file, "State 'abnormal start marker, remove current disk index from directory and skip data'\n"));
} else if (pos_start == MATCH_NOT_FOUND && pos_stop >= 0 && } else if (pos_start == MATCH_NOT_FOUND && pos_stop >= 0 &&
(f_opts.file_state == WRITE_RUNNING || f_opts.file_state == WRITE_START)) { search_state == SEARCH_FILE_DATA) {
// writing in progress, end marker found - stop writing // normal condition, save current file size to index directory
f_opts.file_state = WRITE_STOP; uint64_t disk_pos = dev_curr_pos + pos_stop + (save_from - active_buff);
save_to = save_from + pos_stop; search_state = SEARCH_SKIP;
file_op = write_buffer(&f_opts, save_from, save_to + include_en_marker); idir_result = stop_index(&index_dir, disk_pos);
buff_processed = 1; buff_processed = 1;
if (zero_cross) if (zero_cross)
process = 0; process = 0;
D6(fprintf(debug_file, "State 'finishing file'\n")); D6(fprintf(debug_file, "State 'finishing file'\n"));
} else if (pos_start >= 0 && pos_stop >= 0 && pos_start > pos_stop && } else if (pos_start == MATCH_NOT_FOUND && pos_stop >= 0 && search_state == SEARCH_SKIP) {
f_opts.file_state == WRITE_RUNNING) { // error condition (normally should not happen), drop current read buffer and do nothing
// writing in progress, start marker following stop marker found - this indicates a new file buff_processed = 1;
f_opts.file_state = WRITE_STOP; D6(fprintf(debug_file, "State 'abnormal stop marker, skip data'\n"));
state->rawdev.file_start = dev_curr_pos + pos_start; } else if (pos_start >= 0 && pos_stop >= 0 && pos_start > pos_stop && search_state == SEARCH_FILE_DATA) {
file_pos_saved = 1; // normal condition, start marker following stop marker found - this indicates a new file
save_to = save_from + pos_stop; uint64_t disk_pos = dev_curr_pos + pos_stop + (save_from - active_buff);
file_op = write_buffer(&f_opts, save_from, save_to + include_en_marker); fprintf(debug_file, "dev_curr_pos = 0x%llx, save_from = 0x%p, active_buff = 0x%p\n", dev_curr_pos, save_from, active_buff);
save_from = save_from + pos_start; idir_result = stop_index(&index_dir, disk_pos);
save_to = buff + rd; dump_index_dir(&index_dir);
if (zero_cross) { if (zero_cross == 0) {
state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
idir_result = save_index(state, &index_dir);
save_from = save_from + pos_start + add_stm_len;
// @todo: replace with pointer to current buffer
save_to = buff + rd;
} else {
buff_processed = 1; buff_processed = 1;
process = 0; process = 0;
} }
D6(fprintf(debug_file, "State 'starting new file'\n")); D6(fprintf(debug_file, "State 'stop current file and start new file'\n"));
} else if (pos_start == MATCH_PARTIAL && } else if (pos_start == MATCH_PARTIAL && search_state == SEARCH_SKIP) {
f_opts.file_state == WRITE_STOP) { // partial start marker found in the end of read buffer, get next chunk of data and try to find marker there
// partial start marker found in the end of read buffer - get next chunk of data and try to find marker there
enum match_result result; enum match_result result;
struct crb_ptrs field_markers; struct crb_ptrs field_markers;
struct iovec next_chunk = { struct iovec next_chunk = {
...@@ -694,29 +855,30 @@ int camogm_read(camogm_state *state) ...@@ -694,29 +855,30 @@ int camogm_read(camogm_state *state)
}; };
ssize_t next_rd = read(state->rawdev.rawdev_fd, next_buff, sizeof(next_buff)); ssize_t next_rd = read(state->rawdev.rawdev_fd, next_buff, sizeof(next_buff));
next_chunk.iov_len = next_rd; next_chunk.iov_len = next_rd;
dev_curr_pos += next_rd;
result = check_edge_case(&curr_chunk, &next_chunk, &elphel_st, &field_markers); result = check_edge_case(&curr_chunk, &next_chunk, &elphel_st, &field_markers);
if (result == MATCH_FOUND && f_opts.file_state == WRITE_STOP) { if (result == MATCH_FOUND) {
f_opts.file_state = WRITE_START; search_state = SEARCH_FILE_DATA;
state->rawdev.file_start = dev_curr_pos + pos_start; state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
idir_result = save_index(state, &index_dir);
D6(fprintf(debug_file, "File start position: %llu\n", state->rawdev.file_start)); D6(fprintf(debug_file, "File start position: %llu\n", state->rawdev.file_start));
if (include_markers) { // if (include_markers) {
unsigned char *from = field_markers.first_buff.iov_base; // unsigned char *from = field_markers.first_buff.iov_base;
unsigned char *to = from + field_markers.first_buff.iov_len; // unsigned char *to = from + field_markers.first_buff.iov_len;
file_op = write_buffer(&f_opts, from, to); // file_op = write_buffer(&f_opts, from, to);
from = field_markers.second_buff.iov_base; // from = field_markers.second_buff.iov_base;
to = from + field_markers.second_buff.iov_len; // to = from + field_markers.second_buff.iov_len;
file_op = write_buffer(&f_opts, from, to); // file_op = write_buffer(&f_opts, from, to);
} // }
save_from = next_chunk.iov_base + field_markers.second_buff.iov_len; save_from = next_chunk.iov_base + field_markers.second_buff.iov_len;
save_to = next_chunk.iov_base + next_chunk.iov_len; save_to = next_chunk.iov_base + next_chunk.iov_len;
} else { } else {
save_from = next_chunk.iov_base; save_from = next_chunk.iov_base;
save_to = next_chunk.iov_base + next_chunk.iov_len; save_to = next_chunk.iov_base + next_chunk.iov_len;
} }
dev_curr_pos += next_rd;
active_buff = next_buff;
D6(fprintf(debug_file, "State 'check elphel_st cross boundary'; result = %d\n", result)); D6(fprintf(debug_file, "State 'check elphel_st cross boundary'; result = %d\n", result));
} else if (pos_stop == MATCH_PARTIAL && } else if (pos_stop == MATCH_PARTIAL && search_state == SEARCH_FILE_DATA) {
f_opts.file_state != WRITE_STOP) {
// partial end marker found in the end of read buffer - get next chunk of data and try to find marker there // partial end marker found in the end of read buffer - get next chunk of data and try to find marker there
enum match_result result; enum match_result result;
struct crb_ptrs field_markers; struct crb_ptrs field_markers;
...@@ -729,53 +891,54 @@ int camogm_read(camogm_state *state) ...@@ -729,53 +891,54 @@ int camogm_read(camogm_state *state)
}; };
ssize_t next_rd = read(state->rawdev.rawdev_fd, next_buff, sizeof(next_buff)); ssize_t next_rd = read(state->rawdev.rawdev_fd, next_buff, sizeof(next_buff));
next_chunk.iov_len = next_rd; next_chunk.iov_len = next_rd;
dev_curr_pos += next_rd;
result = check_edge_case(&curr_chunk, &next_chunk, &elphel_en, &field_markers); result = check_edge_case(&curr_chunk, &next_chunk, &elphel_en, &field_markers);
if (result == MATCH_FOUND) { if (result == MATCH_FOUND) {
f_opts.file_state = WRITE_STOP; search_state = SEARCH_SKIP;
file_op = write_buffer(&f_opts, save_from, save_to); uint64_t disk_pos = dev_curr_pos + pos_stop + (save_from - active_buff);
if (include_markers) { idir_result = stop_index(&index_dir, disk_pos);
unsigned char *from = field_markers.first_buff.iov_base; // if (include_markers) {
unsigned char *to = from + field_markers.first_buff.iov_len; // unsigned char *from = field_markers.first_buff.iov_base;
file_op = write_buffer(&f_opts, from, to); // unsigned char *to = from + field_markers.first_buff.iov_len;
from = field_markers.second_buff.iov_base; // file_op = write_buffer(&f_opts, from, to);
to = from + field_markers.second_buff.iov_len; // from = field_markers.second_buff.iov_base;
file_op = write_buffer(&f_opts, from, to); // to = from + field_markers.second_buff.iov_len;
} // file_op = write_buffer(&f_opts, from, to);
// }
save_from = next_chunk.iov_base + field_markers.second_buff.iov_len; save_from = next_chunk.iov_base + field_markers.second_buff.iov_len;
save_to = next_chunk.iov_base + next_chunk.iov_len; save_to = next_chunk.iov_base + next_chunk.iov_len;
} else { } else {
file_op = write_buffer(&f_opts, save_from, save_to); // file_op = write_buffer(&f_opts, save_from, save_to);
save_from = next_chunk.iov_base; save_from = next_chunk.iov_base;
save_to = next_chunk.iov_base + next_chunk.iov_len; save_to = next_chunk.iov_base + next_chunk.iov_len;
} }
dev_curr_pos += next_rd;
active_buff = next_buff;
D6(fprintf(debug_file, "State 'check elphel_en' cross boundary:; result = %d\n", result)); D6(fprintf(debug_file, "State 'check elphel_en' cross boundary:; result = %d\n", result));
} else { } else {
// no markers found and new file has not bee started yet - skip data // no markers found and new file has not bee started yet - skip data
D6(fprintf(debug_file, "Undefined state: pos_start = %d, pos_stop = %d, file_state = %d\n", D6(fprintf(debug_file, "Undefined state: pos_start = %d, pos_stop = %d, search_state = %d\n",
pos_start, pos_stop, f_opts.file_state)); pos_start, pos_stop, search_state));
buff_processed = 1; buff_processed = 1;
if (zero_cross) if (zero_cross)
process = 0; process = 0;
} }
} while (buff_processed == 0 && file_op == FILE_OK); } while (buff_processed == 0 && idir_result == 0);
if (file_op != FILE_OK) { if (idir_result != 0) {
process = 0; process = 0;
} }
dev_curr_pos += rd; dev_curr_pos += rd;
} }
} }
D0(fprintf(debug_file, "\n%d files read from %s\n", f_opts.file_cntr, state->rawdev.rawdev_path)); D0(fprintf(debug_file, "\n%d files read from %s\n", index_dir.size, state->rawdev.rawdev_path));
if (close(state->rawdev.rawdev_fd) != 0) { if (close(state->rawdev.rawdev_fd) != 0) {
perror("Unable to close raw device: "); perror("Unable to close raw device: ");
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
} }
if (f_opts.fh != NULL && fclose(f_opts.fh) != 0) {
perror("Unable to close data file: "); dump_index_dir(&index_dir);
return -CAMOGM_FRAME_FILE_ERR; delete_idir(&index_dir);
}
return 0; return 0;
} }
...@@ -19,6 +19,23 @@ ...@@ -19,6 +19,23 @@
#include "camogm.h" #include "camogm.h"
int camogm_read(camogm_state *state); struct disk_index {
struct disk_index *next;
struct disk_index *prev;
time_t rawtime;
useconds_t usec;
uint32_t port;
size_t f_size;
uint64_t f_offset;
};
struct disk_idir {
struct disk_index *head;
struct disk_index *tail;
size_t size;
};
//int camogm_read(camogm_state *state);
int build_index(camogm_state *state);
#endif /* _CAMOGM_READ_H */ #endif /* _CAMOGM_READ_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