Exemplo n.º 1
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);
}
Exemplo n.º 2
0
static void *zbar_gtk_processing_thread (void *arg)
{
    ZBarGtk *self = ZBAR_GTK(arg);
    if(!self->_private)
        return(NULL);
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);
    g_object_ref(zbar);
    g_assert(zbar->queue);
    g_async_queue_ref(zbar->queue);

    zbar->scanner = zbar_image_scanner_create();
    g_assert(zbar->scanner);

    /* thread side enabled state */
    gboolean video_enabled = FALSE;
    GValue *msg = NULL;

    while(TRUE) {
        if(!msg)
            msg = g_async_queue_pop(zbar->queue);
        g_assert(G_IS_VALUE(msg));

        GType type = G_VALUE_TYPE(msg);
        if(type == G_TYPE_INT) {
            /* video state change */
            int state = g_value_get_int(msg);
            if(state < 0) {
                /* terminate processing thread */
                g_value_unset(msg);
                g_free(msg);
                msg = NULL;
                break;
            }
            g_assert(state >= 0 && state <= 1);
            video_enabled = (state != 0);
        }
        else if(type == G_TYPE_STRING) {
            /* open new video device */
            const char *video_device = g_value_get_string(msg);
            video_enabled = zbar_gtk_video_open(self, video_device);
        }
        else if(type == GDK_TYPE_PIXBUF) {
            /* scan provided image and broadcast results */
            zbar_image_t *image = zbar_image_create();
            GdkPixbuf *pixbuf = GDK_PIXBUF(g_value_dup_object(msg));
            if(zbar_gtk_image_from_pixbuf(image, pixbuf))
                zbar_gtk_process_image(self, image);
            else
                g_object_unref(pixbuf);
            zbar_image_destroy(image);
        }
        else {
            gchar *dbg = g_strdup_value_contents(msg);
            g_warning("unknown message type (%x) passed to thread: %s\n",
                      (unsigned)type, dbg);
            g_free(dbg);
        }
        g_value_unset(msg);
        g_free(msg);
        msg = NULL;

        if(video_enabled) {
            /* release reference to any previous pixbuf */
            zbar_window_draw(zbar->window, NULL);

            if(zbar_video_enable(zbar->video, 1)) {
                zbar_video_error_spew(zbar->video, 0);
                video_enabled = FALSE;
                continue;
            }
            zbar_image_scanner_enable_cache(zbar->scanner, 1);

            while(video_enabled &&
                  !(msg = g_async_queue_try_pop(zbar->queue))) {
                zbar_image_t *image = zbar_video_next_image(zbar->video);
                if(zbar_gtk_process_image(self, image) < 0)
                    video_enabled = FALSE;
                if(image)
                    zbar_image_destroy(image);
            }

            zbar_image_scanner_enable_cache(zbar->scanner, 0);
            if(zbar_video_enable(zbar->video, 0)) {
                zbar_video_error_spew(zbar->video, 0);
                video_enabled = FALSE;
            }
            /* release video image and revert to logo */
            if(zbar->window) {
                zbar_window_draw(zbar->window, NULL);
                gtk_widget_queue_draw(GTK_WIDGET(self));
            }

            if(!video_enabled)
                /* must have been an error while streaming */
                zbar_gtk_video_open(self, NULL);
        }
    }
    if(zbar->window)
        zbar_window_draw(zbar->window, NULL);
    g_object_unref(zbar);
    return(NULL);
}