Пример #1
0
/* separate thread to handle non-pollable video (v4l1) */
static void *proc_video_thread (void *arg)
{
    zebra_processor_t *proc = arg;
    proc_block_sigs();

    (void)proc_lock(proc);
    while(1) {
        /* wait for active to be set */
        assert(!proc->sem);
        assert(pthread_equal(proc->sem_owner, pthread_self()));
        pthread_mutex_lock(&proc->mutex);
        proc->sem++;
        pthread_cond_signal(&proc->cond);
        pthread_cleanup_push(proc_mutex_unlock, &proc->mutex);
        while(!proc->active)
            pthread_cond_wait(&proc->event, &proc->mutex);
        pthread_cleanup_pop(1);

        /* unlocked blocking image input */
        zebra_image_t *img = zebra_video_next_image(proc->video);
        if(!img)
            return(NULL);
        (void)proc_lock(proc);
        if(proc->active)
            process_image(proc, img);
        zebra_image_destroy(img);
    }
}
Пример #2
0
/* used by poll interface.  lock is already held */
static int proc_video_handler (zebra_processor_t *proc,
                               int i)
{
    if(!proc->active)
        return(0);
    /* not expected to block */
    zebra_image_t *img = zebra_video_next_image(proc->video);
    if(!img)
        return(-1);
    int rc = process_image(proc, img);
    zebra_image_destroy(img);
    return(rc);
}
Пример #3
0
static inline int proc_event_wait_unthreaded (zebra_processor_t *proc,
                                              unsigned event,
                                              int timeout,
                                              struct timespec *abstime)
{
    int blocking = proc->active && zebra_video_get_fd(proc->video) < 0;
    proc->events &= ~event;
    /* unthreaded, poll here for window input */
    while(!(proc->events & event)) {
        if(blocking) {
            zebra_image_t *img = zebra_video_next_image(proc->video);
            if(!img)
                return(-1);
            process_image(proc, img);
            zebra_image_destroy(img);
        }
        int reltime = timeout;
        if(reltime >= 0) {
            struct timespec now;
#if _POSIX_TIMERS > 0
            clock_gettime(CLOCK_REALTIME, &now);
#else
            struct timeval ustime;
            gettimeofday(&ustime, NULL);
            now.tv_nsec = ustime.tv_usec * 1000;
            now.tv_sec = ustime.tv_sec;
#endif
            reltime = ((abstime->tv_sec - now.tv_sec) * 1000 +
                       (abstime->tv_nsec - now.tv_nsec) / 1000000);
            if(reltime <= 0)
                return(0);
        }
        if(blocking && (reltime < 0 || reltime > 10))
            reltime = 10;
        if(proc->polling.num)
            proc_poll_inputs(proc, (poll_desc_t*)&proc->polling, reltime);
        else if(!blocking) {
            proc_unlock(proc);
            struct timespec sleepns, remns;
            sleepns.tv_sec = timeout / 1000;
            sleepns.tv_nsec = (timeout % 1000) * 1000000;
            while(nanosleep(&sleepns, &remns) && errno == EINTR)
                sleepns = remns;
            (void)proc_lock(proc);
            return(0);
        }
    }
    return(1);
}
Пример #4
0
/* lock is already held */
static inline int process_image (zebra_processor_t *proc,
                                 zebra_image_t *img)
{
    if(img) {
        uint32_t format = zebra_image_get_format(img);
        zprintf(16, "processing: %.4s(%08" PRIx32 ") %dx%d @%p\n",
                (char*)&format, format,
                zebra_image_get_width(img), zebra_image_get_height(img),
                zebra_image_get_data(img));

        /* FIXME locking all other interfaces while processing is conservative
         * but easier for now and we don't expect this to take long...
         */
        int nsyms = zebra_scan_image(proc->scanner, img);
        if(nsyms < 0)
            return(err_capture(proc, SEV_ERROR, ZEBRA_ERR_UNSUPPORTED,
                               __func__, "unknown image format"));

        if(_zebra_verbosity >= 8) {
            const zebra_symbol_t *sym = zebra_image_first_symbol(img);
            while(sym) {
                zebra_symbol_type_t type = zebra_symbol_get_type(sym);
                int count = zebra_symbol_get_count(sym);
                zprintf(8, "%s%s: %s (%s)\n",
                        zebra_get_symbol_name(type),
                        zebra_get_addon_name(type),
                        zebra_symbol_get_data(sym),
                        (count < 0) ? "uncertain" :
                        (count > 0) ? "duplicate" : "new");
                sym = zebra_symbol_next(sym);
            }
        }

        if(nsyms) {
            emit(proc, EVENT_OUTPUT);
            if(proc->handler)
                /* FIXME only call after filtering (unlocked...?) */
                proc->handler(img, proc->userdata);
        }

        if(proc->force_output) {
            img = zebra_image_convert(img, proc->force_output);
            if(!img)
                return(err_capture(proc, SEV_ERROR, ZEBRA_ERR_UNSUPPORTED,
                                   __func__, "unknown image format"));
        }
    }

    /* display to window if enabled */
    if(proc->window &&
       (zebra_window_draw(proc->window, img) ||
        _zebra_window_invalidate(proc->window)))
        return(err_copy(proc, proc->window));
#if 0
    /* FIXME still don't understand why we need this */
    if(proc->window && _zebra_window_handle_events(proc, 0))
        return(-1);
#endif
    if(proc->force_output && img)
        zebra_image_destroy(img);
    return(0);
}
Пример #5
0
int zebra_scan_image (zebra_image_scanner_t *iscn,
                      zebra_image_t *img)
{
    recycle_syms(iscn, img);

    /* get grayscale image, convert if necessary */
    /*img = zebra_image_convert(img, fourcc('Y','8','0','0'));*/
    if(!img)
        return(-1);

    unsigned w = zebra_image_get_width(img);
    unsigned h = zebra_image_get_height(img);
    const uint8_t *data = zebra_image_get_data(img);
    const uint8_t *p = data;
    int x = 0, y = 0;
#ifdef DEBUG_IMG_SCANNER
    movedelta(0, (h + 1) / 2);
#else
    movedelta(0, 8);
#endif

    if(zebra_scanner_new_scan(iscn->scn))
        symbol_handler(iscn, x, y);

    /* FIXME add density config api */
    /* FIXME less arbitrary lead-out default */
    int quiet = w / 32;
    if(quiet < 8)
        quiet = 8;

    while(y < h) {
        zprintf(32, "img_x+: %03x,%03x @%p\n", x, y, p);
        while(x < w) {
            ASSERT_POS;
            if(zebra_scan_y(iscn->scn, *p))
                symbol_handler(iscn, x, y);
            movedelta(1, 0);
        }
        quiet_border(iscn, quiet, x, y);

        movedelta(-1, 16);
        if(y >= h)
            break;

        zprintf(32, "img_x-: %03x,%03x @%p\n", x, y, p);
        while(x > 0) {
            ASSERT_POS;
            if(zebra_scan_y(iscn->scn, *p))
                symbol_handler(iscn, x, y);
            movedelta(-1, 0);
        }
        quiet_border(iscn, quiet, x, y);

        movedelta(1, 16);
#ifdef DEBUG_IMG_SCANNER
        break;
#endif
    }

#ifndef DEBUG_IMG_SCANNER
    x = y = 0;
    p = data;
    movedelta(8, 0);

    while(x < w) {
        zprintf(32, "img_y+: %03x,%03x @%p\n", x, y, p);
        while(y < h) {
            ASSERT_POS;
            if(zebra_scan_y(iscn->scn, *p))
                symbol_handler(iscn, x, y);
            movedelta(0, 1);
        }
        quiet_border(iscn, quiet, x, y);

        movedelta(16, -1);
        if(x >= w)
            break;

        zprintf(32, "img_y-: %03x,%03x @%p\n", x, y, p);
        while(y >= 0) {
            ASSERT_POS;
            if(zebra_scan_y(iscn->scn, *p))
                symbol_handler(iscn, x, y);
            movedelta(0, -1);
        }
        quiet_border(iscn, quiet, x, y);

        movedelta(16, 1);
    }
#endif

    /* flush scanner pipe */
    if(zebra_scanner_new_scan(iscn->scn))
        symbol_handler(iscn, x, y);

    /* release reference */
    zebra_image_destroy(img);
    return(iscn->img->nsyms);
}