Exemple #1
0
/** Remove this drawable from the list of busy ones */
static void ReleaseDrawable (vlc_object_t *obj, xcb_window_t window)
{
    xcb_window_t *used;
    size_t n = 0;

    vlc_mutex_lock (&serializer);
    used = var_GetAddress (obj->p_libvlc, "xid-in-use");
    assert (used);
    while (used[n] != window)
    {
        assert (used[n]);
        n++;
    }
    do
        used[n] = used[n + 1];
    while (used[++n]);

    if (n == 0)
         var_SetAddress (obj->p_libvlc, "xid-in-use", NULL);
    vlc_mutex_unlock (&serializer);

    if (n == 0)
        free (used);
    /* Variables are reference-counted... */
    var_Destroy (obj->p_libvlc, "xid-in-use");
}
Exemple #2
0
static struct decklink_sys_t *GetDLSys(vlc_object_t *obj)
{
    vlc_object_t *libvlc = VLC_OBJECT(obj->p_libvlc);
    struct decklink_sys_t *sys;

    vlc_mutex_lock(&sys_lock);

    if (var_Type(libvlc, "decklink-sys") == VLC_VAR_ADDRESS)
        sys = (struct decklink_sys_t*)var_GetAddress(libvlc, "decklink-sys");
    else {
        sys = (struct decklink_sys_t*)malloc(sizeof(*sys));
        if (sys) {
            sys->p_output = NULL;
            sys->offset = 0;
            sys->users = 0;
            sys->i_rate = -1;
            vlc_mutex_init(&sys->lock);
            vlc_cond_init(&sys->cond);
            var_Create(libvlc, "decklink-sys", VLC_VAR_ADDRESS);
            var_SetAddress(libvlc, "decklink-sys", (void*)sys);
        }
    }

    vlc_mutex_unlock(&sys_lock);
    return sys;
}
Exemple #3
0
static void ReleaseDLSys(vlc_object_t *obj)
{
    vlc_object_t *libvlc = VLC_OBJECT(obj->p_libvlc);

    vlc_mutex_lock(&sys_lock);

    struct decklink_sys_t *sys = (struct decklink_sys_t*)var_GetAddress(libvlc, "decklink-sys");

    if (--sys->users == 0) {
        msg_Dbg(obj, "Destroying decklink data");
        vlc_mutex_destroy(&sys->lock);
        vlc_cond_destroy(&sys->cond);

        if (sys->p_output) {
            sys->p_output->StopScheduledPlayback(0, NULL, 0);
            sys->p_output->DisableVideoOutput();
            sys->p_output->DisableAudioOutput();
            sys->p_output->Release();
        }

        free(sys);
        var_Destroy(libvlc, "decklink-sys");
    }

    vlc_mutex_unlock(&sys_lock);
}
Exemple #4
0
/**
 * Release the drawable.
 */
static void Close (vlc_object_t *obj)
{
    vout_window_t *wnd = (vout_window_t *)obj;
    void **used, *val = wnd->p_sys;
    size_t n = 0;

    /* Remove this drawable from the list of busy ones */
    vlc_mutex_lock (&serializer);
    used = var_GetAddress (VLC_OBJECT (obj->p_libvlc), "drawables-in-use");
    assert (used);
    while (used[n] != val)
    {
        assert (used[n]);
        n++;
    }
    do
        used[n] = used[n + 1];
    while (used[++n] != NULL);

    if (n == 0)
      /* should not be needed (var_Destroy...) but better safe than sorry: */
         var_SetAddress (obj->p_libvlc, "drawables-in-use", NULL);
    vlc_mutex_unlock (&serializer);

    if (n == 0)
        free (used);
    /* Variables are reference-counted... */
    var_Destroy (obj->p_libvlc, "drawables-in-use");
}
Exemple #5
0
/**************************************************************************
 * get_nsobject
 **************************************************************************/
void * libvlc_media_player_get_nsobject( libvlc_media_player_t *p_mi )
{
    assert (p_mi != NULL);
#ifdef __APPLE__
    return var_GetAddress (p_mi, "drawable-nsobject");
#else
    return NULL;
#endif
}
Exemple #6
0
/**************************************************************************
 * get_hwnd
 **************************************************************************/
void *libvlc_media_player_get_hwnd( libvlc_media_player_t *p_mi )
{
    assert (p_mi != NULL);
#ifdef WIN32
    return var_GetAddress (p_mi, "drawable-hwnd");
#else
    return NULL;
#endif
}
Exemple #7
0
/**
 * This function will free the snapshot addr
 */
static void VoutSnapshotAddrFree( vout_thread_t *p_vout )
{
    block_t *p_image = NULL;

    p_image = (block_t *) var_GetAddress( p_vout, "snapshot-addr" );

    if( p_image != NULL )
        block_Release( p_image );
}
Exemple #8
0
/**
 * Destroy playlist.
 * This is not thread-safe. Any reference to the playlist is assumed gone.
 * (In particular, all interface and services threads must have been joined).
 *
 * \param p_playlist the playlist object
 */
void playlist_Destroy( playlist_t *p_playlist )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);

    /* Remove all services discovery */
    playlist_ServicesDiscoveryKillAll( p_playlist );

    msg_Dbg( p_playlist, "destroying" );

    playlist_Deactivate( p_playlist );
    if( p_sys->p_preparser )
        playlist_preparser_Delete( p_sys->p_preparser );

    /* Release input resources */
    assert( p_sys->p_input == NULL );
    input_resource_Release( p_sys->p_input_resource );

    if( p_playlist->p_media_library != NULL )
        playlist_MLDump( p_playlist );

    PL_LOCK;
    /* Release the current node */
    set_current_status_node( p_playlist, NULL );
    /* Release the current item */
    set_current_status_item( p_playlist, NULL );
    PL_UNLOCK;

    vlc_cond_destroy( &p_sys->signal );
    vlc_mutex_destroy( &p_sys->lock );

    /* Remove all remaining items */
    FOREACH_ARRAY( playlist_item_t *p_del, p_playlist->all_items )
        free( p_del->pp_children );
        vlc_gc_decref( p_del->p_input );
        free( p_del );
    FOREACH_END();
    ARRAY_RESET( p_playlist->all_items );
    FOREACH_ARRAY( playlist_item_t *p_del, p_sys->items_to_delete )
        free( p_del->pp_children );
        vlc_gc_decref( p_del->p_input );
        free( p_del );
    FOREACH_END();
    ARRAY_RESET( p_sys->items_to_delete );

    ARRAY_RESET( p_playlist->items );
    ARRAY_RESET( p_playlist->current );

    vlc_http_cookie_jar_t *cookies = var_GetAddress( p_playlist, "http-cookies" );
    if ( cookies )
    {
        var_Destroy( p_playlist, "http-cookies" );
        vlc_http_cookies_destroy( cookies );
    }

    vlc_object_release( p_playlist );
}
Exemple #9
0
static osd_menu_t *osd_Find( vlc_object_t *p_this, bool visible,
                             const char *func )
{
    osd_menu_t *menu;

    vlc_mutex_lock( &osd_mutex );
    menu = var_GetAddress( p_this->p_libvlc, "osd-object" );
    if( menu == NULL || ( visible && !osd_isVisible(menu) ) )
    {
        vlc_mutex_unlock( &osd_mutex );
        msg_Err( p_this, "%s failed", func );
    }
    return menu;
}
Exemple #10
0
Fichier : intf.c Projet : paa/vlc
static aout_instance_t *findAout (vlc_object_t *obj)
{
    input_thread_t *(*pf_find_input) (vlc_object_t *);

    pf_find_input = var_GetAddress (obj, "find-input-callback");
    if (unlikely(pf_find_input == NULL))
        return NULL;

    input_thread_t *p_input = pf_find_input (obj);
    if (p_input == NULL)
       return NULL;

    aout_instance_t *p_aout = input_GetAout (p_input);
    vlc_object_release (p_input);
    return p_aout;
}
Exemple #11
0
/** Acquire a drawable */
static int AcquireDrawable (vlc_object_t *obj, xcb_window_t window)
{
    xcb_window_t *used;
    size_t n = 0;

    if (var_Create (obj->p_libvlc, "xid-in-use", VLC_VAR_ADDRESS))
        return VLC_ENOMEM;

    /* Keep a list of busy drawables, so we don't overlap videos if there are
     * more than one video track in the stream. */
    vlc_mutex_lock (&serializer);
    used = var_GetAddress (obj->p_libvlc, "xid-in-use");
    if (used != NULL)
    {
        while (used[n])
        {
            if (used[n] == window)
                goto skip;
            n++;
        }
    }

    used = realloc (used, sizeof (*used) * (n + 2));
    if (used != NULL)
    {
        used[n] = window;
        used[n + 1] = 0;
        var_SetAddress (obj->p_libvlc, "xid-in-use", used);
    }
    else
    {
skip:
        msg_Warn (obj, "X11 drawable 0x%08"PRIx8" is busy", window);
        window = 0;
    }
    vlc_mutex_unlock (&serializer);

    return (window == 0) ? VLC_EGENERIC : VLC_SUCCESS;
}
Exemple #12
0
static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
                   block_t *p_buffer )
{
    in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys;
    bridge_t *p_bridge;
    bool b_no_es = true;
    int i;
    int i_date = mdate();

    /* First forward the packet for our own ES */
    if( !p_sys->b_placeholder )
        p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );

    /* Then check all bridged streams */
    vlc_mutex_lock( p_sys->p_lock );

    p_bridge = var_GetAddress( p_stream->p_libvlc, p_sys->psz_name );

    if( p_bridge )
    {
    for ( i = 0; i < p_bridge->i_es_num; i++ )
    {
        if ( !p_bridge->pp_es[i]->b_empty )
            b_no_es = false;

        while ( p_bridge->pp_es[i]->p_block != NULL
                 && (p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay
                       < i_date
                      || p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay
                          < p_bridge->pp_es[i]->i_last) )
        {
            block_t *p_block = p_bridge->pp_es[i]->p_block;
            msg_Dbg( p_stream, "dropping a packet (%"PRId64 ")",
                     i_date - p_block->i_dts - p_sys->i_delay );
            p_bridge->pp_es[i]->p_block
                = p_bridge->pp_es[i]->p_block->p_next;
            block_Release( p_block );
        }

        if ( p_bridge->pp_es[i]->p_block == NULL )
        {
            p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block;
        }

        if ( p_bridge->pp_es[i]->b_changed )
        {
            if ( p_bridge->pp_es[i]->b_empty && p_bridge->pp_es[i]->id != NULL )
            {
                p_stream->p_next->pf_del( p_stream->p_next, p_bridge->pp_es[i]->id );
            }
            else
            {
                /* We need at least two packets to enter the mux. */
                if ( p_bridge->pp_es[i]->p_block == NULL
                      || p_bridge->pp_es[i]->p_block->p_next == NULL )
                {
                    continue;
                }

                p_bridge->pp_es[i]->fmt.i_id += p_sys->i_id_offset;
                if( !p_sys->b_placeholder )
                {
                    p_bridge->pp_es[i]->id = p_stream->p_next->pf_add(
                                p_stream->p_next, &p_bridge->pp_es[i]->fmt );
                    if ( p_bridge->pp_es[i]->id == NULL )
                    {
                        msg_Warn( p_stream, "couldn't create chain for id %d",
                                  p_bridge->pp_es[i]->fmt.i_id );
                    }
                }
                msg_Dbg( p_stream, "bridging in input codec=%4.4s id=%d pos=%d",
                         (char*)&p_bridge->pp_es[i]->fmt.i_codec,
                         p_bridge->pp_es[i]->fmt.i_id, i );
            }
        }
        p_bridge->pp_es[i]->b_changed = false;

        if ( p_bridge->pp_es[i]->b_empty )
            continue;

        if ( p_bridge->pp_es[i]->p_block == NULL )
        {
            if ( p_bridge->pp_es[i]->id != NULL
                  && p_bridge->pp_es[i]->i_last < i_date )
            {
                if( !p_sys->b_placeholder )
                    p_stream->p_next->pf_del( p_stream->p_next,
                                          p_bridge->pp_es[i]->id );
                p_bridge->pp_es[i]->fmt.i_id -= p_sys->i_id_offset;
                p_bridge->pp_es[i]->b_changed = true;
                p_bridge->pp_es[i]->id = NULL;
            }
            continue;
        }

        if ( p_bridge->pp_es[i]->id != NULL || p_sys->b_placeholder)
        {
            block_t *p_block = p_bridge->pp_es[i]->p_block;
            while ( p_block != NULL )
            {
                p_bridge->pp_es[i]->i_last = p_block->i_dts;
                p_block->i_pts += p_sys->i_delay;
                p_block->i_dts += p_sys->i_delay;
                p_block = p_block->p_next;
            }
            sout_stream_id_t *newid = NULL;
            if( p_sys->b_placeholder )
            {
                switch( p_bridge->pp_es[i]->fmt.i_cat )
                {
                    case VIDEO_ES:
                        p_sys->i_last_video = i_date;
                        newid = p_sys->id_video;
                        if( !newid )
                            break;
                        if( !p_sys->b_switch_on_iframe ||
                            p_sys->i_state == placeholder_off ||
                            ( p_bridge->pp_es[i]->fmt.i_cat == VIDEO_ES &&
                              p_bridge->pp_es[i]->p_block->i_flags & BLOCK_FLAG_TYPE_I ) )
                        {
                            p_stream->p_next->pf_send( p_stream->p_next,
                                       newid,
                                       p_bridge->pp_es[i]->p_block );
                            p_sys->i_state = placeholder_off;
                        }
                        break;
                    case AUDIO_ES:
                        newid = p_sys->id_audio;
                        if( !newid )
                            break;
                        p_sys->i_last_audio = i_date;
                    default:
                        p_stream->p_next->pf_send( p_stream->p_next,
                                   newid?newid:p_bridge->pp_es[i]->id,
                                   p_bridge->pp_es[i]->p_block );
                        break;
                }
            }
            else /* !b_placeholder */
                p_stream->p_next->pf_send( p_stream->p_next,
                                       p_bridge->pp_es[i]->id,
                                       p_bridge->pp_es[i]->p_block );
        }
        else
        {
            block_ChainRelease( p_bridge->pp_es[i]->p_block );
        }

        p_bridge->pp_es[i]->p_block = NULL;
        p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block;
    }

    if( b_no_es )
    {
        for ( i = 0; i < p_bridge->i_es_num; i++ )
            free( p_bridge->pp_es[i] );
        free( p_bridge->pp_es );
        free( p_bridge );
        var_Destroy( p_stream->p_libvlc, p_sys->psz_name );
    }
    }

    if( p_sys->b_placeholder )
    {
        switch( id->i_cat )
        {
            case VIDEO_ES:
                if( ( p_sys->i_last_video + p_sys->i_placeholder_delay < i_date
                    && (  !p_sys->b_switch_on_iframe
                       || p_buffer->i_flags & BLOCK_FLAG_TYPE_I ) )
                  || p_sys->i_state == placeholder_on )
                {
                    p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
                    p_sys->i_state = placeholder_on;
                }
                else
                    block_Release( p_buffer );
                break;

            case AUDIO_ES:
                if( p_sys->i_last_audio + p_sys->i_placeholder_delay < i_date )
                    p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
                else
                    block_Release( p_buffer );
                break;

            default:
                block_Release( p_buffer ); /* FIXME: placeholder subs anyone? */
                break;
        }
    }

    vlc_mutex_unlock( p_sys->p_lock );

    return VLC_SUCCESS;
}
Exemple #13
0
static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
{
    out_sout_stream_sys_t *p_sys = (out_sout_stream_sys_t *)p_stream->p_sys;
    bridge_t *p_bridge;
    bridged_es_t *p_es;
    int i;

    if ( p_sys->b_inited )
    {
        msg_Err( p_stream, "bridge-out can only handle 1 es at a time." );
        return NULL;
    }
    p_sys->b_inited = true;

    vlc_mutex_lock( p_sys->p_lock );

    p_bridge = var_GetAddress( p_stream->p_libvlc, p_sys->psz_name );
    if ( p_bridge == NULL )
    {
        p_bridge = xmalloc( sizeof( bridge_t ) );

        var_Create( p_stream->p_libvlc, p_sys->psz_name, VLC_VAR_ADDRESS );
        var_SetAddress( p_stream->p_libvlc, p_sys->psz_name, p_bridge );

        p_bridge->i_es_num = 0;
        p_bridge->pp_es = NULL;
    }

    for ( i = 0; i < p_bridge->i_es_num; i++ )
    {
        if ( p_bridge->pp_es[i]->b_empty && !p_bridge->pp_es[i]->b_changed )
            break;
    }

    if ( i == p_bridge->i_es_num )
    {
        p_bridge->pp_es = xrealloc( p_bridge->pp_es,
                          (p_bridge->i_es_num + 1) * sizeof(bridged_es_t *) );
        p_bridge->i_es_num++;
        p_bridge->pp_es[i] = xmalloc( sizeof(bridged_es_t) );
    }

    p_sys->p_es = p_es = p_bridge->pp_es[i];

    p_es->fmt = *p_fmt;
    p_es->fmt.i_id = p_sys->i_id;
    p_es->p_block = NULL;
    p_es->pp_last = &p_es->p_block;
    p_es->b_empty = false;

    p_es->id = NULL;
    p_es->i_last = VLC_TS_INVALID;
    p_es->b_changed = true;

    msg_Dbg( p_stream, "bridging out input codec=%4.4s id=%d pos=%d",
             (char*)&p_es->fmt.i_codec, p_es->fmt.i_id, i );

    vlc_mutex_unlock( p_sys->p_lock );

    return (sout_stream_id_t *)p_sys;
}
Exemple #14
0
/**
 * Find the drawable set by libvlc application.
 */
static int Open (vlc_object_t *obj, const char *varname, bool ptr)
{
    vout_window_t *wnd = (vout_window_t *)obj;
    void **used, *val;
    size_t n = 0;

    if (var_Create (obj->p_libvlc, "drawables-in-use", VLC_VAR_ADDRESS)
     || var_Create (obj, varname, VLC_VAR_DOINHERIT
                                  | (ptr ? VLC_VAR_ADDRESS : VLC_VAR_INTEGER)))
        return VLC_ENOMEM;

    if (ptr)
        val = var_GetAddress (obj, varname);
    else
        val = (void *)(uintptr_t)var_GetInteger (obj, varname);
    var_Destroy (obj, varname);

    /* Keep a list of busy drawables, so we don't overlap videos if there are
     * more than one video track in the stream. */
    vlc_mutex_lock (&serializer);
    /* TODO: per-type list of busy drawables */
    used = var_GetAddress (VLC_OBJECT (obj->p_libvlc), "drawables-in-use");
    if (used != NULL)
    {
        while (used[n] != NULL)
        {
            if (used[n] == val)
                goto skip;
            n++;
        }
    }

    used = realloc (used, sizeof (*used) * (n + 2));
    if (used != NULL)
    {
        used[n] = val;
        used[n + 1] = NULL;
        var_SetAddress (obj->p_libvlc, "drawables-in-use", used);
    }
    else
    {
skip:
        msg_Warn (wnd, "drawable %p is busy", val);
        val = NULL;
    }
    vlc_mutex_unlock (&serializer);

    if (val == NULL)
        return VLC_EGENERIC;

    if (ptr)
        wnd->handle.hwnd = val;
    else
        wnd->handle.xid = (uintptr_t)val;

    /* FIXME: check that X server matches --x11-display (if specified) */
    /* FIXME: get window size (in platform-dependent ways) */

    wnd->control = Control;
    wnd->p_sys = val;
    return VLC_SUCCESS;
}