Пример #1
0
static void *msg_thread (void *data)
{
    msg_subscription_t *sub = data;
    msg_bank_t *bank = libvlc_bank (sub->instance);

    vlc_mutex_lock (&bank->lock);
    for (;;)
    {
        /* Wait for messages */
        assert (sub->begin < VLC_MSG_QSIZE);
        assert (sub->end < VLC_MSG_QSIZE);
        while (sub->begin != sub->end)
        {
            msg_item_t *msg = sub->items[sub->begin];
            unsigned overruns = sub->overruns;

            if (++sub->begin == VLC_MSG_QSIZE)
                sub->begin = 0;
            sub->overruns = 0;
            vlc_mutex_unlock (&bank->lock);

            sub->func (sub->opaque, msg, overruns);
            msg_Release (msg);

            vlc_mutex_lock (&bank->lock);
        }

        mutex_cleanup_push (&bank->lock);
        vlc_cond_wait (&bank->wait, &bank->lock);
        vlc_cleanup_pop ();
    }
    assert (0);
}
Пример #2
0
/*****************************************************************************
 * ALSAThread: asynchronous thread used to DMA the data to the device
 *****************************************************************************/
static void* ALSAThread( vlc_object_t* p_this )
{
    aout_instance_t * p_aout = (aout_instance_t*)p_this;
    struct aout_sys_t * p_sys = p_aout->output.p_sys;
    int canc = vlc_savecancel ();
    p_sys->p_status = (snd_pcm_status_t *)malloc(snd_pcm_status_sizeof());

    /* Wait for the exact time to start playing (avoids resampling) */
    vlc_mutex_lock( &p_sys->lock );
    while( !p_sys->start_date && vlc_object_alive (p_aout) )
        vlc_cond_wait( &p_sys->wait, &p_sys->lock );
    vlc_mutex_unlock( &p_sys->lock );

    if( !vlc_object_alive (p_aout) )
        goto cleanup;

    mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 );

    while ( vlc_object_alive (p_aout) )
    {
        ALSAFill( p_aout );
    }

cleanup:
    snd_pcm_drop( p_sys->p_snd_pcm );
    free( p_aout->output.p_sys->p_status );
    vlc_restorecancel (canc);
    return NULL;
}
Пример #3
0
void playlist_preparser_Delete( playlist_preparser_t *p_preparser )
{
    vlc_mutex_lock( &p_preparser->lock );
    /* Remove pending item to speed up preparser thread exit */
    while( p_preparser->i_waiting > 0 )
    {
        preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
        vlc_gc_decref( p_entry->p_item );
        free( p_entry );
        REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
    }

    vlc_sem_post( &p_preparser->item_done );

    while( p_preparser->b_live )
        vlc_cond_wait( &p_preparser->wait, &p_preparser->lock );
    vlc_mutex_unlock( &p_preparser->lock );

    /* Destroy the item preparser */
    vlc_sem_destroy( &p_preparser->item_done );
    vlc_cond_destroy( &p_preparser->wait );
    vlc_mutex_destroy( &p_preparser->lock );

    if( p_preparser->p_fetcher != NULL )
        playlist_fetcher_Delete( p_preparser->p_fetcher );
    free( p_preparser );
}
Пример #4
0
picture_t *picture_pool_Wait(picture_pool_t *pool)
{
    unsigned i;

    vlc_mutex_lock(&pool->lock);
    assert(pool->refs > 0);

    while (pool->available == 0)
        vlc_cond_wait(&pool->wait, &pool->lock);

    i = ffsll(pool->available);
    assert(i > 0);
    pool->available &= ~(1ULL << (i - 1));
    vlc_mutex_unlock(&pool->lock);

    picture_t *picture = pool->picture[i - 1];

    if (pool->pic_lock != NULL && pool->pic_lock(picture) != 0) {
        vlc_mutex_lock(&pool->lock);
        pool->available |= 1ULL << (i - 1);
        vlc_cond_signal(&pool->wait);
        vlc_mutex_unlock(&pool->lock);
        return NULL;
    }

    picture_t *clone = picture_pool_ClonePicture(pool, i - 1);
    if (clone != NULL) {
        assert(clone->p_next == NULL);
        atomic_fetch_add(&pool->refs, 1);
    }
    return clone;
}
Пример #5
0
/**************************************************************************
 *       event_async_loop (private) :
 *
 * Send queued events.
 **************************************************************************/
static void * event_async_loop(void * arg)
{
    libvlc_event_manager_t * p_em = arg;
    libvlc_event_listener_t listener;
    libvlc_event_t event;

    vlc_threadvar_set(queue(p_em)->is_asynch_dispatch_thread_var, p_em);

    queue_lock(p_em);
    while (true) {
        int has_listener = pop(p_em, &listener, &event);

        if (has_listener)
        {
            queue_unlock(p_em);
            listener.pf_callback(&event, listener.p_user_data); // This might edit the queue
            queue_lock(p_em);
        }
        else
        {
            queue(p_em)->is_idle = true;

            mutex_cleanup_push(&queue(p_em)->lock);
            vlc_cond_broadcast(&queue(p_em)->signal_idle); // We'll be idle
            vlc_cond_wait(&queue(p_em)->signal, &queue(p_em)->lock);
            vlc_cleanup_pop();

            queue(p_em)->is_idle = false;
        }
    }
    queue_unlock(p_em);
    return NULL;
}
Пример #6
0
static void flush(filter_t *filter)
{
    filter_sys_t *sys = filter->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;

    msg_Dbg(filter, "flush deinterlace filter");

    if (atomic_load(&sys->input_in_transit) ||
            atomic_load(&sys->output_in_transit)) {

        msg_Dbg(filter, "flush: flush ports (input: %d, output: %d in transit)",
                sys->input_in_transit, sys->output_in_transit);
        mmal_port_flush(sys->output);
        mmal_port_flush(sys->input);

        msg_Dbg(filter, "flush: wait for all buffers to be returned");
        vlc_mutex_lock(&sys->buffer_cond_mutex);
        while (atomic_load(&sys->input_in_transit) ||
                atomic_load(&sys->output_in_transit)) {
            vlc_cond_wait(&sys->buffer_cond, &sys->buffer_cond_mutex);
        }
        vlc_mutex_unlock(&sys->buffer_cond_mutex);
    }

    while ((buffer = mmal_queue_get(sys->filtered_pictures))) {
        picture_t *pic = (picture_t *)buffer->user_data;
        msg_Dbg(filter, "flush: release already filtered pic %p",
                (void *)pic);
        picture_Release(pic);
    }
    msg_Dbg(filter, "flush: done");
}
Пример #7
0
static int FfmpegThread( struct thread_context_t *p_context )
{
    while ( !p_context->b_die && !p_context->b_error )
    {
        vlc_mutex_lock( &p_context->lock );
        while ( !p_context->b_work && !p_context->b_die && !p_context->b_error )
        {
            vlc_cond_wait( &p_context->cond, &p_context->lock );
        }
        p_context->b_work = 0;
        vlc_mutex_unlock( &p_context->lock );
        if ( p_context->b_die || p_context->b_error )
            break;

        if ( p_context->pf_func )
        {
            p_context->i_ret = p_context->pf_func( p_context->p_context,
                                                   p_context->arg );
        }

        vlc_mutex_lock( &p_context->lock );
        p_context->b_done = 1;
        vlc_cond_signal( &p_context->cond );
        vlc_mutex_unlock( &p_context->lock );
    }

    return 0;
}
Пример #8
0
static int
EcoreMainLoopCallSync( vout_display_t *vd, mainloop_cb p_cb )
{
    vout_display_sys_t *sys = vd->sys;
    struct mainloop_cb_args args = { .vd = vd, .p_cb = p_cb, .b_signal = false };
    ecore_main_loop_thread_safe_call_async( EcoreMainLoopCb, &args );

    vlc_mutex_lock( &sys->cb_lock );
    while( !args.b_signal )
        vlc_cond_wait( &sys->cb_wait, &sys->cb_lock );
    vlc_mutex_unlock( &sys->cb_lock );

    return args.i_ret;
}

#ifdef HAVE_EVAS_CALLBACK_KEY_UP
static void
EventSendKey( vout_display_t *vd, int i_key )
{
    vout_display_sys_t *sys = vd->sys;
    struct event *p_event = malloc( sizeof(struct event) );

    if( !p_event )
        return;
    p_event->i_type = VOUT_DISPLAY_EVENT_KEY;
    p_event->u.i_key = i_key;
    EVENT_FIFO_PUSH( p_event );
}
Пример #9
0
static int
dialog_wait(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id,
            enum dialog_type i_type, struct dialog_answer *p_answer)
{
    struct dialog_i11e_context context = {
        .p_provider = p_provider,
        .p_id = p_id,
    };
    vlc_interrupt_register(dialog_wait_interrupted, &context);

    vlc_mutex_lock(&p_id->lock);
    /* Wait for the dialog to be dismissed, interrupted or answered */
    while (!p_id->b_cancelled && !p_id->b_answered)
        vlc_cond_wait(&p_id->wait, &p_id->lock);

    int i_ret;
    if (p_id->b_cancelled)
        i_ret = 0;
    else if (p_id->answer.i_type != i_type)
        i_ret = VLC_EGENERIC;
    else
    {
        i_ret = 1;
        memcpy(p_answer, &p_id->answer, sizeof(p_id->answer));
        memset(&p_id->answer, 0, sizeof(p_id->answer));
    }

    vlc_mutex_unlock(&p_id->lock);
    vlc_interrupt_unregister();

    vlc_mutex_lock(&p_provider->lock);
    dialog_remove_locked(p_provider, p_id);
    vlc_mutex_unlock(&p_provider->lock);
    return i_ret;
}
Пример #10
0
/**
 * main SAP handler thread
 * \param p_this the SAP Handler object
 * \return nothing
 */
static void *RunThread (void *self)
{
    sap_address_t *addr = self;

    vlc_mutex_lock (&addr->lock);
    mutex_cleanup_push (&addr->lock);

    for (;;)
    {
        sap_session_t *p_session;
        mtime_t deadline;

        while (addr->first == NULL)
            vlc_cond_wait (&addr->wait, &addr->lock);

        assert (addr->session_count > 0);

        deadline = mdate ();
        for (p_session = addr->first; p_session; p_session = p_session->next)
        {
            send (addr->fd, p_session->data, p_session->length, 0);
            deadline += addr->interval * CLOCK_FREQ / addr->session_count;

            if (vlc_cond_timedwait (&addr->wait, &addr->lock, deadline) == 0)
                break; /* list may have changed! */
        }
    }

    vlc_cleanup_pop ();
    assert (0);
}
Пример #11
0
/**
 * Run the main control thread itself
 */
static void *Thread ( void *data )
{
    playlist_t *p_playlist = data;
    playlist_private_t *p_sys = pl_priv(p_playlist);

    playlist_Lock( p_playlist );
    while( vlc_object_alive( p_playlist ) || p_sys->p_input )
    {
        /* FIXME: what's that ! */
        if( p_sys->b_reset_currently_playing &&
            mdate() - p_sys->last_rebuild_date > 30000 ) // 30 ms
        {
            ResetCurrentlyPlaying( p_playlist,
                                   get_current_status_item( p_playlist ) );
            p_sys->last_rebuild_date = mdate();
        }

        /* If there is an input, check that it doesn't need to die. */
        while( !LoopInput( p_playlist ) )
            vlc_cond_wait( &p_sys->signal, &p_sys->lock );

        LoopRequest( p_playlist );
    }
    playlist_Unlock( p_playlist );

    return NULL;
}
Пример #12
0
static void BackgroundWorkerCancel( struct background_worker* worker, void* id)
{
    vlc_mutex_lock( &worker->lock );
    for( size_t i = 0; i < vlc_array_count( &worker->tail.data ); )
    {
        struct bg_queued_item* item =
            vlc_array_item_at_index( &worker->tail.data, i );

        if( id == NULL || item->id == id )
        {
            vlc_array_remove( &worker->tail.data, i );
            worker->conf.pf_release( item->entity );
            free( item );
            continue;
        }

        ++i;
    }

    while( ( id == NULL && worker->head.active )
        || ( id != NULL && worker->head.id == id ) )
    {
        worker->head.deadline = VLC_TS_0;
        vlc_cond_signal( &worker->head.worker_wait );
        vlc_cond_signal( &worker->tail.wait );
        vlc_cond_wait( &worker->head.wait, &worker->lock );
    }
    vlc_mutex_unlock( &worker->lock );
}
Пример #13
0
/*****************************************************************************
 * Thread:
 *****************************************************************************/
static void *Thread( void *p_thread_data )
{
    goom_thread_t *p_thread = (goom_thread_t*)p_thread_data;
    date_t i_pts;
    int16_t p_data[2][512];
    int i_data = 0, i_count = 0;
    PluginInfo *p_plugin_info;
    int canc = vlc_savecancel ();

    p_plugin_info = goom_init( p_thread->i_width, p_thread->i_height );

    for( ;; )
    {
        uint32_t  *plane;
        picture_t *p_pic;

        /* FIXME the way the update is done is not really good.
         *  Supurious wake up from p_thread->wait will make it generates a frame
         * without using new samples (probably rare as we should not be waiting
         * samples).
         *  The frame rate at which the video is generated is not well controlled
         * nor the time at which each frame is displayed (not smooth)
         */
        /* goom_update is damn slow, so just copy data and release the lock */
        vlc_mutex_lock( &p_thread->lock );
        if( !p_thread->b_exit &&
            FillBuffer( (int16_t *)p_data, &i_data,
                        &i_pts, &p_thread->date, p_thread ) != VLC_SUCCESS )
            vlc_cond_wait( &p_thread->wait, &p_thread->lock );
        bool b_exit = p_thread->b_exit;
        vlc_mutex_unlock( &p_thread->lock );

        if( b_exit )
            break;

        /* Speed selection */
        if( p_thread->i_speed && (++i_count % (p_thread->i_speed+1)) ) continue;

        /* Frame dropping if necessary */
        if( date_Get( &i_pts ) + GOOM_DELAY <= mdate() ) continue;

        plane = goom_update( p_plugin_info, p_data, 0, 0.0,
                             NULL, NULL );

        p_pic = vout_GetPicture( p_thread->p_vout );
        if( unlikely(p_pic == NULL) )
            continue;

        memcpy( p_pic->p[0].p_pixels, plane, p_thread->i_width * p_thread->i_height * 4 );

        p_pic->date = date_Get( &i_pts ) + GOOM_DELAY;
        vout_PutPicture( p_thread->p_vout, p_pic );
    }

    goom_close( p_plugin_info );
    vlc_restorecancel (canc);
    return NULL;
}
Пример #14
0
/**
 * Waits until the variable is inactive (i.e. not executing a callback)
 */
static void WaitUnused(vlc_object_t *obj, variable_t *var)
{
    vlc_object_internals_t *priv = vlc_internals(obj);

    mutex_cleanup_push(&priv->var_lock);
    while (var->b_incallback)
        vlc_cond_wait(&priv->var_wait, &priv->var_lock);
    vlc_cleanup_pop();
}
/*****************************************************************************
 * Run: Thread entry-point
 ****************************************************************************/
static void* Run( void *data )
{
    services_discovery_t *p_sd = ( services_discovery_t * )data;
    services_discovery_sys_t *p_sys = p_sd->p_sys;
    lua_State *L = p_sys->L;

    int cancel = vlc_savecancel();

    lua_getglobal( L, "main" );
    if( !lua_isfunction( L, lua_gettop( L ) ) || lua_pcall( L, 0, 1, 0 ) )
    {
        msg_Err( p_sd, "Error while running script %s, "
                  "function main(): %s", p_sys->psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
        lua_pop( L, 1 );
        vlc_restorecancel( cancel );
        return NULL;
    }
    msg_Dbg( p_sd, "LuaSD script loaded: %s", p_sys->psz_filename );

    /* Force garbage collection, because the core will keep the SD
     * open, but lua will never gc until lua_close(). */
    lua_gc( L, LUA_GCCOLLECT, 0 );

    vlc_restorecancel( cancel );

    /* Main loop to handle search requests */
    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    while( !p_sys->b_exiting )
    {
        /* Wait for a request */
        while( !p_sys->i_query )
            vlc_cond_wait( &p_sys->cond, &p_sys->lock );

        /* Execute every query each one protected against cancelation */
        cancel = vlc_savecancel();
        while( !p_sys->b_exiting && p_sys->i_query )
        {
            char *psz_query = p_sys->ppsz_query[p_sys->i_query - 1];
            REMOVE_ELEM( (char **), p_sys->ppsz_query, p_sys->i_query, p_sys->i_query - 1 );			// sunqueen modify

            vlc_mutex_unlock( &p_sys->lock );
            DoSearch( p_sd, psz_query );
            free( psz_query );
            vlc_mutex_lock( &p_sys->lock );
        }
        /* Force garbage collection, because the core will keep the SD
         * open, but lua will never gc until lua_close(). */
        lua_gc( L, LUA_GCCOLLECT, 0 );

        vlc_restorecancel( cancel );
    }
    vlc_cleanup_run();

    return NULL;
}
Пример #16
0
/**************************************************************************
 * Parse the media.
 **************************************************************************/
void
libvlc_media_parse(libvlc_media_t *media)
{
    preparse_if_needed(media);

    vlc_mutex_lock(&media->parsed_lock);
    while (!media->is_parsed)
        vlc_cond_wait(&media->parsed_cond, &media->parsed_lock);
    vlc_mutex_unlock(&media->parsed_lock);
}
Пример #17
0
void vlc_rwlock_wrlock (vlc_rwlock_t *lock)
{
    vlc_mutex_lock (&lock->mutex);
    /* Wait until nobody owns the lock in either way. */
    while ((lock->readers > 0) || (lock->writer != 0))
        vlc_cond_wait (&lock->wait, &lock->mutex);
    assert (lock->writer == 0);
    lock->writer = GetCurrentThreadId ();
    vlc_mutex_unlock (&lock->mutex);
}
Пример #18
0
static void LoopRequest( playlist_t *p_playlist )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    assert( !p_sys->p_input );

    /* No input. Several cases
     *  - No request, running status -> start new item
     *  - No request, stopped status -> collect garbage
     *  - Request, running requested -> start new item
     *  - Request, stopped requested -> collect garbage
    */
    const int i_status = p_sys->request.b_request ?
                         p_sys->request.i_status : p_sys->status.i_status;

    if( i_status == PLAYLIST_STOPPED || !vlc_object_alive( p_playlist ) )
    {
        p_sys->status.i_status = PLAYLIST_STOPPED;

        if( p_sys->p_input_resource &&
            input_resource_HasVout( p_sys->p_input_resource ) )
        {
            /* XXX We can unlock if we don't issue the wait as we will be
             * call again without anything else done between the calls */
            PL_UNLOCK;

            /* input_resource_t must be manipulated without playlist lock */
            input_resource_TerminateVout( p_sys->p_input_resource );

            PL_LOCK;
        }
        else
        {
            if( vlc_object_alive( p_playlist ) )
                vlc_cond_wait( &p_sys->signal, &p_sys->lock );
        }
        return;
    }

    playlist_item_t *p_item = NextItem( p_playlist );
    if( p_item )
    {
        msg_Dbg( p_playlist, "starting playback of the new playlist item" );
        PlayItem( p_playlist, p_item );
        return;
    }

    msg_Dbg( p_playlist, "nothing to play" );
    p_sys->status.i_status = PLAYLIST_STOPPED;

    if( var_GetBool( p_playlist, "play-and-exit" ) )
    {
        msg_Info( p_playlist, "end of playlist, exiting" );
        libvlc_Quit( p_playlist->p_libvlc );
    }
}
Пример #19
0
/**
 * Receives stream data.
 *
 * Dequeues pending incoming data for an HTTP/2 stream. If there is currently
 * no data block, wait for one.
 *
 * \return a VLC data block, or NULL on stream error or end of stream
 */
static block_t *vlc_h2_stream_read(struct vlc_http_stream *stream)
{
    struct vlc_h2_stream *s = (struct vlc_h2_stream *)stream;
    struct vlc_h2_conn *conn = s->conn;
    struct vlc_h2_frame *f;

    vlc_h2_stream_lock(s);
    while ((f = s->recv_head) == NULL && !s->recv_end && !s->interrupted)
    {
        mutex_cleanup_push(&conn->lock);
        vlc_cond_wait(&s->recv_wait, &conn->lock);
        vlc_cleanup_pop();
    }

    if (f == NULL)
    {
        vlc_h2_stream_unlock(s);
        return NULL;
    }

    s->recv_head = f->next;
    if (f->next == NULL)
    {
        assert(s->recv_tailp == &f->next);
        s->recv_tailp = &s->recv_head;
    }

    /* Credit the receive window if missing credit exceeds 50%. */
    uint_fast32_t credit = VLC_H2_INIT_WINDOW - s->recv_cwnd;
    if (credit >= (VLC_H2_INIT_WINDOW / 2)
     && !vlc_h2_output_send(conn->out,
                            vlc_h2_frame_window_update(s->id, credit)))
        s->recv_cwnd += credit;

    vlc_h2_stream_unlock(s);

    /* This, err, unconventional code to avoid copying data. */
    block_t *block = block_heap_Alloc(f, sizeof (*f) + vlc_h2_frame_size(f));
    if (unlikely(block == NULL))
    {
        free(f);
        vlc_h2_stream_error(conn, s->id, VLC_H2_INTERNAL_ERROR);
        return NULL;
    }

    size_t len;
    uint8_t *buf = vlc_h2_frame_data_get(f, &len);

    assert(block->i_buffer >= len);
    assert(block->p_buffer <= buf);
    assert(block->p_buffer + block->i_buffer >= buf + len);
    block->p_buffer = buf;
    block->i_buffer = len;
    return block;
}
Пример #20
0
/**
 * 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);
}
Пример #21
0
static void* EncoderThread( void *obj )
{
    sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj;
    sout_stream_id_sys_t *id = p_sys->id_video;
    picture_t *p_pic = NULL;
    int canc = vlc_savecancel ();
    block_t *p_block = NULL;

    vlc_mutex_lock( &p_sys->lock_out );

    for( ;; )
    {
        while( !p_sys->b_abort &&
               (p_pic = picture_fifo_Pop( p_sys->pp_pics )) == NULL )
            vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );

        if( p_pic )
        {
            /* release lock while encoding */
            vlc_mutex_unlock( &p_sys->lock_out );
            p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
            picture_Release( p_pic );
            vlc_mutex_lock( &p_sys->lock_out );

            block_ChainAppend( &p_sys->p_buffers, p_block );
        }

        if( p_sys->b_abort )
            break;
    }

    /*Encode what we have in the buffer on closing*/
    while( (p_pic = picture_fifo_Pop( p_sys->pp_pics )) != NULL )
    {
        p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
        picture_Release( p_pic );
        block_ChainAppend( &p_sys->p_buffers, p_block );
    }

    /*Now flush encoder*/
    do {
        p_block = id->p_encoder->pf_encode_video(id->p_encoder, NULL );
        block_ChainAppend( &p_sys->p_buffers, p_block );
    } while( p_block );

    vlc_mutex_unlock( &p_sys->lock_out );

    vlc_restorecancel (canc);

    return NULL;
}
Пример #22
0
Файл: vout.c Проект: Kubink/vlc
static void vd_display(vout_display_t *vd, picture_t *picture,
                subpicture_t *subpicture)
{
    vout_display_sys_t *sys = vd->sys;
    picture_sys_t *pic_sys = picture->p_sys;
    MMAL_BUFFER_HEADER_T *buffer = pic_sys->buffer;
    MMAL_STATUS_T status;

    if (picture->format.i_frame_rate != sys->i_frame_rate ||
        picture->format.i_frame_rate_base != sys->i_frame_rate_base ||
        picture->b_progressive != sys->b_progressive ||
        picture->b_top_field_first != sys->b_top_field_first) {
        sys->b_top_field_first = picture->b_top_field_first;
        sys->b_progressive = picture->b_progressive;
        sys->i_frame_rate = picture->format.i_frame_rate;
        sys->i_frame_rate_base = picture->format.i_frame_rate_base;
        configure_display(vd, NULL, &picture->format);
    }

    if (!pic_sys->displayed || !sys->opaque) {
        buffer->cmd = 0;
        buffer->length = sys->input->buffer_size;

        vlc_mutex_lock(&sys->buffer_mutex);
        while (sys->buffers_in_transit >= MAX_BUFFERS_IN_TRANSIT)
            vlc_cond_wait(&sys->buffer_cond, &sys->buffer_mutex);

        status = mmal_port_send_buffer(sys->input, buffer);
        if (status == MMAL_SUCCESS)
            ++sys->buffers_in_transit;

        vlc_mutex_unlock(&sys->buffer_mutex);
        if (status != MMAL_SUCCESS) {
            msg_Err(vd, "Failed to send buffer to input port. Frame dropped");
            picture_Release(picture);
        }

        pic_sys->displayed = true;
    } else {
        picture_Release(picture);
    }

    display_subpicture(vd, subpicture);

    if (subpicture)
        subpicture_Delete(subpicture);

    if (sys->next_phase_check == 0 && sys->adjust_refresh_rate)
        maintain_phase_sync(vd);
    sys->next_phase_check = (sys->next_phase_check + 1) % PHASE_CHECK_INTERVAL;
}
Пример #23
0
static int media_parse(libvlc_media_t *media, bool b_async,
                       libvlc_media_parse_flag_t parse_flag)
{
    bool needed;

    vlc_mutex_lock(&media->parsed_lock);
    needed = !media->has_asked_preparse;
    media->has_asked_preparse = true;
    if (needed)
        media->is_parsed = false;
    vlc_mutex_unlock(&media->parsed_lock);

    if (needed)
    {
        libvlc_int_t *libvlc = media->p_libvlc_instance->p_libvlc_int;
        input_item_t *item = media->p_input_item;
        input_item_meta_request_option_t art_scope = META_REQUEST_OPTION_NONE;
        input_item_meta_request_option_t parse_scope = META_REQUEST_OPTION_SCOPE_LOCAL;
        int ret;

        if (parse_flag & libvlc_media_fetch_local)
            art_scope |= META_REQUEST_OPTION_SCOPE_LOCAL;
        if (parse_flag & libvlc_media_fetch_network)
            art_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
        if (art_scope != META_REQUEST_OPTION_NONE) {
            ret = libvlc_ArtRequest(libvlc, item, art_scope);
            if (ret != VLC_SUCCESS)
                return ret;
        }

        if (parse_flag & libvlc_media_parse_network)
            parse_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
        if (parse_flag & libvlc_media_do_interact)
            parse_scope |= META_REQUEST_OPTION_DO_INTERACT;
        ret = libvlc_MetaRequest(libvlc, item, parse_scope);
        if (ret != VLC_SUCCESS)
            return ret;
    }
    else
        return VLC_EGENERIC;

    if (!b_async)
    {
        vlc_mutex_lock(&media->parsed_lock);
        while (!media->is_parsed)
            vlc_cond_wait(&media->parsed_cond, &media->parsed_lock);
        vlc_mutex_unlock(&media->parsed_lock);
    }
    return VLC_SUCCESS;
}
Пример #24
0
void vlc_rwlock_wrlock (vlc_rwlock_t *lock)
{
    vlc_mutex_lock (&lock->mutex);
    if (unlikely(lock->writers == ULONG_MAX))
        abort ();
    lock->writers++;
    /* Wait until nobody owns the lock in either way. */
    while ((lock->readers > 0) || (lock->writer != 0))
        vlc_cond_wait (&lock->wait, &lock->mutex);
    lock->writers--;
    assert (lock->writer == 0);
    lock->writer = _gettid ();
    vlc_mutex_unlock (&lock->mutex);
}
Пример #25
0
/*****************************************************************************
 * Close: close the audio device
 *****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
    audio_output_t *p_aout = (audio_output_t *)p_this;
    aout_sys_t *p_sys = p_aout->sys;

    msg_Dbg( p_aout, "closing portaudio");

#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN

    /* Signal end of stream */
    vlc_mutex_lock( &pa_thread->lock_signal );
    pa_thread->b_signal = true;
    vlc_cond_signal( &pa_thread->signal );
    vlc_mutex_unlock( &pa_thread->lock_signal );

    /* Wait until thread is ready */
    vlc_mutex_lock( &pa_thread->lock_wait );
    while( !pa_thread->b_wait )
        vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
    vlc_mutex_unlock( &pa_thread->lock_wait );
    pa_thread->b_wait = false;

#else

    int i_err = Pa_StopStream( p_sys->p_stream );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_StopStream: %d (%s)", i_err,
                 Pa_GetErrorText( i_err ) );
    }
    i_err = Pa_CloseStream( p_sys->p_stream );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_CloseStream: %d (%s)", i_err,
                 Pa_GetErrorText( i_err ) );
    }

    i_err = Pa_Terminate();
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err,
                 Pa_GetErrorText( i_err ) );
    }

#endif

    msg_Dbg( p_aout, "portaudio closed");
    aout_PacketDestroy( p_aout );
    free( p_sys );
}
Пример #26
0
static void* EncoderThread( vlc_object_t* p_this )
{
    sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this;
    sout_stream_id_t *id = p_sys->id_video;
    picture_t *p_pic;
    int canc = vlc_savecancel ();

    while( vlc_object_alive (p_sys) && !p_sys->b_error )
    {
        block_t *p_block;

        vlc_mutex_lock( &p_sys->lock_out );
        while( p_sys->i_last_pic == p_sys->i_first_pic )
        {
            vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
            if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
        }
        if( !vlc_object_alive (p_sys) || p_sys->b_error )
        {
            vlc_mutex_unlock( &p_sys->lock_out );
            break;
        }

        p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
        p_sys->i_first_pic %= PICTURE_RING_SIZE;
        vlc_mutex_unlock( &p_sys->lock_out );

        video_timer_start( id->p_encoder );
        p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
        video_timer_stop( id->p_encoder );

        vlc_mutex_lock( &p_sys->lock_out );
        block_ChainAppend( &p_sys->p_buffers, p_block );

        vlc_mutex_unlock( &p_sys->lock_out );
        picture_Release( p_pic );
    }

    while( p_sys->i_last_pic != p_sys->i_first_pic )
    {
        p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
        p_sys->i_first_pic %= PICTURE_RING_SIZE;
        picture_Release( p_pic );
    }
    block_ChainRelease( p_sys->p_buffers );

    vlc_restorecancel (canc);
    return NULL;
}
Пример #27
0
void vlc_rwlock_rdlock (vlc_rwlock_t *lock)
{
    vlc_mutex_lock (&lock->mutex);
    /* Recursive read-locking is allowed. We only need to ensure that there is
     * no active writer. */
    while (lock->writer != 0)
    {
        assert (lock->readers == 0);
        vlc_cond_wait (&lock->wait, &lock->mutex);
    }
    if (unlikely(lock->readers == ULONG_MAX))
        abort ();
    lock->readers++;
    vlc_mutex_unlock (&lock->mutex);
}
Пример #28
0
/****************************************************************************
 * HttpCallback: Return the index.html file
 ****************************************************************************/
static int HttpCallback( httpd_file_sys_t *p_args,
                         httpd_file_t *p_file,
                         uint8_t *_psz_request,
                         uint8_t **_pp_data, int *pi_data )
{
    VLC_UNUSED(p_file);
    access_sys_t *p_sys = p_args->p_access->p_sys;
    char *psz_request = (char *)_psz_request;
    char **pp_data = (char **)_pp_data;

    vlc_mutex_lock( &p_sys->httpd_mutex );

    p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */
    p_sys->psz_request = psz_request;
    p_sys->b_request_frontend_info = true;
    if ( p_sys->p_cam != NULL )
    {
        p_sys->b_request_mmi_info = true;
    }
    else
    {
        p_sys->psz_mmi_info = strdup( "No available CAM interface\n" );
    }

    do
    {
        vlc_cond_wait( &p_sys->httpd_cond, &p_sys->httpd_mutex );
    }
    while ( p_sys->b_request_frontend_info || p_sys->b_request_mmi_info );

    p_sys->i_httpd_timeout = 0;
    vlc_mutex_unlock( &p_sys->httpd_mutex );

    *pi_data = strlen( psz_constant_header )
                + strlen( p_sys->psz_mmi_info )
                + strlen( psz_constant_middle )
                + strlen( p_sys->psz_frontend_info )
                + strlen( psz_constant_footer ) + 1;
    *pp_data = malloc( *pi_data );

    sprintf( *pp_data, "%s%s%s%s%s", psz_constant_header,
             p_sys->psz_mmi_info, psz_constant_middle,
             p_sys->psz_frontend_info, psz_constant_footer );
    free( p_sys->psz_frontend_info );
    free( p_sys->psz_mmi_info );

    return VLC_SUCCESS;
}
Пример #29
0
VLC_NORETURN
static void *vlc_timer_thread (void *data)
{
    struct vlc_timer *timer = data;

    vlc_mutex_lock (&timer->lock);
    mutex_cleanup_push (&timer->lock);

    for (;;)
    {
        while (timer->value == 0)
            vlc_cond_wait (&timer->reschedule, &timer->lock);

        if (vlc_cond_timedwait (&timer->reschedule, &timer->lock,
                                timer->value) == 0)
            continue;
        if (timer->interval == 0)
            timer->value = 0; /* disarm */
        vlc_mutex_unlock (&timer->lock);

        int canc = vlc_savecancel ();
        timer->func (timer->data);
        vlc_restorecancel (canc);

        mtime_t now = mdate ();
        unsigned misses;

        vlc_mutex_lock (&timer->lock);
        if (timer->interval == 0)
            continue;

        misses = (now - timer->value) / timer->interval;
        timer->value += timer->interval;
        /* Try to compensate for one miss (mwait() will return immediately)
         * but no more. Otherwise, we might busy loop, after extended periods
         * without scheduling (suspend, SIGSTOP, RT preemption, ...). */
        if (misses > 1)
        {
            misses--;
            timer->value += misses * timer->interval;
            atomic_fetch_add_explicit (&timer->overruns, misses,
                                       memory_order_relaxed);
        }
    }

    vlc_cleanup_pop ();
    vlc_assert_unreachable ();
}
Пример #30
0
/*****************************************************************************
 * Run: main thread
 *****************************************************************************/
static void *Run( void *data )
{
    services_discovery_t *p_sd = data;
    services_discovery_sys_t *p_sys  = p_sd->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    for( ;; )
    {
        while( !p_sys->b_update )
            vlc_cond_wait( &p_sys->wait, &p_sys->lock );

        int canc = vlc_savecancel ();
        msg_Dbg( p_sd, "Update required" );

        if( p_sys->update_type == UPDATE_URLS )
        {
          char* psz_urls = var_GetNonEmptyString( p_sd, "podcast-urls" );
          ParseUrls( p_sd, psz_urls );
          free( psz_urls );
        }
        else if( p_sys->update_type == UPDATE_REQUEST )
        {
          ParseRequest( p_sd );
        }

        p_sys->b_update = false;

        for( int i = 0; i < p_sd->p_sys->i_input; i++ )
        {
            input_thread_t *p_input = p_sd->p_sys->pp_input[i];

            if( p_input->b_eof || p_input->b_error )
            {
                input_Stop( p_input, false );
                vlc_thread_join( p_input );
                vlc_object_release( p_input );

                p_sd->p_sys->pp_input[i] = NULL;
                REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
                i--;
            }
        }
        vlc_restorecancel (canc);
    }
    vlc_cleanup_pop();
    assert(0); /* dead code */
}