⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * objects.c: vlc_object_t handling ***************************************************************************** * Copyright (C) 2004-2008 the VideoLAN team * * Authors: Samuel Hocevar <sam@zoy.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//** * \file * This file contains the functions to handle the vlc_object_t type *//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include "../libvlc.h"#include <vlc_vout.h>#include <vlc_aout.h>#include "audio_output/aout_internal.h"#include <vlc_access.h>#include <vlc_demux.h>#include <vlc_stream.h>#include <vlc_sout.h>#include "stream_output/stream_output.h"#include "vlc_interface.h"#include "vlc_codec.h"#include "vlc_filter.h"#include "variables.h"#ifndef WIN32# include <unistd.h>#else# include <io.h># include <fcntl.h># include <errno.h> /* ENOSYS */#endif#include <assert.h>/***************************************************************************** * Local prototypes *****************************************************************************/static int  DumpCommand( vlc_object_t *, char const *,                         vlc_value_t, vlc_value_t, void * );static vlc_object_t * FindObject    ( vlc_object_t *, int, int );static vlc_object_t * FindObjectName( vlc_object_t *, const char *, int );static void           PrintObject   ( vlc_object_t *, const char * );static void           DumpStructure ( vlc_object_t *, int, char * );static vlc_list_t   * NewList       ( int );static void           ListReplace   ( vlc_list_t *, vlc_object_t *, int );/*static void           ListAppend    ( vlc_list_t *, vlc_object_t * );*/static int            CountChildren ( vlc_object_t *, int );static void           ListChildren  ( vlc_list_t *, vlc_object_t *, int );static void vlc_object_destroy( vlc_object_t *p_this );static void vlc_object_detach_unlocked (vlc_object_t *p_this);#ifdef LIBVLC_REFCHECKstatic vlc_threadvar_t held_objects;typedef struct held_list_t{    struct held_list_t *next;    vlc_object_t *obj;} held_list_t;static void held_objects_destroy (void *);#endif/***************************************************************************** * Local structure lock *****************************************************************************/static vlc_mutex_t structure_lock;static unsigned    object_counter = 0;void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,                           int i_type, const char *psz_type ){    vlc_object_t *p_new;    vlc_object_internals_t *p_priv;    /* NOTE:     * VLC objects are laid out as follow:     * - first the LibVLC-private per-object data,     * - then VLC_COMMON members from vlc_object_t,     * - finally, the type-specific data (if any).     *     * This function initializes the LibVLC and common data,     * and zeroes the rest.     */    p_priv = calloc( 1, sizeof( *p_priv ) + i_size );    if( p_priv == NULL )        return NULL;    assert (i_size >= sizeof (vlc_object_t));    p_new = (vlc_object_t *)(p_priv + 1);    p_new->i_object_type = i_type;    p_new->psz_object_type = psz_type;    p_new->psz_object_name = NULL;    p_new->b_die = false;    p_new->b_error = false;    p_new->b_dead = false;    p_new->b_force = false;    p_new->psz_header = NULL;    if (p_this)        p_new->i_flags = p_this->i_flags            & (OBJECT_FLAGS_NODBG|OBJECT_FLAGS_QUIET|OBJECT_FLAGS_NOINTERACT);    p_priv->p_vars = calloc( sizeof( variable_t ), 16 );    if( !p_priv->p_vars )    {        free( p_priv );        return NULL;    }    libvlc_global_data_t *p_libvlc_global;    if( p_this == NULL )    {        /* Only the global root object is created out of the blue */        p_libvlc_global = (libvlc_global_data_t *)p_new;        p_new->p_libvlc = NULL;        object_counter = 0; /* reset */        p_priv->next = p_priv->prev = p_new;        vlc_mutex_init( &structure_lock );#ifdef LIBVLC_REFCHECK        /* TODO: use the destruction callback to track ref leaks */        vlc_threadvar_create( &held_objects, held_objects_destroy );#endif    }    else    {        p_libvlc_global = vlc_global();        if( i_type == VLC_OBJECT_LIBVLC )            p_new->p_libvlc = (libvlc_int_t*)p_new;        else            p_new->p_libvlc = p_this->p_libvlc;    }    vlc_spin_init( &p_priv->ref_spin );    p_priv->i_refcount = 1;    p_priv->pf_destructor = NULL;    p_priv->b_thread = false;    p_new->p_parent = NULL;    p_priv->pp_children = NULL;    p_priv->i_children = 0;    p_new->p_private = NULL;    /* Initialize mutexes and condvars */    vlc_mutex_init( &p_priv->lock );    vlc_cond_init( p_new, &p_priv->wait );    vlc_mutex_init( &p_priv->var_lock );    vlc_spin_init( &p_priv->spin );    p_priv->pipes[0] = p_priv->pipes[1] = -1;    p_priv->next = VLC_OBJECT (p_libvlc_global);#if !defined (LIBVLC_REFCHECK)    /* ... */#elif defined (LIBVLC_USE_PTHREAD)    p_priv->creator_id = pthread_self ();#elif defined (WIN32)    p_priv->creator_id = GetCurrentThreadId ();#endif    vlc_mutex_lock( &structure_lock );    p_priv->prev = vlc_internals (p_libvlc_global)->prev;    vlc_internals (p_libvlc_global)->prev = p_new;    vlc_internals (p_priv->prev)->next = p_new;    p_new->i_object_id = object_counter++; /* fetch THEN increment */    vlc_mutex_unlock( &structure_lock );    if( i_type == VLC_OBJECT_LIBVLC )    {        var_Create( p_new, "list", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );        var_AddCallback( p_new, "list", DumpCommand, NULL );        var_Create( p_new, "tree", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );        var_AddCallback( p_new, "tree", DumpCommand, NULL );        var_Create( p_new, "vars", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );        var_AddCallback( p_new, "vars", DumpCommand, NULL );    }    return p_new;}/** * Allocates and initializes a vlc object. * * @param i_type known object type (all of them are negative integer values), *               or object byte size (always positive). * * @return the new object, or NULL on error. */void * __vlc_object_create( vlc_object_t *p_this, int i_type ){    const char   * psz_type;    size_t         i_size;    switch( i_type )    {        case VLC_OBJECT_INTF:            i_size = sizeof(intf_thread_t);            psz_type = "interface";            break;        case VLC_OBJECT_DECODER:            i_size = sizeof(decoder_t);            psz_type = "decoder";            break;        case VLC_OBJECT_PACKETIZER:            i_size = sizeof(decoder_t);            psz_type = "packetizer";            break;        case VLC_OBJECT_ENCODER:            i_size = sizeof(encoder_t);            psz_type = "encoder";            break;        case VLC_OBJECT_AOUT:            i_size = sizeof(aout_instance_t);            psz_type = "audio output";            break;        case VLC_OBJECT_OPENGL:            i_size = sizeof( vout_thread_t );            psz_type = "opengl";            break;        case VLC_OBJECT_ANNOUNCE:            i_size = sizeof( announce_handler_t );            psz_type = "announce";            break;        default:            assert( i_type > 0 ); /* unknown type?! */            i_size = i_type;            i_type = VLC_OBJECT_GENERIC;            psz_type = "generic";            break;    }    return vlc_custom_create( p_this, i_size, i_type, psz_type );}/** **************************************************************************** * Set the destructor of a vlc object * * This function sets the destructor of the vlc object. It will be called * when the object is destroyed when the its refcount reaches 0. * (It is called by the internal function vlc_object_destroy()) *****************************************************************************/void __vlc_object_set_destructor( vlc_object_t *p_this,                                  vlc_destructor_t pf_destructor ){    vlc_object_internals_t *p_priv = vlc_internals(p_this );    p_priv->pf_destructor = pf_destructor;}/** **************************************************************************** * Destroy a vlc object (Internal) * * This function destroys an object that has been previously allocated with * vlc_object_create. The object's refcount must be zero and it must not be * attached to other objects in any way. *****************************************************************************/static void vlc_object_destroy( vlc_object_t *p_this ){    vlc_object_internals_t *p_priv = vlc_internals( p_this );    /* Objects are always detached beforehand */    assert( !p_this->p_parent );    /* Send a kill to the object's thread if applicable */    vlc_object_kill( p_this );    /* If we are running on a thread, wait until it ends */    if( p_priv->b_thread )    {        msg_Warn (p_this->p_libvlc, /* do NOT use a dead object for logging! */                  "%s %d destroyed while thread alive (VLC might crash)",                  p_this->psz_object_type, p_this->i_object_id);        vlc_thread_join( p_this );    }    /* Call the custom "subclass" destructor */    if( p_priv->pf_destructor )        p_priv->pf_destructor( p_this );    /* Destroy the associated variables, starting from the end so that     * no memmove calls have to be done. */    while( p_priv->i_vars )    {        var_Destroy( p_this, p_priv->p_vars[p_priv->i_vars - 1].psz_name );    }    free( p_priv->p_vars );    vlc_mutex_destroy( &p_priv->var_lock );    free( p_this->psz_header );    if( p_this->p_libvlc == NULL )    {#ifndef NDEBUG        libvlc_global_data_t *p_global = (libvlc_global_data_t *)p_this;        assert( p_global == vlc_global() );        /* Test for leaks */        if (p_priv->next != p_this)        {            vlc_object_t *leaked = p_priv->next, *first = leaked;            do            {                /* We are leaking this object */                fprintf( stderr,                         "ERROR: leaking object (id:%i, type:%s, name:%s)\n",                         leaked->i_object_id, leaked->psz_object_type,                         leaked->psz_object_name );                /* Dump libvlc object to ease debugging */                vlc_object_dump( leaked );                fflush(stderr);                leaked = vlc_internals (leaked)->next;            }            while (leaked != first);            /* Dump global object to ease debugging */            vlc_object_dump( p_this );            /* Strongly abort, cause we want these to be fixed */            abort();        }#endif        /* We are the global object ... no need to lock. */        vlc_mutex_destroy( &structure_lock );#ifdef LIBVLC_REFCHECK        held_objects_destroy( vlc_threadvar_get( &held_objects ) );        vlc_threadvar_delete( &held_objects );#endif    }    FREENULL( p_this->psz_object_name );#if defined(WIN32) || defined(UNDER_CE)    /* if object has an associated thread, close it now */    if( p_priv->thread_id )       CloseHandle(p_priv->thread_id);#endif    vlc_spin_destroy( &p_priv->ref_spin );    vlc_mutex_destroy( &p_priv->lock );    vlc_cond_destroy( &p_priv->wait );    vlc_spin_destroy( &p_priv->spin );    if( p_priv->pipes[1] != -1 )        close( p_priv->pipes[1] );    if( p_priv->pipes[0] != -1 )        close( p_priv->pipes[0] );    free( p_priv );}/** Inter-object signaling */void __vlc_object_lock( vlc_object_t *obj )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -