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

2024-02-06 16:38

本文主要是介绍JM8.6解码端是如何从配置文件decoder.cfg获取数据的? (init_conf函数),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      在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 fileif((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 formatfscanf(fd,"%*[^\n]");fscanf(fd,"%s",inp->reffile);               // reference filefscanf(fd,"%*[^\n]");// Frame buffer sizefscanf(fd,"%d,",&inp->dpb_size);   // may be overwritten in case of RTP NALfscanf(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 computationfscanf(fd,"%*[^\n]");fscanf(fd,"%d,",&inp->poc_scale);   // offset used for SNR computationfscanf(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 ratefscanf(fd, "%*[^\n]");fscanf(fd,"%ld,",&inp->B_decoder);             // Decoder buffer sizefscanf(fd, "%*[^\n]");fscanf(fd,"%ld,",&inp->F_decoder);             // Decoder initial delayfscanf(fd, "%*[^\n]"); fscanf(fd,"%s",inp->LeakyBucketParamFile);    // file where Leaky Bucket params (computed by encoder) are storedfscanf(fd,"%*[^\n]");
#endiffclose (fd);#if TRACEif ((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 filecalc_buffer(inp);fprintf(stdout,"--------------------------------------------------------------------------\n");
#endiffprintf(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.

 

 

 

这篇关于JM8.6解码端是如何从配置文件decoder.cfg获取数据的? (init_conf函数)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/684916

相关文章

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

Java 中编码与解码的具体实现方法

《Java中编码与解码的具体实现方法》在Java中,字符编码与解码是处理数据的重要组成部分,正确的编码和解码可以确保字符数据在存储、传输、读取时不会出现乱码,本文将详细介绍Java中字符编码与解码的... 目录Java 中编码与解码的实现详解1. 什么是字符编码与解码?1.1 字符编码(Encoding)1

python中update()函数的用法和一些例子

《python中update()函数的用法和一些例子》update()方法是字典对象的方法,用于将一个字典中的键值对更新到另一个字典中,:本文主要介绍python中update()函数的用法和一些... 目录前言用法注意事项示例示例 1: 使用另一个字典来更新示例 2: 使用可迭代对象来更新示例 3: 使用

Spring Boot项目如何使用外部application.yml配置文件启动JAR包

《SpringBoot项目如何使用外部application.yml配置文件启动JAR包》文章介绍了SpringBoot项目通过指定外部application.yml配置文件启动JAR包的方法,包括... 目录Spring Boot项目中使用外部application.yml配置文件启动JAR包一、基本原理

Python lambda函数(匿名函数)、参数类型与递归全解析

《Pythonlambda函数(匿名函数)、参数类型与递归全解析》本文详解Python中lambda匿名函数、灵活参数类型和递归函数三大进阶特性,分别介绍其定义、应用场景及注意事项,助力编写简洁高效... 目录一、lambda 匿名函数:简洁的单行函数1. lambda 的定义与基本用法2. lambda