Beispiel #1
0
int zbar_processor_init (zbar_processor_t *proc,
                         const char *dev,
                         int enable_display)
{
    int rc, input_threaded;
    
    _zbar_mutex_lock(&proc->mutex);
    _zbar_thread_stop(&proc->input_thread, &proc->mutex);
    
    _zbar_processor_lock(proc);
    _zbar_mutex_unlock(&proc->mutex);

    rc = 0;
   
    if(!dev && !enable_display)
        /* nothing to do */
        goto done;

    /* spawn input monitor thread */
    input_threaded = proc->threaded ;
    if(input_threaded &&
       _zbar_thread_start(&proc->input_thread, proc_input_thread, proc,
                          &proc->mutex)) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                         "spawning input thread");
        goto done;
    }

 done:
    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #2
0
static ZTHREAD proc_input_thread (void *arg)
{
    zbar_processor_t *proc = arg;
    zbar_thread_t *thread = &proc->input_thread;
    int rc;

    _zbar_mutex_lock(&proc->mutex);
    thread->running = 1;
    _zbar_event_trigger(&thread->activity);
    zprintf(4, "spawned input thread\n");

    rc = 0;
    while(thread->started && rc >= 0) {
        _zbar_mutex_unlock(&proc->mutex);
        rc = _zbar_processor_input_wait(proc, &thread->notify, -1);
        _zbar_mutex_lock(&proc->mutex);
    }

    _zbar_mutex_unlock(&proc->mutex);
    _zbar_processor_close(proc);
    _zbar_mutex_lock(&proc->mutex);

    thread->running = 0;
    _zbar_event_trigger(&thread->activity);
    _zbar_mutex_unlock(&proc->mutex);
    return(0);
}
Beispiel #3
0
void zbar_processor_set_userdata (zbar_processor_t *proc,
                                  void *userdata)
{
    _zbar_mutex_lock(&proc->mutex);
    proc->userdata = userdata;
    _zbar_mutex_unlock(&proc->mutex);
}
Beispiel #4
0
static __inline int proc_wait_unthreaded (zbar_processor_t *proc,
                                        proc_waiter_t *waiter,
                                        zbar_timer_t *timeout)
{
	int blocking = 0;// proc->streaming && zbar_video_get_fd(proc->video) < 0;
    _zbar_mutex_unlock(&proc->mutex);

    int rc = 1;
    while(rc > 0 && (waiter->events & EVENTS_PENDING)) {
        /* FIXME lax w/the locking (though shouldn't matter...) */
        //if(blocking) {
        //    zbar_image_t *img = zbar_video_next_image(proc->video);
        //    if(!img) {
        //        rc = -1;
        //        break;
        //    }

            /* FIXME reacquire API lock! (refactor w/video thread?) */
        //    _zbar_mutex_lock(&proc->mutex);
        //    _zbar_process_image(proc, img);
        //    zbar_image_destroy(img);
        //    _zbar_mutex_unlock(&proc->mutex);
        //}
        int reltime = _zbar_timer_check(timeout);
        if(blocking && (reltime < 0 || reltime > MAX_INPUT_BLOCK))
            reltime = MAX_INPUT_BLOCK;
        rc = _zbar_processor_input_wait(proc, NULL, reltime);
    }
    _zbar_mutex_lock(&proc->mutex);
    return(rc);
}
Beispiel #5
0
int _zbar_processor_handle_input (zbar_processor_t *proc,
                                  int input)
{
    int event = EVENT_INPUT;
    switch(input) {
    case -1:
        event |= EVENT_CANCELED;
        _zbar_processor_set_visible(proc, 0);
        err_capture(proc, SEV_WARNING, ZBAR_ERR_CLOSED, __func__,
                    "user closed display window");
        break;

    case 'd':
        proc->dumping = 1;
        return(0);

    case '+':
    case '=':
       
        break;

    case '-':
        
        break;
    }

    _zbar_mutex_lock(&proc->mutex);
    proc->input = input;
    if(input == -1 && proc->visible && proc->streaming)
        /* also cancel outstanding output waiters */
        event |= EVENT_OUTPUT;
    _zbar_processor_notify(proc, event);
    _zbar_mutex_unlock(&proc->mutex);
    return(input);
}
Beispiel #6
0
int zbar_process_one (zbar_processor_t *proc,
                      int timeout)
{
    proc_enter(proc);
    int streaming = proc->streaming;
    _zbar_mutex_unlock(&proc->mutex);

    int rc = 0;
    if(!proc->video) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                         "video input not initialized");
        goto done;
    }

    if(!streaming) {
        rc = zbar_processor_set_active(proc, 1);
        if(rc)
            goto done;
    }

    zbar_timer_t timer;
    rc = _zbar_processor_wait(proc, EVENT_OUTPUT,
                              _zbar_timer_init(&timer, timeout));

    if(!streaming && zbar_processor_set_active(proc, 0))
        rc = -1;

 done:
    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #7
0
int zbar_processor_set_visible (zbar_processor_t *proc,
                                int visible)
{
    proc_enter(proc);
    _zbar_mutex_unlock(&proc->mutex);

    int rc = 0;
    if(proc->window) {
        if(proc->video)
            rc = _zbar_processor_set_size(proc,
                                          zbar_video_get_width(proc->video),
                                          zbar_video_get_height(proc->video));
        if(!rc)
            rc = _zbar_processor_set_visible(proc, visible);

        if(!rc)
            proc->visible = (visible != 0);
    }
    else if(visible)
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                         "processor display window not initialized");

    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #8
0
int zbar_processor_user_wait (zbar_processor_t *proc,
                              int timeout)
{
    int rc;
    proc_enter(proc);
    _zbar_mutex_unlock(&proc->mutex);

    rc = -1;
    if(proc->visible || proc->streaming || timeout >= 0) {
        zbar_timer_t timer;
        rc = _zbar_processor_wait(proc, EVENT_INPUT,
                                  _zbar_timer_init(&timer, timeout));
    }

    if(!proc->visible)
        rc = err_capture(proc, SEV_WARNING, ZBAR_ERR_CLOSED, __func__,
                         "display window not available for input");

    if(rc > 0)
        rc = proc->input;

    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #9
0
void *zbar_processor_get_userdata (const zbar_processor_t *proc)
{
    zbar_processor_t *ncproc = (zbar_processor_t*)proc;
    _zbar_mutex_lock(&ncproc->mutex);
    void *userdata = (void*)ncproc->userdata;
    _zbar_mutex_unlock(&ncproc->mutex);
    return(userdata);
}
Beispiel #10
0
static ZTHREAD proc_video_thread (void *arg)
{
    zbar_processor_t *proc = arg;
    zbar_thread_t *thread = &proc->video_thread;

    _zbar_mutex_lock(&proc->mutex);
    _zbar_thread_init(thread);
    zprintf(4, "spawned video thread\n");

    while(thread->started) {
        /* wait for video stream to be active */
        while(thread->started && !proc->streaming)
            _zbar_event_wait(&thread->notify, &proc->mutex, NULL);
        if(!thread->started)
            break;

        /* blocking capture image from video */
        _zbar_mutex_unlock(&proc->mutex);
        zbar_image_t *img = zbar_video_next_image(proc->video);
        _zbar_mutex_lock(&proc->mutex);

        if(!img && !proc->streaming)
            continue;
        else if(!img)
            /* FIXME could abort streaming and keep running? */
            break;

        /* acquire API lock */
        _zbar_processor_lock(proc);
        _zbar_mutex_unlock(&proc->mutex);

        if(thread->started && proc->streaming)
            _zbar_process_image(proc, img);

        zbar_image_destroy(img);

        _zbar_mutex_lock(&proc->mutex);
        /* release API lock */
        _zbar_processor_unlock(proc, 0);
    }

    thread->running = 0;
    _zbar_event_trigger(&thread->activity);
    _zbar_mutex_unlock(&proc->mutex);
    return(0);
}
Beispiel #11
0
int zbar_processor_set_active (zbar_processor_t *proc,
                               int active)
{
    proc_enter(proc);

    int rc;
    if(!proc->video) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                         "video input not initialized");
        goto done;
    }
    _zbar_mutex_unlock(&proc->mutex);

    zbar_image_scanner_enable_cache(proc->scanner, active);

    rc = zbar_video_enable(proc->video, active);
    if(!rc) {
        _zbar_mutex_lock(&proc->mutex);
        proc->streaming = active;
        _zbar_mutex_unlock(&proc->mutex);
        rc = _zbar_processor_enable(proc);
    }
    else
        err_copy(proc, proc->video);

    if(!proc->streaming && proc->window) {
        if(zbar_window_draw(proc->window, NULL) && !rc)
            rc = err_copy(proc, proc->window);
        _zbar_processor_invalidate(proc);
    }

    _zbar_mutex_lock(&proc->mutex);
    if(proc->video_thread.started)
        _zbar_event_trigger(&proc->video_thread.notify);

 done:
    proc_leave(proc);
    return(rc);
}
Beispiel #12
0
static ZTHREAD vfw_capture_thread (void *arg)
{
    zbar_video_t *vdo = arg;
    video_state_t *state = vdo->state;
    zbar_thread_t *thr = &state->thread;

    state->hwnd = capCreateCaptureWindow(NULL, WS_POPUP, 0, 0, 1, 1, NULL, 0);
    if(!state->hwnd)
        goto done;

    _zbar_mutex_lock(&vdo->qlock);
    _zbar_thread_init(thr);
    zprintf(4, "spawned vfw capture thread (thr=%04lx)\n",
            _zbar_thread_self());

    MSG msg;
    int rc = 0;
    while(thr->started && rc >= 0 && rc <= 1) {
        _zbar_mutex_unlock(&vdo->qlock);

        rc = MsgWaitForMultipleObjects(1, &thr->notify, 0,
                                       INFINITE, QS_ALLINPUT);
        if(rc == 1)
            while(PeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_REMOVE))
                if(rc > 0) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }

        _zbar_mutex_lock(&vdo->qlock);
    }

 done:
    thr->running = 0;
    _zbar_event_trigger(&thr->activity);
    _zbar_mutex_unlock(&vdo->qlock);
    return(0);
}
Beispiel #13
0
int zbar_processor_set_visible (zbar_processor_t *proc,
                                int visible)
{
    int rc = 0;
    proc_enter(proc);
    _zbar_mutex_unlock(&proc->mutex);

    rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                         "processor display window not initialized");

    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #14
0
static LRESULT CALLBACK vfw_stream_cb (HWND hwnd,
                                       VIDEOHDR *hdr)
{
    if(!hwnd || !hdr)
        return(0);
    zbar_video_t *vdo = (void*)capGetUserData(hwnd);

    _zbar_mutex_lock(&vdo->qlock);
    zbar_image_t *img = vdo->state->image;
    if(!img) {
        _zbar_mutex_lock(&vdo->qlock);
        img = video_dq_image(vdo);
    }
    if(img) {
        img->data = hdr->lpData;
        img->datalen = hdr->dwBufferLength;
        vdo->state->image = img;
        SetEvent(vdo->state->captured);
    }
    _zbar_mutex_unlock(&vdo->qlock);

    return(1);
}
Beispiel #15
0
static int vfw_stop (zbar_video_t *vdo)
{
    video_state_t *state = vdo->state;
    if(!capCaptureAbort(state->hwnd))
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                           "stopping video stream"));

    _zbar_mutex_lock(&vdo->qlock);
    if(state->image)
        state->image = NULL;
    SetEvent(state->captured);
    _zbar_mutex_unlock(&vdo->qlock);
    return(0);
}
Beispiel #16
0
static LRESULT CALLBACK vfw_error_cb (HWND hwnd,
                                      int errid,
                                      const char *errmsg)
{
    if(!hwnd)
        return(0);
    zbar_video_t *vdo = (void*)capGetUserData(hwnd);
    zprintf(2, "id=%d msg=%s\n", errid, errmsg);
    _zbar_mutex_lock(&vdo->qlock);
    vdo->state->image = NULL;
    SetEvent(vdo->state->captured);
    _zbar_mutex_unlock(&vdo->qlock);
    return(1);
}
Beispiel #17
0
static int proc_kick_handler (zbar_processor_t *proc,
                              int i)
{
    processor_state_t *state = proc->state;
    //zprintf(5, "kicking %d fds\n", state->polling.num);

    unsigned junk[2];
    //int rc = read(state->kick_fds[0], junk, 2 * sizeof(unsigned));

    assert(proc->threaded);
    _zbar_mutex_lock(&proc->mutex);
    proc_cache_polling(proc->state);
    _zbar_mutex_unlock(&proc->mutex);
    //return(rc);
    return(-1);
}
Beispiel #18
0
/* lock must be held */
int _zbar_event_wait (zbar_event_t *event,
                      zbar_mutex_t *lock,
                      zbar_timer_t *timeout)
{
    if(lock)
        _zbar_mutex_unlock(lock);
    int rc = WaitForSingleObject(*event, _zbar_timer_check(timeout));
    if(lock)
        _zbar_mutex_lock(lock);

    if(!rc)
        return(1); /* got event */
    if(rc == WAIT_TIMEOUT)
        return(0); /* timed out */
    return(-1); /* error (FIXME save info) */
}
Beispiel #19
0
int zbar_process_image (zbar_processor_t *proc,
                        zbar_image_t *img)
{
    int rc;
    proc_enter(proc);
    _zbar_mutex_unlock(&proc->mutex);

    rc = 0;
    
    if(!rc) {
        zbar_image_scanner_enable_cache(proc->scanner, 0);
        rc = _zbar_process_image(proc, img);
        if(proc->streaming)
            zbar_image_scanner_enable_cache(proc->scanner, 1);
    }

    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #20
0
static zbar_image_t *vfw_dq (zbar_video_t *vdo)
{
    zbar_image_t *img = vdo->state->image;
    if(!img) {
        _zbar_mutex_unlock(&vdo->qlock);
        int rc = WaitForSingleObject(vdo->state->captured, INFINITE);
        _zbar_mutex_lock(&vdo->qlock);
        if(!rc)
            img = vdo->state->image;
        else
            img = NULL;
        /*FIXME handle errors? */
    }
    else
        ResetEvent(vdo->state->captured);
    if(img)
        vdo->state->image = NULL;

    video_unlock(vdo);
    return(img);
}
Beispiel #21
0
int zbar_process_image (zbar_processor_t *proc,
                        zbar_image_t *img)
{
    proc_enter(proc);
    _zbar_mutex_unlock(&proc->mutex);

    int rc = 0;
    if(img && proc->window)
        rc = _zbar_processor_set_size(proc,
                                      zbar_image_get_width(img),
                                      zbar_image_get_height(img));
    if(!rc) {
        zbar_image_scanner_enable_cache(proc->scanner, 0);
        rc = _zbar_process_image(proc, img);
        if(proc->streaming)
            zbar_image_scanner_enable_cache(proc->scanner, 1);
    }

    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}
Beispiel #22
0
int _zbar_processor_wait (zbar_processor_t *proc,
                          unsigned events,
                          zbar_timer_t *timeout)
{
    _zbar_mutex_lock(&proc->mutex);
    int save_level = proc->lock_level;
    proc_waiter_t *waiter = proc_waiter_queue(proc);
    waiter->events = events & EVENTS_PENDING;

    _zbar_processor_unlock(proc, 1);
    int rc;
    if(proc->threaded)
        rc = _zbar_event_wait(&waiter->notify, &proc->mutex, timeout);
    else
        rc = proc_wait_unthreaded(proc, waiter, timeout);

    if(rc <= 0 || !proc->threaded) {
        /* reacquire api lock */
        waiter->events &= EVENT_CANCELED;
        proc->wait_next = NULL;
        if(!proc->lock_level) {
            proc_waiter_t *w = proc_waiter_dequeue(proc);
            assert(w == waiter);
        }
        else
            _zbar_event_wait(&waiter->notify, &proc->mutex, NULL);
    }
    if(rc > 0 && (waiter->events & EVENT_CANCELED))
        rc = -1;

    assert(proc->lock_level == 1);
    assert(_zbar_thread_is_self(proc->lock_owner));

    proc->lock_level = save_level;
    proc_waiter_release(proc, waiter);
    _zbar_mutex_unlock(&proc->mutex);
    return(rc);
}
Beispiel #23
0
static __inline int proc_enter (zbar_processor_t *proc)
{
    _zbar_mutex_lock(&proc->mutex);
    return(_zbar_processor_lock(proc));
}
Beispiel #24
0
/* API lock is already held */
int _zbar_process_image (zbar_processor_t *proc,
                         zbar_image_t *img)
{
    uint32_t force_fmt = proc->force_output;
    int nsyms, rc;
    if(img) {
        zbar_image_t *tmp;
        uint32_t format = zbar_image_get_format(img);
        zprintf(16, "processing: %.4s(%08lx) %dx%d @%p\n",
                (char*)&format, format,
                zbar_image_get_width(img), zbar_image_get_height(img),
                zbar_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...
         */
        tmp = zbar_image_convert(img, fourcc('Y','8','0','0'));
        if(!tmp)
            goto error;

        if(proc->syms) {
            zbar_symbol_set_ref(proc->syms, -1);
            proc->syms = NULL;
        }
        zbar_image_scanner_recycle_image(proc->scanner, img);
        nsyms = zbar_scan_image(proc->scanner, tmp);
        _zbar_image_swap_symbols(img, tmp);

        zbar_image_destroy(tmp);
        tmp = NULL;
        if(nsyms < 0)
            goto error;

        proc->syms = zbar_image_scanner_get_results(proc->scanner);
        if(proc->syms)
            zbar_symbol_set_ref(proc->syms, 1);

        if(_zbar_verbosity >= 8) {
            const zbar_symbol_t *sym = zbar_image_first_symbol(img);
            while(sym) {
                zbar_symbol_type_t type = zbar_symbol_get_type(sym);
                int count = zbar_symbol_get_count(sym);
                zprintf(8, "%s%s: %s (%d pts) (q=%d) (%s)\n",
                        zbar_get_symbol_name(type),
                        zbar_get_addon_name(type),
                        zbar_symbol_get_data(sym),
                        zbar_symbol_get_loc_size(sym),
                        zbar_symbol_get_quality(sym),
                        (count < 0) ? "uncertain" :
                        (count > 0) ? "duplicate" : "new");
                sym = zbar_symbol_next(sym);
            }
        }

        if(nsyms) {
            /* FIXME only call after filtering */
            _zbar_mutex_lock(&proc->mutex);
            _zbar_processor_notify(proc, EVENT_OUTPUT);
            _zbar_mutex_unlock(&proc->mutex);
            if(proc->handler)
                proc->handler(img, proc->userdata);
        }

        if(force_fmt) {
            zbar_symbol_set_t *syms = img->syms;
            img = zbar_image_convert(img, force_fmt);
            if(!img)
                goto error;
            img->syms = syms;
            zbar_symbol_set_ref(syms, 1);
        }
    }

    /* display to window if enabled */
    rc = 0;
    
    if(force_fmt && img)
        zbar_image_destroy(img);
    return(rc);

error:
    return(err_capture(proc, SEV_ERROR, ZBAR_ERR_UNSUPPORTED,
                       __func__, "unknown image format"));
}
Beispiel #25
0
int zbar_processor_init (zbar_processor_t *proc,
                         const char *dev,
                         int enable_display)
{
    if(proc->video)
        zbar_processor_set_active(proc, 0);

    if(proc->window && !proc->input_thread.started)
        _zbar_processor_close(proc);

    _zbar_mutex_lock(&proc->mutex);
    _zbar_thread_stop(&proc->input_thread, &proc->mutex);
    _zbar_thread_stop(&proc->video_thread, &proc->mutex);

    _zbar_processor_lock(proc);
    _zbar_mutex_unlock(&proc->mutex);

    if(proc->window) {
        zbar_window_destroy(proc->window);
        proc->window = NULL;
    }

    int rc = 0;
    if(proc->video) {
        zbar_video_destroy(proc->video);
        proc->video = NULL;
    }

    if(!dev && !enable_display)
        /* nothing to do */
        goto done;

    if(enable_display) {
        proc->window = zbar_window_create();
        if(!proc->window) {
            rc = err_capture(proc, SEV_FATAL, ZBAR_ERR_NOMEM,
                             __func__, "allocating window resources");
            goto done;
        }
    }

    if(dev) {
        proc->video = zbar_video_create();
        if(!proc->video) {
            rc = err_capture(proc, SEV_FATAL, ZBAR_ERR_NOMEM,
                             __func__, "allocating video resources");
            goto done;
        }
        if(proc->req_width || proc->req_height)
            zbar_video_request_size(proc->video,
                                     proc->req_width, proc->req_height);
        if(proc->req_intf)
            zbar_video_request_interface(proc->video, proc->req_intf);
        if((proc->req_iomode &&
            zbar_video_request_iomode(proc->video, proc->req_iomode)) ||
           zbar_video_open(proc->video, dev)) {
            rc = err_copy(proc, proc->video);
            goto done;
        }
    }

    /* spawn blocking video thread */
    int video_threaded = (proc->threaded && proc->video &&
                          zbar_video_get_fd(proc->video) < 0);
    if(video_threaded &&
       _zbar_thread_start(&proc->video_thread, proc_video_thread, proc,
                          &proc->mutex)) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                         "spawning video thread");
        goto done;
    }

    /* spawn input monitor thread */
    int input_threaded = (proc->threaded &&
                          (proc->window ||
                           (proc->video && !video_threaded)));
    if(input_threaded &&
       _zbar_thread_start(&proc->input_thread, proc_input_thread, proc,
                          &proc->mutex)) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                         "spawning input thread");
        goto done;
    }

    if(proc->window && !input_threaded &&
       (rc = proc_open(proc)))
        goto done;

    if(proc->video && proc->force_input) {
        if(zbar_video_init(proc->video, proc->force_input))
            rc = err_copy(proc, proc->video);
    }
    else if(proc->video) {
        int retry = -1;
        if(proc->window) {
            retry = zbar_negotiate_format(proc->video, proc->window);
            if(retry)
                fprintf(stderr,
                        "WARNING: no compatible input to output format\n"
                        "...trying again with output disabled\n");
        }
        if(retry)
            retry = zbar_negotiate_format(proc->video, NULL);

        if(retry) {
            zprintf(1, "ERROR: no compatible %s format\n",
                    (proc->video) ? "video input" : "window output");
            rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_UNSUPPORTED,
                             __func__, "no compatible image format");
        }
    }

 done:
    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}