(1) 宏定义的超级父类-VLC_COMMON_MEMBERS:
/*****************************************************************************
* Common structure members
*****************************************************************************/
/* VLC_COMMON_MEMBERS : members common to all basic vlc objects */
#define VLC_COMMON_MEMBERS \
/** \name VLC_COMMON_MEMBERS \
* these members are common for all vlc objects \
*/ \
/**@{*/ \
const char *psz_object_type; \
\
/* Messages header */ \
char *psz_header; \
int i_flags; \
\
/* Object properties */ \
bool b_force; /**< set by the outside (eg. module_need()) */ \
\
/* Stuff related to the libvlc structure */ \
libvlc_int_t *p_libvlc; /** (root of all evil) - 1 */ \
\
vlc_object_t * p_parent; /**> our parent */ \
\
/**@}*/
(2) vlc_object_t : 主要的一个数据结构
/** The main vlc_object_t structure */
struct vlc_object_t
{
VLC_COMMON_MEMBERS
};
typedef struct vlc_object_t vlc_object_t;
(3) vlc_value_t :
/**
* VLC value structure
*/
typedef union
{
int64_t i_int;
bool b_bool;
float f_float;
char * psz_string;
void * p_address;
vlc_object_t * p_object;
vlc_list_t * p_list;
mtime_t i_time;
struct { int32_t x; int32_t y; } coords;
} vlc_value_t;
----------
关于Union: 这个数据结构。本质上讲与结构体相近,但从包装角度来看有所差异:
Union中可以定义多个成员,union的大小由最大的成员大小决定。
Union成员共享一块大小的内存,一次只能使用其中的一个成员。
对某一个成员赋值,会覆盖掉其他成员的值(也不奇怪,因为Union中的成员共享一块内存。但前提是成员所占字节数相同。当成员所占字节数不同时,仅仅会覆盖掉相应字节上的值。
,比如char成员赋值就不会把整个int成员覆盖掉,因为char只占一个字节,而int只占四个字节)。
联合体union的存放顺序是所有成员都从低地址开始存放。
再扯点关于Static关键字
在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。
(1)第一个作用:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。
下面是a.c的内容
#include增加这条语句
char a = ‘A‘; // global variable
void msg()
{
printf("Hello\n");
}
你可能会问:为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。
此例中,a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。
如果加了static,就会对其它源文件隐藏。例如在a和msg的定义前加上static,main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。
(2)static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化
共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。
(3)static的第三个作用是默认初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。
最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。
下面是main.c的内容
除了头文件,需要声明函数:void msg();
int main(void)
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
(4) input_thread_t :
/**
* Main structure representing an input thread. This structure is mostly
* private. The only public fields are READ-ONLY. You must use the helpers
* to modify them
*/
struct input_thread_t
{
VLC_COMMON_MEMBERS
bool b_error;
bool b_eof;
bool b_preparsing;
bool b_dead;
/* All other data is input_thread is PRIVATE. You can't access it
* outside of src/input */
input_thread_private_t *p;
};
--> input_thread_private_t *p:
/** Private input fields */
struct input_thread_private_t
{
/* Global properties */
double f_fps;
int i_state;
bool b_can_pause;
bool b_can_rate_control;
bool b_can_pace_control;
/* Current state */
bool b_recording;
int i_rate;
/* Playtime configuration and state */
int64_t i_start; /* :start-time,0 by default */
int64_t i_stop; /* :stop-time, 0 if none */
int64_t i_run; /* :run-time, 0 if none */
int64_t i_time; /* Current time */
bool b_fast_seek;/* :input-fast-seek */
/* Output */
bool b_out_pace_control; /* XXX Move it ot es_sout ? */
sout_instance_t *p_sout; /* Idem ? */
es_out_t *p_es_out;
es_out_t *p_es_out_display;
/* Title infos FIXME multi-input (not easy) ? */
int i_title;
input_title_t **title;
int i_title_offset;
int i_seekpoint_offset;
/* User bookmarks FIXME won't be easy with multiples input */
seekpoint_t bookmark;
int i_bookmark;
seekpoint_t **pp_bookmark;
/* Input attachment */
int i_attachment;
input_attachment_t **attachment;
demux_t **attachment_demux;
/* Main input properties */
/* Input item */
input_item_t *p_item;
/* Main source */
input_source_t input;
/* Slave sources (subs, and others) */
int i_slave;
input_source_t **slave;
/* Resources */
input_resource_t *p_resource;
input_resource_t *p_resource_private;
/* Stats counters */
struct {
counter_t *p_read_packets;
counter_t *p_read_bytes;
counter_t *p_input_bitrate;
counter_t *p_demux_read;
counter_t *p_demux_bitrate;
counter_t *p_demux_corrupted;
counter_t *p_demux_discontinuity;
counter_t *p_decoded_audio;
counter_t *p_decoded_video;
counter_t *p_decoded_sub;
counter_t *p_sout_sent_packets;
counter_t *p_sout_sent_bytes;
counter_t *p_sout_send_bitrate;
counter_t *p_played_abuffers;
counter_t *p_lost_abuffers;
counter_t *p_displayed_pictures;
counter_t *p_lost_pictures;
vlc_mutex_t counters_lock;
} counters;
/* Buffer of pending actions */
vlc_mutex_t lock_control;
vlc_cond_t wait_control;
int i_control;
input_control_t control[INPUT_CONTROL_FIFO_SIZE];
bool b_abort;
bool is_running;
vlc_thread_t thread;
};
-------> sout_instance_t
/** Stream output instance (FIXME: should be private to src/ to avoid
* invalid unsynchronized access) */
struct sout_instance_t
{
VLC_COMMON_MEMBERS
char *psz_sout;
/** count of output that can't control the space */
int i_out_pace_nocontrol;
vlc_mutex_t lock;
sout_stream_t *p_stream;
};
----------------------------------------> vlc_mutex_t 互斥对象
typedef struct vlc_thread *vlc_thread_t;
typedef struct
{
bool dynamic;
union
{
struct
{
bool locked;
unsigned long contention;
};
CRITICAL_SECTION mutex;
};
} vlc_mutex_t;
---------------------------------------> sout_stream_t
/** Stream output instance (FIXME: should be private to src/ to avoid
* invalid unsynchronized access) */
struct sout_instance_t
{
VLC_COMMON_MEMBERS
char *psz_sout;
/** count of output that can't control the space */
int i_out_pace_nocontrol;
vlc_mutex_t lock;
sout_stream_t *p_stream;
};
-------------> es_out_t
一系列函数指针
struct es_out_t
{
es_out_id_t *(*pf_add) ( es_out_t *, const es_format_t * );
int (*pf_send) ( es_out_t *, es_out_id_t *, block_t * );
void (*pf_del) ( es_out_t *, es_out_id_t * );
int (*pf_control)( es_out_t *, int i_query, va_list );
void (*pf_destroy)( es_out_t * );
es_out_sys_t *p_sys;
};
------------>input_item_t
struct input_item_t
{
int i_id; /**< Identifier of the item */
char *psz_name; /**< text describing this item */
char *psz_uri; /**< mrl of this item */
int i_options; /**< Number of input options */
char **ppsz_options; /**< Array of input options */
uint8_t *optflagv; /**< Some flags of input options */
unsigned optflagc;
mtime_t i_duration; /**< Duration in microseconds */
int i_categories; /**< Number of info categories */
info_category_t **pp_categories; /**< Pointer to the first info category */
int i_es; /**< Number of es format descriptions */
es_format_t **es; /**< Es formats */
input_stats_t *p_stats; /**< Statistics */
vlc_meta_t *p_meta;
int i_epg; /**< Number of EPG entries */
vlc_epg_t **pp_epg; /**< EPG entries */
vlc_event_manager_t event_manager;
vlc_mutex_t lock; /**< Lock for the item */
uint8_t i_type; /**< Type (file, disc, ... see input_item_type_e) */
bool b_error_when_reading;/**< Error When Reading */
};
------------->input_source_t
/* input_source_t: gathers all information per input source */
typedef struct
{
demux_t *p_demux; /**< Demux plugin instance */
/* Title infos for that input */
bool b_title_demux; /* Titles/Seekpoints provided by demux */
int i_title;
input_title_t **title;
int i_title_offset;
int i_seekpoint_offset;
int i_title_start;
int i_title_end;
int i_seekpoint_start;
int i_seekpoint_end;
/* Properties */
bool b_can_pause;
bool b_can_pace_control;
bool b_can_rate_control;
bool b_can_stream_record;
bool b_rescale_ts;
/* */
int64_t i_pts_delay;
bool b_eof; /* eof of demuxer */
} input_source_t;
------------->counter_t
typedef struct counter_t
{
int i_compute_type;
int i_samples;
counter_sample_t ** pp_samples;
mtime_t last_update;
} counter_t;