JM8.6解码端是如何从配置文件decoder.cfg获取数据的? (init

在ldecod.c文件的main中调用了init_conf函数,这个函数实际上就实现了程序从配置文件读数据的过程. 之前说过,在JM8.6编码端,Configure函数起着做配置文件encoder_baseline.cfg数据的作用,现在来看看解码端的init_conf函数.

main中是这样调用的:

init_conf(input, argv[1]);

其中input是一个结构体指针,字符串指针argv[1]实际上就指向了字符串"decoder.cfg", 进入init_conf函数看看:

void init_conf(struct inp_par *inp,char *config_filename){ FILE *fd; int NAL_mode; // read the decoder configuration file if((fd=fopen(config_filename,"r")) == NULL) {snprintf(errortext, ET_SIZE, "Error: Control file %s not found\n",config_filename);error(errortext, 300); } fscanf(fd,"%s",inp->infile);// H.264 compressed input bitsream// 过滤配置文件中的“注释” fscanf(fd,"%*[^\n]"); fscanf(fd,"%s",inp->outfile);// YUV 4:2:2 input format fscanf(fd,"%*[^\n]"); fscanf(fd,"%s",inp->reffile);// reference file fscanf(fd,"%*[^\n]");// Frame buffer size fscanf(fd,"%d,",&inp->dpb_size); // may be overwritten in case of RTP NAL fscanf(fd,"%*[^\n]"); if (inp->dpb_size < 1) {snprintf(errortext, ET_SIZE, "Decoded Picture Buffer Size is %d. It has to be at least 1",inp->dpb_size);error(errortext,1); } fscanf(fd,"%d",&(NAL_mode));// NAL modefscanf(fd,"%*[^\n]"); switch(NAL_mode) { case 0:inp->FileFormat = PAR_OF_ANNEXB;break; case 1:inp->FileFormat = PAR_OF_RTP;break; default:snprintf(errortext, ET_SIZE, "NAL mode %i is not supported", NAL_mode);error(errortext,400); } fscanf(fd,"%d,",&inp->ref_offset); // offset used for SNR computation fscanf(fd,"%*[^\n]"); fscanf(fd,"%d,",&inp->poc_scale); // offset used for SNR computation fscanf(fd,"%*[^\n]");if (inp->poc_scale < 1 || inp->poc_scale > 2) {snprintf(errortext, ET_SIZE, "Poc Scale is %d. It has to be 1 or 2",inp->poc_scale);error(errortext,1); }#ifdef _LEAKYBUCKET_ fscanf(fd,"%ld,",&inp->R_decoder);// Decoder rate fscanf(fd, "%*[^\n]"); fscanf(fd,"%ld,",&inp->B_decoder);// Decoder buffer size fscanf(fd, "%*[^\n]"); fscanf(fd,"%ld,",&inp->F_decoder);// Decoder initial delay fscanf(fd, "%*[^\n]"); fscanf(fd,"%s",inp->LeakyBucketParamFile); // file where Leaky Bucket params (computed by encoder) are stored fscanf(fd,"%*[^\n]");#endif fclose (fd);#if TRACE if ((p_trace=fopen(TRACEFILE,"w"))==0)// append new statistic at the end {snprintf(errortext, ET_SIZE, "Error open file %s!",TRACEFILE);error(errortext,500); }#endifif ((p_out=fopen(inp->outfile,"wb"))==0) {snprintf(errortext, ET_SIZE, "Error open file %s ",inp->outfile);error(errortext,500); }/* if ((p_out2=fopen("out.yuv","wb"))==0) {snprintf(errortext, ET_SIZE, "Error open file %s ",inp->outfile);error(errortext,500); }*/ fprintf(stdout,"————————————————————————–\n"); fprintf(stdout," Decoder config file: %s \n",config_filename); fprintf(stdout,"————————————————————————–\n"); fprintf(stdout," Input H.264 bitstream: %s \n",inp->infile); fprintf(stdout," Output decoded YUV 4:2:0: %s \n",inp->outfile); fprintf(stdout," Output status file: %s \n",LOGFILE); if ((p_ref=fopen(inp->reffile,"rb"))==0) {fprintf(stdout," Input reference file: %s does not exist \n",inp->reffile);fprintf(stdout,"SNR values are not available\n"); } elsefprintf(stdout," Input reference file: %s \n",inp->reffile); fprintf(stdout,"————————————————————————–\n");#ifdef _LEAKYBUCKET_ fprintf(stdout," Rate_decoder: %8ld \n",inp->R_decoder); fprintf(stdout," B_decoder: %8ld \n",inp->B_decoder); fprintf(stdout," F_decoder: %8ld \n",inp->F_decoder); fprintf(stdout," LeakyBucketParamFile: %s \n",inp->LeakyBucketParamFile); // Leaky Bucket Param file calc_buffer(inp); fprintf(stdout,"————————————————————————–\n");#endif fprintf(stdout,"POC must = frame# or field# for SNRs to be correct\n"); fprintf(stdout,"Frame POC QP SnrY SnrU SnrV Time(ms)\n");}

可见,通过调用init_conf函数,实际上就是把argv[1]对应的配置文件的数据往input对应的结构体中倾倒,像倒茶一般, 这样,程序中的全局的指针变量对应的结构体就获得了配置文件encoder.cfg中的数据.

最后,,附带给出配置文件decoder.cfg中的内容:

只有流过血的手指才能弹出世间的绝唱。

JM8.6解码端是如何从配置文件decoder.cfg获取数据的? (init

相关文章:

你感兴趣的文章:

标签云: