x265探索与研究(六):main()函数
x265源码的入口函数是main(),本文分析main()的主要功能。首先给出main()函数的功能及其代码结构;其次给出main()函数源码以及分析;最后给出main()函数中的主要功能函数的具体功能。
1、main()函数的功能及其代码结构
main()函数的主要功能是解析参数并进行编码的一些准备工作,调用了如下几个重要的函数:
(1)cliopt.parse()函数:解析参数
(2)api->encoder_open()函数:打开编码器配置
(3)api->encoder_headers()函数:设置NAL相关信息
(4)api->encoder_encode()函数:进入编码函数
(5)api->encoder_close()函数:结束编码并进行总结
注:encoder_open()函数、encoder_headers()函数、encoder_encode()函数与encoder_close()函数均位于api.app中。
对应的函数关系图如下图所示:
2、main()函数源码以及分析
main()函数的源码分析如下代码中的注释,代码如下:
/*=============================================================*/
/*
====== Analysed by: RuiDong Fang
====== Csdn Blog: http://blog.csdn.net/frd2009041510
====== Date: 2016.04.10
====== Funtion: x265的入口main()函数
*/
/*=============================================================*/
/* CLI return codes:
*
* 0 - encode successful
* 1 - unable to parse command line
* 2 - unable to open encoder
* 3 - unable to generate stream headers
* 4 - encoder abort
* 5 - unable to open csv file
*
*/
int main(int argc, char **argv) //主函数入口
{
#if HAVE_VLD
// This uses Microsoft's proprietary WCHAR type, but this only builds on Windows to start with
VLDSetReportOptions(VLD_OPT_REPORT_TO_DEBUGGER | VLD_OPT_REPORT_TO_FILE, L"x265_leaks.txt");
#endif
PROFILE_INIT();
THREAD_NAME("API", 0);
GetConsoleTitle(orgConsoleTitle, CONSOLE_TITLE_SIZE); //获取控制台窗口
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED);
ReconPlay* reconPlay = NULL;
CLIOptions cliopt;
if (cliopt.parse(argc, argv)) //==========分析参数,对编码器的参数进行设定,打开文件
{
cliopt.destroy();
if (cliopt.api)
cliopt.api->param_free(cliopt.param);
exit(1);
}
x265_param* param = cliopt.param;
const x265_api* api = cliopt.api;
/* This allows muxers to modify bitstream format */
cliopt.output->setParam(param);
if (cliopt.reconPlayCmd)
reconPlay = new ReconPlay(cliopt.reconPlayCmd, *param);
/* note: we could try to acquire a different libx265 API here based on
* the profile found during option parsing, but it must be done before
* opening an encoder */
x265_encoder *encoder = api->encoder_open(param); //==========encoder_open()函数,打印编码器配置
if (!encoder) //若打不开编码器配置,提示错误
{
x265_log(param, X265_LOG_ERROR, "failed to open encoder\n");
cliopt.destroy();
api->param_free(param);
api->cleanup();
exit(2);
}
/* get the encoder parameters post-initialization */
api->encoder_parameters(encoder, param);
if (cliopt.csvfn)
{
cliopt.csvfpt = x265_csvlog_open(*api, *param, cliopt.csvfn, cliopt.csvLogLevel);
if (!cliopt.csvfpt)
{
x265_log(param, X265_LOG_ERROR, "Unable to open CSV log file <%s>, aborting\n", cliopt.csvfn);
cliopt.destroy();
if (cliopt.api)
cliopt.api->param_free(cliopt.param);
exit(5);
}
}
/* Contr