JM8.6编码器中的Configure函数究竟做了什么?(编程思想:抽象,间接)

        从字面意思来看,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函数就是专门干这个的.

 

 

     

 

    

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值