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); }
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); }
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); }
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)); } }
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); }
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); }
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); }
// ----------------------------------------------------------------------------- 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); }
static inline void full_lock(struct obs_scene *scene) { video_lock(scene); audio_lock(scene); }