Esempio n. 1
0
zbar_image_t *zbar_video_next_image (zbar_video_t *vdo)
{
    unsigned frame;
    zbar_image_t *img;

    if(video_lock(vdo))
        return(NULL);
    if(!vdo->active) {
        video_unlock(vdo);
        return(NULL);
    }

    frame = vdo->frame++;
    img = vdo->dq(vdo);
    if(img) {
        img->seq = frame;
        if(vdo->num_images < 2) {
            /* return a *copy* of the video image and immediately recycle
             * the driver's buffer to avoid deadlocking the resources
             */
            zbar_image_t *tmp = img;
            video_lock(vdo);
            img = vdo->shadow_image;
            vdo->shadow_image = (img) ? img->next : NULL;
            video_unlock(vdo);
                
            if(!img) {
                img = zbar_image_create();
                assert(img);
                img->refcnt = 0;
                img->src = vdo;
                /* recycle the shadow images */

                img->format = vdo->format;
                zbar_image_set_size(img, vdo->width, vdo->height);
                img->datalen = vdo->datalen;
                img->data = malloc(vdo->datalen);
            }
            img->cleanup = _zbar_video_recycle_shadow;
            img->seq = frame;
            memcpy((void*)img->data, tmp->data, img->datalen);
            _zbar_video_recycle_image(tmp);
        }
        else
            img->cleanup = _zbar_video_recycle_image;
        _zbar_image_refcnt(img, 1);
    }
    return(img);
}
Esempio n. 2
0
int zbar_video_open (zbar_video_t *vdo,
                     const char *dev)
{
    char *ldev = NULL;
    int rc;
    zbar_video_enable(vdo, 0);
    video_lock(vdo);
    if(vdo->intf != VIDEO_INVALID) {
        if(vdo->cleanup) {
            vdo->cleanup(vdo);
            vdo->cleanup = NULL;
        }
        zprintf(1, "closed camera (fd=%d)\n", vdo->fd);
        vdo->intf = VIDEO_INVALID;
    }
    video_unlock(vdo);

    if(!dev)
        return(0);

    if((unsigned char)dev[0] < 0x10) {
        /* default linux device, overloaded for other platforms */
        int id = dev[0];
        dev = ldev = strdup("/dev/video0");
        ldev[10] = '0' + id;
    }

    rc = _zbar_video_open(vdo, dev);

    if(ldev)
        free(ldev);
    return(rc);
}
Esempio n. 3
0
static int v4l2_nq (zbar_video_t *vdo,
                    zbar_image_t *img)
{
    if(vdo->iomode == VIDEO_READWRITE)
        return(video_nq_image(vdo, img));

    if(video_unlock(vdo))
        return(-1);

    struct v4l2_buffer vbuf;
    memset(&vbuf, 0, sizeof(vbuf));
    vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if(vdo->iomode == VIDEO_MMAP) {
        vbuf.memory = V4L2_MEMORY_MMAP;
        vbuf.index = img->srcidx;
    }
    else {
        vbuf.memory = V4L2_MEMORY_USERPTR;
        vbuf.m.userptr = (unsigned long)img->data;
        vbuf.length = img->datalen;
        vbuf.index = img->srcidx; /* FIXME workaround broken drivers */
    }
    if(ioctl(vdo->fd, VIDIOC_QBUF, &vbuf) < 0)
        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                           "queuing video buffer (VIDIOC_QBUF)"));
    return(0);
}
Esempio n. 4
0
static void _zbar_video_recycle_shadow (zbar_image_t *img)
{
    zbar_video_t *vdo = img->src;
    assert(vdo);
    assert(img->srcidx == -1);
    video_lock(vdo);
    img->next = vdo->shadow_image;
    vdo->shadow_image = img;
    video_unlock(vdo);
}
Esempio n. 5
0
static zbar_image_t *v4l2_dq (zbar_video_t *vdo)
{
    zbar_image_t *img;
    int fd = vdo->fd;

    if(vdo->iomode != VIDEO_READWRITE) {
        video_iomode_t iomode = vdo->iomode;
        if(video_unlock(vdo))
            return(NULL);

        struct v4l2_buffer vbuf;
        memset(&vbuf, 0, sizeof(vbuf));
        vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if(iomode == VIDEO_MMAP)
            vbuf.memory = V4L2_MEMORY_MMAP;
        else
            vbuf.memory = V4L2_MEMORY_USERPTR;

        if(ioctl(fd, VIDIOC_DQBUF, &vbuf) < 0)
            return(NULL);

        if(iomode == VIDEO_MMAP) {
            assert(vbuf.index >= 0);
            assert(vbuf.index < vdo->num_images);
            img = vdo->images[vbuf.index];
        }
        else {
            /* reverse map pointer back to image (FIXME) */
            assert(vbuf.m.userptr >= (unsigned long)vdo->buf);
            assert(vbuf.m.userptr < (unsigned long)(vdo->buf + vdo->buflen));
            int i = (vbuf.m.userptr - (unsigned long)vdo->buf) / vdo->datalen;
            assert(i >= 0);
            assert(i < vdo->num_images);
            img = vdo->images[i];
            assert(vbuf.m.userptr == (unsigned long)img->data);
        }
    }
    else {
        img = video_dq_image(vdo);
        if(!img)
            return(NULL);

        /* FIXME should read entire image */
        unsigned long datalen = read(fd, (void*)img->data, img->datalen);
        if(datalen < 0)
            return(NULL);
        else if(datalen != img->datalen)
            zprintf(0, "WARNING: read() size mismatch: 0x%lx != 0x%lx\n",
                    datalen, img->datalen);
    }
    return(img);
}
Esempio n. 6
0
static void _zbar_video_recycle_image (zbar_image_t *img)
{
    zbar_video_t *vdo = img->src;
    assert(vdo);
    assert(img->srcidx >= 0);
    video_lock(vdo);
    if(vdo->images[img->srcidx] != img)
        vdo->images[img->srcidx] = img;
    if(vdo->active)
        vdo->nq(vdo, img);
    else
        video_unlock(vdo);
}
Esempio n. 7
0
static void scene_video_tick(void *data, float seconds)
{
	struct obs_scene *scene = data;
	struct obs_scene_item *item;

	video_lock(scene);
	item = scene->first_item;
	while (item) {
		if (item->item_render)
			gs_texrender_reset(item->item_render);
		item = item->next;
	}
	video_unlock(scene);

	UNUSED_PARAMETER(seconds);
}
Esempio n. 8
0
static void scene_video_render(void *data, gs_effect_t *effect)
{
	DARRAY(struct obs_scene_item*) remove_items;
	struct obs_scene *scene = data;
	struct obs_scene_item *item;

	da_init(remove_items);

	video_lock(scene);
	item = scene->first_item;

	gs_blend_state_push();
	gs_reset_blend_state();

	while (item) {
		if (obs_source_removed(item->source)) {
			struct obs_scene_item *del_item = item;
			item = item->next;

			remove_without_release(del_item);
			da_push_back(remove_items, &del_item);
			continue;
		}

		if (source_size_changed(item))
			update_item_transform(item);

		if (item->user_visible) {
			gs_matrix_push();
			gs_matrix_mul(&item->draw_transform);
			obs_source_video_render(item->source);
			gs_matrix_pop();
		}

		item = item->next;
	}

	gs_blend_state_pop();

	video_unlock(scene);

	for (size_t i = 0; i < remove_items.num; i++)
		obs_sceneitem_release(remove_items.array[i]);
	da_free(remove_items);

	UNUSED_PARAMETER(effect);
}
Esempio n. 9
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);
}
Esempio n. 10
0
int zbar_video_enable (zbar_video_t *vdo,
                       int enable)
{
    if(vdo->active == enable)
        return(0);

    if(enable) {
        if(vdo->intf == VIDEO_INVALID)
            return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                               "video device not opened"));

        if(!vdo->initialized &&
           zbar_negotiate_format(vdo, NULL))
            return(-1);
    }

    if(video_lock(vdo))
        return(-1);
    vdo->active = enable;
    if(enable) {
        /* enqueue all buffers */
        int i;
        for(i = 0; i < vdo->num_images; i++)
            if(vdo->nq(vdo, vdo->images[i]) ||
               ((i + 1 < vdo->num_images) && video_lock(vdo)))
                return(-1);
        
        return(vdo->start(vdo));
    }
    else {
        int i;
        for(i = 0; i < vdo->num_images; i++)
            vdo->images[i]->next = NULL;
        vdo->nq_image = vdo->dq_image = NULL;
        if(video_unlock(vdo))
            return(-1);

        return(vdo->stop(vdo));
    }
}
Esempio n. 11
0
// -----------------------------------------------------------------------------
static void *tracking_thread(void *arg)
{
    globals.tracking = 1;
    tracking_args_t *data = (tracking_args_t *)arg;
    track_coords_t coords;
    video_data_t vid_data;
    unsigned long buff_sz = 0;
    uint8_t *jpg_buf = NULL, *rgb_buff = NULL;
    int delta, frames_computed = 0, tracking_fps = 0, streaming_fps = 0;
    struct timespec t0, t1, tc;

    clock_gettime(CLOCK_REALTIME, &t0);
    while (data->running) {
        // lock the colordetect parameters and determine our tracking fps
        pthread_mutex_lock(&data->lock);
        streaming_fps = video_get_fps();
        tracking_fps = MIN(data->trackingRate, streaming_fps);
        pthread_mutex_unlock(&data->lock);

        // if tracking is disable - sleep and check for a change every second
        if (tracking_fps <= 0 || globals.tracking == 0) {
            sleep(1);
            continue;
        }

        // make synchronous frame read -- sleep for a second and retry on fail
        if (!video_lock(&vid_data, ACCESS_SYNC)) {
            syslog(LOG_ERR, "colordetect failed to lock frame\n");
            sleep(1);
            continue;
        }

        clock_gettime(CLOCK_REALTIME, &tc);
        delta = timespec_delta(&t0, &tc);
        if (((frames_computed * 1000000) / delta) >= tracking_fps) {
            video_unlock();
            continue;
        }

        // copy the jpeg to our buffer now that we're safely locked
        if (buff_sz < vid_data.length) {
            free(jpg_buf);
            buff_sz = vid_data.length;
            jpg_buf = (uint8_t *)malloc(buff_sz);
        }

        memcpy(jpg_buf, vid_data.data, vid_data.length);
        video_unlock();

        if (0 != jpeg_rd_mem(jpg_buf, buff_sz, &rgb_buff,
                             &coords.width, &coords.height)) {
            colordetect_hsl_fp32(rgb_buff, &data->color, &coords);
            frames_computed++;
        }

        pthread_mutex_lock(&data->coord_lock);

        // copy over the updated coordinates to the global struct
        globals.coords = coords;

        // inform any listeners that new data is available
        pthread_cond_broadcast(&globals.coord_cond);
        pthread_mutex_unlock(&data->coord_lock);

        if (frames_computed >= streaming_fps) {
            // every time we hit the streaming fps, dump out the tracking rate
            clock_gettime(CLOCK_REALTIME, &t1);
            real_t delta = timespec_delta(&t0, &t1) / (real_t)1000000;
            syslog(LOG_INFO, "tracking fps: %f\n", streaming_fps / delta);
            frames_computed = 0;
            t0 = t1;
        }
    }

    pthread_exit(NULL);
}
Esempio n. 12
0
static inline void full_unlock(struct obs_scene *scene)
{
	audio_unlock(scene);
	video_unlock(scene);
}