void load_tab(unsigned char tab) { struct widget_config *w_cfg; DTABS("Loading tab %d\n", tab); /* stop rendering */ video_pause(); /* reset widgets module */ widgets_reset(); /* default video profile */ video_apply_config(0); if (tab == 0) { w_cfg = (struct widget_config*) tab0_widgets; } else { w_cfg = config.widgets; } /* load widgets config */ while (w_cfg->tab != TABS_END) { if (w_cfg->tab == tab) load_widget_config(w_cfg); w_cfg++; } load_widgets(); /* resume video rendering */ video_resume(); active_tab = tab; DTABS("Loaded\n"); }
int video_stop() { if (video_pause() != VIDEO_OK) return VIDEO_ERROR; if (video_seek(0, VIDEO_SEEK_ABSOLUTE) != VIDEO_OK) return VIDEO_ERROR; return VIDEO_OK; }
void load_tab(unsigned char tab) { struct widget_config *w_cfg = &config.widgets[0]; struct widget *w; struct widget_config tmp_wcfg; struct widget **aw = active_widgets; DTABS("Loading tab %d\n", tab); /* stop rendering */ video_pause(); while ((*aw) != NULL) { if ((*aw)->ops->close != NULL) { DTABS("closing widget %p: %s\n", *aw, (*aw)->ops->name); (*aw)->ops->close(*aw); } aw++; } aw = active_widgets; /* reset widgets module */ widgets_reset(); if (tab == 0) { /* zero tab */ /* console */ tmp_wcfg.widget_id = WIDGET_CONSOLE_ID; tmp_wcfg.x = 0; tmp_wcfg.y = 0; tmp_wcfg.props.vjust = VJUST_TOP; tmp_wcfg.props.hjust = HJUST_LEFT; w = load_widget(&tmp_wcfg); tmp_wcfg.widget_id = WIDGET_VIDEOLVL_ID; tmp_wcfg.props.hjust = HJUST_RIGHT; w = load_widget(&tmp_wcfg); } else { /* load tab widgets */ while (w_cfg->tab != TABS_END) { if (w_cfg->tab == tab) { w = load_widget(w_cfg); if (w == NULL) break; *(aw++) = w; } w_cfg++; } } *aw = NULL; /* resume video rendering */ video_resume(); active_tab = tab; DTABS("Loaded\n"); }
/****************************************************************************** Description.: this thread worker grabs a frame and copies it to the global buffer Input Value.: unused Return Value: unused, always NULL ******************************************************************************/ void *cam_thread(void *arg) { int cid = 0, id = (int)arg; context *activecam, *pcontext = &cams[id]; pglobal = pcontext->pglobal; activecam = pcontext; /* set cleanup handler to cleanup allocated ressources */ pthread_cleanup_push(cam_cleanup, pcontext); while(!pglobal->stop) { if(cid != camera) { video_pause(activecam->videoIn); cid = camera; activecam = &cams[id + cid]; IPRINT("Switch to camera..: %s\n", mdev[cid]); video_unpause(activecam->videoIn); } while(activecam->videoIn->streamingState == STREAMING_PAUSED) { usleep(1); // maybe not the best way so FIXME } /* grab a frame */ if(uvcGrab(activecam->videoIn) < 0) { IPRINT("Error grabbing frames\n"); exit(EXIT_FAILURE); } DBG("received frame of size: %d from plugin: %d\n", activecam->videoIn->buf.bytesused, activecam->id); /* * Workaround for broken, corrupted frames: * Under low light conditions corrupted frames may get captured. * The good thing is such frames are quite small compared to the regular pictures. * For example a VGA (640x480) webcam picture is normally >= 8kByte large, * corrupted frames are smaller. */ if(activecam->videoIn->buf.bytesused < minimum_size) { DBG("dropping too small frame, assuming it as broken\n"); continue; } /* copy JPG picture to global buffer */ pthread_mutex_lock(&pglobal->in[pcontext->id].db); /* * If capturing in YUV mode convert to JPEG now. * This compression requires many CPU cycles, so try to avoid YUV format. * Getting JPEGs straight from the webcam, is one of the major advantages of * Linux-UVC compatible devices. */ if(activecam->videoIn->formatIn == V4L2_PIX_FMT_YUYV) { DBG("compressing frame from input: %d\n", (int)activecam->id); pglobal->in[pcontext->id].size = compress_yuyv_to_jpeg(activecam->videoIn, pglobal->in[pcontext->id].buf, activecam->videoIn->framesizeIn, gquality); } else { DBG("copying frame from input: %d\n", (int)activecam->id); pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, activecam->videoIn->tmpbuffer, activecam->videoIn->buf.bytesused); } /* copy this frame's timestamp to user space */ pglobal->in[pcontext->id].timestamp = activecam->videoIn->buf.timestamp; /* signal fresh_frame */ pthread_cond_broadcast(&pglobal->in[pcontext->id].db_update); pthread_mutex_unlock(&pglobal->in[pcontext->id].db); /* only use usleep if the fps is below 5, otherwise the overhead is too long */ if(activecam->videoIn->fps < 5) { DBG("waiting for next frame for %d us\n", 1000 * 1000 / activecam->videoIn->fps); usleep(1000 * 1000 / activecam->videoIn->fps); } else { DBG("waiting for next frame\n"); } } DBG("leaving input thread, calling cleanup function now\n"); pthread_cleanup_pop(1); return NULL; }
int dtvideo_pause (void *video_priv) { dtvideo_context_t *vctx = (dtvideo_context_t *) video_priv; return video_pause (vctx); }
void video_stop(int id) { video_pause(id); video_set_seek(id, 0); }