在看FFMPEG的源码时,进入main()函数的第一句程序就是:
03149 int main(int argc, char **argv) 03150 { 03151 OptionsContext o = { 0 };
这里涉及到结构体变量的初始化,结构体变量的初始化方式很多,这里是其中一种。
OptionContext是一个结构体,其定义为下面:
00073 typedef struct OptionsContext { 00074 /* input/output options */ 00075 int64_t start_time; 00076 const char *format; 00077 00078 SpecifierOpt *codec_names; 00079 int nb_codec_names; 00080 SpecifierOpt *audio_channels; 00081 int nb_audio_channels; 00082 SpecifierOpt *audio_sample_rate; 00083 int nb_audio_sample_rate; 00084 SpecifierOpt *frame_rates; 00085 int nb_frame_rates; 00086 SpecifierOpt *frame_sizes; 00087 int nb_frame_sizes; 00088 SpecifierOpt *frame_pix_fmts; 00089 int nb_frame_pix_fmts; 00090 00091 /* input options */ 00092 int64_t input_ts_offset; 00093 int rate_emu; 00094 00095 SpecifierOpt *ts_scale; 00096 int nb_ts_scale; 00097 SpecifierOpt *dump_attachment; 00098 int nb_dump_attachment; 00099 00100 /* output options */ 00101 StreamMap *stream_maps; 00102 int nb_stream_maps; 00103 AudioChannelMap *audio_channel_maps; /* one info entry per -map_channel */ 00104 int nb_audio_channel_maps; /* number of (valid) -map_channel settings */ 00105 int metadata_global_manual; 00106 int metadata_streams_manual; 00107 int metadata_chapters_manual; 00108 const char **attachments; 00109 int nb_attachments; 00110 00111 int chapters_input_file; 00112 00113 int64_t recording_time; 00114 uint64_t limit_filesize; 00115 float mux_preload; 00116 float mux_max_delay; 00117 int shortest; 00118 00119 int video_disable; 00120 int audio_disable; 00121 int subtitle_disable; 00122 int data_disable; 00123 00124 /* indexed by output file stream index */ 00125 int *streamid_map; 00126 int nb_streamid_map; 00127 00128 SpecifierOpt *metadata; 00129 int nb_metadata; 00130 SpecifierOpt *max_frames; 00131 int nb_max_frames; 00132 SpecifierOpt *bitstream_filters; 00133 int nb_bitstream_filters; 00134 SpecifierOpt *codec_tags; 00135 int nb_codec_tags; 00136 SpecifierOpt *sample_fmts; 00137 int nb_sample_fmts; 00138 SpecifierOpt *qscale; 00139 int nb_qscale; 00140 SpecifierOpt *forced_key_frames; 00141 int nb_forced_key_frames; 00142 SpecifierOpt *force_fps; 00143 int nb_force_fps; 00144 SpecifierOpt *frame_aspect_ratios; 00145 int nb_frame_aspect_ratios; 00146 SpecifierOpt *rc_overrides; 00147 int nb_rc_overrides; 00148 SpecifierOpt *intra_matrices; 00149 int nb_intra_matrices; 00150 SpecifierOpt *inter_matrices; 00151 int nb_inter_matrices; 00152 SpecifierOpt *top_field_first; 00153 int nb_top_field_first; 00154 SpecifierOpt *metadata_map; 00155 int nb_metadata_map; 00156 SpecifierOpt *presets; 00157 int nb_presets; 00158 SpecifierOpt *copy_initial_nonkeyframes; 00159 int nb_copy_initial_nonkeyframes; 00160 SpecifierOpt *copy_prior_start; 00161 int nb_copy_prior_start; 00162 SpecifierOpt *filters; 00163 int nb_filters; 00164 SpecifierOpt *fix_sub_duration; 00165 int nb_fix_sub_duration; 00166 SpecifierOpt *pass; 00167 int nb_pass; 00168 SpecifierOpt *passlogfiles; 00169 int nb_passlogfiles; 00170 } OptionsContext;
OptionContext o = { 0 };
这种初始化的的结果就是,将OptionContext的成员变量中整型、浮点型成员都赋值为0,指针变量则指向NULL。
但是,OptionContext o = 0是不对的,在VS上报错说是:error C2440: 'initializing' : cannot convert from 'int' to 'OptionContext',原来是不支持整型与OptionContext之间类型的强制转换。
我不能理解的就是结构体变量初始化方式在C99标准上没有类似的,除了常用的结构体变量初始化之外,还有以下方式:
采用标记化结构初始化语法:
结构体形式为:
struct 结构体变量{
成员1;
成员2;
成员3;
、、、
、、、
};
初始化方式1:struct 结构体变量 结构体变量名=
{
.成员1= 成员1变量值,
.成员2=成员2变量值,
.成员3=成员3变量值,
、、、
.成员n=成员n变量值,
}
注意:成员变量值形式和成员变量类型要保持一致,例如,若是成员2为字符型数据,那成员2变量值必须用字符串形式表示;
当采用上面形式定义时,可以不按照成员的定义顺序去初始化,顺序可以打乱;
可以多次赋值,但是以最后一次赋值为准;
或者是:初始化方式2:struct 结构体变量 结构体体变量名 =
{
成员1变量值,
成员2变量值,
成员3变量值,
、、、
、、、
成员n变量值,
}
注意:当采用方式2初始化时,结构体中的成员必须依次进行初始化,并且变量值顺序必须与对应的成员的顺序一致。
举例:
这是FFMPEG上的结构体AVOutputFormat的定义:
typedef struct AVOutputFormat {
const char *name;
const char *long_name;
const char *mime_type;
const char *extensions; /**< comma separated filename extensions */
int priv_data_size;/** size of private data so that it can be allocated in the wrapper */
/* output support */
enum CodecID audio_codec; /**< default audio codec */
enum CodecID video_codec; /**< default video codec */
int (*write_header)(struct AVFormatContext *);
int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
int (*write_trailer)(struct AVFormatContext *);
/** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */
int flags;
/** currently only used to set pixel format if not YUV420P */
int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *);
int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, AVPacket *in, int flush);
/**
*list of supported codec_id-codec_tag pairs,ordered by "better choice first"
* the arrays are all CODEC_ID_NONE terminated
*/
const struct AVCodecTag **codec_tag;
/* private fields */
struct AVOutputFormat *next;
} AVOutputFormat;
然后这个结构体的 初始化为:
AVOutputFormat flv_muxer = {
"flv",
"flv format",
"video/x-flv",
"flv",
sizeof(FLVContext),
#ifdef CONFIG_LIBMP3LAME
CODEC_ID_MP3,
#else // CONFIG_LIBMP3LAME
CODEC_ID_NONE,
CODEC_ID_FLV1,
flv_write_header,
flv_write_packet,
flv_write_trailer,
.codec_tag= (const AVCodecTag*[]){flv_video_codec_ids, flv_audio_codec_ids, 0},
}
注意:如果仅仅对部分的成员变量进行初始化,要求初始化的数据至少有一个,其他没有初始化的 成员变量由系统完成初始化,为其完成初始值。各种基本数据类型的成员变量初始化缺省值为:
整型:int:0
字符型:char:‘\0x0’
浮点型:float:0.0
双精度型:double:0.0
字符数组:char array[n]:""
整型数组:int array[n]:{0,0,0、、、,0}