struct
libvlc_media_t
{
libvlc_event_manager_t * p_event_manager;
int b_preparsed;
input_item_t *p_input_item;
int i_refcount;
libvlc_instance_t *p_libvlc_instance;
libvlc_state_t state;
VLC_FORWARD_DECLARE_OBJECT(libvlc_media_list_t*) p_subitems; /* A media descriptor can have Sub items. This is the only dependancy we really have on media_list */
void *p_user_data;
};
struct
libvlc_media_player_t
{
int i_refcount;
vlc_mutex_t object_lock;
input_thread_t * p_input_thread;
struct libvlc_instance_t * p_libvlc_instance; /* Parent instance */
libvlc_media_t * p_md; /* current media descriptor */
libvlc_event_manager_t * p_event_manager;
struct
{
void *hwnd;
void *nsobject;
uint32_t xid;
uint32_t agl;
} drawable;
bool b_own_its_input_thread;
};
struct
libvlc_instance_t
{
libvlc_int_t *p_libvlc_int;
vlm_t *p_vlm;
int b_playlist_locked;
unsigned ref_count;
int verbosity;
vlc_mutex_t instance_lock;
vlc_mutex_t event_callback_lock;
struct libvlc_callback_entry_list_t *p_callback_list;
};
in control/audio.c
static
aout_instance_t *GetAOut( libvlc_instance_t *p_instance,
libvlc_exception_t *p_exception )
{
if( !p_instance )
return NULL;
aout_instance_t * p_aout = NULL;
p_aout = vlc_object_find( p_instance->p_libvlc_int, VLC_OBJECT_AOUT, FIND_CHILD );
if( !p_aout )
{
libvlc_exception_raise( p_exception, "No active audio output" );
return NULL;
}
return p_aout;
}
Libvlc
详细过程
///////////////////////////////////////////////////////////////////////
libvlc_instance_t
* libvlc_new( int argc, const char *const *argv,
libvlc_exception_t *p_e )
{
libvlc_instance_t *p_new;
int i_ret;
libvlc_int_t *p_libvlc_int = libvlc_InternalCreate();
if( !p_libvlc_int ) RAISENULL( "VLC initialization failed" );
p_new = malloc( sizeof( libvlc_instance_t ) );
if( !p_new ) RAISENULL( "Out of memory" );
const char *my_argv[argc + 2];
my_argv[0] = "libvlc"; /* dummy arg0, skipped by getopt() et al */
for( int i = 0; i < argc; i++ )
my_argv[i + 1] = argv[i];
my_argv[argc + 1] = NULL; /* C calling conventions require a NULL */
/** \todo Look for interface settings. If we don't have any, add -I dummy */
/* Because we probably don't want a GUI by default */
i_ret = libvlc_InternalInit( p_libvlc_int, argc + 1, my_argv );
if( i_ret )
{
libvlc_InternalDestroy( p_libvlc_int );
free( p_new );
if( i_ret == VLC_EEXITSUCCESS )
return NULL;
else
RAISENULL( "VLC initialization failed" );
}
p_new->p_libvlc_int = p_libvlc_int;
p_new->p_vlm = NULL;
p_new->b_playlist_locked = 0;
p_new->ref_count = 1;
p_new->verbosity = 1;
p_new->p_callback_list = NULL;
vlc_mutex_init(&p_new->instance_lock);
vlc_mutex_init(&p_new->event_callback_lock);
return p_new;
}
////////////////////////////////////////////////////////////
libvlc_media_t
* libvlc_media_new_from_input_item(
libvlc_instance_t *p_instance,
input_item_t *p_input_item,
libvlc_exception_t *p_e )
{
libvlc_media_t * p_md;
if (!p_input_item)
{
libvlc_exception_raise( p_e, "No input item given" );
return NULL;
}
p_md = malloc( sizeof(libvlc_media_t) );
if( !p_md )
{
libvlc_exception_raise( p_e, "Not enough memory" );
return NULL;
}
p_md->p_libvlc_instance = p_instance;
p_md->p_input_item = p_input_item;
p_md->b_preparsed = false;
p_md->i_refcount = 1;
p_md->p_user_data = NULL;
p_md->state = libvlc_NothingSpecial;
/* A media descriptor can be a playlist. When you open a playlist
* It can give a bunch of item to read. */
p_md->p_subitems = NULL;
p_md->p_event_manager = libvlc_event_manager_new( p_md, p_instance, p_e );
libvlc_event_manager_register_event_type( p_md->p_event_manager,
libvlc_MediaMetaChanged, p_e );
libvlc_event_manager_register_event_type( p_md->p_event_manager,
libvlc_MediaSubItemAdded, p_e );
libvlc_event_manager_register_event_type( p_md->p_event_manager,
libvlc_MediaFreed, p_e );
libvlc_event_manager_register_event_type( p_md->p_event_manager,
libvlc_MediaDurationChanged, p_e );
libvlc_event_manager_register_event_type( p_md->p_event_manager,
libvlc_MediaStateChanged, p_e );
vlc_gc_incref( p_md->p_input_item );
install_input_item_observer( p_md );
return p_md;
}
// aout_buffer_t
的由来
aout_buffer_t
* aout_DecNewBuffer( aout_input_t * p_input,
size_t i_nb_samples )
{
aout_buffer_t * p_buffer;
mtime_t duration;
aout_lock_input( NULL, p_input );
if ( p_input->b_error )
{
aout_unlock_input( NULL, p_input );
return NULL;
}
duration = (1000000 * (mtime_t)i_nb_samples) / p_input->input.i_rate;
/* This necessarily allocates in the heap. */
aout_BufferAlloc( &p_input->input_alloc, duration, NULL, p_buffer );
if( p_buffer != NULL )
p_buffer->i_nb_bytes = i_nb_samples * p_input->input.i_bytes_per_frame
/ p_input->input.i_frame_length;
/* Suppose the decoder doesn't have more than one buffered buffer */
p_input->b_changed = false;
aout_unlock_input( NULL, p_input );
if( p_buffer == NULL )
return NULL;
p_buffer->i_nb_samples = i_nb_samples;
p_buffer->start_date = p_buffer->end_date = 0;
return p_buffer;
}