/** * Initializes an asynchronous timer. * @warning Asynchronous timers are processed from an unspecified thread. * Multiple occurences of a single interval timer are serialized; they cannot * run concurrently. * * @param id pointer to timer to be initialized * @param func function that the timer will call * @param data parameter for the timer function * @return 0 on success, a system error code otherwise. */ int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data) { struct vlc_timer *timer = malloc (sizeof (*timer)); if (unlikely(timer == NULL)) return ENOMEM; vlc_mutex_init (&timer->lock); vlc_cond_init (&timer->reschedule); assert (func); timer->func = func; timer->data = data; timer->value = 0; timer->interval = 0; vlc_atomic_set(&timer->overruns, 0); if (vlc_clone (&timer->thread, vlc_timer_thread, timer, VLC_THREAD_PRIORITY_INPUT)) { vlc_cond_destroy (&timer->reschedule); vlc_mutex_destroy (&timer->lock); free (timer); return ENOMEM; } *id = timer; return 0; }
/** * Delete an update_t struct * * \param p_update update_t* pointer * \return nothing */ void update_Delete( update_t *p_update ) { assert( p_update ); if( p_update->p_check ) { vlc_join( p_update->p_check->thread, NULL ); free( p_update->p_check ); } if( p_update->p_download ) { vlc_atomic_set( &p_update->p_download->aborted, 1 ); vlc_join( p_update->p_download->thread, NULL ); vlc_object_release( p_update->p_download ); } vlc_mutex_destroy( &p_update->lock ); free( p_update->release.psz_url ); free( p_update->release.psz_desc ); free( p_update->p_pkey ); free( p_update ); }
/** * Marks the audio output for restart, to update any parameter of the output * plug-in (e.g. output device or channel mapping). */ void aout_RequestRestart (audio_output_t *aout) { aout_owner_t *owner = aout_owner (aout); /* DO NOT remove AOUT_RESTART_INPUT. You need to change the atomic ops. */ vlc_atomic_set (&owner->restart, AOUT_RESTART_OUTPUT|AOUT_RESTART_INPUT); }
picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_resource_t *p_resource ) { video_format_t fmt = *p_fmt; /* It is needed to be sure all information are filled */ video_format_Setup( &fmt, p_fmt->i_chroma, p_fmt->i_width, p_fmt->i_height, p_fmt->i_sar_num, p_fmt->i_sar_den ); if( p_fmt->i_x_offset < p_fmt->i_width && p_fmt->i_y_offset < p_fmt->i_height && p_fmt->i_visible_width > 0 && p_fmt->i_x_offset + p_fmt->i_visible_width <= p_fmt->i_width && p_fmt->i_visible_height > 0 && p_fmt->i_y_offset + p_fmt->i_visible_height <= p_fmt->i_height ) video_format_CopyCrop( &fmt, p_fmt ); /* */ picture_t *p_picture = calloc( 1, sizeof(*p_picture) ); if( !p_picture ) return NULL; /* Make sure the real dimensions are a multiple of 16 */ if( picture_Setup( p_picture, fmt.i_chroma, fmt.i_width, fmt.i_height, fmt.i_sar_num, fmt.i_sar_den ) ) { free( p_picture ); return NULL; } if( p_resource ) { p_picture->p_sys = p_resource->p_sys; p_picture->gc.pf_destroy = p_resource->pf_destroy; assert( p_picture->gc.p_sys == NULL ); for( int i = 0; i < p_picture->i_planes; i++ ) { p_picture->p[i].p_pixels = p_resource->p[i].p_pixels; p_picture->p[i].i_lines = p_resource->p[i].i_lines; p_picture->p[i].i_pitch = p_resource->p[i].i_pitch; } } else { if( AllocatePicture( p_picture ) ) { free( p_picture ); return NULL; } } /* */ p_picture->format = fmt; vlc_atomic_set( &p_picture->gc.refcount, 1 ); if( p_picture->gc.pf_destroy == NULL ) p_picture->gc.pf_destroy = PictureDestroy; return p_picture; }
/** * Atomically set the reference count to 1. * @param p_gc reference counted object * @param pf_destruct destruction calback * @return p_gc. */ void *vlc_gc_init (gc_object_t *p_gc, void (*pf_destruct) (gc_object_t *)) { /* There is no point in using the GC if there is no destructor... */ assert (pf_destruct); p_gc->pf_destructor = pf_destruct; vlc_atomic_set (&p_gc->refs, 1); return p_gc; }
void vlc_cancel (vlc_thread_t thread_id) { pthread_cond_t *cond; vlc_atomic_set(&thread_id->killed, true); vlc_mutex_lock(&thread_id->lock); cond = thread_id->cond; if (cond) pthread_cond_broadcast(cond); vlc_mutex_unlock(&thread_id->lock); }
static int vlc_clone_attr (vlc_thread_t *th, void *(*entry) (void *), void *data, bool detach) { vlc_thread_t thread = malloc (sizeof (*thread)); if (unlikely(thread == NULL)) return ENOMEM; int ret; sigset_t oldset; { sigset_t set; sigemptyset (&set); sigdelset (&set, SIGHUP); sigaddset (&set, SIGINT); sigaddset (&set, SIGQUIT); sigaddset (&set, SIGTERM); sigaddset (&set, SIGPIPE); /* We don't want this one, really! */ pthread_sigmask (SIG_BLOCK, &set, &oldset); } vlc_sem_init(&thread->finished, 0); vlc_atomic_set(&thread->killed, false); thread->killable = true; thread->cond = NULL; thread->entry = entry; thread->data = data; vlc_mutex_init(&thread->lock); pthread_attr_t attr; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE); ret = pthread_create (&thread->thread, &attr, detach ? detached_thread : joinable_thread, thread); pthread_attr_destroy (&attr); pthread_sigmask (SIG_SETMASK, &oldset, NULL); *th = thread; return ret; }
void MessagesDialog::changeVerbosity( int i_verbosity ) { vlc_atomic_set( &this->verbosity, i_verbosity ); }
int picture_Setup( picture_t *p_picture, vlc_fourcc_t i_chroma, int i_width, int i_height, int i_sar_num, int i_sar_den ) { /* Store default values */ p_picture->i_planes = 0; for( unsigned i = 0; i < VOUT_MAX_PLANES; i++ ) { plane_t *p = &p_picture->p[i]; p->p_pixels = NULL; p->i_pixel_pitch = 0; } vlc_atomic_set( &p_picture->gc.refcount, 0 ); p_picture->gc.pf_destroy = NULL; p_picture->gc.p_sys = NULL; p_picture->i_nb_fields = 2; video_format_Setup( &p_picture->format, i_chroma, i_width, i_height, i_sar_num, i_sar_den ); const vlc_chroma_description_t *p_dsc = vlc_fourcc_GetChromaDescription( p_picture->format.i_chroma ); if( !p_dsc ) return VLC_EGENERIC; /* We want V (width/height) to respect: (V * p_dsc->p[i].w.i_num) % p_dsc->p[i].w.i_den == 0 (V * p_dsc->p[i].w.i_num/p_dsc->p[i].w.i_den * p_dsc->i_pixel_size) % 16 == 0 Which is respected if you have V % lcm( p_dsc->p[0..planes].w.i_den * 16) == 0 */ int i_modulo_w = 1; int i_modulo_h = 1; unsigned int i_ratio_h = 1; for( unsigned i = 0; i < p_dsc->plane_count; i++ ) { i_modulo_w = LCM( i_modulo_w, 16 * p_dsc->p[i].w.den ); i_modulo_h = LCM( i_modulo_h, 16 * p_dsc->p[i].h.den ); if( i_ratio_h < p_dsc->p[i].h.den ) i_ratio_h = p_dsc->p[i].h.den; } i_modulo_h = LCM( i_modulo_h, 32 ); const int i_width_aligned = ( i_width + i_modulo_w - 1 ) / i_modulo_w * i_modulo_w; const int i_height_aligned = ( i_height + i_modulo_h - 1 ) / i_modulo_h * i_modulo_h; const int i_height_extra = 2 * i_ratio_h; /* This one is a hack for some ASM functions */ for( unsigned i = 0; i < p_dsc->plane_count; i++ ) { plane_t *p = &p_picture->p[i]; p->i_lines = (i_height_aligned + i_height_extra ) * p_dsc->p[i].h.num / p_dsc->p[i].h.den; p->i_visible_lines = i_height * p_dsc->p[i].h.num / p_dsc->p[i].h.den; p->i_pitch = i_width_aligned * p_dsc->p[i].w.num / p_dsc->p[i].w.den * p_dsc->pixel_size; p->i_visible_pitch = i_width * p_dsc->p[i].w.num / p_dsc->p[i].w.den * p_dsc->pixel_size; p->i_pixel_pitch = p_dsc->pixel_size; assert( (p->i_pitch % 16) == 0 ); } p_picture->i_planes = p_dsc->plane_count; return VLC_SUCCESS; }
DeckLinkCaptureDelegate(demux_t *demux) : demux_(demux) { vlc_atomic_set(&m_ref_, 1); }
/** * Creates an audio output */ int aout_DecNew( audio_output_t *p_aout, const audio_sample_format_t *p_format, const audio_replay_gain_t *p_replay_gain, const aout_request_vout_t *p_request_vout ) { /* Sanitize audio format */ if( p_format->i_channels > 32 ) { msg_Err( p_aout, "too many audio channels (%u)", p_format->i_channels ); return -1; } if( p_format->i_channels <= 0 ) { msg_Err( p_aout, "no audio channels" ); return -1; } if( p_format->i_channels != aout_FormatNbChannels( p_format ) ) { msg_Err( p_aout, "incompatible audio channels count with layout mask" ); return -1; } if( p_format->i_rate > 192000 ) { msg_Err( p_aout, "excessive audio sample frequency (%u)", p_format->i_rate ); return -1; } if( p_format->i_rate < 4000 ) { msg_Err( p_aout, "too low audio sample frequency (%u)", p_format->i_rate ); return -1; } aout_owner_t *owner = aout_owner(p_aout); #ifdef RECYCLE /* Calling decoder is responsible for serializing aout_DecNew() and * aout_DecDelete(). So no need to lock to _read_ those properties. */ if (owner->module != NULL) /* <- output exists */ { /* Check if we can recycle the existing output and pipelines */ if (AOUT_FMTS_IDENTICAL(&owner->input_format, p_format)) return 0; /* TODO? If the new input format is closer to the output format than * the old input format was, then the output could be recycled. The * input pipeline however would need to be restarted. */ /* No recycling: delete everything and restart from scratch */ aout_Shutdown (p_aout); } #endif int ret = 0; /* TODO: reduce lock scope depending on decoder's real need */ aout_lock( p_aout ); assert (owner->module == NULL); /* Create the audio output stream */ var_Destroy( p_aout, "audio-device" ); var_Destroy( p_aout, "audio-channels" ); owner->input_format = *p_format; vlc_atomic_set (&owner->restart, 0); if( aout_OutputNew( p_aout, p_format ) < 0 ) { ret = -1; goto error; } /* Allocate a software mixer */ assert (owner->volume.mixer == NULL); owner->volume.mixer = aout_MixerNew (p_aout, owner->mixer_format.i_format); aout_ReplayGainInit (&owner->gain.data, p_replay_gain); var_AddCallback (p_aout, "audio-replay-gain-mode", ReplayGainCallback, owner); var_TriggerCallback (p_aout, "audio-replay-gain-mode"); /* Create the audio filtering "input" pipeline */ date_Init (&owner->sync.date, owner->mixer_format.i_rate, 1); date_Set (&owner->sync.date, VLC_TS_INVALID); assert (owner->input == NULL); owner->input = aout_InputNew (p_aout, p_format, &owner->mixer_format, p_request_vout); if (owner->input == NULL) { struct audio_mixer *mixer = owner->volume.mixer; owner->volume.mixer = NULL; aout_OutputDelete (p_aout); aout_unlock (p_aout); aout_MixerDelete (mixer); return -1; } error: aout_unlock( p_aout ); return ret; }