Commit 89d1c8fe authored by Andrey Filippov's avatar Andrey Filippov

Merge branch 'master' of github.com:Elphel/elphel-apps-camogm

parents 8177e5eb 8431e010
...@@ -212,6 +212,21 @@ void put_uint64(void *buf, u_int64_t val) ...@@ -212,6 +212,21 @@ void put_uint64(void *buf, u_int64_t val)
tmp[7] = (val >>= 8) & 0xff; 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 * @brief Initialize the state of the program
* @param[in] state pointer to #camogm_state structure containing program state * @param[in] state pointer to #camogm_state structure containing program state
...@@ -259,7 +274,7 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num) ...@@ -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.end_pos = state->rawdev.start_pos;
state->rawdev.curr_pos_w = state->rawdev.start_pos; state->rawdev.curr_pos_w = state->rawdev.start_pos;
state->rawdev.curr_pos_r = 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->rawdev.mmap_default_size = MMAP_CHUNK_SIZE;
state->sock_port = port_num; state->sock_port = port_num;
} }
...@@ -378,7 +393,6 @@ int camogm_start(camogm_state *state) ...@@ -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); 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 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) { 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)); D0(fprintf(debug_file, "%s:%d: wrong signature - %d\r\n", __FILE__, __LINE__, (int)state->frame_params[chn].signffff));
state->cirbuf_rp[chn] = -1; state->cirbuf_rp[chn] = -1;
...@@ -928,7 +942,7 @@ void camogm_set_start_after_timestamp(camogm_state *state, double d) ...@@ -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) 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; int _dur = 0, _udur = 0, _dur_raw, _udur_raw;
FILE* f; FILE* f;
char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS]; char *_state, *_output_format, *_using_exif, *_using_global_pointer, *_compressor_state[SENSOR_PORTS];
...@@ -985,8 +999,10 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -985,8 +999,10 @@ void camogm_status(camogm_state *state, char * fn, int xml)
return; return;
} }
} }
if (state->vf) _len = ftell(state->vf); // for ogm if (state->rawdev_op)
else if ((state->ivf) >= 0) _len = lseek(state->ivf, 0, SEEK_CUR); //for mov _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) { switch (state->prog_state) {
case STATE_STOPPED: case STATE_STOPPED:
_state = "stopped"; _state = "stopped";
...@@ -1022,7 +1038,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -1022,7 +1038,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
" <frame_number>%d</frame_number>\n" \ " <frame_number>%d</frame_number>\n" \
" <start_after_timestamp>%f</start_after_timestamp>\n" \ " <start_after_timestamp>%f</start_after_timestamp>\n" \
" <file_duration>%d.%06d</file_duration>\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" \ " <frames_skip_left>%d</frames_skip_left>\n" \
" <seconds_skip_left>%d</seconds_skip_left>\n" \ " <seconds_skip_left>%d</seconds_skip_left>\n" \
" <frame_width>%d</frame_width>\n" \ " <frame_width>%d</frame_width>\n" \
...@@ -1104,7 +1120,7 @@ void camogm_status(camogm_state *state, char * fn, int xml) ...@@ -1104,7 +1120,7 @@ void camogm_status(camogm_state *state, char * fn, int xml)
fprintf(f, "frame \t%d\n", state->frameno); fprintf(f, "frame \t%d\n", state->frameno);
fprintf(f, "start_after_timestamp \t%f\n", state->start_after_timestamp); 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 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, "width \t%d (0x%x)\n", state->width, state->width);
fprintf(f, "height \t%d (0x%x)\n", state->height, state->height); fprintf(f, "height \t%d (0x%x)\n", state->height, state->height);
fprintf(f, "\n"); fprintf(f, "\n");
...@@ -1902,6 +1918,7 @@ int main(int argc, char *argv[]) ...@@ -1902,6 +1918,7 @@ int main(int argc, char *argv[])
ret = open_files(&sstate); ret = open_files(&sstate);
if (ret < 0) if (ret < 0)
return ret; return ret;
check_compressors(&sstate);
if (pthread_create(&sstate.rawdev.tid, NULL, reader, &sstate) != 0 || if (pthread_create(&sstate.rawdev.tid, NULL, reader, &sstate) != 0 ||
pthread_detach(sstate.rawdev.tid) != 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__)); D0(fprintf(debug_file, "%s:line %d: Can not start reading thread in detached state\n", __FILE__, __LINE__));
...@@ -1955,7 +1972,7 @@ int waitDaemonEnabled(unsigned int port, int daemonBit) // <0 - use default ...@@ -1955,7 +1972,7 @@ int waitDaemonEnabled(unsigned int port, int daemonBit) // <0 - use default
unsigned long this_frame = GLOBALPARS(port, G_THIS_FRAME); 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, // 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 // 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; if (this_frame == GLOBALPARS(port, G_THIS_FRAME)) return 1;
return 0; return 0;
} }
......
...@@ -123,6 +123,7 @@ typedef struct { ...@@ -123,6 +123,7 @@ typedef struct {
uint64_t mmap_current_size; uint64_t mmap_current_size;
uint64_t mmap_offset; uint64_t mmap_offset;
uint64_t file_start; uint64_t file_start;
int64_t total_rec_len;
pthread_t tid; pthread_t tid;
volatile int thread_state; volatile int thread_state;
unsigned char *disk_mmap; unsigned char *disk_mmap;
......
...@@ -41,6 +41,18 @@ void camogm_free_jpeg(void) ...@@ -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. * @brief Called every time the JPEG files recording is started.
* *
...@@ -135,6 +147,8 @@ int camogm_frame_jpeg(camogm_state *state) ...@@ -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))); D0(fprintf(debug_file, "Can not pass IO vector to driver: %s\n", strerror(errno)));
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
} }
// update statistics
state->rawdev.total_rec_len += camogm_get_jpeg_size(state);
} }
return 0; return 0;
......
...@@ -349,6 +349,8 @@ else ...@@ -349,6 +349,8 @@ else
case "listdevices": case "listdevices":
exec ("cat /proc/partitions", $arr1); exec ("cat /proc/partitions", $arr1);
exec ("cat /proc/mounts", $arr2); exec ("cat /proc/mounts", $arr2);
$ret = get_mnt_dev();
$mnt_dev = $ret["devices"];
$j = 0; $j = 0;
// first two lines are header and empty line separator, skip them // first two lines are header and empty line separator, skip them
$i = 2; $i = 2;
...@@ -372,35 +374,50 @@ else ...@@ -372,35 +374,50 @@ else
} }
$j = 0; $j = 0;
foreach ($partitions as $partition) { foreach ($partitions as $partition) {
echo "<item>"; $include = false;
echo "<partition>/dev/".$partition."</partition>"; foreach ($mnt_dev as $dev) {
echo "<size>".round($size[$j]/1024/1024, 2) ." GB</size>"; if (strpos($dev, $partition))
$j++; $include = true;
$i = 0;
while($i < count($arr2)) {
if(strpos($arr2[$i], $partition))
{
$parts = explode(" ", $arr2[$i]);
$mountpoint = $parts[1];
$filesystem = $parts[2];
}
$i++;
}
if ($mountpoint != "") {
echo "<mountpoint>".$mountpoint."</mountpoint>";
$mountpoint = "";
} else {
echo "<mountpoint>none</mountpoint>";
} }
if ($filesystem != "") { if ($include) {
echo "<filesystem>".$filesystem."</filesystem>"; echo "<item>";
$filesystem = ""; echo "<partition>/dev/".$partition."</partition>";
} else { echo "<size>".round($size[$j]/1024/1024, 2) ." GB</size>";
echo "<filesystem>none</filesystem>"; $j++;
$i = 0;
while($i < count($arr2)) {
if(strpos($arr2[$i], $partition))
{
$parts = explode(" ", $arr2[$i]);
$mountpoint = $parts[1];
$filesystem = $parts[2];
}
$i++;
}
if ($mountpoint != "") {
echo "<mountpoint>".$mountpoint."</mountpoint>";
$mountpoint = "";
} else {
echo "<mountpoint>none</mountpoint>";
}
if ($filesystem != "") {
echo "<filesystem>".$filesystem."</filesystem>";
$filesystem = "";
} else {
echo "<filesystem>none</filesystem>";
}
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>"; echo "</item>";
} }
break; break;
case "mkdir": case "mkdir":
$dir_name = $_GET['name']; $dir_name = $_GET['name'];
...@@ -601,6 +618,63 @@ function xml_footer() { ...@@ -601,6 +618,63 @@ function xml_footer() {
echo "</camogm_interface>\n"; 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;
}
?> ?>
...@@ -256,4 +256,8 @@ table.state_table td { ...@@ -256,4 +256,8 @@ table.state_table td {
#live_image_auto_update { #live_image_auto_update {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
}
.radio_class {
margin-top: 1px;
} }
\ No newline at end of file
// store path to partition that camogm is currently using
var rawdev_path = "";
// shows if partition selection should be updated
var update_dev_radio = false;
function timer_functions(){ function timer_functions(){
list_files(getCookie("current_dir")); list_files(getCookie("current_dir"));
update_state(); update_state();
...@@ -17,13 +22,17 @@ function init() { ...@@ -17,13 +22,17 @@ function init() {
//setTimeout('update_audio_form(document.getElementById("audioform"))', 1500); //setTimeout('update_audio_form(document.getElementById("audioform"))', 1500);
//setTimeout('calc_split_size()', 2300); //setTimeout('calc_split_size()', 2300);
//setTimeout('scan_devices()', 3000); //setTimeout('scan_devices()', 3000);
update_name_scheme(); update_name_scheme();
check_audio_hardware(); check_audio_hardware();
update_audio_form(document.getElementById("audioform")); update_audio_form(document.getElementById("audioform"));
calc_split_size(); calc_split_size();
//calling "is_mounted" at response //calling "is_mounted" at response
scan_devices("is_mounted(selected_device)"); //global_timer = setInterval(timer_functions,2000);
//global_timer = setInterval(timer_functions,2000); if (document.getElementById('fast_rec').checked) {
makeRequest('camogm_interface.php', '?cmd=list_raw_devices');
} else {
scan_devices("is_mounted(selected_device)");
}
} }
function reload() { function reload() {
makeRequest('camogm_interface.php', '?cmd=run_camogm'); makeRequest('camogm_interface.php', '?cmd=run_camogm');
...@@ -104,7 +113,9 @@ function process_is_hdd_mounted(xmldoc) { ...@@ -104,7 +113,9 @@ function process_is_hdd_mounted(xmldoc) {
//scan_devices() - fills the device list. //scan_devices() - fills the device list.
function scan_devices(callback) { function scan_devices(callback) {
makeRequest('camogm_interface.php','?cmd=listdevices',callback); if (document.getElementById('fast_rec').checked == false) {
makeRequest('camogm_interface.php','?cmd=listdevices',callback);
}
} }
var devices = Array(); var devices = Array();
...@@ -384,6 +395,8 @@ function process_request(xmldoc) { ...@@ -384,6 +395,8 @@ function process_request(xmldoc) {
case "listdevices": case "listdevices":
process_scan_devices(xmldoc); process_scan_devices(xmldoc);
break; break;
case "list_raw_devices":
process_raw_dev_list(xmldoc);
default: default:
break; break;
} }
...@@ -423,6 +436,18 @@ function process_recording(xmldoc) { ...@@ -423,6 +436,18 @@ function process_recording(xmldoc) {
if (xmldoc.getElementsByTagName('buffer_overruns')[0].firstChild.data > 0) if (xmldoc.getElementsByTagName('buffer_overruns')[0].firstChild.data > 0)
alert ("Buffer overrun! current datarate exceeds max. write rate") alert ("Buffer overrun! current datarate exceeds max. write rate")
// update partition selection
if (update_dev_radio) {
var radios = document.getElementsByName('rawdev_path');
rawdev_path = xmldoc.getElementsByTagName('raw_device_path')[0].firstChild.data;
for (var i = 0; i < radios.length; i++) {
if (rawdev_path == '"' + radios[i].value + '"') {
radios[i].checked = true;
}
}
update_dev_radio = false;
}
} }
recording = false; recording = false;
function update_state() { function update_state() {
...@@ -535,7 +560,9 @@ function help(caller) { ...@@ -535,7 +560,9 @@ function help(caller) {
case 'debug': case 'debug':
alert("The higher the debug-level the more information is written to the debug file (it may slow down camogm and cause it to drop frames even if it could handle it with no/lower debug-level output).") alert("The higher the debug-level the more information is written to the debug file (it may slow down camogm and cause it to drop frames even if it could handle it with no/lower debug-level output).")
break; break;
case 'fast_rec':
alert("Enable or disable fast recoding feature. The disk drive should have at least one partition without file system or" +
"any data on it to enable this feature.");
} }
} }
function format_changed(parent) { function format_changed(parent) {
...@@ -747,13 +774,73 @@ function toggle_buffer() { ...@@ -747,13 +774,73 @@ function toggle_buffer() {
} }
} }
// enable fast recording through disk driver /** Enable or disable page controls in accordance to new state which cat be one of 'fast_rec' or 'standart_rec' */
function fast_rec_changed(parent) function set_controls_state(new_state)
{ {
if (parent.checked) { var radios = document.getElementsByName('container');
if (new_state == 'fast_rec') {
radios_disable = true;
document.getElementById('radioJpg').checked = true; document.getElementById('radioJpg').checked = true;
document.getElementById('directory').disabled = true; document.getElementById('directory').disabled = true;
} else { } else {
radios_disable = false;
document.getElementById('directory').disabled = false; document.getElementById('directory').disabled = false;
if (document.getElementById('submit_button').disabled == true)
document.getElementById('submit_button').disabled = false;
}
for (var i = 0; i < radios.length; i++) {
radios[i].disabled = radios_disable;
}
}
/** Enable fast recording through disk driver */
function fast_rec_changed(parent)
{
if (parent.checked) {
makeRequest('camogm_interface.php', '?cmd=list_raw_devices');
} else {
scan_devices("is_mounted(selected_device)");
set_controls_state('standart_rec');
}
}
/** Show raw devices table and change the state of controls */
function process_raw_dev_list(xmldoc)
{
var content = "";
var items = xmldoc.getElementsByTagName('item');
content += "";
if (items.length > 0) {
set_controls_state('fast_rec');
content += "<table cellpadding='5' cellspacing='0' cellmargin='0'>";
content += "<tr><td></td><td><b>Partition</b></td><td><b></b></td><td><b>Size</b></td><td><b></b></td><td></td></tr>";
for (var i = 0; i < items.length; i++) {
var partition = items[i].childNodes[0];
var size = items[i].childNodes[1];
content += "<tr><td><input type=\"radio\" id=\"radio_dev_" + i + "\" class=\"radio_class\" name=\"rawdev_path\" value=\"" +
partition.firstChild.nodeValue + "\" ";
if (i == 0) {
content += "checked ";
}
content += "/></td>" +
"<td>" + partition.firstChild.nodeValue + "</td>" +
"<td></td><td>" + size.firstChild.nodeValue + " GB" + "</td>" +
"<td></td><td></td></tr>";
}
content += "</table>";
} else {
content += "<p class=\"alert\">Device partitions without file system are not found. Fast recording can not be started. " +
"Create a partition without file system on it and try again.</p>";
document.getElementById('submit_button').disabled = true;
}
document.getElementById('ajax_devices').innerHTML = content;
// get current partition if we have more than one available and update selection
if (items.length > 1) {
update_dev_radio = true;
makeRequest('camogm_interface.php', '?cmd=status');
} }
} }
...@@ -117,28 +117,38 @@ ...@@ -117,28 +117,38 @@
// format tab submit // format tab submit
if (isset($_POST['settings_format'])){ if (isset($_POST['settings_format'])){
switch($_POST['container']){ if (!isset($_POST['fastrec_checkbox'])) {
case'ogm': switch($_POST['container']){
$container = $_POST['container']; case'ogm':
break; $container = $_POST['container'];
case'jpg': break;
$container = $_POST['container']; case'jpg':
break; $container = $_POST['container'];
case'mov': break;
$container = $_POST['container']; case'mov':
break; $container = $_POST['container'];
default: break;
$container = "mov"; default:
break; $container = "mov";
break;
}
$rawdev_path = "";
$prefix = $_POST['prefix'];
} else {
// fast recording supports jpeg format only
$container = "jpeg";
$rawdev_path = $_POST['rawdev_path'];
$prefix = "";
} }
if ($camogm_running) { if ($camogm_running) {
// set format // set format
fprintf($fcmd, "format=%s;\n", $container); fprintf($fcmd, "format=%s;\n", $container);
// set record directory // set record directory
$prefix = $_POST['prefix']; if ($prefix != "") {
fprintf($fcmd, "prefix=%s;\n", $prefix); fprintf($fcmd, "prefix=%s;\n", $prefix);
setcookie("directory", $prefix); // save as cookie so we can get prefered record directory even after camera reboot setcookie("directory", $prefix); // save as cookie so we can get prefered record directory even after camera reboot
}
//set debug file //set debug file
$debug = $_POST['debug']; $debug = $_POST['debug'];
...@@ -150,6 +160,11 @@ ...@@ -150,6 +160,11 @@
} }
else else
fprintf($fcmd, "debug;\ndebuglev=1;\n"); fprintf($fcmd, "debug;\ndebuglev=1;\n");
if ($rawdev_path != "")
fprintf($fcmd, "rawdev_path=%s;\n", $rawdev_path);
else
fprintf($fcmd, "rawdev_path;\n");
} }
} }
...@@ -573,7 +588,7 @@ ...@@ -573,7 +588,7 @@
else else
echo "<input type=\"radio\" id=\"radioJpg\" style=\"top:3px; position:relative;\" name=\"container\" value=\"jpg\" onChange=\"format_changed(this);\"> JPEG Sequence<br />"; echo "<input type=\"radio\" id=\"radioJpg\" style=\"top:3px; position:relative;\" name=\"container\" value=\"jpg\" onChange=\"format_changed(this);\"> JPEG Sequence<br />";
?> ?>
<input id="fast_rec" type="checkbox" style="left:1px; top:3px; position:relative;" name="" value="" onChange="fast_rec_changed(this)"> Use fast recording <input id="fast_rec" type="checkbox" style="left:1px; top:3px; position:relative;" name="fastrec_checkbox" value="checked" onChange="fast_rec_changed(this)" checked="checked"> Use fast recording
<a href="#" onClick="help('fast_rec');"><img src="images/help.png"></a><br /> <a href="#" onClick="help('fast_rec');"><img src="images/help.png"></a><br />
<br /> <br />
...@@ -594,7 +609,7 @@ ...@@ -594,7 +609,7 @@
</select> </select>
<a href="#" onClick="help('debug');"><img src="images/help.png"></a><br /> <a href="#" onClick="help('debug');"><img src="images/help.png"></a><br />
<br /> <br />
<input name="settings_format" type="submit" value="OK"> <input id="submit_button" name="settings_format" type="submit" value="OK">
</form> </form>
</div> </div>
<div class="TabbedPanelsContent"> <div class="TabbedPanelsContent">
......
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