static void Inhibit (vlc_inhibit_t *ih, unsigned mask) { vlc_inhibit_sys_t *sys = ih->p_sys; bool suspend = (mask & VLC_INHIBIT_DISPLAY) != 0; mtime_t delay = suspend ? 30 * CLOCK_FREQ : INT64_C(0); vlc_timer_schedule (sys->timer, false, delay, delay); }
/** * Process one RTP packet from the de-jitter queue. */ static void rtp_process (void *data) { demux_t *demux = data; demux_sys_t *p_sys = demux->p_sys; mtime_t deadline; vlc_mutex_lock (&p_sys->lock); if (rtp_dequeue (demux, p_sys->session, &deadline)) vlc_timer_schedule (p_sys->timer, true, deadline, 0); vlc_mutex_unlock (&p_sys->lock); }
/** * Destroys an initialized timer. If needed, the timer is first disarmed. * This function is undefined if the specified timer is not initialized. * * @warning This function <b>must</b> be called before the timer data can be * freed and before the timer callback function can be unloaded. * * @param timer timer to destroy */ void vlc_timer_destroy (vlc_timer_t timer) { vlc_timer_schedule (timer, false, 0, 0); vlc_mutex_lock (&timer->lock); while (timer->users != 0) vlc_cond_wait (&timer->wait, &timer->lock); vlc_mutex_unlock (&timer->lock); vlc_cond_destroy (&timer->wait); vlc_mutex_destroy (&timer->lock); free (timer); }
static void CALLBACK vlc_timer_do (unsigned timer_id, unsigned msg, DWORD_PTR user, DWORD_PTR unused1, DWORD_PTR unused2) { struct vlc_timer *timer = (struct vlc_timer *) user; assert (timer_id == timer->id); (void) msg; (void) unused1; (void) unused2; timer->func (timer->data); if (timer->interval) { mtime_t interval = timer->interval * 1000; vlc_timer_schedule (timer, false, interval, interval); } }
/***************************************************************************** * CreateFilter: allocates RSS video filter *****************************************************************************/ static int CreateFilter( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; char *psz_urls; int i_ttl; /* Allocate structure */ p_sys = p_filter->p_sys = (filter_sys_t *)malloc( sizeof( filter_sys_t ) ); // sunqueen modify if( p_sys == NULL ) return VLC_ENOMEM; config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options, p_filter->p_cfg ); /* Get the urls to parse: must be non empty */ psz_urls = var_CreateGetNonEmptyString( p_filter, CFG_PREFIX "urls" ); if( !psz_urls ) { msg_Err( p_filter, "The list of urls must not be empty" ); free( p_sys ); return VLC_EGENERIC; } /* Fill the p_sys structure with the configuration */ p_sys->i_title = var_CreateGetInteger( p_filter, CFG_PREFIX "title" ); p_sys->i_cur_feed = 0; p_sys->i_cur_item = p_sys->i_title == scroll_title ? -1 : 0; p_sys->i_cur_char = 0; p_sys->i_feeds = 0; p_sys->p_feeds = NULL; p_sys->i_speed = var_CreateGetInteger( p_filter, CFG_PREFIX "speed" ); p_sys->i_length = var_CreateGetInteger( p_filter, CFG_PREFIX "length" ); p_sys->b_images = var_CreateGetBool( p_filter, CFG_PREFIX "images" ); i_ttl = __MAX( 0, var_CreateGetInteger( p_filter, CFG_PREFIX "ttl" ) ); p_sys->psz_marquee = (char *)malloc( p_sys->i_length + 1 ); // sunqueen modify if( p_sys->psz_marquee == NULL ) { free( psz_urls ); free( p_sys ); return VLC_ENOMEM; } p_sys->psz_marquee[p_sys->i_length] = '\0'; p_sys->p_style = text_style_New(); if( p_sys->p_style == NULL ) goto error; p_sys->i_xoff = var_CreateGetInteger( p_filter, CFG_PREFIX "x" ); p_sys->i_yoff = var_CreateGetInteger( p_filter, CFG_PREFIX "y" ); p_sys->i_pos = var_CreateGetInteger( p_filter, CFG_PREFIX "position" ); p_sys->p_style->i_font_alpha = 255 - var_CreateGetInteger( p_filter, CFG_PREFIX "opacity" ); p_sys->p_style->i_font_color = var_CreateGetInteger( p_filter, CFG_PREFIX "color" ); p_sys->p_style->i_font_size = var_CreateGetInteger( p_filter, CFG_PREFIX "size" ); if( p_sys->b_images && p_sys->p_style->i_font_size == -1 ) { msg_Warn( p_filter, "rss-size wasn't specified. Feed images will thus be displayed without being resized" ); } /* Parse the urls */ if( ParseUrls( p_filter, psz_urls ) ) goto error; /* Misc init */ vlc_mutex_init( &p_sys->lock ); p_filter->pf_sub_source = Filter; p_sys->last_date = (mtime_t)0; p_sys->b_fetched = false; /* Create and arm the timer */ if( vlc_timer_create( &p_sys->timer, Fetch, p_filter ) ) { vlc_mutex_destroy( &p_sys->lock ); goto error; } vlc_timer_schedule( p_sys->timer, false, 1, (mtime_t)(i_ttl)*1000000 ); free( psz_urls ); return VLC_SUCCESS; error: if( p_sys->p_style ) text_style_Delete( p_sys->p_style ); free( p_sys->psz_marquee ); free( psz_urls ); free( p_sys ); return VLC_ENOMEM; }
static void Inhibit( vlc_inhibit_t *p_ih, bool suspend ) { mtime_t d = suspend ? 30*CLOCK_FREQ : 0; vlc_timer_schedule( p_ih->p_sys->timer, false, d, d ); }
/** * Probes and initializes. */ static int Open (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; demux_sys_t *p_sys = malloc (sizeof (*p_sys)); if (p_sys == NULL) return VLC_ENOMEM; demux->p_sys = p_sys; /* Connect to X server */ char *display = var_InheritString (obj, "x11-display"); int snum; xcb_connection_t *conn = xcb_connect (display, &snum); free (display); if (xcb_connection_has_error (conn)) { free (p_sys); return VLC_EGENERIC; } p_sys->conn = conn; /* Find configured screen */ if (!strcmp (demux->psz_access, "screen")) { const xcb_setup_t *setup = xcb_get_setup (conn); const xcb_screen_t *scr = NULL; for (xcb_screen_iterator_t i = xcb_setup_roots_iterator (setup); i.rem > 0; xcb_screen_next (&i)) { if (snum == 0) { scr = i.data; break; } snum--; } if (scr == NULL) { msg_Err (obj, "bad X11 screen number"); goto error; } p_sys->window = scr->root; } else /* Determine capture window */ if (!strcmp (demux->psz_access, "window")) { char *end; unsigned long ul = strtoul (demux->psz_location, &end, 0); if (*end || ul > 0xffffffff) { msg_Err (obj, "bad X11 drawable %s", demux->psz_location); goto error; } p_sys->window = ul; xcb_composite_query_version_reply_t *r = xcb_composite_query_version_reply (conn, xcb_composite_query_version (conn, 0, 4), NULL); if (r == NULL || r->minor_version < 2) { msg_Err (obj, "X Composite extension not available"); free (r); goto error; } msg_Dbg (obj, "using Composite extension v%"PRIu32".%"PRIu32, r->major_version, r->minor_version); free (r); xcb_composite_redirect_window (conn, p_sys->window, XCB_COMPOSITE_REDIRECT_AUTOMATIC); } else goto error; /* Window properties */ p_sys->pixmap = xcb_generate_id (conn); p_sys->w = var_InheritInteger (obj, "screen-width"); p_sys->h = var_InheritInteger (obj, "screen-height"); if (p_sys->w != 0 || p_sys->h != 0) p_sys->follow_mouse = var_InheritBool (obj, "screen-follow-mouse"); else /* Following mouse is meaningless if width&height are dynamic. */ p_sys->follow_mouse = false; if (!p_sys->follow_mouse) /* X and Y are meaningless if following mouse */ { p_sys->x = var_InheritInteger (obj, "screen-left"); p_sys->y = var_InheritInteger (obj, "screen-top"); } /* Initializes format */ p_sys->rate = var_InheritFloat (obj, "screen-fps"); if (!p_sys->rate) goto error; p_sys->interval = (float)CLOCK_FREQ / p_sys->rate; if (!p_sys->interval) goto error; var_Create (obj, "screen-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT); p_sys->cur_w = 0; p_sys->cur_h = 0; p_sys->es = NULL; p_sys->pts = VLC_TS_INVALID; if (vlc_timer_create (&p_sys->timer, Demux, demux)) goto error; vlc_timer_schedule (p_sys->timer, false, 1, p_sys->interval); /* Initializes demux */ demux->pf_demux = NULL; demux->pf_control = Control; return VLC_SUCCESS; error: xcb_disconnect (p_sys->conn); free (p_sys); return VLC_EGENERIC; }
/** * Control callback */ static int Control (demux_t *demux, int query, va_list args) { demux_sys_t *p_sys = demux->p_sys; switch (query) { case DEMUX_GET_POSITION: { float *v = va_arg (args, float *); *v = 0.; return VLC_SUCCESS; } case DEMUX_GET_LENGTH: case DEMUX_GET_TIME: { int64_t *v = va_arg (args, int64_t *); *v = 0; return VLC_SUCCESS; } /* TODO: get title info -> crawl visible windows */ case DEMUX_GET_PTS_DELAY: { int64_t *v = va_arg (args, int64_t *); *v = var_GetInteger (demux, "screen-caching") * UINT64_C(1000); return VLC_SUCCESS; } case DEMUX_CAN_PAUSE: { bool *v = (bool*)va_arg( args, bool * ); *v = true; return VLC_SUCCESS; } case DEMUX_SET_PAUSE_STATE: { bool pausing = va_arg (args, int); if (!pausing) { vlc_mutex_lock (&p_sys->lock); p_sys->pts = VLC_TS_INVALID; es_out_Control (demux->out, ES_OUT_RESET_PCR); vlc_mutex_unlock (&p_sys->lock); } vlc_timer_schedule (p_sys->timer, false, pausing ? 0 : 1, p_sys->interval); return VLC_SUCCESS; } case DEMUX_CAN_CONTROL_PACE: case DEMUX_CAN_CONTROL_RATE: case DEMUX_CAN_SEEK: { bool *v = (bool*)va_arg( args, bool * ); *v = false; return VLC_SUCCESS; } } return VLC_EGENERIC; }
/** * Probes and initializes. */ static int Open (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; demux_sys_t *p_sys = malloc (sizeof (*p_sys)); if (p_sys == NULL) return VLC_ENOMEM; demux->p_sys = p_sys; /* Connect to X server */ char *display = var_CreateGetNonEmptyString (obj, "x11-display"); int snum; xcb_connection_t *conn = xcb_connect (display, &snum); free (display); if (xcb_connection_has_error (conn)) { free (p_sys); return VLC_EGENERIC; } p_sys->conn = conn; /* Find configured screen */ const xcb_setup_t *setup = xcb_get_setup (conn); const xcb_screen_t *scr = NULL; for (xcb_screen_iterator_t i = xcb_setup_roots_iterator (setup); i.rem > 0; xcb_screen_next (&i)) { if (snum == 0) { scr = i.data; break; } snum--; } if (scr == NULL) { msg_Err (obj, "bad X11 screen number"); goto error; } /* Determine capture window */ p_sys->root = scr->root; if (!strcmp (demux->psz_access, "screen")) p_sys->window = p_sys->root; else if (!strcmp (demux->psz_access, "window")) { char *end; unsigned long ul = strtoul (demux->psz_path, &end, 0); if (*end || ul > 0xffffffff) { msg_Err (obj, "bad X11 drawable %s", demux->psz_path); goto error; } p_sys->window = ul; } else goto error; /* Window properties */ p_sys->x = var_CreateGetInteger (obj, "screen-left"); p_sys->y = var_CreateGetInteger (obj, "screen-top"); p_sys->w = var_CreateGetInteger (obj, "screen-width"); p_sys->h = var_CreateGetInteger (obj, "screen-height"); uint32_t chroma = 0; uint8_t bpp; for (const xcb_format_t *fmt = xcb_setup_pixmap_formats (setup), *end = fmt + xcb_setup_pixmap_formats_length (setup); fmt < end; fmt++) { if (fmt->depth != scr->root_depth) continue; bpp = fmt->depth; switch (fmt->depth) { case 32: if (fmt->bits_per_pixel == 32) chroma = VLC_CODEC_RGBA; break; case 24: if (fmt->bits_per_pixel == 32) { chroma = VLC_CODEC_RGB32; bpp = 32; } else if (fmt->bits_per_pixel == 24) chroma = VLC_CODEC_RGB24; break; case 16: if (fmt->bits_per_pixel == 16) chroma = VLC_CODEC_RGB16; break; case 15: if (fmt->bits_per_pixel == 16) chroma = VLC_CODEC_RGB15; break; case 8: /* XXX: screw grey scale! */ if (fmt->bits_per_pixel == 8) chroma = VLC_CODEC_RGB8; break; } if (chroma != 0) break; } if (!chroma) { msg_Err (obj, "unsupported pixmap formats"); goto error; } /* Initializes format */ float rate = var_CreateGetFloat (obj, "screen-fps"); if (!rate) goto error; p_sys->interval = (float)CLOCK_FREQ / rate; if (!p_sys->interval) goto error; var_Create (obj, "screen-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT); es_format_Init (&p_sys->fmt, VIDEO_ES, chroma); p_sys->fmt.video.i_chroma = chroma; p_sys->fmt.video.i_bits_per_pixel = bpp; p_sys->fmt.video.i_sar_num = p_sys->fmt.video.i_sar_den = 1; p_sys->fmt.video.i_frame_rate = 1000 * rate; p_sys->fmt.video.i_frame_rate_base = 1000; p_sys->es = NULL; p_sys->pts = VLC_TS_INVALID; vlc_mutex_init (&p_sys->lock); if (vlc_timer_create (&p_sys->timer, Demux, demux)) goto error; vlc_timer_schedule (p_sys->timer, false, 1, p_sys->interval); /* Initializes demux */ demux->pf_demux = NULL; demux->pf_control = Control; return VLC_SUCCESS; error: xcb_disconnect (p_sys->conn); free (p_sys); return VLC_EGENERIC; }
int main (void) { struct timer_data data; mtime_t ts; int val; vlc_mutex_init (&data.lock); vlc_cond_init (&data.wait); data.count = 0; val = vlc_timer_create (&data.timer, callback, &data); assert (val == 0); vlc_timer_destroy (data.timer); assert (data.count == 0); val = vlc_timer_create (&data.timer, callback, &data); assert (val == 0); vlc_timer_schedule (data.timer, false, CLOCK_FREQ << 20, CLOCK_FREQ); vlc_timer_destroy (data.timer); assert (data.count == 0); val = vlc_timer_create (&data.timer, callback, &data); assert (val == 0); /* Relative timer */ ts = mdate (); vlc_timer_schedule (data.timer, false, 1, CLOCK_FREQ / 100); vlc_mutex_lock (&data.lock); while (data.count <= 10) vlc_cond_wait(&data.wait, &data.lock); ts = mdate () - ts; printf ("%u iterations in %"PRId64" us\n", data.count, ts); data.count = 0; vlc_mutex_unlock (&data.lock); assert(ts >= (CLOCK_FREQ / 10)); vlc_timer_schedule (data.timer, false, 0, 0); /* Absolute timer */ ts = mdate (); vlc_timer_schedule (data.timer, true, ts + CLOCK_FREQ / 10, CLOCK_FREQ / 100); vlc_mutex_lock (&data.lock); while (data.count <= 10) vlc_cond_wait(&data.wait, &data.lock); ts = mdate () - ts; printf ("%u iterations in %"PRId64" us\n", data.count, ts); vlc_mutex_unlock (&data.lock); assert(ts >= (CLOCK_FREQ / 5)); vlc_timer_destroy (data.timer); vlc_cond_destroy (&data.wait); vlc_mutex_destroy (&data.lock); return 0; }