mirror of
https://github.com/eddyem/CCD_Capture.git
synced 2026-08-12 09:49:25 +03:00
fixed SHM deadlock, need to fix more troubles
This commit is contained in:
@@ -49,7 +49,7 @@ set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
# cmake -DDEBUG=yes -> debugging
|
||||
if(DEBUG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g3 -ggdb -Werror")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb -Werror")
|
||||
add_definitions(-DEBUG)
|
||||
set(CMAKE_BUILD_TYPE DEBUG)
|
||||
set(CMAKE_VERBOSE_MAKEFILE "ON")
|
||||
|
||||
@@ -31,10 +31,10 @@ extern cc_Wheel wheel;
|
||||
|
||||
// flags for image processing
|
||||
typedef enum{
|
||||
IM_ERROR,
|
||||
IM_SLEEP,
|
||||
IM_STARTED,
|
||||
IM_READY,
|
||||
IM_ERROR
|
||||
} imstate_t;
|
||||
|
||||
// devices
|
||||
@@ -63,10 +63,7 @@ static double exptime = 0., starttime = 0.;
|
||||
// return constant string with error code description
|
||||
static const char *errcode(int ecode){
|
||||
switch(ecode){
|
||||
#ifndef STR
|
||||
#define STR(par) # par
|
||||
#endif
|
||||
#define ECASE(code) case code: return STR(code)
|
||||
#define ECASE(code) case code: return # code
|
||||
ECASE(S_OK);
|
||||
ECASE(S_FALSE);
|
||||
ECASE(E_UNEXPECTED);
|
||||
@@ -131,6 +128,7 @@ static void camclose(){
|
||||
free(toupcam.data);
|
||||
toupcam.data = NULL;
|
||||
}
|
||||
toupcam.state = IM_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +239,20 @@ static int campoll(cc_capture_status *st, float *remain){
|
||||
static void EventCallback(unsigned nEvent, void _U_ *pCallbackCtx){
|
||||
DBG("CALLBACK with evt %d", nEvent);
|
||||
if(!toupcam.hcam || !toupcam.data){ DBG("NO data!"); return; }
|
||||
if(nEvent != TOUPCAM_EVENT_IMAGE){ DBG("Not image event"); return; }
|
||||
switch(nEvent){
|
||||
case TOUPCAM_EVENT_DISCONNECTED:
|
||||
WARNX(_("Camera disconnected"));
|
||||
camclose();
|
||||
return;
|
||||
case TOUPCAM_EVENT_ERROR:
|
||||
WARNX(_("Error occured"));
|
||||
camcancel();
|
||||
case TOUPCAM_EVENT_IMAGE:
|
||||
break;
|
||||
default:
|
||||
DBG("Not an image event");
|
||||
return;
|
||||
}
|
||||
ToupcamFrameInfoV4 info = {0};
|
||||
//DBG("LOCK");
|
||||
pthread_mutex_lock(&toupcam.mutex);
|
||||
|
||||
218
ccdcapture.c
218
ccdcapture.c
@@ -49,36 +49,56 @@ static sem_t *sem = SEM_FAILED;
|
||||
// client-side SHM lock
|
||||
int cc_lock_shm(int isserver){
|
||||
if(sem == SEM_FAILED){
|
||||
LOGERR("cc_lock_shm(): can't lock NULL");
|
||||
DBG("Can't lock NULL");
|
||||
return FALSE;
|
||||
}
|
||||
struct timespec ts = {.tv_sec = 0, .tv_nsec = 10000000};
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts); // sem_timedwait waits for absolute time!
|
||||
ts.tv_nsec += 100000000; // 100 ms
|
||||
if(ts.tv_nsec > 999999999){
|
||||
ts.tv_nsec -= 1000000000;
|
||||
++ts.tv_sec;
|
||||
}
|
||||
#ifdef EBUG
|
||||
double tstart = sl_dtime();
|
||||
#endif
|
||||
DBG("Try to lock");
|
||||
if(isserver){
|
||||
int locked = TRUE;
|
||||
while(sem_timedwait(sem, &ts) && locked){
|
||||
switch(errno){
|
||||
case EINTR:
|
||||
DBG("Interrupt -> try to lock again");
|
||||
break;
|
||||
default: // timeout or other error -> force locking
|
||||
DBG("Error locking -> force unlock");
|
||||
locked = FALSE;
|
||||
int locked = TRUE;
|
||||
while(locked){
|
||||
if(0 == sem_timedwait(sem, &ts)){
|
||||
locked = FALSE;
|
||||
break;
|
||||
}
|
||||
DBG("Errno=%d (%s)", errno, strerror(errno));
|
||||
if(errno == EINTR){
|
||||
DBG("Interrupt -> try to lock again");
|
||||
}else{
|
||||
if(errno == ENOENT || errno == EINVAL){
|
||||
DBG("No semaphore -> can't lock");
|
||||
LOGERR("cc_lock_shm(): no semaphore -> can't lock");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if(locked){
|
||||
double t0 = sl_dtime();
|
||||
while(sem_trywait(sem) && sl_dtime() - t0 < 0.1) sem_post(sem); // force locking
|
||||
if(sl_dtime() - t0 >= 0.1) return FALSE; // can't lock - timeout
|
||||
}
|
||||
}else{
|
||||
if(sem_timedwait(sem, &ts)){
|
||||
DBG("Image semaphore is locked too long by other side");
|
||||
return FALSE; // can't lock
|
||||
DBG("Error locking -> %s", (isserver) ? "force unlock" : "exit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG("Semaphore locked");
|
||||
return TRUE;
|
||||
DBG("locked=%d; time=%g", locked, sl_dtime() - tstart);
|
||||
if(!locked){
|
||||
DBG("Semaphore locked");
|
||||
return TRUE;
|
||||
}
|
||||
if(isserver){
|
||||
double t0 = sl_dtime();
|
||||
LOGERR("cc_lock_shm(): still locked -> force unlock");
|
||||
while(sem_trywait(sem) && sl_dtime() - t0 < 0.1) sem_post(sem); // force locking
|
||||
if(sl_dtime() - t0 >= 0.1){
|
||||
LOGERR("cc_lock_shm(): failed to unlock");
|
||||
}
|
||||
}else{
|
||||
DBG("Image semaphore is locked too long by other side");
|
||||
}
|
||||
return FALSE; // can't lock
|
||||
}
|
||||
|
||||
void cc_unlock_shm(){
|
||||
@@ -89,10 +109,11 @@ void cc_unlock_shm(){
|
||||
if(sem_post(sem)){
|
||||
switch(errno){
|
||||
case EOVERFLOW: // already unlocked
|
||||
DBG("Already unlocked");
|
||||
break;
|
||||
default: // not a valid? or other?
|
||||
WARN(_("Can't unlock image semaphore"));
|
||||
LOGERR("Can't unlock image semaphore");
|
||||
ERR(_("Can't unlock image semaphore (is server alive?)"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -109,16 +130,21 @@ void cc_init_sem(int isserver){
|
||||
sem = sem_open(SEM_NAME, 0);
|
||||
}
|
||||
if(sem == SEM_FAILED){
|
||||
LOGERR("sem_open failed: %s", strerror(errno));
|
||||
WARNX("sem_open() failed: %s", strerror(errno));
|
||||
LOGERR("sem_open() failed: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void cc_remove_sem(){
|
||||
if(sem == SEM_FAILED) return;
|
||||
sem_close(sem);
|
||||
if(sem != SEM_FAILED){
|
||||
sem_post(sem); // try to unlock if it was locked
|
||||
sem_close(sem);
|
||||
}
|
||||
DBG("semaphore closed\n");
|
||||
if(-1 == sem_unlink(SEM_NAME))
|
||||
if(-1 == sem_unlink(SEM_NAME)){
|
||||
LOGERR("Can't delete semaphore");
|
||||
WARNX(_("Can't delete semaphore"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,6 +201,10 @@ int cc_open_socket(int isserver, char *path, int isnet){
|
||||
WARN("socket()");
|
||||
continue;
|
||||
}
|
||||
int bufsz = 33554432; // 32MB for buffer size
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsz, sizeof(int));
|
||||
bufsz = 33554432;
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsz, sizeof(int));
|
||||
if(isserver){
|
||||
int reuseaddr = 1;
|
||||
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){
|
||||
@@ -219,6 +249,10 @@ int cc_senddata(int fd, void *data, size_t l){
|
||||
while(total < l){
|
||||
ssize_t sent = send(fd, (char*)data + total, l - total, MSG_NOSIGNAL);
|
||||
if(sent <= 0){
|
||||
if(errno == EAGAIN){
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
WARN("send()");
|
||||
LOGWARN("send()");
|
||||
break; // error
|
||||
@@ -339,12 +373,8 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
|
||||
int shmid = -1;
|
||||
int flags = (imsize) ? IPC_CREAT | 0666 : 0;
|
||||
shmid = shmget(key, 0, flags);
|
||||
if(shmid < 0 && imsize == 0){ // no SHM segment for client
|
||||
WARN(_("Can't get shared memory segment %d"), key);
|
||||
return NULL;
|
||||
}
|
||||
struct shmid_ds buf;
|
||||
if(imsize){ // check if segment exists and its size equal to needs
|
||||
struct shmid_ds buf;
|
||||
if(shmctl(shmid, IPC_STAT, &buf) > -1 && shmsize != buf.shm_segsz){ // remove already existing segment
|
||||
DBG("Need to remove already existing segment");
|
||||
shmctl(shmid, IPC_RMID, NULL);
|
||||
@@ -355,11 +385,18 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
|
||||
return NULL;
|
||||
}
|
||||
}else{
|
||||
#ifdef EBUG
|
||||
struct shmid_ds buf;
|
||||
if(shmctl(shmid, IPC_STAT, &buf)) WARNX(_("Can't get SHM data"));
|
||||
else DBG("SHM size = %zd", buf.shm_segsz);
|
||||
#endif
|
||||
if(shmid < 0){ // no SHM segment for client
|
||||
WARN(_("Can't get shared memory segment %d"), key);
|
||||
return NULL;
|
||||
}
|
||||
if(shmctl(shmid, IPC_STAT, &buf)){
|
||||
WARNX(_("Can't get SHM data"));
|
||||
return NULL;
|
||||
}else DBG("SHM size = %zd", buf.shm_segsz);
|
||||
if(buf.shm_perm.mode & SHM_DEST){
|
||||
WARNX(_("SHM buffer marked for deletion"));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode
|
||||
cc_IMG *ptr = shmat(shmid, NULL, 0);
|
||||
@@ -368,7 +405,7 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
|
||||
return NULL;
|
||||
}
|
||||
if(!imsize){
|
||||
if(ptr->MAGICK != CC_SHM_MAGIC){
|
||||
if(ptr->MAGICK != CC_SHM_MAGIC || buf.shm_segsz < ptr->bytelen + sizeof(cc_IMG)){
|
||||
WARNX(_("Shared memory %d isn't belongs to image server"), key);
|
||||
shmdt(ptr);
|
||||
return NULL;
|
||||
@@ -953,3 +990,106 @@ cc_hresult cc_plugin_customcmd(const char *str, cc_parhandler_t *handlers, cc_ch
|
||||
#undef ADDL
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief cc_newimage - create new empty image
|
||||
* @param bitpix - 8 or 16
|
||||
* @param w - width
|
||||
* @param h - height
|
||||
* @return pointer to allocated image or NULL if failed
|
||||
*/
|
||||
cc_IMG *cc_newimage(uint8_t bitpix, int w, int h){
|
||||
FNAME();
|
||||
if(w < 1 || h < 1){
|
||||
DBG("Error: w=%d, h=%d", w, h);
|
||||
return NULL;
|
||||
}
|
||||
cc_IMG *newima = calloc(1, sizeof(cc_IMG));
|
||||
if(!newima){
|
||||
WARN("calloc()");
|
||||
return FALSE;
|
||||
}
|
||||
int N = bitpix / 8;
|
||||
if(N < 1 || N > 2){
|
||||
DBG("Error: %d bytes per pixel", N);
|
||||
free(newima);
|
||||
return NULL;
|
||||
}
|
||||
size_t ds = N * w * h;
|
||||
newima->data = calloc(1, ds);
|
||||
if(!newima->data){
|
||||
WARN("calloc()");
|
||||
free(newima);
|
||||
return NULL;
|
||||
}
|
||||
newima->datasize = newima->bytelen = ds;
|
||||
newima->w = w;
|
||||
newima->h = h;
|
||||
newima->MAGICK = CC_SHM_MAGIC;
|
||||
pthread_mutex_init(&newima->mutex, NULL);
|
||||
DBG("Created new image %dx%d", w, h);
|
||||
return newima;
|
||||
}
|
||||
|
||||
void cc_freeimage(cc_IMG **i){
|
||||
if(!i || !*i) return;
|
||||
cc_IMG *ptr = *i;
|
||||
free(ptr->data);
|
||||
free(ptr);
|
||||
*i = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief cc_copyimage - copy `src` to `dest`
|
||||
* @param dest - destination (dest->data would be reallocated if not enough)
|
||||
* @param src - source image
|
||||
* @param isshm - ==TRUE if `src` is in shared memory
|
||||
* @return FALSE if failed
|
||||
*/
|
||||
int cc_copyimage(cc_IMG *dest, cc_IMG *src, int isshm){
|
||||
FNAME();
|
||||
if(!src || !dest || !src->data) return FALSE;
|
||||
if(src->MAGICK != CC_SHM_MAGIC){
|
||||
WARNX(_("Wrong image: bad magick (0x%X instead of 0x%X)"), src->MAGICK, CC_SHM_MAGIC);
|
||||
return FALSE;
|
||||
}
|
||||
if(src->bytelen < 1){
|
||||
WARNX(_("Wrong image size"));
|
||||
return FALSE;
|
||||
}
|
||||
DBG("Lock");
|
||||
pthread_mutex_lock(&dest->mutex);
|
||||
if(!dest->data || dest->datasize < src->bytelen){
|
||||
size_t newsz = 1024 * (1 + src->bytelen / 1024);
|
||||
DBG("resize from %zd to %zd bytes", dest->datasize, newsz);
|
||||
void *nxt = realloc(dest->data, newsz);
|
||||
if(!nxt){
|
||||
LOGERR("realloc() failed");
|
||||
WARN("realloc()");
|
||||
pthread_mutex_unlock(&dest->mutex);
|
||||
return FALSE;
|
||||
}
|
||||
dest->data = nxt;
|
||||
dest->datasize = newsz;
|
||||
DBG("Success");
|
||||
}
|
||||
DBG("Copy fields");
|
||||
#define COPY(field) dest->field = src->field;
|
||||
COPY(timestamp);
|
||||
COPY(bitpix);
|
||||
COPY(w);
|
||||
COPY(h);
|
||||
COPY(bytelen);
|
||||
COPY(imnumber);
|
||||
#undef COPY
|
||||
DBG("Copy %zd bytes of data", src->bytelen);
|
||||
void *srcdata = src->data;
|
||||
if(isshm){
|
||||
srcdata = (void*)((uint8_t*)src + sizeof(cc_IMG));
|
||||
DBG("Copy from SHM by offset; srcptr: %p; datastart: %p, offset: %zd", src, srcdata, sizeof(cc_IMG));
|
||||
}
|
||||
memcpy(dest->data, srcdata, src->bytelen);
|
||||
DBG("All OK");
|
||||
pthread_mutex_unlock(&dest->mutex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
20
ccdcapture.h
20
ccdcapture.h
@@ -34,20 +34,22 @@
|
||||
#define SEM_NAME "ccdcapture"
|
||||
|
||||
// base image parameters - sent by socket and stored in shared memory
|
||||
typedef struct __attribute__((packed)){
|
||||
typedef struct{ // __attribute__((packed))
|
||||
uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm
|
||||
pthread_mutex_t mutex; // mutex for working with image data
|
||||
double timestamp; // timestamp of image taken
|
||||
uint8_t bitpix; // bits per pixel (8 or 16)
|
||||
int w, h; // image size
|
||||
int gotstat; // stat counted
|
||||
size_t bytelen; // size of image in bytes
|
||||
size_t datasize; // size of `data` buffer
|
||||
size_t imnumber; // counter of images captured from server's start
|
||||
uint8_t bitpix; // bits per pixel (8 or 16)
|
||||
uint16_t max, min; // min/max values
|
||||
float avr, std; // statistics
|
||||
size_t bytelen; // size of image in bytes
|
||||
size_t imnumber; // counter of images captured from server's start
|
||||
void *data; // pointer to data (next byte after this struct) - only for server
|
||||
/* `data` is uint8_t or uint16_t depending on `bitpix` */
|
||||
char fitsheader[FITS_HEADER_STRINGS_MAX][FLEN_CARD]; // FITS-header for given image
|
||||
size_t headerstrings; // amount of records in header
|
||||
/* `data` is uint8_t or uint16_t depending on `bitpix` */
|
||||
void *data; // pointer to data (next byte after this struct) - only for server
|
||||
char fitsheader[FITS_HEADER_STRINGS_MAX][FLEN_CARD]; // FITS-header for given image
|
||||
} cc_IMG;
|
||||
|
||||
typedef struct{
|
||||
@@ -323,6 +325,10 @@ void cc_charbufaddline(cc_charbuff *b, const char *s);
|
||||
cc_strbuff *cc_strbufnew(size_t size, size_t stringsize);
|
||||
void cc_strbufdel(cc_strbuff **buf);
|
||||
|
||||
cc_IMG *cc_newimage(uint8_t bitpix, int w, int h);
|
||||
int cc_copyimage(cc_IMG *dest, cc_IMG *src, int isshm);
|
||||
void cc_freeimage(cc_IMG **i);
|
||||
|
||||
const char *cc_hresult2str(cc_hresult r);
|
||||
cc_hresult cc_str2hresult(const char *str);
|
||||
int cc_setNtries(int n);
|
||||
|
||||
41
ccdfunc.c
41
ccdfunc.c
@@ -196,6 +196,7 @@ do{ int status = 0, kt = 0; \
|
||||
// return FALSE if failed
|
||||
int saveFITS(cc_IMG *img, char **outp){
|
||||
int ret = FALSE;
|
||||
if(!img || !img->data || !outp) return FALSE;
|
||||
char fnam[PATH_MAX+1];
|
||||
if(!GP->outfile && !GP->outfileprefix){
|
||||
LOGWARN("Image not saved: neither filename nor filename prefix pointed");
|
||||
@@ -221,6 +222,7 @@ int saveFITS(cc_IMG *img, char **outp){
|
||||
LOGERR("Can't save image with prefix %s", GP->outfileprefix);
|
||||
}
|
||||
}
|
||||
pthread_mutex_lock(&img->mutex);
|
||||
int width = img->w, height = img->h;
|
||||
long naxes[2] = {width, height};
|
||||
struct tm *tm_time;
|
||||
@@ -275,6 +277,7 @@ fits_write_history(fp, bufhdr->buf, &s);
|
||||
if(fitserror) goto cloerr;
|
||||
TRYFITS(fits_close_file, fp);
|
||||
cloerr:
|
||||
pthread_mutex_unlock(&img->mutex);
|
||||
if(fitserror == 0){
|
||||
LOGMSG("Save file '%s'", fnam);
|
||||
verbose(VERBOSE_PRIMARY, _("File saved as '%s'"), fnam);
|
||||
@@ -839,17 +842,16 @@ static volatile int exitgrab = FALSE;
|
||||
static volatile size_t lastgrabno = 0;
|
||||
static void *grabnext(void *arg){
|
||||
FNAME();
|
||||
cc_IMG *ima = (cc_IMG*) arg;
|
||||
if(!arg) return NULL;
|
||||
cc_IMG *ima = (cc_IMG*)arg;
|
||||
do{
|
||||
if(exitgrab) return NULL;
|
||||
TIMESTAMP("Start next exp");
|
||||
TIMEINIT();
|
||||
if(!ima || !camera) return NULL;
|
||||
if(!camera) return NULL;
|
||||
if(!camera->startexposition) ERRX(_("Camera plugin have no function `start exposition`"));
|
||||
if(!camera->startexposition()){
|
||||
WARNX(_("Can't start exposition"));
|
||||
usleep(10000);
|
||||
continue;
|
||||
ERRX(_("Can't start exposition"));
|
||||
}
|
||||
cc_capture_status cs = CAPTURE_ABORTED;
|
||||
TIMESTAMP("Poll");
|
||||
@@ -866,6 +868,7 @@ static void *grabnext(void *arg){
|
||||
//calculate_stat(ima);
|
||||
TIMESTAMP("OK");
|
||||
}while(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -875,7 +878,7 @@ static void *grabnext(void *arg){
|
||||
* @param img - pointer to cc_IMG* (if cc_IMG* is NULL, will be allocated here)
|
||||
* @return TRUE if new image available
|
||||
*/
|
||||
int ccdcaptured(cc_IMG **imgptr){
|
||||
int ccdcaptured(cc_IMG *imgptr){
|
||||
if(!imgptr) return FALSE;
|
||||
//TIMESTAMP("ccdcaptured() start");
|
||||
static pthread_t grabthread = 0;
|
||||
@@ -891,32 +894,21 @@ int ccdcaptured(cc_IMG **imgptr){
|
||||
DBG("OK");
|
||||
return FALSE;
|
||||
}
|
||||
cc_frameformat fmt = camera->geometry;
|
||||
int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin;
|
||||
cc_IMG *ima = NULL;
|
||||
if(*imgptr && ((*imgptr)->w != raw_width || (*imgptr)->h != raw_height)) FREE(*imgptr);
|
||||
if(!*imgptr){
|
||||
uint16_t *img = MALLOC(uint16_t, raw_width * raw_height);
|
||||
DBG("\n\nAllocated image 2x%dx%d=%d", raw_width, raw_height, 2 * raw_width * raw_height);
|
||||
ima = MALLOC(cc_IMG, 1);
|
||||
ima->data = img;
|
||||
ima->w = raw_width;
|
||||
ima->h = raw_height;
|
||||
*imgptr = ima;
|
||||
}else ima = *imgptr;
|
||||
//cc_frameformat fmt = camera->geometry;
|
||||
//int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin;
|
||||
|
||||
if(!grabthread){ // start new grab
|
||||
TIMESTAMP("Start new grab");
|
||||
TIMEINIT();
|
||||
if(pthread_create(&grabthread, NULL, &grabnext, (void*)ima)){
|
||||
if(pthread_create(&grabthread, NULL, &grabnext, (void*)imgptr)){
|
||||
WARN(_("Can't create grabbing thread"));
|
||||
grabthread = 0;
|
||||
}
|
||||
}else{ // grab in process
|
||||
if(ima->imnumber != lastgrabno){ // done
|
||||
if(imgptr->imnumber != lastgrabno){ // done
|
||||
/*ssize_t delta = ima->imnumber - lastgrabno;
|
||||
if(delta > 0 && delta != 1) WARNX("ccdcaptured(): missed %zd images", delta-1);*/
|
||||
lastgrabno = ima->imnumber;
|
||||
lastgrabno = imgptr->imnumber;
|
||||
TIMESTAMP("Got exp #%zd", lastgrabno);
|
||||
framerate();
|
||||
return TRUE;
|
||||
@@ -963,9 +955,6 @@ int start_socket(int isserver){
|
||||
}
|
||||
DBG("Close socket");
|
||||
close(sock);
|
||||
if(isserver){
|
||||
close(imsock);
|
||||
signals(0);
|
||||
}
|
||||
if(isserver) close(imsock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ void closewheel();
|
||||
void closecam();
|
||||
#ifdef IMAGEVIEW
|
||||
void framerate();
|
||||
int ccdcaptured(cc_IMG **img);
|
||||
int ccdcaptured(cc_IMG *img);
|
||||
#endif
|
||||
|
||||
int start_socket(int isserver);
|
||||
|
||||
374
client.c
374
client.c
@@ -51,9 +51,7 @@ static int xc0,yc0,xc1,yc1; // current format
|
||||
static volatile atomic_int grabno = 0;
|
||||
static int oldgrabno = 0;
|
||||
// IPC key for shared memory
|
||||
static cc_IMG ima = {0}, *shmima = NULL; // ima - local storage, shmima - shm (if available)
|
||||
static size_t imbufsz = 0; // image buffer for allocated `ima`
|
||||
static uint8_t *imbuf = NULL; // we can't use shmima->data as it belongs to server, so we use `imbuf` and set ima.data = imbuf
|
||||
static cc_IMG *locima = NULL, *shmima = NULL; // ima - local storage, shmima - shm (if available)
|
||||
static volatile atomic_int current_image_number = -1; // for net-parser - last number of exposed image
|
||||
|
||||
#if 0
|
||||
@@ -82,7 +80,7 @@ static char *readmsg(int fd){
|
||||
#endif
|
||||
|
||||
#define CMP_ANS(cmd, ans) strncmp(cmd, ans, sizeof(cmd)-1)
|
||||
// parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY')
|
||||
// parser of CCD server messages; return parsing result
|
||||
static cc_hresult parseans(char *ans){
|
||||
if(!ans) return CC_RESULT_BADKEY;
|
||||
//TIMESTAMP("parseans() begin");
|
||||
@@ -97,18 +95,17 @@ static cc_hresult parseans(char *ans){
|
||||
}
|
||||
char *val = cc_get_keyval(&ans); // now `ans` is a key and `val` its value
|
||||
if(0 == CMP_ANS(CC_CMD_EXPSTATE, ans)){
|
||||
int st = atoi(val);
|
||||
atomic_store(&expstate, st);
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
return CC_RESULT_SILENCE;
|
||||
int st = atoi(val), oldst = atomic_load(&expstate);
|
||||
if(oldst != CAMERA_FRAMERDY){
|
||||
atomic_store(&expstate, st);
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
}
|
||||
}else if(0 == CMP_ANS(CC_CMD_FRAMEMAX, ans)){
|
||||
sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1);
|
||||
DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1);
|
||||
return CC_RESULT_SILENCE;
|
||||
}else if(0 == CMP_ANS(CC_CMD_FRAMEFORMAT, ans)){
|
||||
sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1);
|
||||
DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1);
|
||||
return CC_RESULT_SILENCE;
|
||||
}else if(0 == CMP_ANS(CC_CMD_IMNUMBER, ans)){
|
||||
atomic_store(¤t_image_number, atoi(val));
|
||||
}
|
||||
@@ -120,46 +117,62 @@ static cc_hresult parseans(char *ans){
|
||||
// if msg != NULL - wait for it in answer
|
||||
static int getans(int sock, const char *msg){
|
||||
double t0 = sl_dtime();
|
||||
char buf[BUFSIZ+1];
|
||||
int idx = 0;
|
||||
char *ans = NULL;
|
||||
static sl_ringbuffer_t *RB = NULL;
|
||||
if(!RB){
|
||||
RB = sl_RB_new(BUFSIZ);
|
||||
if(!RB){
|
||||
WARNX(_("Can't allocate buffer"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
TIMESTAMP("GetAns(%s)", msg);
|
||||
double tmout = answer_timeout + 5.; // make first timeout larger for slow networks
|
||||
// TODO: increase first timeout up to 15-30s (add key?)
|
||||
cc_hresult res = CC_RESULT_FAIL;
|
||||
char buf[256];
|
||||
while(sl_dtime() - t0 < tmout){
|
||||
ans = NULL;
|
||||
if(1 == sl_canread(sock)){
|
||||
ssize_t got = read(sock, buf+idx, BUFSIZ-idx);
|
||||
ssize_t got = read(sock, buf, 255);
|
||||
if(got > 0){
|
||||
idx += got;
|
||||
buf[idx] = 0;
|
||||
char *nl = strchr(buf, '\n');
|
||||
if(nl){
|
||||
*nl = 0;
|
||||
ans = buf;
|
||||
DBG("got '%s'", ans);
|
||||
DBG("Got %zd bytes (%s)", got, buf);
|
||||
if(got != (ssize_t)sl_RB_write(RB, (uint8_t*)buf, got)){
|
||||
WARNX("Ringbuffer overflow??");
|
||||
sl_RB_clearbuf(RB);
|
||||
return FALSE;
|
||||
}
|
||||
}else if(got < 0){
|
||||
DBG("ERR: got=%zd", got);
|
||||
if(errno == EAGAIN){
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
WARNX(_("Server disconnected?"));
|
||||
LOGWARN("Server disconnected?");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if(!ans) continue;
|
||||
if(sl_RB_hasbyte(RB, '\n') < 0) continue;
|
||||
DBG("Got newline in RB");
|
||||
if(sl_RB_readline(RB, buf, 255) < 1){
|
||||
WARNX(_("Got empty string"));
|
||||
continue;
|
||||
}
|
||||
// got answer -> make timeout less
|
||||
tmout = answer_timeout;
|
||||
t0 = sl_dtime();
|
||||
TIMESTAMP("Got from server: %s", ans);
|
||||
verbose(VERBOSE_PRIMARY, "\t%s", ans);
|
||||
DBG("1 msg-> %s, ans -> %s", msg, ans);
|
||||
res = parseans(ans);
|
||||
DBG("2 msg-> %s, ans -> %s; result: %d", msg, ans, res);
|
||||
TIMESTAMP("Got from server: %s", buf);
|
||||
verbose(VERBOSE_PRIMARY, "\t%s", buf);
|
||||
DBG("1 msg-> %s, ans -> %s", msg, buf);
|
||||
res = parseans(buf);
|
||||
DBG("2 msg-> %s, ans -> %s; result: %d", msg, buf, res);
|
||||
if(msg){
|
||||
if(res != CC_RESULT_SILENCE || strncmp(ans, msg, strlen(msg))) continue;
|
||||
if(res != CC_RESULT_SILENCE || strncmp(buf, msg, strlen(msg))) continue;
|
||||
else res = CC_RESULT_OK;
|
||||
}
|
||||
DBG("Got answer -> break");
|
||||
break;
|
||||
}
|
||||
TIMESTAMP("GetAns(%s), ans: '%s', result: %d", msg, ans, res);
|
||||
if(!ans) DBG("Got no answer from server; result=%d", res);
|
||||
TIMESTAMP("GetAns(%s), result: %d", msg, res);
|
||||
if(res == CC_RESULT_OK) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -269,7 +282,6 @@ static int readNbytes(int fd, size_t N, uint8_t *buf){
|
||||
size_t got = 0, need = N;
|
||||
double t0 = sl_dtime();
|
||||
while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& sl_canread(fd)*/ && need){
|
||||
t0 = sl_dtime();
|
||||
ssize_t rd = read(fd, buf + got, need);
|
||||
if(rd <= 0){
|
||||
if(errno == EAGAIN || errno == EWOULDBLOCK) continue;
|
||||
@@ -277,11 +289,119 @@ static int readNbytes(int fd, size_t N, uint8_t *buf){
|
||||
signals(1);
|
||||
}
|
||||
got += rd; need -= rd;
|
||||
t0 = sl_dtime();
|
||||
}
|
||||
if(need) return FALSE; // didn't got whole packet
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int refresh_shm(){
|
||||
if(!shmima){
|
||||
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
|
||||
if(shmima){
|
||||
cc_init_sem(FALSE);
|
||||
DBG("Got access to shared memory");
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
int shmid = shmget(GP->shmkey, 0, 0);
|
||||
if(shmid < 0){
|
||||
// Segment was deleted
|
||||
shmdt(shmima);
|
||||
shmima = NULL;
|
||||
// refresh connection
|
||||
return refresh_shm();
|
||||
}
|
||||
struct shmid_ds buf;
|
||||
if(shmctl(shmid, IPC_STAT, &buf) == 0){
|
||||
if(buf.shm_perm.mode & SHM_DEST){ // marked for deletion
|
||||
shmdt(shmima);
|
||||
shmima = NULL;
|
||||
return refresh_shm();
|
||||
}
|
||||
// valid segment
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int lockshm(){
|
||||
int locked = FALSE;
|
||||
double t0 = sl_dtime();
|
||||
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
|
||||
if(cc_lock_shm(FALSE)){
|
||||
DBG("Locked");
|
||||
locked = TRUE;
|
||||
break;
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
if(!locked) WARNX(_("Can't lock shared memory"));
|
||||
return locked;
|
||||
}
|
||||
|
||||
static int getshmimage(int *shmlocked){
|
||||
if(!shmlocked || !shmima) return FALSE;
|
||||
if(!refresh_shm()) return FALSE;
|
||||
if(!*shmlocked && !(*shmlocked = lockshm())) return FALSE;
|
||||
DBG("Server's imno: %zd, bytelen: %zd", shmima->imnumber, shmima->bytelen);
|
||||
int ret = cc_copyimage(locima, shmima, TRUE);
|
||||
TIMESTAMP("Got by shared memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int getsocksizes(int *imsock){
|
||||
if(!imsock || *imsock > -1) return FALSE;
|
||||
DBG("Open socket @ %s", GP->imageport);
|
||||
*imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
|
||||
if(*imsock < 0){
|
||||
WARNX(_("Can't open image transport socket"));
|
||||
return FALSE;
|
||||
}
|
||||
// get image size
|
||||
cc_IMG ima;
|
||||
if(!readNbytes(*imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
|
||||
WARNX(_("Can't read image header over socket"));
|
||||
return FALSE;
|
||||
}
|
||||
if(ima.MAGICK != CC_SHM_MAGIC || ima.bytelen < 1) return FALSE;
|
||||
// now copy fields
|
||||
#define COPY(field) locima->field = ima.field;
|
||||
COPY(timestamp);
|
||||
COPY(bitpix);
|
||||
COPY(w);
|
||||
COPY(h);
|
||||
COPY(bytelen);
|
||||
COPY(imnumber);
|
||||
#undef COPY
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int getsockimage(int *imsock){
|
||||
if(!imsock || *imsock < 0) return FALSE;
|
||||
pthread_mutex_lock(&locima->mutex);
|
||||
if(locima->datasize < locima->bytelen){
|
||||
size_t newsz = 1024 * (1 + locima->bytelen / 1024);
|
||||
void *nxt = realloc(locima->data, newsz);
|
||||
if(!nxt){
|
||||
LOGERR("realloc() failed");
|
||||
WARN("realloc()");
|
||||
pthread_mutex_unlock(&locima->mutex);
|
||||
return FALSE;
|
||||
}
|
||||
locima->data = nxt;
|
||||
}
|
||||
int ok = readNbytes(*imsock, locima->bytelen, locima->data);
|
||||
pthread_mutex_unlock(&locima->mutex);
|
||||
if(!ok){
|
||||
WARNX(_("Can't read image data"));
|
||||
return FALSE;
|
||||
}
|
||||
TIMESTAMP("Got by socket");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getimage - read image from shared memory or socket
|
||||
* @param askheader == TRUE for storing FITS-header
|
||||
@@ -291,132 +411,85 @@ static int getimage(int askheader){
|
||||
FNAME();
|
||||
int imsock = -1, shmlocked = FALSE, ret = FALSE;
|
||||
static double oldtimestamp = -1.;
|
||||
TIMESTAMP("Get image sizes");
|
||||
if(shmima){ // read image from shared memory
|
||||
DBG("Try to read from SHM");
|
||||
double t0 = sl_dtime();
|
||||
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
|
||||
if(cc_lock_shm(FALSE)){
|
||||
DBG("Locked");
|
||||
shmlocked = TRUE;
|
||||
break;
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
if(!shmlocked){
|
||||
WARNX(_("Can't lock shared memory"));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(&ima, shmima, sizeof(cc_IMG));
|
||||
}else{ // get image by socket
|
||||
if(imsock < 0){
|
||||
DBG("Open socket @ %s", GP->imageport);
|
||||
imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
|
||||
}
|
||||
if(imsock < 0) ERRX(_("getimage(): can't open image transport socket"));
|
||||
// get image size
|
||||
if(!readNbytes(imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
|
||||
WARNX(_("Can't read image header"));
|
||||
goto eofg;
|
||||
TIMESTAMP("Get image sizes (or full image over SHM)");
|
||||
if(!locima){
|
||||
locima = cc_newimage(16, 1024, 1024);
|
||||
if(!locima){
|
||||
WARN("calloc()"); return FALSE;
|
||||
}
|
||||
}
|
||||
if(ima.MAGICK != CC_SHM_MAGIC){
|
||||
WARNX(_("Wrong image: bad magick"));
|
||||
goto eofg;
|
||||
}
|
||||
if(ima.bytelen < 1){
|
||||
WARNX(_("Wrong image size"));
|
||||
goto eofg;
|
||||
}
|
||||
DBG("bytelen=%zd, w=%d, h=%d; bitpix=%d", ima.bytelen, ima.w, ima.h, ima.bitpix);
|
||||
// realloc memory if needed
|
||||
if(imbufsz < ima.bytelen){
|
||||
size_t newsz = 1024 * (1 + ima.bytelen / 1024);
|
||||
DBG("Reallocate memory from %zd to %zd", imbufsz, newsz);
|
||||
uint8_t *b = imbuf;
|
||||
imbuf = realloc(imbuf, imbufsz);
|
||||
if(imbuf){
|
||||
imbufsz = newsz;
|
||||
DBG("Size after realloc: %zd", imbufsz);
|
||||
}else{
|
||||
WARNX(_("Can't reallocate memory for image buffer"));
|
||||
imbuf = b;
|
||||
goto eofg;
|
||||
}
|
||||
}
|
||||
ima.data = imbuf; // renew this value each time after getting `ima` from server
|
||||
TIMESTAMP("Start of data read");
|
||||
if(shmima){
|
||||
uint8_t *datastart = ((uint8_t*)shmima) + sizeof(cc_IMG);
|
||||
DBG("first image byte: %d; bytelen: %zd", *datastart, ima.bytelen);
|
||||
memcpy(imbuf, datastart, ima.bytelen);
|
||||
TIMESTAMP("Got by shared memory");
|
||||
if(!askheader){
|
||||
cc_unlock_shm();
|
||||
shmlocked = FALSE;
|
||||
}
|
||||
ret = TRUE;
|
||||
}else{
|
||||
if(!readNbytes(imsock, ima.bytelen, imbuf)){
|
||||
ret = getshmimage(&shmlocked);
|
||||
if(!ret){ // can't get by shm -> try over NET
|
||||
DBG("Try to get image over network");
|
||||
if(!getsocksizes(&imsock)) goto eofg;
|
||||
TIMESTAMP("Start of data read");
|
||||
ret = getsockimage(&imsock);
|
||||
if(!ret){
|
||||
WARNX(_("Can't read image data"));
|
||||
goto eofg;
|
||||
}
|
||||
ret = TRUE;
|
||||
TIMESTAMP("Got by socket");
|
||||
}
|
||||
DBG("timestamps new-old=%g; imno: %zd", ima.timestamp - oldtimestamp, ima.imnumber);
|
||||
if(ima.timestamp != oldtimestamp){ // test if image is really new
|
||||
oldtimestamp = ima.timestamp;
|
||||
atomic_store(&grabno, ima.imnumber);
|
||||
TIMESTAMP("Got image #%zd", ima.imnumber);
|
||||
DBG("timestamps new-old=%g; imno: %zd", locima->timestamp - oldtimestamp, locima->imnumber);
|
||||
if(locima->timestamp != oldtimestamp){ // test if image is really new
|
||||
oldtimestamp = locima->timestamp;
|
||||
atomic_store(&grabno, locima->imnumber);
|
||||
TIMESTAMP("Got image #%zd", locima->imnumber);
|
||||
if(askheader){ // read FITS-header for later saving
|
||||
if(shmima){
|
||||
size_t rsz = FLEN_CARD * ima.headerstrings;
|
||||
memcpy(ima.fitsheader, shmima->fitsheader, rsz);
|
||||
if(locima->headerstrings > FITS_HEADER_STRINGS_MAX){
|
||||
WARNX(_("Too many FITS headers, truncating"));
|
||||
locima->headerstrings = FITS_HEADER_STRINGS_MAX;
|
||||
}
|
||||
size_t rsz = FLEN_CARD * locima->headerstrings;
|
||||
memcpy(locima->fitsheader, shmima->fitsheader, rsz);
|
||||
cc_unlock_shm();
|
||||
shmlocked = FALSE;
|
||||
}else{
|
||||
uint8_t card[FLEN_CARD];
|
||||
for(size_t i = 0; i < ima.headerstrings; ++i){
|
||||
for(size_t i = 0; i < locima->headerstrings; ++i){
|
||||
if(!readNbytes(imsock, FLEN_CARD, card)){
|
||||
WARNX(_("Can't read full header, got %zd records from %zd"), i, ima.headerstrings);
|
||||
WARNX(_("Can't read full header, got %zd records from %zd"), i, locima->headerstrings);
|
||||
break;
|
||||
}
|
||||
memcpy(&ima.fitsheader[i], card, FLEN_CARD);
|
||||
memcpy(&locima->fitsheader[i], card, FLEN_CARD);
|
||||
}
|
||||
close(imsock);
|
||||
imsock = -1;
|
||||
}
|
||||
if(GP->addhdr){ // add records from client-side files
|
||||
char **nxtfile = GP->addhdr;
|
||||
while(*nxtfile){
|
||||
cc_kwfromfile(&ima, *(nxtfile++));
|
||||
cc_kwfromfile(locima, *(nxtfile++));
|
||||
}
|
||||
}
|
||||
}else ima.headerstrings = 0;
|
||||
}else WARNX("Still got old image");
|
||||
}else locima->headerstrings = 0;
|
||||
}else WARNX(_("Still got old image"));
|
||||
eofg:
|
||||
if(imsock != -1) close(imsock); // reopen in next time in case of error
|
||||
if(imsock > -1) close(imsock); // reopen in next time in case of error
|
||||
if(shmlocked) cc_unlock_shm();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// get number of current image; return number or -1 if got error/timeout
|
||||
// get number of current image
|
||||
static int curImNo(int sock){
|
||||
int N = -1;
|
||||
if(shmima){
|
||||
if(!cc_lock_shm(FALSE)) return -1;
|
||||
int CurNo = shmima->imnumber;
|
||||
cc_unlock_shm();
|
||||
return CurNo;
|
||||
if(lockshm()){
|
||||
N = shmima->imnumber;
|
||||
cc_unlock_shm();
|
||||
atomic_store(¤t_image_number, N);
|
||||
}
|
||||
}
|
||||
// no shared memory: try to get number over TCP
|
||||
SENDCMDW(CC_CMD_IMNUMBER);
|
||||
return atomic_load(¤t_image_number);
|
||||
if(N < 0){ // no shared memory: try to get number over TCP
|
||||
SENDCMDW(CC_CMD_IMNUMBER);
|
||||
N = atomic_load(¤t_image_number);
|
||||
}
|
||||
return N;
|
||||
}
|
||||
|
||||
void client(int sock){
|
||||
if(sock < 0) ERRX(_("Can't run without command socket"));
|
||||
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to force workign through image socket
|
||||
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
|
||||
if(shmima) cc_init_sem(FALSE);
|
||||
DBG("Got access to shared memory: %s", shmima ? "OK" : "FAIL");
|
||||
}
|
||||
if(!GP->forceimsock) refresh_shm(); // init shm buffer if user don't ask to force workign through image socket
|
||||
if(GP->restart){
|
||||
SENDCMDW(CC_CMD_RESTART);
|
||||
return;
|
||||
@@ -426,6 +499,7 @@ void client(int sock){
|
||||
TIMESTAMP("Got headers");
|
||||
double t0 = sl_dtime(), tw, tstart;
|
||||
int Nremain = 0, nframe = 1;
|
||||
atomic_store(&expstate, CAMERA_IDLE); // could be changed earlier
|
||||
// if client gives filename/prefix or Nframes, make exposition
|
||||
if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){
|
||||
Nremain = GP->nframes;
|
||||
@@ -434,7 +508,6 @@ void client(int sock){
|
||||
} else return; // just send headers and exit
|
||||
double timeout = CC_CLIENT_TIMEOUT;
|
||||
verbose(VERBOSE_PRIMARY, _("Exposing frame 1..."));
|
||||
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
verbose(VERBOSE_PRIMARY, _("Wait for exposition end"));
|
||||
t0 = sl_dtime();
|
||||
@@ -443,6 +516,7 @@ void client(int sock){
|
||||
while(sl_dtime() - t0 < timeout){
|
||||
if(sl_dtime() - tw > CC_WAIT_TIMEOUT){
|
||||
SENDCMDW(CC_CMD_TREMAIN); // get remained time
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
tw = sl_dtime();
|
||||
usleep(100000);
|
||||
}
|
||||
@@ -450,9 +524,6 @@ void client(int sock){
|
||||
t0 = sl_dtime(); // refresh timeout until exp not ends
|
||||
usleep(1000);
|
||||
continue;
|
||||
}else{
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
usleep(1000);
|
||||
}
|
||||
int curst = atomic_load(&expstate);
|
||||
DBG("Current state: %d", curst);
|
||||
@@ -465,23 +536,23 @@ void client(int sock){
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(curst == CAMERA_FRAMERDY){
|
||||
int cur = curImNo(sock);
|
||||
if(curst == CAMERA_FRAMERDY || cur != lastImNo){
|
||||
atomic_store(&expstate, CAMERA_IDLE);
|
||||
int cur = curImNo(sock);
|
||||
DBG("Current state: %d, imno: %d", atomic_load(&expstate), cur);
|
||||
DBG("Current imno: %d", cur);
|
||||
if(Nremain > 1){ // start next capture
|
||||
verbose(VERBOSE_PRIMARY, _("Exposing frame %d..."), nframe);
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
|
||||
tstart = sl_dtime();
|
||||
}
|
||||
int failed = TRUE;
|
||||
if(lastImNo < cur){
|
||||
if(lastImNo != cur){
|
||||
lastImNo = cur;
|
||||
verbose(VERBOSE_SECONDARY, _("Frame ready, try to grab"));
|
||||
if(!getimage(TRUE)){
|
||||
WARNX(_("Can't get next image"));
|
||||
}else{
|
||||
if(saveFITS(&ima, &lastfilename)){
|
||||
if(saveFITS(locima, &lastfilename)){
|
||||
--Nremain;
|
||||
++nframe;
|
||||
failed = FALSE;
|
||||
@@ -534,9 +605,8 @@ static void *grabnext(void _U_ *arg){
|
||||
int lastImNo = curImNo(sock);
|
||||
while(1){
|
||||
if(!getWin()) exit(1);
|
||||
TIMESTAMP("End of cycle, start new");
|
||||
atomic_store(&expstate, CAMERA_CAPTURE);
|
||||
DBG("Current state: %d", atomic_load(&expstate));
|
||||
TIMESTAMP("Start of capturing cycle");
|
||||
atomic_store(&expstate, CAMERA_IDLE);
|
||||
TIMEINIT();
|
||||
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture
|
||||
double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime();
|
||||
@@ -547,24 +617,29 @@ static void *grabnext(void _U_ *arg){
|
||||
}
|
||||
TIMESTAMP("Wait for exposition ends (%g s), sleep for %dus", timeout, sleept);
|
||||
int curst = CAMERA_CAPTURE;
|
||||
int cur = lastImNo;
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
while(sl_dtime() - t0 < timeout){
|
||||
DBG("start sleep for %dus", sleept);
|
||||
usleep(sleept);
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
cur = curImNo(sock);
|
||||
curst = atomic_load(&expstate);
|
||||
if(curst != CAMERA_CAPTURE) break;
|
||||
if(curst != CAMERA_CAPTURE || cur != lastImNo) break;
|
||||
if(sl_dtime() - t0 > GP->exptime && sleept != CC_IMWAIT_SLEEP){
|
||||
DBG("Set sleeping time to %dus", sleept);
|
||||
sleept = CC_IMWAIT_SLEEP;
|
||||
DBG("Set sleeping time to %dus", sleept);
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
}
|
||||
}
|
||||
int cur = curImNo(sock);
|
||||
if(sl_dtime() - t0 >= timeout || curst != CAMERA_FRAMERDY || cur <= lastImNo){
|
||||
SENDCMDW(CC_CMD_EXPSTATE);
|
||||
curst = atomic_load(&expstate);
|
||||
if(curst == CAMERA_ERROR) ERRX(_("Camera in error state"));
|
||||
if(sl_dtime() - t0 >= timeout && cur != lastImNo){
|
||||
WARNX(_("Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d (timeout: %g)"), curst, sl_dtime() - t0, lastImNo, cur, timeout);
|
||||
continue;
|
||||
}
|
||||
lastImNo = cur;
|
||||
TIMESTAMP("Frame ready (%d from server's start)", cur);
|
||||
TIMESTAMP("Frame ready (%d from start)", cur);
|
||||
getimage(FALSE);
|
||||
}
|
||||
return NULL;
|
||||
@@ -585,7 +660,7 @@ static void *waitimage(void _U_ *arg){
|
||||
t0 = tcur;
|
||||
}
|
||||
int cur = curImNo(sock);
|
||||
if(cur <= lastImNo){
|
||||
if(cur == lastImNo){
|
||||
usleep(CC_IMWAIT_SLEEP);
|
||||
continue;
|
||||
}
|
||||
@@ -600,7 +675,7 @@ static void *waitimage(void _U_ *arg){
|
||||
}
|
||||
|
||||
// try to capture images for viewer
|
||||
int sockcaptured(cc_IMG **imgptr){
|
||||
int sockcaptured(cc_IMG *imgptr){
|
||||
//TIMESTAMP("sockcaptured() start");
|
||||
if(!imgptr) return FALSE;
|
||||
static pthread_t grabthread = 0;
|
||||
@@ -634,13 +709,12 @@ int sockcaptured(cc_IMG **imgptr){
|
||||
}else{ // grab in process
|
||||
int curno = atomic_load(&grabno);
|
||||
if(curno != oldgrabno){ // image is ready
|
||||
TIMESTAMP("Image #%d ready", curno);
|
||||
if(*imgptr && (*imgptr != &ima)) free(*imgptr);
|
||||
*imgptr = &ima;
|
||||
TIMESTAMP("Image #%d ready (old was %d)", curno, oldgrabno);
|
||||
oldgrabno = curno;
|
||||
framerate();
|
||||
//TIMESTAMP("sockcaptured() end, return TRUE");
|
||||
return TRUE;
|
||||
int ret = cc_copyimage(imgptr, locima, FALSE);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
//TIMESTAMP("sockcaptured() end, return FALSE");
|
||||
|
||||
2
client.h
2
client.h
@@ -24,5 +24,5 @@
|
||||
void client(int fd);
|
||||
#ifdef IMAGEVIEW
|
||||
void init_grab_sock(int sock);
|
||||
int sockcaptured(cc_IMG **img);
|
||||
int sockcaptured(cc_IMG *img);
|
||||
#endif
|
||||
|
||||
92
imageview.c
92
imageview.c
@@ -288,13 +288,15 @@ static void createGLwin(char *title, int w, int h, rawimage *rawdata){
|
||||
if(!initialized) imageview_init();
|
||||
if(win) killwindow();
|
||||
win = MALLOC(windowData, 1);
|
||||
int wh = w * h;
|
||||
win->rawdata = MALLOC(uint8_t, wh);
|
||||
rawimage *raw;
|
||||
if(rawdata){
|
||||
raw = rawdata;
|
||||
}else{
|
||||
raw = MALLOC(rawimage, 1);
|
||||
if(raw){
|
||||
raw->rawdata = MALLOC(GLubyte, w*h*3);
|
||||
raw->rawdata = MALLOC(GLubyte, wh*3);
|
||||
raw->w = w;
|
||||
raw->h = h;
|
||||
raw->changed = 1;
|
||||
@@ -445,15 +447,12 @@ result: 0.0014689s
|
||||
|
||||
/**
|
||||
* @brief equalize - hystogram equalization
|
||||
* @param ori (io) - input/output data
|
||||
* @param w,h - image width and height
|
||||
* @return data allocated here
|
||||
* @param img (i) - input image
|
||||
*/
|
||||
static uint8_t *equalize(cc_IMG *img, int w, int h){
|
||||
uint8_t *retn = MALLOC(uint8_t, w*h);
|
||||
static void equalize(cc_IMG *img){
|
||||
double orig_hysto[0x10000] = {0.}; // original hystogram
|
||||
uint8_t eq_levls[0x10000] = {0}; // levels to convert: newpix = eq_levls[oldpix]
|
||||
int s = w*h;
|
||||
int s = img->h * img->w;
|
||||
//double t0 = dtime();
|
||||
/* -- takes too long because of sync
|
||||
#pragma omp parallel
|
||||
@@ -492,6 +491,7 @@ static uint8_t *equalize(cc_IMG *img, int w, int h){
|
||||
}
|
||||
//WARNX("equal: %gs", dtime()-t0);
|
||||
//OMP_FOR() -- takes the same time!
|
||||
uint8_t *retn = win->rawdata;
|
||||
if(bytes == 1){
|
||||
uint8_t *data = (uint8_t*) img->data;
|
||||
for(int i = 0; i < s; ++i){
|
||||
@@ -504,7 +504,6 @@ static uint8_t *equalize(cc_IMG *img, int w, int h){
|
||||
}
|
||||
}
|
||||
//WARNX("result: %gs", dtime()-t0);
|
||||
return retn;
|
||||
}
|
||||
/*
|
||||
no omp @ histo:
|
||||
@@ -518,10 +517,9 @@ cuts: 0.00188208s
|
||||
*/
|
||||
|
||||
// count image cuts as [median-sigma median+5sigma]
|
||||
static uint8_t *mkcuts(cc_IMG *img, int w, int h){
|
||||
uint8_t *retn = MALLOC(uint8_t, w*h);
|
||||
static void mkcuts(cc_IMG *img){
|
||||
int orig_hysto[0x10000] = {0.}; // original hystogram
|
||||
int s = w*h;
|
||||
int s = img->h * img->w;
|
||||
double sum = 0., sum2 = 0.;
|
||||
int bytes = cc_getNbytes(img);
|
||||
TIMESTAMP("Make histogram");
|
||||
@@ -584,9 +582,11 @@ static uint8_t *mkcuts(cc_IMG *img, int w, int h){
|
||||
//WARNX("stat: %gs", dtime()-t0);
|
||||
// DEBUG: 2ms without OMP; 0.7ms with
|
||||
TIMESTAMP("apply cuts");
|
||||
uint8_t *retn = win->rawdata;
|
||||
if(bytes == 1){
|
||||
DBG("8 bit data");
|
||||
uint8_t *data = (uint8_t*) img->data;
|
||||
OMP_FOR()
|
||||
//OMP_FOR()
|
||||
for(int i = 0; i < s; ++i){
|
||||
uint16_t old = data[i];
|
||||
if(old > high){ retn[i] = 255; continue; }
|
||||
@@ -594,8 +594,9 @@ static uint8_t *mkcuts(cc_IMG *img, int w, int h){
|
||||
retn[i] = (uint8_t)(A*(old - low));
|
||||
}
|
||||
}else{
|
||||
DBG("16 bit data");
|
||||
uint16_t *data = (uint16_t*) img->data;
|
||||
OMP_FOR()
|
||||
//OMP_FOR()
|
||||
for(int i = 0; i < s; ++i){
|
||||
uint16_t old = data[i];
|
||||
if(old > high){ retn[i] = 255; continue; }
|
||||
@@ -603,8 +604,8 @@ static uint8_t *mkcuts(cc_IMG *img, int w, int h){
|
||||
retn[i] = (uint8_t)(A*(old - low));
|
||||
}
|
||||
}
|
||||
DBG("Done");
|
||||
//WARNX("cuts: %gs", dtime()-t0);
|
||||
return retn;
|
||||
}
|
||||
|
||||
static void change_displayed_image(cc_IMG *img){
|
||||
@@ -614,29 +615,43 @@ static void change_displayed_image(cc_IMG *img){
|
||||
TIMESTAMP("Got image #%zd", img->imnumber);
|
||||
if(delta > 0 && delta != 1) WARNX(_("Missed %zd images"), delta-1);
|
||||
lastN = img->imnumber;
|
||||
//pthread_mutex_lock(&win->mutex);
|
||||
rawimage *im = win->image;
|
||||
DBG("imh=%d, imw=%d, ch=%u, cw=%u", im->h, im->w, img->h, img->w);
|
||||
pthread_mutex_lock(&win->mutex);
|
||||
int w = img->w, h = img->h, s = w*h;
|
||||
if(!im || (im->h != h) || (im->w != w)){ // realloc image to new size
|
||||
pthread_mutex_lock(&win->mutex);
|
||||
if(!win->image || ! win->rawdata || (win->image->h != h) || (win->image->w != w)){ // realloc image & raw image to new size
|
||||
//pthread_mutex_lock(&win->mutex);
|
||||
DBG("\n\nRealloc rawdata");
|
||||
if(!im) im = MALLOC(rawimage, 1);
|
||||
if(im->h*im->w < s) im->rawdata = realloc(im->rawdata, s*3);
|
||||
im->h = h; im->w = w;
|
||||
win->image = im;
|
||||
uint8_t *raw = win->image->rawdata;
|
||||
win->image->rawdata = realloc(win->image->rawdata, s*3);
|
||||
if(!win->image->rawdata){
|
||||
WARN("realloc()");
|
||||
LOGERR("Realloc() error");
|
||||
win->image->rawdata = raw;
|
||||
return;
|
||||
}
|
||||
win->image->h = h; win->image->w = w;
|
||||
raw = win->rawdata;
|
||||
win->rawdata = realloc(win->rawdata, s);
|
||||
if(!win->rawdata){
|
||||
WARN("realloc()");
|
||||
LOGERR("Realloc() error");
|
||||
win->rawdata = raw;
|
||||
return;
|
||||
}
|
||||
DBG("win->image changed");
|
||||
pthread_mutex_unlock(&win->mutex);
|
||||
//pthread_mutex_unlock(&win->mutex);
|
||||
}
|
||||
rawimage *im = win->image;
|
||||
uint8_t *raw = win->rawdata;
|
||||
DBG("imh=%d, imw=%d, ch=%u, cw=%u", im->h, im->w, img->h, img->w);
|
||||
TIMESTAMP("level correction");
|
||||
uint8_t *newima;
|
||||
if(imequalize){
|
||||
DBG("equalize");
|
||||
newima = equalize(img, w, h);
|
||||
equalize(img);
|
||||
}else{
|
||||
DBG("cuts");
|
||||
newima = mkcuts(img, w, h);
|
||||
mkcuts(img);
|
||||
}
|
||||
//pthread_mutex_lock(&win->mutex);
|
||||
GLubyte *dst = im->rawdata;
|
||||
TIMESTAMP("colorfun");
|
||||
//double t0 = dtime();
|
||||
@@ -645,17 +660,16 @@ static void change_displayed_image(cc_IMG *img){
|
||||
OMP_FOR()
|
||||
for(int i = 0; i < s; ++i){
|
||||
GLubyte *t = &dst[i*3];
|
||||
t[0] = t[1] = t[2] = colorfun(newima[i]);
|
||||
t[0] = t[1] = t[2] = colorfun(raw[i]);
|
||||
}
|
||||
}else{
|
||||
// without OMP: 3.6ms; with OMP: 1.7ms
|
||||
OMP_FOR()
|
||||
for(int i = 0; i < s; ++i){
|
||||
gray2rgb(colorfun(newima[i] / 256.), &dst[i*3]);
|
||||
gray2rgb(colorfun(raw[i] / 256.), &dst[i*3]);
|
||||
}
|
||||
}
|
||||
//WARNX("Conversion time: %g", dtime()-t0);
|
||||
FREE(newima);
|
||||
/*
|
||||
// mirror image around Y
|
||||
int w3 = w*3, h1 = h-1, wsz = w3*sizeof(GLubyte);
|
||||
@@ -672,7 +686,7 @@ static void change_displayed_image(cc_IMG *img){
|
||||
}*/
|
||||
DBG("Unlock");
|
||||
win->image->changed = 1;
|
||||
//pthread_mutex_unlock(&win->mutex);
|
||||
pthread_mutex_unlock(&win->mutex);
|
||||
}
|
||||
|
||||
void closeGL(){ // killed by external signal or ctrl+c
|
||||
@@ -704,7 +718,11 @@ int viewer(imagefunc newimage){
|
||||
WARNX(_("Can't open OpenGL window, image preview will be inaccessible"));
|
||||
return 1;
|
||||
}
|
||||
cc_IMG *img = NULL;
|
||||
static cc_IMG *locimage = NULL;
|
||||
if(!locimage){
|
||||
locimage = cc_newimage(16, 1024, 1024);
|
||||
if(!locimage) return 1;
|
||||
}
|
||||
//double t0 = dtime();
|
||||
while(1){
|
||||
if(!win || win->killthread){ // got kill from ctrl+q
|
||||
@@ -717,10 +735,10 @@ int viewer(imagefunc newimage){
|
||||
}
|
||||
if((win->winevt & WINEVT_GETIMAGE) || !(win->winevt & WINEVT_PAUSE)){
|
||||
//DBG("CHK new image, t=%g", dtime()-t0);
|
||||
if(newimage(&img)){
|
||||
if(newimage(locimage)){
|
||||
TIMESTAMP("got image -> change");
|
||||
win->winevt &= ~WINEVT_GETIMAGE;
|
||||
change_displayed_image(img); // change image if refreshed
|
||||
change_displayed_image(locimage); // change image if refreshed
|
||||
TIMESTAMP("changed");
|
||||
}
|
||||
//DBG("Next cycle, t=%g", dtime()-t0);
|
||||
@@ -737,19 +755,19 @@ int viewer(imagefunc newimage){
|
||||
GP->outfileprefix = strdup("ccd_capture-screenshot");
|
||||
verbose(VERBOSE_PRIMARY, _("Set output prefix to %s"), GP->outfileprefix);
|
||||
}
|
||||
saveFITS(img, NULL);
|
||||
saveFITS(locimage, NULL);
|
||||
win->winevt &= ~WINEVT_SAVEIMAGE;
|
||||
}
|
||||
if(win->winevt & WINEVT_ROLLCOLORFUN){
|
||||
roll_colorfun();
|
||||
win->winevt &= ~WINEVT_ROLLCOLORFUN;
|
||||
change_displayed_image(img);
|
||||
change_displayed_image(locimage);
|
||||
}
|
||||
if(win->winevt & WINEVT_EQUALIZE){
|
||||
win->winevt &= ~WINEVT_EQUALIZE;
|
||||
imequalize = !imequalize;
|
||||
verbose(VERBOSE_PRIMARY, _("Equalization of histogram: %s"), imequalize ? N_("on") : N_("off"));
|
||||
change_displayed_image(img);
|
||||
change_displayed_image(locimage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ typedef struct{
|
||||
int ID; // identificator of OpenGL window
|
||||
char *title; // title of window
|
||||
GLuint Tex; // texture for image inside window
|
||||
rawimage *image; // raw image data
|
||||
rawimage *image; // colour image data
|
||||
uint8_t *rawdata; // raw data after processing
|
||||
int w; int h; // window size
|
||||
float x; float y; // image offset coordinates
|
||||
float x0; float y0; // center of window for coords conversion
|
||||
@@ -82,6 +83,6 @@ void conv_mouse_to_image_coords(int x, int y, float *X, float *Y, windowData *wi
|
||||
void conv_image_to_mouse_coords(float X, float Y, int *x, int *y, windowData *window);
|
||||
windowData* getWin();
|
||||
|
||||
typedef int (*imagefunc)(cc_IMG**);
|
||||
typedef int (*imagefunc)(cc_IMG*);
|
||||
|
||||
int viewer(imagefunc);
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-14 14:47+0300\n"
|
||||
"POT-Creation-Date: 2026-07-21 09:39+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -28,46 +28,46 @@ msgstr ""
|
||||
msgid "Get signal %d - exit"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:91
|
||||
#: main.c:88
|
||||
msgid "Can't use outfile name and prefix together"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:94 ccdfunc.c:213
|
||||
#: main.c:91 ccdfunc.c:214
|
||||
#, c-format
|
||||
msgid "File %s exists!"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:97
|
||||
#: main.c:94
|
||||
#, c-format
|
||||
msgid "Can't set answer timeout to %g"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:101
|
||||
#: main.c:98
|
||||
msgid ""
|
||||
"Options `port` and `path` can't be used together! Point `port` for TCP "
|
||||
"socket or `path` for UNIX."
|
||||
msgstr ""
|
||||
|
||||
#: main.c:106
|
||||
#: main.c:103
|
||||
#, c-format
|
||||
msgid "Wrong port value: %d"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:119
|
||||
#: main.c:116
|
||||
#, c-format
|
||||
msgid "Set image port to %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:122
|
||||
#: main.c:119
|
||||
msgid "Can't be client and standalone in same time!"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:127
|
||||
#: main.c:124
|
||||
#, c-format
|
||||
msgid "Log file %s @ level %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:129
|
||||
#: main.c:126
|
||||
msgid "Can't create log file"
|
||||
msgstr ""
|
||||
|
||||
@@ -331,546 +331,566 @@ msgstr ""
|
||||
msgid "%d unused parameters:\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:202
|
||||
#: ccdfunc.c:203
|
||||
msgid "Image not saved: neither filename nor filename prefix pointed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:220
|
||||
#: ccdfunc.c:221
|
||||
#, c-format
|
||||
msgid "Can't save file with prefix %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:280
|
||||
#: ccdfunc.c:283
|
||||
#, c-format
|
||||
msgid "File saved as '%s'"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:289
|
||||
#: ccdfunc.c:292
|
||||
msgid "Error saving file"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:344
|
||||
#: ccdfunc.c:347
|
||||
#, c-format
|
||||
msgid "Image stat:\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:353
|
||||
#: ccdfunc.c:356
|
||||
msgid "Focuser device not pointed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:360
|
||||
#: ccdfunc.c:363
|
||||
msgid "No focusers found"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:384
|
||||
#: ccdfunc.c:387
|
||||
#, c-format
|
||||
msgid "Found focuser #%d: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:390
|
||||
#: ccdfunc.c:393
|
||||
#, c-format
|
||||
msgid "Found %d focusers, you point number %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:394
|
||||
#: ccdfunc.c:397
|
||||
msgid "Can't set active focuser number"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:408
|
||||
#: ccdfunc.c:411
|
||||
msgid "Can't get focuser limit positions"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:415
|
||||
#: ccdfunc.c:418
|
||||
msgid "Can't get current focuser position"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:429
|
||||
#: ccdfunc.c:432
|
||||
#, c-format
|
||||
msgid "Can't set position %g: out of limits [%g, %g]"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:433
|
||||
#: ccdfunc.c:436
|
||||
msgid "Can't home focuser"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:435
|
||||
#: ccdfunc.c:438
|
||||
#, c-format
|
||||
msgid "Can't set position %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:443
|
||||
#: ccdfunc.c:446
|
||||
msgid "Wheel device not pointed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:450
|
||||
#: ccdfunc.c:453
|
||||
msgid "No wheels found"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:474
|
||||
#: ccdfunc.c:477
|
||||
#, c-format
|
||||
msgid "Found wheel #%d: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:480
|
||||
#: ccdfunc.c:483
|
||||
#, c-format
|
||||
msgid "Found %d wheels, you point number %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:484
|
||||
#: ccdfunc.c:487
|
||||
msgid "Can't set active wheel number"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:489
|
||||
#: ccdfunc.c:492
|
||||
#, c-format
|
||||
msgid "Wheel model: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:498
|
||||
#: ccdfunc.c:501
|
||||
msgid "Can't get current wheel position"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:500
|
||||
#: ccdfunc.c:503
|
||||
msgid "Can't get max wheel position"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:507
|
||||
#: ccdfunc.c:510
|
||||
#, c-format
|
||||
msgid "Wheel position should be from 0 to %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:511
|
||||
#: ccdfunc.c:514
|
||||
#, c-format
|
||||
msgid "Can't set wheel position %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:526
|
||||
#: ccdfunc.c:529
|
||||
msgid "Camera plugin have no capture polling funtion."
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:532
|
||||
#: ccdfunc.c:535
|
||||
#, c-format
|
||||
msgid "%.1f seconds till exposition ends"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:547
|
||||
#: ccdfunc.c:550
|
||||
msgid "Camera device not pointed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:554 ccdfunc.c:555
|
||||
#: ccdfunc.c:557 ccdfunc.c:558
|
||||
msgid "No cameras found"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:575
|
||||
#: ccdfunc.c:578
|
||||
msgid "Camera plugin have no model name getter"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:580
|
||||
#: ccdfunc.c:583
|
||||
#, c-format
|
||||
msgid "Found camera #%d: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:586
|
||||
#: ccdfunc.c:589
|
||||
#, c-format
|
||||
msgid "Found %d cameras, you point number %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:590
|
||||
#: ccdfunc.c:593
|
||||
msgid "Can't set active camera number"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:596
|
||||
#: ccdfunc.c:599
|
||||
msgid "Camera plugin have no custom commands"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:605 ccdfunc.c:608
|
||||
#: ccdfunc.c:608 ccdfunc.c:611
|
||||
#, c-format
|
||||
msgid "Command '%s'"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:610
|
||||
#: ccdfunc.c:613
|
||||
#, c-format
|
||||
msgid " returns \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:621
|
||||
#: ccdfunc.c:624
|
||||
msgid "Camera plugin have no fun speed setter"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:624
|
||||
#: ccdfunc.c:627
|
||||
msgid "Can't set fan speed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:625
|
||||
#: ccdfunc.c:628
|
||||
#, c-format
|
||||
msgid "Set fan speed to %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:630
|
||||
#: ccdfunc.c:633
|
||||
#, c-format
|
||||
msgid "Camera model: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:631
|
||||
#: ccdfunc.c:634
|
||||
#, c-format
|
||||
msgid "Pixel size: %g x %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:637
|
||||
#: ccdfunc.c:640
|
||||
#, c-format
|
||||
msgid "Full array: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:640
|
||||
#: ccdfunc.c:643
|
||||
#, c-format
|
||||
msgid "Field of view: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:643
|
||||
#: ccdfunc.c:646
|
||||
#, c-format
|
||||
msgid "Current format: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:646
|
||||
#: ccdfunc.c:649
|
||||
#, c-format
|
||||
msgid "Maximal geometry (WxH): %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:647
|
||||
#: ccdfunc.c:650
|
||||
#, c-format
|
||||
msgid "Minimal offset: %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:648
|
||||
#: ccdfunc.c:651
|
||||
#, c-format
|
||||
msgid "Geometry steps: offset - %dx%d, size - %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:652
|
||||
#: ccdfunc.c:655
|
||||
#, c-format
|
||||
msgid "Current binning: %d x %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:655
|
||||
#: ccdfunc.c:658
|
||||
#, c-format
|
||||
msgid "Current settings: %d bits per pixel"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:658
|
||||
#: ccdfunc.c:661
|
||||
#, c-format
|
||||
msgid "Current brightness: %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:660
|
||||
#: ccdfunc.c:663
|
||||
#, c-format
|
||||
msgid "Current gain: %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:662
|
||||
#: ccdfunc.c:665
|
||||
#, c-format
|
||||
msgid "Maximal gain: %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:664
|
||||
#: ccdfunc.c:667
|
||||
msgid "Camera plugin have no temperature setter"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:665
|
||||
#: ccdfunc.c:668
|
||||
#, c-format
|
||||
msgid "Can't set T to %g degC"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:673
|
||||
#: ccdfunc.c:676
|
||||
#, c-format
|
||||
msgid "Shutter command: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:675
|
||||
#: ccdfunc.c:678
|
||||
#, c-format
|
||||
msgid "Can't run shutter command %s (unsupported?)"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:678
|
||||
#: ccdfunc.c:681
|
||||
#, c-format
|
||||
msgid "Try to configure I/O port as %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:680
|
||||
#: ccdfunc.c:683
|
||||
msgid "Can't configure (unsupported?)"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:686
|
||||
#: ccdfunc.c:689
|
||||
msgid "Can't get IOport state (unsupported?)"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:689
|
||||
#: ccdfunc.c:692
|
||||
#, c-format
|
||||
msgid "Try to write %d to I/O port"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:691
|
||||
#: ccdfunc.c:694
|
||||
msgid "Can't set IOport"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:698
|
||||
#: ccdfunc.c:701
|
||||
#, c-format
|
||||
msgid "Set gain to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:699
|
||||
#: ccdfunc.c:702
|
||||
#, c-format
|
||||
msgid "Can't set gain to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:704
|
||||
#: ccdfunc.c:707
|
||||
#, c-format
|
||||
msgid "Set brightness to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:705
|
||||
#: ccdfunc.c:708
|
||||
#, c-format
|
||||
msgid "Can't set brightness to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:711 server.c:330
|
||||
#: ccdfunc.c:714 server.c:353
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:723 server.c:331
|
||||
#: ccdfunc.c:726 server.c:354
|
||||
msgid "Can't set given geometry"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:727
|
||||
#: ccdfunc.c:730
|
||||
#, c-format
|
||||
msgid "Can't set %d flushes"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:730
|
||||
#: ccdfunc.c:733
|
||||
msgid "Camera plugin have no exposition setter"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:732
|
||||
#: ccdfunc.c:735
|
||||
#, c-format
|
||||
msgid "Can't set exposure time to %f seconds"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:735
|
||||
#: ccdfunc.c:738
|
||||
msgid "Can't change frame type"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:738
|
||||
#: ccdfunc.c:741
|
||||
msgid "Can't set bit depth"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:740
|
||||
#: ccdfunc.c:743
|
||||
msgid "Can't set readout speed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:741
|
||||
#: ccdfunc.c:744
|
||||
#, c-format
|
||||
msgid "Readout mode: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:742
|
||||
#: ccdfunc.c:745
|
||||
msgid "Only show statistics"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:745
|
||||
#: ccdfunc.c:748
|
||||
msgid "Can't get current binning"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:770
|
||||
#: ccdfunc.c:773
|
||||
#, c-format
|
||||
msgid "Capture frame %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:771 ccdfunc.c:848 server.c:195
|
||||
#: ccdfunc.c:774 ccdfunc.c:852 server.c:203
|
||||
msgid "Camera plugin have no function `start exposition`"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:773 ccdfunc.c:850 server.c:201
|
||||
#: ccdfunc.c:776 ccdfunc.c:854 server.c:208
|
||||
msgid "Can't start exposition"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:778
|
||||
#: ccdfunc.c:781
|
||||
msgid "Can't capture image"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:781
|
||||
#: ccdfunc.c:784
|
||||
msgid "Read grabbed image"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:783 ccdfunc.c:863 server.c:218
|
||||
#: ccdfunc.c:786 ccdfunc.c:865 server.c:239
|
||||
msgid "Camera plugin have no function `capture`"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:785 ccdfunc.c:864
|
||||
#: ccdfunc.c:788 ccdfunc.c:866
|
||||
msgid "Can't grab image"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:799 client.c:499
|
||||
#: ccdfunc.c:802 client.c:573
|
||||
#, c-format
|
||||
msgid "%d seconds till pause ends\n"
|
||||
msgstr ""
|
||||
|
||||
#. for(int i = 0; i < NFRM; ++i) printf("last[%d]=%g\n", i, lastn[i]);
|
||||
#: ccdfunc.c:834
|
||||
#: ccdfunc.c:837
|
||||
#, c-format
|
||||
msgid "Framerate=%.2f (%g seconds for exp); mean framerate=%.2f"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:861
|
||||
#: ccdfunc.c:863
|
||||
msgid "Some error when capture"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:912
|
||||
#: ccdfunc.c:904
|
||||
msgid "Can't create grabbing thread"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:943
|
||||
#: ccdfunc.c:935
|
||||
msgid "Point network port or UNIX-socket path"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:947
|
||||
#: ccdfunc.c:939
|
||||
msgid "start_socket(): can't open socket"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:956
|
||||
#: ccdfunc.c:948
|
||||
msgid "Need exposition time!"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:126
|
||||
#: server.c:129
|
||||
msgid "Can't unlock socket mutex"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:163
|
||||
#: server.c:167
|
||||
msgid "Can't allocate memory for image"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:247
|
||||
#: server.c:216
|
||||
msgid "Camera disconnected"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:222
|
||||
msgid "Something's wrong with camera"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:270
|
||||
msgid "No camera device"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1060
|
||||
#: server.c:1092
|
||||
msgid "server(): need at least command socket fd"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1061
|
||||
#: server.c:1093
|
||||
msgid "Server run without image transport socket"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1082
|
||||
#: server.c:1115
|
||||
msgid "No devices found"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1127
|
||||
#: server.c:1160
|
||||
msgid "Client wants an image, but there's no data"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1156
|
||||
#: server.c:1189
|
||||
msgid "Limit of connections reached"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1225
|
||||
#: server.c:1258
|
||||
#, c-format
|
||||
msgid "Can't create %s"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1261
|
||||
#: server.c:1294
|
||||
msgid "Can't lock mutex"
|
||||
msgstr ""
|
||||
|
||||
#. send message and wait any answer
|
||||
#. send message and wait answer starting with 'cmd'
|
||||
#. send command and wait for answer on it
|
||||
#: client.c:42 client.c:44 client.c:46 client.c:276
|
||||
#: client.c:42 client.c:44 client.c:46 client.c:288
|
||||
msgid "Server disconnected"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:173
|
||||
#: client.c:124
|
||||
msgid "Can't allocate buffer"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:149
|
||||
msgid "Server disconnected?"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:157
|
||||
msgid "Got empty string"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:186
|
||||
msgid "Send custom plugin commands\n"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:307
|
||||
#: client.c:340
|
||||
msgid "Can't lock shared memory"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:316
|
||||
msgid "getimage(): can't open image transport socket"
|
||||
#: client.c:359
|
||||
msgid "Can't open image transport socket"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:319
|
||||
msgid "Can't read image header"
|
||||
#: client.c:365
|
||||
msgid "Can't read image header over socket"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:324
|
||||
msgid "Wrong image: bad magick"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:328
|
||||
msgid "Wrong image size"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:342
|
||||
msgid "Can't reallocate memory for image buffer"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:361
|
||||
#: client.c:398 client.c:428
|
||||
msgid "Can't read image data"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:380
|
||||
#: client.c:440
|
||||
msgid "Too many FITS headers, truncating"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:451
|
||||
#, c-format
|
||||
msgid "Can't read full header, got %zd records from %zd"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:414 client.c:517
|
||||
#: client.c:466
|
||||
msgid "Still got old image"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:491 client.c:591
|
||||
msgid "Can't run without command socket"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:436
|
||||
#: client.c:510
|
||||
msgid "Exposing frame 1..."
|
||||
msgstr ""
|
||||
|
||||
#: client.c:439
|
||||
#: client.c:512
|
||||
msgid "Wait for exposition end"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:457
|
||||
#: client.c:531
|
||||
msgid "Can't make exposition"
|
||||
msgstr ""
|
||||
|
||||
#. start next capture
|
||||
#. last image -> should re-expose
|
||||
#: client.c:459 client.c:470 client.c:489
|
||||
#: client.c:533 client.c:544 client.c:563
|
||||
#, c-format
|
||||
msgid "Exposing frame %d..."
|
||||
msgstr ""
|
||||
|
||||
#: client.c:477
|
||||
#: client.c:551
|
||||
msgid "Frame ready, try to grab"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:479
|
||||
#: client.c:553
|
||||
msgid "Can't get next image"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:487
|
||||
#: client.c:561
|
||||
msgid "Got already saved image, wait next"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:511
|
||||
#: client.c:585
|
||||
msgid "Server timeout"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:560
|
||||
#: client.c:636
|
||||
msgid "Camera in error state"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:638
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d "
|
||||
"(timeout: %g)"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:620 client.c:627
|
||||
#: client.c:698 client.c:705
|
||||
msgid "Can't create capturing thread"
|
||||
msgstr ""
|
||||
|
||||
@@ -878,47 +898,47 @@ msgstr ""
|
||||
msgid "Already initialized!"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:312
|
||||
#: imageview.c:314
|
||||
msgid "Can't init mutex!"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:425
|
||||
#: imageview.c:427
|
||||
#, c-format
|
||||
msgid "Histogram conversion: %s"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:615
|
||||
#: imageview.c:616
|
||||
#, c-format
|
||||
msgid "Missed %zd images"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:697
|
||||
#: imageview.c:711
|
||||
msgid "No image changing function defined"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:704
|
||||
#: imageview.c:718
|
||||
msgid "Can't open OpenGL window, image preview will be inaccessible"
|
||||
msgstr ""
|
||||
|
||||
#. save image
|
||||
#: imageview.c:734
|
||||
#: imageview.c:752
|
||||
msgid "Make screenshot"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:738
|
||||
#: imageview.c:756
|
||||
#, c-format
|
||||
msgid "Set output prefix to %s"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:751
|
||||
#: imageview.c:769
|
||||
#, c-format
|
||||
msgid "Equalization of histogram: %s"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:751
|
||||
#: imageview.c:769
|
||||
msgid "on"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:751
|
||||
#: imageview.c:769
|
||||
msgid "off"
|
||||
msgstr ""
|
||||
|
||||
332
locale/ru/ru.po
332
locale/ru/ru.po
@@ -7,7 +7,7 @@
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-14 14:45+0300\n"
|
||||
"POT-Creation-Date: 2026-07-21 09:39+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -16,17 +16,17 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ccdfunc.c:610
|
||||
#: ccdfunc.c:613
|
||||
#, c-format
|
||||
msgid " returns \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:532
|
||||
#: ccdfunc.c:535
|
||||
#, c-format
|
||||
msgid "%.1f seconds till exposition ends"
|
||||
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
|
||||
|
||||
#: ccdfunc.c:799 client.c:499
|
||||
#: ccdfunc.c:802 client.c:573
|
||||
#, c-format
|
||||
msgid "%d seconds till pause ends\n"
|
||||
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
|
||||
@@ -48,320 +48,335 @@ msgstr "
|
||||
msgid "CMOS gain level"
|
||||
msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
|
||||
|
||||
#: ccdfunc.c:547
|
||||
#: ccdfunc.c:550
|
||||
msgid "Camera device not pointed"
|
||||
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
|
||||
|
||||
#: ccdfunc.c:630
|
||||
#: server.c:216
|
||||
#, fuzzy
|
||||
msgid "Camera disconnected"
|
||||
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
|
||||
|
||||
#: client.c:636
|
||||
msgid "Camera in error state"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:633
|
||||
#, c-format
|
||||
msgid "Camera model: %s"
|
||||
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
|
||||
|
||||
#: ccdfunc.c:526
|
||||
#: ccdfunc.c:529
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no capture polling funtion."
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:596
|
||||
#: ccdfunc.c:599
|
||||
msgid "Camera plugin have no custom commands"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:730
|
||||
#: ccdfunc.c:733
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no exposition setter"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:621
|
||||
#: ccdfunc.c:624
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no fun speed setter"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:783 ccdfunc.c:863 server.c:218
|
||||
#: ccdfunc.c:786 ccdfunc.c:865 server.c:239
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no function `capture`"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:771 ccdfunc.c:848 server.c:195
|
||||
#: ccdfunc.c:774 ccdfunc.c:852 server.c:203
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no function `start exposition`"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:575
|
||||
#: ccdfunc.c:578
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no model name getter"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: ccdfunc.c:664
|
||||
#: ccdfunc.c:667
|
||||
#, fuzzy
|
||||
msgid "Camera plugin have no temperature setter"
|
||||
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
|
||||
|
||||
#: server.c:163
|
||||
#: client.c:124
|
||||
#, fuzzy
|
||||
msgid "Can't allocate buffer"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: server.c:167
|
||||
#, fuzzy
|
||||
msgid "Can't allocate memory for image"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: main.c:122
|
||||
#: main.c:119
|
||||
msgid "Can't be client and standalone in same time!"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:778
|
||||
#: ccdfunc.c:781
|
||||
msgid "Can't capture image"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: ccdfunc.c:735
|
||||
#: ccdfunc.c:738
|
||||
msgid "Can't change frame type"
|
||||
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
|
||||
|
||||
#: ccdfunc.c:680
|
||||
#: ccdfunc.c:683
|
||||
msgid "Can't configure (unsupported?)"
|
||||
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
|
||||
|
||||
#: server.c:1225
|
||||
#: server.c:1258
|
||||
#, fuzzy, c-format
|
||||
msgid "Can't create %s"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: client.c:620 client.c:627
|
||||
#: client.c:698 client.c:705
|
||||
#, fuzzy
|
||||
msgid "Can't create capturing thread"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: ccdfunc.c:912
|
||||
#: ccdfunc.c:904
|
||||
#, fuzzy
|
||||
msgid "Can't create grabbing thread"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
|
||||
|
||||
#: main.c:129
|
||||
#: main.c:126
|
||||
#, fuzzy
|
||||
msgid "Can't create log file"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: ccdfunc.c:686
|
||||
#: ccdfunc.c:689
|
||||
msgid "Can't get IOport state (unsupported?)"
|
||||
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
|
||||
|
||||
#: ccdfunc.c:745
|
||||
#: ccdfunc.c:748
|
||||
msgid "Can't get current binning"
|
||||
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
|
||||
|
||||
#: ccdfunc.c:415
|
||||
#: ccdfunc.c:418
|
||||
msgid "Can't get current focuser position"
|
||||
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
|
||||
|
||||
#: ccdfunc.c:498
|
||||
#: ccdfunc.c:501
|
||||
#, fuzzy
|
||||
msgid "Can't get current wheel position"
|
||||
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
|
||||
|
||||
#: ccdfunc.c:408
|
||||
#: ccdfunc.c:411
|
||||
msgid "Can't get focuser limit positions"
|
||||
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
|
||||
|
||||
#: ccdfunc.c:500
|
||||
#: ccdfunc.c:503
|
||||
msgid "Can't get max wheel position"
|
||||
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
|
||||
|
||||
#: client.c:479
|
||||
#: client.c:553
|
||||
#, fuzzy
|
||||
msgid "Can't get next image"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: ccdfunc.c:785 ccdfunc.c:864
|
||||
#: ccdfunc.c:788 ccdfunc.c:866
|
||||
msgid "Can't grab image"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: ccdfunc.c:433
|
||||
#: ccdfunc.c:436
|
||||
msgid "Can't home focuser"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
|
||||
|
||||
#: imageview.c:312
|
||||
#: imageview.c:314
|
||||
msgid "Can't init mutex!"
|
||||
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
|
||||
|
||||
#: server.c:1261
|
||||
#: server.c:1294
|
||||
#, fuzzy
|
||||
msgid "Can't lock mutex"
|
||||
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
|
||||
|
||||
#: client.c:307
|
||||
#: client.c:340
|
||||
#, fuzzy
|
||||
msgid "Can't lock shared memory"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: client.c:457
|
||||
#: client.c:531
|
||||
msgid "Can't make exposition"
|
||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
#: imageview.c:704
|
||||
#: imageview.c:718
|
||||
msgid "Can't open OpenGL window, image preview will be inaccessible"
|
||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
|
||||
|
||||
#: client.c:380
|
||||
#: client.c:359
|
||||
#, fuzzy
|
||||
msgid "Can't open image transport socket"
|
||||
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
|
||||
|
||||
#: client.c:451
|
||||
#, c-format
|
||||
msgid "Can't read full header, got %zd records from %zd"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:361
|
||||
#: client.c:398 client.c:428
|
||||
#, fuzzy
|
||||
msgid "Can't read image data"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: client.c:319
|
||||
#: client.c:365
|
||||
#, fuzzy
|
||||
msgid "Can't read image header"
|
||||
msgid "Can't read image header over socket"
|
||||
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
|
||||
|
||||
#: client.c:342
|
||||
msgid "Can't reallocate memory for image buffer"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:675
|
||||
#: ccdfunc.c:678
|
||||
#, c-format
|
||||
msgid "Can't run shutter command %s (unsupported?)"
|
||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
|
||||
|
||||
#: client.c:414 client.c:517
|
||||
#: client.c:491 client.c:591
|
||||
#, fuzzy
|
||||
msgid "Can't run without command socket"
|
||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
|
||||
|
||||
#: ccdfunc.c:220
|
||||
#: ccdfunc.c:221
|
||||
#, c-format
|
||||
msgid "Can't save file with prefix %s"
|
||||
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
|
||||
|
||||
#: ccdfunc.c:727
|
||||
#: ccdfunc.c:730
|
||||
#, c-format
|
||||
msgid "Can't set %d flushes"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
|
||||
|
||||
#: ccdfunc.c:691
|
||||
#: ccdfunc.c:694
|
||||
msgid "Can't set IOport"
|
||||
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
|
||||
|
||||
#: ccdfunc.c:665
|
||||
#: ccdfunc.c:668
|
||||
#, c-format
|
||||
msgid "Can't set T to %g degC"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
|
||||
|
||||
#: ccdfunc.c:590
|
||||
#: ccdfunc.c:593
|
||||
msgid "Can't set active camera number"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
|
||||
|
||||
#: ccdfunc.c:394
|
||||
#: ccdfunc.c:397
|
||||
msgid "Can't set active focuser number"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
|
||||
|
||||
#: ccdfunc.c:484
|
||||
#: ccdfunc.c:487
|
||||
msgid "Can't set active wheel number"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
|
||||
|
||||
#: main.c:97
|
||||
#: main.c:94
|
||||
#, fuzzy, c-format
|
||||
msgid "Can't set answer timeout to %g"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
|
||||
|
||||
#: ccdfunc.c:711 server.c:330
|
||||
#: ccdfunc.c:714 server.c:353
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
|
||||
|
||||
#: ccdfunc.c:738
|
||||
#: ccdfunc.c:741
|
||||
msgid "Can't set bit depth"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
|
||||
|
||||
#: ccdfunc.c:705
|
||||
#: ccdfunc.c:708
|
||||
#, c-format
|
||||
msgid "Can't set brightness to %g"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
|
||||
|
||||
#: ccdfunc.c:732
|
||||
#: ccdfunc.c:735
|
||||
#, c-format
|
||||
msgid "Can't set exposure time to %f seconds"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
|
||||
|
||||
#: ccdfunc.c:624
|
||||
#: ccdfunc.c:627
|
||||
msgid "Can't set fan speed"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
|
||||
|
||||
#: ccdfunc.c:699
|
||||
#: ccdfunc.c:702
|
||||
#, c-format
|
||||
msgid "Can't set gain to %g"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
|
||||
|
||||
#: ccdfunc.c:723 server.c:331
|
||||
#: ccdfunc.c:726 server.c:354
|
||||
msgid "Can't set given geometry"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
|
||||
|
||||
#: ccdfunc.c:435
|
||||
#: ccdfunc.c:438
|
||||
#, c-format
|
||||
msgid "Can't set position %g"
|
||||
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
|
||||
|
||||
#: ccdfunc.c:429
|
||||
#: ccdfunc.c:432
|
||||
#, c-format
|
||||
msgid "Can't set position %g: out of limits [%g, %g]"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
|
||||
|
||||
#: ccdfunc.c:740
|
||||
#: ccdfunc.c:743
|
||||
msgid "Can't set readout speed"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
|
||||
|
||||
#: ccdfunc.c:511
|
||||
#: ccdfunc.c:514
|
||||
#, c-format
|
||||
msgid "Can't set wheel position %d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
|
||||
|
||||
#: ccdfunc.c:773 ccdfunc.c:850 server.c:201
|
||||
#: ccdfunc.c:776 ccdfunc.c:854 server.c:208
|
||||
msgid "Can't start exposition"
|
||||
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
#: server.c:126
|
||||
#: server.c:129
|
||||
#, fuzzy
|
||||
msgid "Can't unlock socket mutex"
|
||||
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
|
||||
|
||||
#: main.c:91
|
||||
#: main.c:88
|
||||
#, fuzzy
|
||||
msgid "Can't use outfile name and prefix together"
|
||||
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
|
||||
|
||||
#: ccdfunc.c:770
|
||||
#: ccdfunc.c:773
|
||||
#, c-format
|
||||
msgid "Capture frame %d"
|
||||
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
|
||||
|
||||
#: server.c:1127
|
||||
#: server.c:1160
|
||||
msgid "Client wants an image, but there's no data"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:605 ccdfunc.c:608
|
||||
#: ccdfunc.c:608 ccdfunc.c:611
|
||||
#, c-format
|
||||
msgid "Command '%s'"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:652
|
||||
#: ccdfunc.c:655
|
||||
#, fuzzy, c-format
|
||||
msgid "Current binning: %d x %d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
|
||||
|
||||
#: ccdfunc.c:658
|
||||
#: ccdfunc.c:661
|
||||
#, fuzzy, c-format
|
||||
msgid "Current brightness: %g"
|
||||
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
|
||||
|
||||
#: ccdfunc.c:643
|
||||
#: ccdfunc.c:646
|
||||
#, c-format
|
||||
msgid "Current format: %s"
|
||||
msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s"
|
||||
|
||||
#: ccdfunc.c:660
|
||||
#: ccdfunc.c:663
|
||||
#, fuzzy, c-format
|
||||
msgid "Current gain: %g"
|
||||
msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s"
|
||||
|
||||
#: ccdfunc.c:655
|
||||
#: ccdfunc.c:658
|
||||
#, c-format
|
||||
msgid "Current settings: %d bits per pixel"
|
||||
msgstr ""
|
||||
@@ -370,91 +385,91 @@ msgstr ""
|
||||
msgid "Display image in OpenGL window"
|
||||
msgstr "ÏÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
|
||||
|
||||
#: imageview.c:751
|
||||
#: imageview.c:769
|
||||
#, c-format
|
||||
msgid "Equalization of histogram: %s"
|
||||
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
|
||||
|
||||
#: ccdfunc.c:289
|
||||
#: ccdfunc.c:292
|
||||
msgid "Error saving file"
|
||||
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
|
||||
|
||||
#. start next capture
|
||||
#. last image -> should re-expose
|
||||
#: client.c:459 client.c:470 client.c:489
|
||||
#: client.c:533 client.c:544 client.c:563
|
||||
#, c-format
|
||||
msgid "Exposing frame %d..."
|
||||
msgstr ""
|
||||
|
||||
#: client.c:436
|
||||
#: client.c:510
|
||||
msgid "Exposing frame 1..."
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:640
|
||||
#: ccdfunc.c:643
|
||||
#, c-format
|
||||
msgid "Field of view: %s"
|
||||
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
|
||||
|
||||
#: main.c:94 ccdfunc.c:213
|
||||
#: main.c:91 ccdfunc.c:214
|
||||
#, c-format
|
||||
msgid "File %s exists!"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:280
|
||||
#: ccdfunc.c:283
|
||||
#, c-format
|
||||
msgid "File saved as '%s'"
|
||||
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
|
||||
|
||||
#: ccdfunc.c:353
|
||||
#: ccdfunc.c:356
|
||||
msgid "Focuser device not pointed"
|
||||
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
|
||||
|
||||
#: ccdfunc.c:586
|
||||
#: ccdfunc.c:589
|
||||
#, c-format
|
||||
msgid "Found %d cameras, you point number %d"
|
||||
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
|
||||
|
||||
#: ccdfunc.c:390
|
||||
#: ccdfunc.c:393
|
||||
#, c-format
|
||||
msgid "Found %d focusers, you point number %d"
|
||||
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
|
||||
|
||||
#: ccdfunc.c:480
|
||||
#: ccdfunc.c:483
|
||||
#, c-format
|
||||
msgid "Found %d wheels, you point number %d"
|
||||
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
|
||||
|
||||
#: ccdfunc.c:580
|
||||
#: ccdfunc.c:583
|
||||
#, c-format
|
||||
msgid "Found camera #%d: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:384
|
||||
#: ccdfunc.c:387
|
||||
#, c-format
|
||||
msgid "Found focuser #%d: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:474
|
||||
#: ccdfunc.c:477
|
||||
#, c-format
|
||||
msgid "Found wheel #%d: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:477
|
||||
#: client.c:551
|
||||
msgid "Frame ready, try to grab"
|
||||
msgstr ""
|
||||
|
||||
#. for(int i = 0; i < NFRM; ++i) printf("last[%d]=%g\n", i, lastn[i]);
|
||||
#: ccdfunc.c:834
|
||||
#: ccdfunc.c:837
|
||||
#, c-format
|
||||
msgid "Framerate=%.2f (%g seconds for exp); mean framerate=%.2f"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:637
|
||||
#: ccdfunc.c:640
|
||||
#, c-format
|
||||
msgid "Full array: %s"
|
||||
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
|
||||
|
||||
#: ccdfunc.c:648
|
||||
#: ccdfunc.c:651
|
||||
#, c-format
|
||||
msgid "Geometry steps: offset - %dx%d, size - %dx%d"
|
||||
msgstr ""
|
||||
@@ -465,11 +480,15 @@ msgstr ""
|
||||
msgid "Get signal %d - exit"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:487
|
||||
#: client.c:561
|
||||
msgid "Got already saved image, wait next"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:425
|
||||
#: client.c:157
|
||||
msgid "Got empty string"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:427
|
||||
#, c-format
|
||||
msgid "Histogram conversion: %s"
|
||||
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
|
||||
@@ -478,32 +497,32 @@ msgstr "
|
||||
msgid "INET image socket port"
|
||||
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ"
|
||||
|
||||
#: ccdfunc.c:202
|
||||
#: ccdfunc.c:203
|
||||
msgid "Image not saved: neither filename nor filename prefix pointed"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:344
|
||||
#: ccdfunc.c:347
|
||||
#, c-format
|
||||
msgid "Image stat:\n"
|
||||
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
|
||||
|
||||
#: client.c:560
|
||||
#: client.c:638
|
||||
#, c-format
|
||||
msgid "Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d "
|
||||
"(timeout: %g)"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:1156
|
||||
#: server.c:1189
|
||||
msgid "Limit of connections reached"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:127
|
||||
#: main.c:124
|
||||
#, c-format
|
||||
msgid "Log file %s @ level %d\n"
|
||||
msgstr ""
|
||||
|
||||
#. save image
|
||||
#: imageview.c:734
|
||||
#: imageview.c:752
|
||||
msgid "Make screenshot"
|
||||
msgstr ""
|
||||
|
||||
@@ -512,22 +531,22 @@ msgstr ""
|
||||
msgid "Master killed with sig=%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:662
|
||||
#: ccdfunc.c:665
|
||||
#, c-format
|
||||
msgid "Maximal gain: %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:646
|
||||
#: ccdfunc.c:649
|
||||
#, c-format
|
||||
msgid "Maximal geometry (WxH): %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:647
|
||||
#: ccdfunc.c:650
|
||||
#, c-format
|
||||
msgid "Minimal offset: %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: imageview.c:615
|
||||
#: imageview.c:616
|
||||
#, c-format
|
||||
msgid "Missed %zd images"
|
||||
msgstr ""
|
||||
@@ -536,63 +555,63 @@ msgstr ""
|
||||
msgid "N flushes before exposing (default: 1)"
|
||||
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
|
||||
|
||||
#: ccdfunc.c:956
|
||||
#: ccdfunc.c:948
|
||||
msgid "Need exposition time!"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:247
|
||||
#: server.c:270
|
||||
msgid "No camera device"
|
||||
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
|
||||
|
||||
#: ccdfunc.c:554 ccdfunc.c:555
|
||||
#: ccdfunc.c:557 ccdfunc.c:558
|
||||
msgid "No cameras found"
|
||||
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
|
||||
|
||||
#: server.c:1082
|
||||
#: server.c:1115
|
||||
#, fuzzy
|
||||
msgid "No devices found"
|
||||
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
|
||||
|
||||
#: ccdfunc.c:360
|
||||
#: ccdfunc.c:363
|
||||
msgid "No focusers found"
|
||||
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
|
||||
|
||||
#: imageview.c:697
|
||||
#: imageview.c:711
|
||||
msgid "No image changing function defined"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:450
|
||||
#: ccdfunc.c:453
|
||||
msgid "No wheels found"
|
||||
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
|
||||
|
||||
#: ccdfunc.c:742
|
||||
#: ccdfunc.c:745
|
||||
msgid "Only show statistics"
|
||||
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
|
||||
|
||||
#: main.c:101
|
||||
#: main.c:98
|
||||
msgid "Options `port` and `path` can't be used together! Point `port` for "
|
||||
"TCP socket or `path` for UNIX."
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:631
|
||||
#: ccdfunc.c:634
|
||||
#, c-format
|
||||
msgid "Pixel size: %g x %g"
|
||||
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
|
||||
|
||||
#: ccdfunc.c:943
|
||||
#: ccdfunc.c:935
|
||||
msgid "Point network port or UNIX-socket path"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:781
|
||||
#: ccdfunc.c:784
|
||||
msgid "Read grabbed image"
|
||||
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
|
||||
|
||||
#: ccdfunc.c:741
|
||||
#: ccdfunc.c:744
|
||||
#, c-format
|
||||
msgid "Readout mode: %s"
|
||||
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
|
||||
|
||||
#: client.c:173
|
||||
#: client.c:186
|
||||
#, fuzzy
|
||||
msgid "Send custom plugin commands\n"
|
||||
msgstr "ÏÓÏÂÙÅ ËÏÍÁÎÄÙ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ"
|
||||
@@ -600,59 +619,76 @@ msgstr "
|
||||
#. send message and wait any answer
|
||||
#. send message and wait answer starting with 'cmd'
|
||||
#. send command and wait for answer on it
|
||||
#: client.c:42 client.c:44 client.c:46 client.c:276
|
||||
#: client.c:42 client.c:44 client.c:46 client.c:288
|
||||
#, fuzzy
|
||||
msgid "Server disconnected"
|
||||
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
|
||||
|
||||
#: server.c:1061
|
||||
#: client.c:149
|
||||
#, fuzzy
|
||||
msgid "Server disconnected?"
|
||||
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
|
||||
|
||||
#: server.c:1093
|
||||
msgid "Server run without image transport socket"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:511
|
||||
#: client.c:585
|
||||
msgid "Server timeout"
|
||||
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
|
||||
|
||||
#: ccdfunc.c:704
|
||||
#: ccdfunc.c:707
|
||||
#, c-format
|
||||
msgid "Set brightness to %g"
|
||||
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
|
||||
|
||||
#: ccdfunc.c:625
|
||||
#: ccdfunc.c:628
|
||||
#, c-format
|
||||
msgid "Set fan speed to %d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
|
||||
|
||||
#: ccdfunc.c:698
|
||||
#: ccdfunc.c:701
|
||||
#, c-format
|
||||
msgid "Set gain to %g"
|
||||
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
|
||||
|
||||
#: main.c:119
|
||||
#: main.c:116
|
||||
#, fuzzy, c-format
|
||||
msgid "Set image port to %s\n"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
|
||||
|
||||
#: imageview.c:738
|
||||
#: imageview.c:756
|
||||
#, c-format
|
||||
msgid "Set output prefix to %s"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:673
|
||||
#: ccdfunc.c:676
|
||||
#, c-format
|
||||
msgid "Shutter command: %s\n"
|
||||
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
|
||||
|
||||
#: ccdfunc.c:861
|
||||
#: ccdfunc.c:863
|
||||
msgid "Some error when capture"
|
||||
msgstr "ïÛÉÂËÁ ÐÒÉ ÚÁÈ×ÁÔÅ"
|
||||
|
||||
#: ccdfunc.c:678
|
||||
#: server.c:222
|
||||
msgid "Something's wrong with camera"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:466
|
||||
msgid "Still got old image"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:440
|
||||
msgid "Too many FITS headers, truncating"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:681
|
||||
#, c-format
|
||||
msgid "Try to configure I/O port as %d"
|
||||
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
|
||||
|
||||
#: ccdfunc.c:689
|
||||
#: ccdfunc.c:692
|
||||
#, c-format
|
||||
msgid "Try to write %d to I/O port"
|
||||
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
|
||||
@@ -661,34 +697,26 @@ msgstr "
|
||||
msgid "UNIX socket name (command socket)"
|
||||
msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ"
|
||||
|
||||
#: client.c:439
|
||||
#: client.c:512
|
||||
#, fuzzy
|
||||
msgid "Wait for exposition end"
|
||||
msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
|
||||
|
||||
#: ccdfunc.c:443
|
||||
#: ccdfunc.c:446
|
||||
msgid "Wheel device not pointed"
|
||||
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
|
||||
|
||||
#: ccdfunc.c:489
|
||||
#: ccdfunc.c:492
|
||||
#, fuzzy, c-format
|
||||
msgid "Wheel model: %s"
|
||||
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
|
||||
|
||||
#: ccdfunc.c:507
|
||||
#: ccdfunc.c:510
|
||||
#, c-format
|
||||
msgid "Wheel position should be from 0 to %d"
|
||||
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
|
||||
|
||||
#: client.c:328
|
||||
msgid "Wrong image size"
|
||||
msgstr ""
|
||||
|
||||
#: client.c:324
|
||||
msgid "Wrong image: bad magick"
|
||||
msgstr ""
|
||||
|
||||
#: main.c:106
|
||||
#: main.c:103
|
||||
#, c-format
|
||||
msgid "Wrong port value: %d"
|
||||
msgstr ""
|
||||
@@ -775,10 +803,6 @@ msgstr ""
|
||||
msgid "get value of I/O port pins"
|
||||
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
|
||||
|
||||
#: client.c:316
|
||||
msgid "getimage(): can't open image transport socket"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:92
|
||||
msgid "horizontal binning to N pixels"
|
||||
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
|
||||
@@ -844,11 +868,11 @@ msgstr "
|
||||
msgid "observing program name"
|
||||
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
|
||||
|
||||
#: imageview.c:751
|
||||
#: imageview.c:769
|
||||
msgid "off"
|
||||
msgstr "×ÙËÌ"
|
||||
|
||||
#: imageview.c:751
|
||||
#: imageview.c:769
|
||||
msgid "on"
|
||||
msgstr "×ËÌ"
|
||||
|
||||
@@ -892,7 +916,7 @@ msgstr "
|
||||
msgid "run in 8-bit mode"
|
||||
msgstr "8-ÂÉÔÎÙÊ ÒÅÖÉÍ"
|
||||
|
||||
#: server.c:1060
|
||||
#: server.c:1092
|
||||
msgid "server(): need at least command socket fd"
|
||||
msgstr ""
|
||||
|
||||
@@ -928,7 +952,7 @@ msgstr "
|
||||
msgid "start (!=0) or stop(==0) infinity capturing loop"
|
||||
msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ"
|
||||
|
||||
#: ccdfunc.c:947
|
||||
#: ccdfunc.c:939
|
||||
msgid "start_socket(): can't open socket"
|
||||
msgstr ""
|
||||
|
||||
|
||||
11
main.c
11
main.c
@@ -58,16 +58,13 @@ void signals(int signo){
|
||||
if(!GP->client){
|
||||
DBG("Cancel capturing and close all");
|
||||
stop_server();
|
||||
camstop();
|
||||
closewheel();
|
||||
focclose();
|
||||
}
|
||||
}else exit(signo);
|
||||
#ifdef IMAGEVIEW
|
||||
DBG("KILL GL");
|
||||
closeGL();
|
||||
#endif
|
||||
DBG("exit(%d)", signo);
|
||||
exit(signo);
|
||||
//DBG("exit(%d)", signo);
|
||||
//exit(signo);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
@@ -148,7 +145,7 @@ int main(int argc, char **argv){
|
||||
return start_socket(isserver);
|
||||
}
|
||||
#ifdef IMAGEVIEW
|
||||
if(GP->showimage){ // activate image vindow in capture or simple viewer mode
|
||||
if(GP->showimage){ // activate image window in capture or simple viewer mode
|
||||
imagefunc imfn = NULL;
|
||||
if(GP->cameradev || GP->commondev){if(camerainit) imfn = ccdcaptured;} // capture mode
|
||||
else imfn = NULL; // TODO - simple file viewer
|
||||
|
||||
95
server.c
95
server.c
@@ -43,6 +43,9 @@ static _Atomic cc_camera_state camstate = CAMERA_IDLE;
|
||||
static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes, infty = 0;
|
||||
static cc_frameformat frmformatmax = {0}, curformat = {0}; // maximal format
|
||||
|
||||
// image in shared memory
|
||||
static cc_IMG *ima = NULL;
|
||||
|
||||
static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions
|
||||
static int wmaxpos = 0.; // wheel max pos
|
||||
static float tremain = 0.; // time when capture done
|
||||
@@ -114,10 +117,10 @@ static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/
|
||||
// return TRUE if `locmutex` can be locked
|
||||
static int lock(){
|
||||
if(pthread_mutex_trylock(&locmutex)){
|
||||
//DBG("\n\nAlready locked");
|
||||
DBG("\n\nAlready locked &locmutex");
|
||||
return FALSE;
|
||||
}
|
||||
//DBG("LOCK()");
|
||||
//DBG("\n\nLOCK(&locmutex)");
|
||||
return TRUE;
|
||||
}
|
||||
static void unlock(){
|
||||
@@ -125,11 +128,9 @@ static void unlock(){
|
||||
LOGERR("Can't unlock socket mutex");
|
||||
ERR(_("Can't unlock socket mutex"));
|
||||
}
|
||||
//DBG("UNLOCK()");
|
||||
//DBG("\n\nUNLOCK(&locmutex)");
|
||||
}
|
||||
|
||||
static cc_IMG *ima = NULL;
|
||||
|
||||
// cleanup semaphore, stop server processes
|
||||
void stop_server(){
|
||||
isrunning = 0;
|
||||
@@ -139,6 +140,7 @@ void stop_server(){
|
||||
if(isrunning == -1) break;
|
||||
usleep(1000);
|
||||
}
|
||||
DBG("OK, remove semaphore...");
|
||||
// destroy semaphore
|
||||
cc_remove_sem();
|
||||
}
|
||||
@@ -150,8 +152,9 @@ static void fixima(){
|
||||
int locked = FALSE;
|
||||
TIMESTAMP("Lock socket");
|
||||
// lock socket operations
|
||||
while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(1000);
|
||||
while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(100000);
|
||||
if(!locked){
|
||||
LOGDBG("fixima(): force unlock");
|
||||
DBG("Still locked from outside -> unlock/lock");
|
||||
while(!lock()) unlock(); // force unlocking if can't do this gracefully
|
||||
}else DBG("LOCK takes %gs", sl_dtime()-t0);
|
||||
@@ -159,13 +162,16 @@ static void fixima(){
|
||||
TIMESTAMP("Check SHM image");
|
||||
// allocate memory for largest possible image
|
||||
if(!ima){
|
||||
ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
|
||||
size_t len = camera->array.h * camera->array.w * 2;
|
||||
ima = cc_getshm(GP->shmkey, len);
|
||||
if(!ima) ERR(_("Can't allocate memory for image"));
|
||||
ima->datasize = ima->bytelen;
|
||||
// init shared semaphore
|
||||
cc_init_sem(TRUE);
|
||||
}
|
||||
TIMESTAMP("Lock SHM image");
|
||||
cc_lock_shm(TRUE);
|
||||
LOGDBG("fixima(): SHM locked");
|
||||
shmkey = GP->shmkey;
|
||||
//if(raw_width == ima->w && raw_height == ima->h) return; // all OK
|
||||
DBG("curformat: %dx%d", curformat.w, curformat.h);
|
||||
@@ -179,12 +185,14 @@ static void fixima(){
|
||||
ima->bytelen = raw_height * raw_width * cc_getNbytes(ima);
|
||||
DBG("new image: %dx%d", raw_width, raw_height);
|
||||
cc_unlock_shm();
|
||||
LOGDBG("fixima(): SHM UNlocked");
|
||||
unlock();
|
||||
TIMESTAMP("All OK");
|
||||
}
|
||||
|
||||
// functions for processCAM finite state machine
|
||||
static inline void cameraidlestate(){ // idle - wait for capture commands
|
||||
static double Tcheck = 0.;
|
||||
if(camflags & FLAG_STARTCAPTURE){ // start capturing
|
||||
TIMESTAMP("Start exposition");
|
||||
camflags &= ~(FLAG_STARTCAPTURE | FLAG_CANCEL);
|
||||
@@ -194,15 +202,28 @@ static inline void cameraidlestate(){ // idle - wait for capture commands
|
||||
LOGERR("Camera plugin have no function `start exposition`");
|
||||
WARNX(_("Camera plugin have no function `start exposition`"));
|
||||
camstate = CAMERA_ERROR;
|
||||
return;
|
||||
}
|
||||
if(!camera->startexposition()){
|
||||
LOGERR("Can't start exposition");
|
||||
WARNX(_("Can't start exposition"));
|
||||
camstate = CAMERA_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(camstate == CAMERA_ERROR || (camstate == CAMERA_IDLE && sl_dtime() - Tcheck > 5.)){
|
||||
Tcheck = sl_dtime();
|
||||
if(!camera->check()){
|
||||
LOGERR("Camera disconnected");
|
||||
ERRX(_("Camera disconnected"));
|
||||
}
|
||||
if(camera->setDevNo && !camera->setDevNo(GP->camdevno)){
|
||||
LOGERR("Can't set active camera # %d, try 0", GP->camdevno);
|
||||
if(!camera->setDevNo(0)){
|
||||
LOGERR("Can't set active camera # 0, restart");
|
||||
ERRX(_("Something's wrong with camera"));
|
||||
}
|
||||
}
|
||||
camstate = CAMERA_IDLE;
|
||||
}
|
||||
}
|
||||
static inline void cameracapturestate(){ // capturing - wait for exposition ends
|
||||
cc_capture_status cs;
|
||||
@@ -221,6 +242,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
|
||||
return;
|
||||
}
|
||||
cc_lock_shm(TRUE);
|
||||
LOGDBG("cameracapturestate(): SHM locked");
|
||||
if(!camera->capture(ima)){
|
||||
LOGERR("Can't capture image");
|
||||
camstate = CAMERA_ERROR;
|
||||
@@ -233,6 +255,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
|
||||
++ima->imnumber; // increment counter
|
||||
}
|
||||
cc_unlock_shm();
|
||||
LOGDBG("cameracapturestate(): SHM UNlocked");
|
||||
TIMESTAMP("Captured and unlocked");
|
||||
}
|
||||
camstate = CAMERA_FRAMERDY;
|
||||
@@ -434,7 +457,7 @@ static cc_hresult binhandler(_U_ int fd, const char *key, const char *val){
|
||||
if(r){
|
||||
if(0 == strcmp(key, CC_CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin);
|
||||
else snprintf(buf, 63, "%s=%d", key, GP->vbin);
|
||||
if(val) fixima();
|
||||
//if(val) fixima();
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
}
|
||||
@@ -590,7 +613,7 @@ static cc_hresult formathandler(int fd, const char *key, const char *val){
|
||||
if(!r) return CC_RESULT_FAIL;
|
||||
curformat = fmt;
|
||||
DBG("curformat: w=%d, h=%d", curformat.w, curformat.h);
|
||||
fixima();
|
||||
//fixima();
|
||||
}
|
||||
if(0 == strcmp(key, CC_CMD_FRAMEMAX)) snprintf(buf, 63, CC_CMD_FRAMEMAX "=%d,%d,%d,%d",
|
||||
frmformatmax.xoff, frmformatmax.yoff, frmformatmax.xoff+frmformatmax.w, frmformatmax.yoff+frmformatmax.h);
|
||||
@@ -624,11 +647,11 @@ static cc_hresult expstatehandler(int fd, _U_ const char *key, const char *val){
|
||||
else if(n == CAMERA_CAPTURE){ // start exposition
|
||||
if(GP->exptime < 1e-9){ // need exposition time to be set
|
||||
return CC_RESULT_FAIL;
|
||||
}
|
||||
}/*
|
||||
if(camstate == CAMERA_CAPTURE){
|
||||
DBG("Capture in process when user ask '%s=%s'", key, val);
|
||||
return CC_RESULT_BUSY; // in progress
|
||||
}
|
||||
}*/
|
||||
TIMESTAMP("Get FLAG_STARTCAPTURE");
|
||||
TIMEINIT();
|
||||
camflags |= FLAG_STARTCAPTURE;
|
||||
@@ -658,7 +681,7 @@ static cc_hresult _8bithandler(int fd, _U_ const char *key, const char *val){
|
||||
int s = atoi(val);
|
||||
if(s != 0 && s != 1) return CC_RESULT_BADVAL;
|
||||
if(!camera->setbitdepth(!s)) return CC_RESULT_FAIL;
|
||||
fixima();
|
||||
//fixima();
|
||||
GP->_8bit = s;
|
||||
}
|
||||
snprintf(buf, 63, CC_CMD_8BIT "=%d", GP->_8bit);
|
||||
@@ -669,8 +692,10 @@ static cc_hresult imnohandler(int fd, const char *key, const char _U_ *val){
|
||||
if(!ima) return CC_RESULT_FAIL;
|
||||
char buf[64];
|
||||
cc_lock_shm(TRUE);
|
||||
LOGDBG("imnohandler(): SHM locked");
|
||||
int No = ima->imnumber;
|
||||
cc_unlock_shm();
|
||||
LOGDBG("imnohandler(): SHM UNlocked");
|
||||
snprintf(buf, 63, "%s=%d", key, No);
|
||||
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
|
||||
return CC_RESULT_SILENCE;
|
||||
@@ -1025,31 +1050,38 @@ static void *sendimage(void *C){
|
||||
int client = *(int*)C;
|
||||
if(ima->h < 1 || ima->w < 1) return NULL;
|
||||
DBG("client fd: %d", client);
|
||||
cc_lock_shm(TRUE);
|
||||
cc_IMG *locimage = calloc(1, sizeof(cc_IMG));
|
||||
void *data = calloc(1, ima->bytelen);
|
||||
if(!locimage || !data){
|
||||
cc_unlock_shm();
|
||||
if(data) free(data);
|
||||
if(locimage) free(locimage);
|
||||
double t0 = sl_dtime();
|
||||
int locked = FALSE;
|
||||
while(!(locked = cc_lock_shm(FALSE)) && sl_dtime() - t0 < MUTEX_LOCK_TMOUT);
|
||||
if(!locked){
|
||||
LOGERR("sendimage(): can't lock SHM");
|
||||
close(client);
|
||||
return NULL;
|
||||
}
|
||||
LOGDBG("sendimage(): SHM locked");
|
||||
cc_IMG *locimage = cc_newimage(ima->bitpix, ima->w, ima->h);
|
||||
if(!locimage || !cc_copyimage(locimage, ima, FALSE)){
|
||||
cc_unlock_shm();
|
||||
LOGDBG("sendimage(): SHM UNlocked");
|
||||
LOGERR("Can't copy new frame to local image");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(locimage, ima, sizeof(cc_IMG));
|
||||
memcpy(data, ima->data, ima->bytelen);
|
||||
cc_unlock_shm();
|
||||
LOGDBG("sendimage(): SHM UNlocked");
|
||||
do{
|
||||
// send image body
|
||||
if(!cc_senddata(client, locimage, sizeof(cc_IMG))) break;
|
||||
// send image itself (client can close socket if don't need image data)
|
||||
if(!cc_senddata(client, data, locimage->bytelen)) break;
|
||||
if(!cc_senddata(client, locimage->data, locimage->bytelen)) break;
|
||||
// send FITS header (client can close socket if don't need it)
|
||||
for(size_t i = 0; i < locimage->headerstrings; ++i){ // send header
|
||||
if(!cc_senddata(client, &locimage->fitsheader[i], FLEN_CARD)) break;
|
||||
}
|
||||
}while(0);
|
||||
free(locimage);
|
||||
free(data);
|
||||
close(client);
|
||||
shutdown(client, SHUT_WR); // tell client we are closing socket
|
||||
recv(client, locimage->data, locimage->bytelen, MSG_NOSIGNAL); // block until client close his side
|
||||
cc_freeimage(&locimage);
|
||||
close(client); // OK, we can close socket
|
||||
TIMESTAMP("Image sent");
|
||||
DBG("%d closed", client);
|
||||
return NULL;
|
||||
@@ -1069,6 +1101,7 @@ void server(int sock, int imsock){
|
||||
LOGERR("server(): error in listen() for command socket");
|
||||
return;
|
||||
}
|
||||
TIMEINIT();
|
||||
// init everything
|
||||
int ctr = 3;
|
||||
if(startFocuser()) --ctr;
|
||||
@@ -1079,7 +1112,7 @@ void server(int sock, int imsock){
|
||||
camdevini(0);
|
||||
if(ctr == 3){
|
||||
LOGERR("server(): no devices found");
|
||||
WARNX(_("No devices found"));
|
||||
ERRX(_("No devices found"));
|
||||
}
|
||||
// start camera thread
|
||||
pthread_t camthread;
|
||||
@@ -1123,7 +1156,7 @@ void server(int sock, int imsock){
|
||||
DBG("client=%d", client);
|
||||
// sending image could be a very long operation -> run it in separate thread
|
||||
if(client > -1){
|
||||
if(ima->imnumber == 0){
|
||||
if(!ima || ima->imnumber == 0){
|
||||
WARNX(_("Client wants an image, but there's no data"));
|
||||
close(client);
|
||||
}else{
|
||||
@@ -1267,7 +1300,9 @@ static int parsestring(int fd, cc_handleritem *handlers, char *str){
|
||||
if(h->handler) r = h->handler(fd, str, val);
|
||||
else r = CC_RESULT_FAIL;
|
||||
}
|
||||
if(l) unlock();
|
||||
if(l){
|
||||
unlock();
|
||||
}
|
||||
if(r == CC_RESULT_DISCONNECTED){
|
||||
DBG("handler return CC_RESULT_DISCONNECTED");
|
||||
return FALSE;
|
||||
|
||||
Reference in New Issue
Block a user