在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 mode
fscanf(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);
}
#endif
if ((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");
}
else
fprintf(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中的内容:
test.264 ........H.264 coded bitstream
test_dec.yuv ........Output file, YUV 4:2:0 format
test_rec.yuv ........Ref sequence (for SNR)
10 ........Decoded Picture Buffer size
0 ........NAL mode (0=Annex B, 1: RTP packets)
0 ........SNR computation offset
1 ........Poc Scale (1 or 2)
500000 ........Rate_Decoder
104000 ........B_decoder
73000 ........F_decoder
leakybucketparam.cfg ........LeakyBucket Params
This is a file containing input parameters to the JVT H.264/AVC decoder.
The text line following each parameter is discarded by the decoder.