JM8.6编码器中的Configure函数究竟做了什么?(编程思想:抽象,间接)
来源:互联网 发布:档案管理系统软件源码 编辑:程序博客网 时间:2024/04/27 16:55
从字面意思来看,configure就是配置的意思,顾名思义,Configure函数就是配置函数了。配置函数的作用是给程序配置(设定)一些初始的值,这些值在很大程度上相当于一个开关.
在用别人写的软件的时候,我们经常在软件的界面的某一个对话框里面输入一个参数,然后软件里的程序就会捕捉到这个对话框里面的参数,这样就把用户设定的参数传到了程序里面。细想一下,在JM8.6编码器中就是这样的,这里的“对话框”实际上是一个配置文件,比如:encoder_baseline.cfg. 那为什么需要这样一个配置文件呢?原因很简单,为了抽象,为了间接. 抽象是为了更好地重用. 间接又可以实现职责的分离,即用户可以通过配置文件来设定自己想用的参数,而不需要去改软件的程序.
先来简要地看一个结构体类型InputParameters, 在编码器的global.h中,是这么定义的:
typedef struct{ //档次 int ProfileIDC; //!< profile idc //级别 int LevelIDC; //!< level idc //编码的帧数 int no_frames; //!< number of frames to be encoded //第一帧QP int qp0; //!< QP of first frame //剩余帧QP int qpN; //!< QP of remaining frames //隔n帧编码 int jumpd; //!< number of frames to skip in input sequence (e.g 2 takes frame 0,3,6,9...) int hadamard; /*!< 0: 'normal' SAD in 1/3 pixel search. 1: use 4x4 Haphazard transform and ' Sum of absolute transform difference' in 1/3 pixel search */ //搜索范围 int search_range; /*!< search range - integer pel search and 16x16 blocks. The search window is generally around the predicted vector. Max vector is 2xmcrange. For 8x8 and 4x4 block sizes the search range is 1/2 of that for 16x16 blocks. */ //参考帧数 int num_reference_frames; //!< number of reference frames to be used int P_List0_refs; int B_List0_refs; int B_List1_refs; //图像宽度和高度必须是整MB的 int img_width; //!< image width (must be a multiple of 16 pels) int img_height; //!< image height (must be a multiple of 16 pels) //目前只支持4 : 2 : 0 int yuv_format; //!< GH: YUV format (0=4:0:0, 1=4:2:0, 2=4:2:2, 3=4:4:4,currently only 4:2:0 is supported) //目前只支持8位色深 int color_depth; //!< GH: YUV color depth per component in bit/pel (currently only 8 bit/pel is supported) int intra_upd; /*!< For error robustness. 0: no special action. 1: One GOB/frame is intra coded as regular 'update'. 2: One GOB every 2 frames is intra coded etc. In connection with this intra update, restrictions is put on motion vectors to prevent errors to propagate from the past */ int blc_size[8][2]; //!< array for different block sizes int slice_mode; //!< Indicate what algorithm to use for setting slices int slice_argument; //!< Argument to the specified slice algorithm //帧间宏块是否可用作帧内预测 int UseConstrainedIntraPred; //!< 0: Inter MB pixels are allowed for intra prediction 1: Not allowed int infile_header; //!< If input file has a header set this to the length of the header //输入,输出,重建,跟踪. (4个文件名) char infile[100]; //!< YUV 4:2:0 input format char outfile[100]; //!< H.264 compressed output bitstream char ReconFile[100]; //!< Reconstructed Pictures char TraceFile[100]; //!< Trace Outputs int intra_period; //!< Random Access period though intra // IDR片 int idr_enable;//!< Encode intra slices as IDR //编码帧的开始位置 int start_frame;//!< Encode sequence starting from Frame start_frame // B pictures int successive_Bframe; //!< number of B frames that will be used int qpB; //!< QP of B frames int direct_type; //!< Direct Mode type to be used (0: Temporal, 1: Spatial) int directInferenceFlag; //!< Direct Inference Flag // SP Pictures int sp_periodicity; //!< The periodicity of SP-pictures int qpsp; //!< SP Picture QP for prediction error int qpsp_pred; //!< SP Picture QP for predicted block int WeightedPrediction; //!< Weighted prediciton for P frames (0: not used, 1: explicit) int WeightedBiprediction; //!< Weighted prediciton for B frames (0: not used, 1: explicit, 2: implicit) int StoredBPictures; //!< Stored (Reference) B pictures replace P pictures (0: not used, 1: used) //熵编码方式 int symbol_mode; //!< Specifies the mode the symbols are mapped on bits //输出文件方式(output file mode)即0:Annex B, 1:RTP int of_mode; //!< Specifies the mode of the output file //分割方式 int partition_mode; //!< Specifies the mode of data partitioning //帧间搜索方式 int InterSearch16x16; int InterSearch16x8; int InterSearch8x16; int InterSearch8x8; int InterSearch8x4; int InterSearch4x8; int InterSearch4x4; char PictureTypeSequence[MAXPICTURETYPESEQUENCELEN]; int FrameRate; int chroma_qp_index_offset;#ifdef _FULL_SEARCH_RANGE_ int full_search;#endif#ifdef _ADAPT_LAST_GROUP_ int last_frame;#endif#ifdef _CHANGE_QP_ int qpN2, qpB2, qp2start; int qp02;#endif int rdopt;#ifdef _LEAKYBUCKET_ int NumberLeakyBuckets; char LeakyBucketRateFile[100]; char LeakyBucketParamFile[100];#endif int PicInterlace; //!< picture adaptive frame/field int MbInterlace; //!< macroblock adaptive frame/field int IntraBottom; //!< Force Intra Bottom at GOP periods. int LossRateA; //!< assumed loss probablility of partition A (or full slice), in per cent, used for loss-aware R/D optimization int LossRateB; //!< assumed loss probablility of partition B, in per cent, used for loss-aware R/D int LossRateC; //!< assumed loss probablility of partition C, in per cent, used for loss-aware R/D int NoOfDecoders; int RestrictRef; int NumFramesInELSubSeq; int NumFrameIn2ndIGOP; int RandomIntraMBRefresh; //!< Number of pseudo-random intra-MBs per picture int LFSendParameters; int LFDisableIdc; int LFAlphaC0Offset; int LFBetaOffset; int SparePictureOption; int SPDetectionThreshold; int SPPercentageThreshold; // FMO char SliceGroupConfigFileName[100]; //!< Filename for config info fot type 0, 2, 6 int num_slice_groups_minus1; //!< "FmoNumSliceGroups" in encoder.cfg, same as FmoNumSliceGroups, which should be erased later int slice_group_map_type; int *top_left; //!< top_left and bottom_right store values indicating foregrounds int *bottom_right; int *slice_group_id; //!< slice_group_id is for slice group type being 6 int *run_length_minus1; //!< run_length_minus1 is for slice group type being 0 int slice_group_change_direction_flag; int slice_group_change_rate_minus1; int slice_group_change_cycle; int redundant_slice_flag; //! whether redundant slices exist, JVT-D101 int pic_order_cnt_type; // POC200301 int context_init_method; int model_number; //! Rate Control on JVT standard int RCEnable; int bit_rate; int SeinitialQP; int basicunit; int channel_type; // FastME enable(快速运动估计) int FMEnable;} InputParameters;
可以看出, InputParameters结构体类型实际上就是对各种输入参数的一个打包. 在lencod.c中有下面的全局变量定义:
InputParameters inputs, *input = &inputs;
最终配置文件的信息都会导入到input->...里面,那么究竟怎么导入呢?这就要看Configure函数了,在main中, Configure函数是这样被调用的:
Configure (argc, argv);
在典型的正常配置下(可以在VC6.0中配置), argc = 3, argv[0]指向"...lencod.exe", argv[1]指向"-d", argv[2]指向 "encoder_baseline.cfg", 也就是说,有了argc和argv,就有了配置文件的名字. 下面进入Configure函数看看:(说明,只给出程序正常进入的部分,只为示意)
void Configure(int ac, char *av[]){ char *content, *filename; //configinput 在configfile.h中定义为:InputParameters configinput; //下面语句将configinput中的数据项全部置为0 memset (&configinput, 0, sizeof (InputParameters)); configinput.LevelIDC = LEVEL_IDC; configinput.ProfileIDC = PROFILE_IDC; filename = av[2]; //获得了正确的"encoder_baseline.cfg" //content指向了堆内存,堆内存中的内容串是配置文件的内容串,很长 content = GetConfigFileContent (filename); //下面对content指向的内容串进行分析 //以便让lencod.c中的全局变量input->...从配置文件中获取足够信息 ParseContent (content, strlen(content)); free (content); PatchInp();//对input->...的合法性进行检验}
原来, Configure函数就是专门干这个的.
- JM8.6编码器中的Configure函数究竟做了什么?(编程思想:抽象,间接)
- PeekMessage究竟做了什么?
- OpenGL中glRotatef()函数究竟对矩阵做了什么
- JM8.6编码器主要函数调用关系小结
- OpenSSL中的SSL_connect函数究竟做了哪些事?
- suspend和resume究竟做了什么?
- new/delete究竟做了些什么
- const 它究竟做了什么?
- setContentView() 究竟都做了什么?
- 分析JM8.6中的写码流函数WriteAnnexbNALU
- (转)Fintech路上券商究竟做错了什么?漏做了什么?
- main函数之前究竟发生了什么?
- main函数之前究竟发生了什么?
- 程序员究竟做什么
- C++编译器创建的默认构造究竟做了什么??
- 三极管的基极电流究竟做了什么?
- 【Java笔记】类的构造器究竟做了什么?
- ActivityThread的main方法究竟做了什么?
- 一百、创建 基于页面视图控制器的应用程序
- PHP中的strlen()和mb_strlen
- JQuery 执行效率问题
- 屏蔽掉Ogre1.7版本以后的 LOGO和FPS数据显示
- CORE Computer Science Conference Rankings计算机顶级会议排名
- JM8.6编码器中的Configure函数究竟做了什么?(编程思想:抽象,间接)
- c++内存布局(一)
- QTP中数据库检查点功能的使用
- XYMultipleSeriesRenderer 绘制K线图,点击弹出pop
- 理解内存SRAM、DRAM、SDRAM、DDR3、DDR4
- C++内存布局(二)
- 得到IMSI信息
- ARM交叉编译环境
- oracle 数据连接后显示????