Loading src/camogm.c +25 −8 Original line number Diff line number Diff line Loading @@ -212,6 +212,21 @@ void put_uint64(void *buf, u_int64_t val) tmp[7] = (val >>= 8) & 0xff; } /** * @brief Detect running compressors and update active channels mask. This function should be * called right after all driver files are opened. * @param state pointer to #camogm_state structure containing program state * @return none */ void check_compressors(camogm_state *state) { for (int i = 0; i < SENSOR_PORTS; i++) { if (getGPValue(i, P_COMPRESSOR_RUN) != COMPRESSOR_RUN_STOP) { state->active_chn |= 1 << i; } } } /** * @brief Initialize the state of the program * @param[in] state pointer to #camogm_state structure containing program state Loading Loading @@ -259,7 +274,7 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num) state->rawdev.end_pos = state->rawdev.start_pos; state->rawdev.curr_pos_w = state->rawdev.start_pos; state->rawdev.curr_pos_r = state->rawdev.start_pos; state->active_chn = ALL_CHN_ACTIVE; state->active_chn = ALL_CHN_INACTIVE; state->rawdev.mmap_default_size = MMAP_CHUNK_SIZE; state->sock_port = port_num; } Loading Loading @@ -378,7 +393,6 @@ int camogm_start(camogm_state *state) memcpy(&(state->frame_params[chn]), (unsigned long* )&ccam_dma_buf[chn][state->metadata_start >> 2], 32); state->jpeg_len = state->frame_params[chn].frame_length; // frame_params.frame_length are now the length of bitstream if (state->frame_params[chn].signffff != 0xffff) { D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->frame_params[chn].signffff)); state->cirbuf_rp[chn] = -1; Loading Loading @@ -928,7 +942,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d) */ void camogm_status(camogm_state *state, char * fn, int xml) { int _len = 0; int64_t _len = 0; int _dur = 0, _udur = 0, _dur_raw, _udur_raw; FILE* f; char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS]; Loading Loading @@ -985,8 +999,10 @@ void camogm_status(camogm_state *state, char * fn, int xml) return; } } if (state->vf) _len = ftell(state->vf); // for ogm else if ((state->ivf) >= 0) _len = lseek(state->ivf, 0, SEEK_CUR); //for mov if (state->rawdev_op) _len = state->rawdev.total_rec_len; else if (state->vf) _len = (int64_t)ftell(state->vf); // for ogm else if ((state->ivf) >= 0) _len = (int64_t)lseek(state->ivf, 0, SEEK_CUR); //for mov switch (state->prog_state) { case STATE_STOPPED: _state = "stopped"; Loading Loading @@ -1022,7 +1038,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) " <frame_number>%d</frame_number>\n" \ " <start_after_timestamp>%f</start_after_timestamp>\n" \ " <file_duration>%d.%06d</file_duration>\n" \ " <file_length>%d</file_length>\n" \ " <file_length>%" PRId64 "</file_length>\n" \ " <frames_skip_left>%d</frames_skip_left>\n" \ " <seconds_skip_left>%d</seconds_skip_left>\n" \ " <frame_width>%d</frame_width>\n" \ Loading Loading @@ -1104,7 +1120,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) fprintf(f, "frame \t%d\n", state->frameno); fprintf(f, "start_after_timestamp \t%f\n", state->start_after_timestamp); fprintf(f, "file duration \t%d.%06d sec\n", _dur, _udur); fprintf(f, "file length \t%d B\n", _len); fprintf(f, "file length \t%" PRId64 " B\n", _len); fprintf(f, "width \t%d (0x%x)\n", state->width, state->width); fprintf(f, "height \t%d (0x%x)\n", state->height, state->height); fprintf(f, "\n"); Loading Loading @@ -1902,6 +1918,7 @@ int main(int argc, char *argv[]) ret = open_files(&sstate); if (ret < 0) return ret; check_compressors(&sstate); if (pthread_create(&sstate.rawdev.tid, NULL, reader, &sstate) != 0 || pthread_detach(sstate.rawdev.tid) != 0) { D0(fprintf(debug_file, "%s:line %d: Can not start reading thread in detached state\n", __FILE__, __LINE__)); Loading Loading @@ -1955,7 +1972,7 @@ int waitDaemonEnabled(unsigned int port, int daemonBit) // <0 - use default unsigned long this_frame = GLOBALPARS(port, G_THIS_FRAME); // No semaphors, so it is possible to miss event and wait until the streamer will be re-enabled before sending message, // but it seems not so terrible lseek(state->fd_circ[state->port_num], LSEEK_DAEMON_CIRCBUF + lastDaemonBit[port], SEEK_END); lseek(state->fd_circ[port], LSEEK_DAEMON_CIRCBUF + lastDaemonBit[port], SEEK_END); if (this_frame == GLOBALPARS(port, G_THIS_FRAME)) return 1; return 0; } Loading src/camogm.h +1 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ typedef struct { uint64_t mmap_current_size; uint64_t mmap_offset; uint64_t file_start; int64_t total_rec_len; pthread_t tid; volatile int thread_state; unsigned char *disk_mmap; Loading src/camogm_jpeg.c +14 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,18 @@ void camogm_free_jpeg(void) { } /** Calculate the total length of current frame */ int64_t camogm_get_jpeg_size(camogm_state *state) { int64_t len = 0; for (int i = 0; i < state->chunk_index - 1; i++) { len += state->packetchunks[i + 1].bytes; } return len; } /** * @brief Called every time the JPEG files recording is started. * Loading Loading @@ -135,6 +147,8 @@ int camogm_frame_jpeg(camogm_state *state) D0(fprintf(debug_file, "Can not pass IO vector to driver: %s\n", strerror(errno))); return -CAMOGM_FRAME_FILE_ERR; } // update statistics state->rawdev.total_rec_len += camogm_get_jpeg_size(state); } return 0; Loading src/camogmgui/camogm_interface.php +99 −25 Original line number Diff line number Diff line Loading @@ -349,6 +349,8 @@ else case "listdevices": exec ("cat /proc/partitions", $arr1); exec ("cat /proc/mounts", $arr2); $ret = get_mnt_dev(); $mnt_dev = $ret["devices"]; $j = 0; // first two lines are header and empty line separator, skip them $i = 2; Loading @@ -372,6 +374,12 @@ else } $j = 0; foreach ($partitions as $partition) { $include = false; foreach ($mnt_dev as $dev) { if (strpos($dev, $partition)) $include = true; } if ($include) { echo "<item>"; echo "<partition>/dev/".$partition."</partition>"; echo "<size>".round($size[$j]/1024/1024, 2) ." GB</size>"; Loading Loading @@ -400,7 +408,16 @@ else } echo "</item>"; } } break; case "list_raw_devices": $devices = get_raw_dev(); foreach ($devices as $device => $size) { echo "<item>"; echo "<raw_device>" . $device . "</raw_device>"; echo "<size>" . round($size / 1048576, 2) . "</size>"; echo "</item>"; } break; case "mkdir": $dir_name = $_GET['name']; Loading Loading @@ -601,6 +618,63 @@ function xml_footer() { echo "</camogm_interface>\n"; } /** Get a list of disk devices which have file system and can be mounted. This function * uses 'blkid' command from busybox. */ function get_mnt_dev() { exec("blkid", $ids); $i = 0; foreach ($ids as $id) { $devices[$i] = preg_replace('/: +.*/', "", $id); if (preg_match('/(?<=TYPE=")[a-z0-9]+(?=")/', $id, $fs) == 1) $fs_types[$i] = $fs[0]; else $fs_types[$i] = "none"; $i++; } return array("devices" => $devices, "types" => $fs_types); } /** Get a list of devices whithout file system which can be used for raw disk storage from camogm. */ function get_raw_dev() { $j = 0; $regexp = '/([0-9]+) +(sd[a-z0-9]+$)/'; $names = array(); $ret = get_mnt_dev(); $devices = $ret["devices"]; $types = $ret["types"]; exec("cat /proc/partitions", $partitions); // get a list of all suitable partitions // the first two elements of an array are table header and empty line delimiter, skip them for ($i = 2; $i < count($partitions); $i++) { // select SATA devices only if (preg_match($regexp, $partitions[$i], $name) == 1) { $names[$name[2]] = $name[1]; $j++; } } // filter out partitions with file system $i = 0; $raw_devices = array(); foreach ($names as $name => $size) { $found = false; foreach ($devices as $device) { if (strpos($device, $name) !== false) $found = true; } if ($found === false) { // current partition is not found in the blkid list, add it to raw devices $raw_devices["/dev/" . $name] = $size; $i++; } } return $raw_devices; } ?> src/camogmgui/camogmgui.css +4 −0 Original line number Diff line number Diff line Loading @@ -257,3 +257,7 @@ table.state_table td { margin: 0px; padding: 0px; } .radio_class { margin-top: 1px; } No newline at end of file Loading
src/camogm.c +25 −8 Original line number Diff line number Diff line Loading @@ -212,6 +212,21 @@ void put_uint64(void *buf, u_int64_t val) tmp[7] = (val >>= 8) & 0xff; } /** * @brief Detect running compressors and update active channels mask. This function should be * called right after all driver files are opened. * @param state pointer to #camogm_state structure containing program state * @return none */ void check_compressors(camogm_state *state) { for (int i = 0; i < SENSOR_PORTS; i++) { if (getGPValue(i, P_COMPRESSOR_RUN) != COMPRESSOR_RUN_STOP) { state->active_chn |= 1 << i; } } } /** * @brief Initialize the state of the program * @param[in] state pointer to #camogm_state structure containing program state Loading Loading @@ -259,7 +274,7 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num) state->rawdev.end_pos = state->rawdev.start_pos; state->rawdev.curr_pos_w = state->rawdev.start_pos; state->rawdev.curr_pos_r = state->rawdev.start_pos; state->active_chn = ALL_CHN_ACTIVE; state->active_chn = ALL_CHN_INACTIVE; state->rawdev.mmap_default_size = MMAP_CHUNK_SIZE; state->sock_port = port_num; } Loading Loading @@ -378,7 +393,6 @@ int camogm_start(camogm_state *state) memcpy(&(state->frame_params[chn]), (unsigned long* )&ccam_dma_buf[chn][state->metadata_start >> 2], 32); state->jpeg_len = state->frame_params[chn].frame_length; // frame_params.frame_length are now the length of bitstream if (state->frame_params[chn].signffff != 0xffff) { D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->frame_params[chn].signffff)); state->cirbuf_rp[chn] = -1; Loading Loading @@ -928,7 +942,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d) */ void camogm_status(camogm_state *state, char * fn, int xml) { int _len = 0; int64_t _len = 0; int _dur = 0, _udur = 0, _dur_raw, _udur_raw; FILE* f; char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS]; Loading Loading @@ -985,8 +999,10 @@ void camogm_status(camogm_state *state, char * fn, int xml) return; } } if (state->vf) _len = ftell(state->vf); // for ogm else if ((state->ivf) >= 0) _len = lseek(state->ivf, 0, SEEK_CUR); //for mov if (state->rawdev_op) _len = state->rawdev.total_rec_len; else if (state->vf) _len = (int64_t)ftell(state->vf); // for ogm else if ((state->ivf) >= 0) _len = (int64_t)lseek(state->ivf, 0, SEEK_CUR); //for mov switch (state->prog_state) { case STATE_STOPPED: _state = "stopped"; Loading Loading @@ -1022,7 +1038,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) " <frame_number>%d</frame_number>\n" \ " <start_after_timestamp>%f</start_after_timestamp>\n" \ " <file_duration>%d.%06d</file_duration>\n" \ " <file_length>%d</file_length>\n" \ " <file_length>%" PRId64 "</file_length>\n" \ " <frames_skip_left>%d</frames_skip_left>\n" \ " <seconds_skip_left>%d</seconds_skip_left>\n" \ " <frame_width>%d</frame_width>\n" \ Loading Loading @@ -1104,7 +1120,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) fprintf(f, "frame \t%d\n", state->frameno); fprintf(f, "start_after_timestamp \t%f\n", state->start_after_timestamp); fprintf(f, "file duration \t%d.%06d sec\n", _dur, _udur); fprintf(f, "file length \t%d B\n", _len); fprintf(f, "file length \t%" PRId64 " B\n", _len); fprintf(f, "width \t%d (0x%x)\n", state->width, state->width); fprintf(f, "height \t%d (0x%x)\n", state->height, state->height); fprintf(f, "\n"); Loading Loading @@ -1902,6 +1918,7 @@ int main(int argc, char *argv[]) ret = open_files(&sstate); if (ret < 0) return ret; check_compressors(&sstate); if (pthread_create(&sstate.rawdev.tid, NULL, reader, &sstate) != 0 || pthread_detach(sstate.rawdev.tid) != 0) { D0(fprintf(debug_file, "%s:line %d: Can not start reading thread in detached state\n", __FILE__, __LINE__)); Loading Loading @@ -1955,7 +1972,7 @@ int waitDaemonEnabled(unsigned int port, int daemonBit) // <0 - use default unsigned long this_frame = GLOBALPARS(port, G_THIS_FRAME); // No semaphors, so it is possible to miss event and wait until the streamer will be re-enabled before sending message, // but it seems not so terrible lseek(state->fd_circ[state->port_num], LSEEK_DAEMON_CIRCBUF + lastDaemonBit[port], SEEK_END); lseek(state->fd_circ[port], LSEEK_DAEMON_CIRCBUF + lastDaemonBit[port], SEEK_END); if (this_frame == GLOBALPARS(port, G_THIS_FRAME)) return 1; return 0; } Loading
src/camogm.h +1 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ typedef struct { uint64_t mmap_current_size; uint64_t mmap_offset; uint64_t file_start; int64_t total_rec_len; pthread_t tid; volatile int thread_state; unsigned char *disk_mmap; Loading
src/camogm_jpeg.c +14 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,18 @@ void camogm_free_jpeg(void) { } /** Calculate the total length of current frame */ int64_t camogm_get_jpeg_size(camogm_state *state) { int64_t len = 0; for (int i = 0; i < state->chunk_index - 1; i++) { len += state->packetchunks[i + 1].bytes; } return len; } /** * @brief Called every time the JPEG files recording is started. * Loading Loading @@ -135,6 +147,8 @@ int camogm_frame_jpeg(camogm_state *state) D0(fprintf(debug_file, "Can not pass IO vector to driver: %s\n", strerror(errno))); return -CAMOGM_FRAME_FILE_ERR; } // update statistics state->rawdev.total_rec_len += camogm_get_jpeg_size(state); } return 0; Loading
src/camogmgui/camogm_interface.php +99 −25 Original line number Diff line number Diff line Loading @@ -349,6 +349,8 @@ else case "listdevices": exec ("cat /proc/partitions", $arr1); exec ("cat /proc/mounts", $arr2); $ret = get_mnt_dev(); $mnt_dev = $ret["devices"]; $j = 0; // first two lines are header and empty line separator, skip them $i = 2; Loading @@ -372,6 +374,12 @@ else } $j = 0; foreach ($partitions as $partition) { $include = false; foreach ($mnt_dev as $dev) { if (strpos($dev, $partition)) $include = true; } if ($include) { echo "<item>"; echo "<partition>/dev/".$partition."</partition>"; echo "<size>".round($size[$j]/1024/1024, 2) ." GB</size>"; Loading Loading @@ -400,7 +408,16 @@ else } echo "</item>"; } } break; case "list_raw_devices": $devices = get_raw_dev(); foreach ($devices as $device => $size) { echo "<item>"; echo "<raw_device>" . $device . "</raw_device>"; echo "<size>" . round($size / 1048576, 2) . "</size>"; echo "</item>"; } break; case "mkdir": $dir_name = $_GET['name']; Loading Loading @@ -601,6 +618,63 @@ function xml_footer() { echo "</camogm_interface>\n"; } /** Get a list of disk devices which have file system and can be mounted. This function * uses 'blkid' command from busybox. */ function get_mnt_dev() { exec("blkid", $ids); $i = 0; foreach ($ids as $id) { $devices[$i] = preg_replace('/: +.*/', "", $id); if (preg_match('/(?<=TYPE=")[a-z0-9]+(?=")/', $id, $fs) == 1) $fs_types[$i] = $fs[0]; else $fs_types[$i] = "none"; $i++; } return array("devices" => $devices, "types" => $fs_types); } /** Get a list of devices whithout file system which can be used for raw disk storage from camogm. */ function get_raw_dev() { $j = 0; $regexp = '/([0-9]+) +(sd[a-z0-9]+$)/'; $names = array(); $ret = get_mnt_dev(); $devices = $ret["devices"]; $types = $ret["types"]; exec("cat /proc/partitions", $partitions); // get a list of all suitable partitions // the first two elements of an array are table header and empty line delimiter, skip them for ($i = 2; $i < count($partitions); $i++) { // select SATA devices only if (preg_match($regexp, $partitions[$i], $name) == 1) { $names[$name[2]] = $name[1]; $j++; } } // filter out partitions with file system $i = 0; $raw_devices = array(); foreach ($names as $name => $size) { $found = false; foreach ($devices as $device) { if (strpos($device, $name) !== false) $found = true; } if ($found === false) { // current partition is not found in the blkid list, add it to raw devices $raw_devices["/dev/" . $name] = $size; $i++; } } return $raw_devices; } ?>
src/camogmgui/camogmgui.css +4 −0 Original line number Diff line number Diff line Loading @@ -257,3 +257,7 @@ table.state_table td { margin: 0px; padding: 0px; } .radio_class { margin-top: 1px; } No newline at end of file