1.tlv����Դ��
2.使用protobuf实现序列化与反序列化
3.TLV320AIC23çåºç¨
tlv����Դ��
FPGA高端项目:SDI 视频+音频编解码,解解析提供工程源码和技术支持
本文详述了一款使用Xilinx 7系列Kintex7--xc7ktffg-2型号FPGA实现的析源3G-SDI视频+音频编解码方案,涵盖了编码、数据音频解码及视频解码过程,解解析并提供了完整的析源工程源码及技术支持。该设计适用于需要处理SDI视频与音频的数据源码网站收入项目,如医疗、解解析军工领域或图像处理等高速接口相关应用。析源
设计分为三部分:3G-SDI视频编码、数据3G-SDI音频解码和3G-SDI视频解码,解解析整合为一个工程,析源包括视频发送和视频+音频接收功能。数据在视频接收阶段,解解析首先通过GVA芯片进行均衡EQ处理,析源随后使用Xilinx官方GTX原语进行串并转换,数据调用SMPTE SD/HD/3G-SDI IP核实现解码。音频解码则采用UHD-SDI Audio IP核,最后将音频数据转换为i2s格式并输出到扬声器。同花顺源码公式视频发送部分,使用静态彩条作为源数据,通过SMPTE SD/HD/3G-SDI IP核编码,并由GTX进行串化,GV芯片增强驱动,最终通过SDI转HDMI盒子显示。
设计参考了Xilinx官方文档,确保了在不同输入状态下的线速率切换,确保了GTX的稳定运行。IP配置简洁明了,支持SD-SDI、HD-SDI和3G-SDI的编解码。音频解码后输出至i2s模块,再通过TLVAIC芯片播放SDI音频。视频发送通过静态彩条生成,经过编码、串化及驱动增强后,crmphp源码下载通过SDI接口输出至显示器。
该设计在Vivado.2版本下实现,提供了一套完整的工程源码,供用户移植及开发使用。同时,作者还提供了相关的GT高速接口解决方案,包括基于A7系列FPGA的GTP方案、K7或ZYNQ系列FPGA的GTX方案、KU或V7系列FPGA的GTH方案及KU+系列FPGA的GTY方案。
为了帮助用户更好地理解和应用该设计,作者在文章末尾提供了获取完整工程源码及技术支持的方式。请注意,由于代码文件较大,无法通过邮箱发送,而是采用百度网盘链接方式提供下载。请耐心阅读至文章结尾,按照指引获取资源。帧率计算源码
特别提醒:本工程及其源码仅供个人学习和研究使用,禁止用于商业用途。如在使用过程中遇到问题或有任何疑问,请随时联系博主或关注官方渠道,获取技术支持。本设计及源码包含了作者和网络资源的贡献,若有冒犯之处,请私信博主批评指正。
使用protobuf实现序列化与反序列化
protobuf是用来干嘛的?
protobuf是一种用于对结构数据进行序列化的工具,从而实现数据存储和交换。(主要用于网络通信中收发两端进行消息交互。所谓的“结构数据”是指类似于struct结构体的数据,可用于表示一个网络消息。当结构体中存在函数指针类型时,直接对其存储或传输相当于是“浅拷贝”,而对其序列化后则是“深拷贝”。)
序列化:将结构数据或者对象转换成能够用于存储和传输的apk 项目 源码格式。 反序列化:在其他的计算环境中,将序列化后的数据还原为数据结构和对象。
从“序列化”字面上的理解,似乎使用C语言中的struct结构体就可以实现序列化的功能:将结构数据填充到定义好的结构体中的对应字段即可,接收方再对结构体进行解析。
在单机的不同进程间通信时,使用struct结构体这种方法实现“序列化”和“反序列化”的功能问题不大,但是,在网络编程中,即面向网络中不同主机间的通信时,则不能使用struct结构体,原因在于:
(1)跨语言平台,例如发送方是用C语言编写的程序,接收方是用Java语言编写的程序,不同语言的struct结构体定义方式不同,不能直接解析;
(2)struct结构体存在内存对齐和CPU不兼容的问题。
因此,在网络编程中,实现“序列化”和“反序列化”功能需要使用通用的组件,如 Json、XML、protobuf 等。
① 性能高效: 与XML相比,protobuf更小(3 ~ 倍)、更快( ~ 倍)、更为简单。
② 语言无关、平台无关: protobuf支持Java、C++、Python等多种语言,支持多个平台。
③ 扩展性、兼容性强: 只需要使用protobuf对结构数据进行一次描述,即可从各种数据流中读取结构数据,更新数据结构时不会破坏原有的程序。
Protobuf与XML、Json的性能对比:
测试万次序列化:
测试万次反序列化:
protobuf 2 中有三种数据类型限定修饰符:
required表示字段必选,optional表示字段可选,repeated表示一个数组类型。
其中, required 和 optional 已在 proto3 弃用了。
protobuf中常用的数据类型:
下载protobuf压缩包后,解压、配置、编译、安装,即可使用protoc命令查看Linux中是否安装成功:
使用protobuf时,需要先根据应用需求编写 .proto 文件定义消息体格式,例如:
其中,syntax关键字表示使用的protobuf的版本,如不指定则默认使用 "proto2";package关键字表示“包”,生成目标语言文件后对应C++中的namespace命名空间,用于防止不同的消息类型间的命名冲突。
然后使用 protobuf编译器(protoc命令)将编写好的 .proto 文件生成目标语言文件(例如目标语言是C++,则会生成 .cc 和 .h 文件),例如:
其中:
$SRC_DIR表示 .proto文件所在的源目录; $DST_DIR表示生成目标语言代码的目标目录; xxx.proto表示要对哪个.proto文件进行解析; --cpp_out表示生成C++代码。
编译完成后,将会在目标目录中生成xxx.pb.h和xxx.pb.cc文件,将其引入到我们的C++工程中即可实现使用protobuf进行序列化:
在C++源文件中包含xxx.pb.h头文件,在g++编译时链接xxx.pb.cc源文件即可:
在protobuf源码中的/examples 目录下有官方提供的protobuf使用示例:addressbook.proto
参考官方示例实现C++使用protobuf进行序列化和反序列化:
addressbook.proto :生成的addressbook.pb.h 文件内容摘要:add_person.cpp :
输出结果:
三种序列化的方法没有本质上的区别,只是序列化后输出的格式不同,可以供不同的应用场景使用。 序列化的API函数均为const成员函数,因为序列化不会改变类对象的内容,而是将序列化的结果保存到函数入参指定的地址中。
.proto文件中的option选项用于配置protobuf编译后生成目标语言文件中的代码量,可设置为SPEED, CODE_SIZE, LITE_RUNTIME 三种。 默认option选项为 SPEED,常用的选项为 LITE_RUNTIME。
三者的区别在于:
① SPEED(默认值): 表示生成的代码运行效率高,但是由此生成的代码编译后会占用更多的空间。
② CODE_SIZE: 与SPEED恰恰相反,代码运行效率较低,但是由此生成的代码编译后会占用更少的空间,通常用于资源有限的平台,如Mobile。
③ LITE_RUNTIME: 生成的代码执行效率高,同时生成代码编译后的所占用的空间也非常少。 这是以牺牲Protobuf提供的反射功能为代价的。 因此我们在C++中链接Protobuf库时仅需链接libprotobuf-lite,而非protobuf。
SPEED 和 LITE_RUNTIME相比,在于调试级别上,例如 msg.SerializeToString(&str;); 在 SPEED 模式下会利用反射机制打印出详细字段和字段值,但是 LITE_RUNTIME 则仅仅打印字段值组成的字符串。
因此:可以在调试阶段使用 SPEED 模式,而上线以后提升性能使用 LITE_RUNTIME 模式优化。
最直观的区别是使用三种不同的 option 选项时,编译后产生的 .pb.h 中自定义的类所继承的 protobuf类不同:
① protobuf 将消息里的每个字段进行编码后,再利用TLV或者TV的方式进行数据存储; ② protobuf 对于不同类型的数据会使用不同的编码和存储方式; ③ protobuf 的编码和存储方式是其性能优越、数据体积小的原因。
TLVAICçåºç¨
TLVAICçåºç¨:åºäºDDKçTLVAICåç¼è§£ç å¨ç驱å¨è®¾è®¡
DSP/BIOS Driver Developerâs Kit(DDK)æ¯TI为ç®å驱å¨ç¨åºå¼å为TMSç³»åDSPåå ¶EVMæ¿çæä¾ç驱å¨ç¨åºå¼åå¥ä»¶ã该å¥ä»¶ä¸ºTMSç³»ååç§å¤å´å¨ä»¶æä¾å®æ´çæ åå驱å¨ç¨åºæ¨¡åï¼ä½¿å¾é©±å¨ç¨åºå¯ä»¥å¾æ¹ä¾¿å°ç§»æ¤å°å ¶ä»åºç¨ä¸ï¼å¤§å¤§æé«é©±å¨ç¨åºå¼åçæçãDDKæ¯å¯¹æ¯ç§TMSç³»åDSPé½æä¾çè¯çæ¯æåº(Chip Support LibraryâCSL)çè¡¥å ï¼CSLæä¾å¯¹å¤å´å¨ä»¶å¯åå¨é ç½®ååå§åççä½çº§æ§å¶ï¼DDKå®å ¨éè¿CSLæ¥å¯¹å¤å´å¨ä»¶è¿è¡æ§å¶ãç®åå°è¯´ãDDK建ç«å¨CSLä¸å±ï¼æ以ç¨DDKæ¥å¼å驱å¨ç¨åºå°æ´ä¸ºå¿«æ·ä¸å¯ç§»æ¤æ§æ´å¥½ã
DDK为å¼å驱å¨ç¨åºå®ä¹äºæ å模ååä¸ç³»åçAPIã为ç®åç¨åºè®¾è®¡ãæ å模åå被å为äºä¸ªå±æ¬¡ï¼å ¶ä¸é«å±ç§°ä¸ºClass driverï¼ä½å±ç§°ä¸ºMiniâdriverãClass driveiä¸å¨ä»¶ç¸å¯¹ç¬ç«ï¼å®æ诸å¦ç¼å²åºç®¡çå请æ±åæ¥çåè½ï¼åæ¶æ®æ¼çä¸APIåMiniâdriveräºè æ¥å£çè§è²ãMiniâdriverå®æç¹å®çå¨ä»¶åå§ååæ§å¶åè½ï¼å®ç¬¦åIOM(I/O Miniâdriver)çæ¥å£æ åãDDKçè¿ç§åå±ç»æ使å¾é©±å¨å¼å人åä» éäºè§£åä¸çMiniâdriver APIå°±å¯ä»¥å®ææ´ä½å¤å´å¨ä»¶ç驱å¨è®¾è®¡ï¼èä¸è¿ä¸è¿ç¨æ¯è®¾è®¡æ´ä¸ªé©±å¨ç¨åºè¦ç®åå¾å¤ï¼å 为Class driveræ§å¶äºç¼å²åºç®¡çååæ¥çãDDKæä¾3ç§Class driverï¼åå«ä¸ºSIO/DIOãPIP/PIOåGIOï¼å®ä»¬é½å¯ä»¥åä»»ä½Miniâdriverç»å使ç¨ã
2 TLVAICç驱å¨è®¾è®¡åºç¡
DDKçæ å模åç»æå¦å¾1æ示ãé«å±çåºç¨ååºå±é©±å¨ç¸äºæ²¡æç´æ¥çå ³èï¼å¼åä¸åªééè¿Class driveræ§å¶Miniâdriverã
ä¸é¢ä»¥DM EVMæ¿ä¸ºä¾ï¼è¯´æåºäºDDKçTLVAICç驱å¨ç¨åºè®¾è®¡æ¹æ³ã
é¦å ï¼éè¦ä½¿ç¨é ç½®å·¥å ·å»ºç«é©±å¨ç¨åºçå ¥å£ãå¨DSP/BIOS con_figä¸çcdbæ件ä¸ï¼ä¾æ¬¡éæ©In-puffOutplut---Deviee DriversâUserâdefined Driversï¼å¨è¿äºä¾ç¨ä¸ä¸è¬å·²ç»æ·»å äºudevCodecï¼å¦æéè¦çè¯ï¼ç¨æ·å¯ä»¥èªè¡æ·»å æç¼è¾ãå³é®åå»éæ©Propertiesé项æ¥ç¼è¾å ¶å±æ§ï¼å ¶å±æ§åºè®¾ç½®å¦ä¸ï¼
Commentï¼å¯ä»¥å å ¥èªå·±ç注é
lnit functionï¼é®å ¥EVMDM_EDMA_AICä¸init
Function table ptrï¼é®å ¥ EVMDM_EDMA_A-ICä¸Fxn8
Function table typeï¼éæ©IOM_Fxns
Deviceidï¼è¯¥é¡¹ä¼è¢«èªå¨å¿½ç¥ï¼å 为DM EVMæ¿ä¸åªæä¸åTLVAIC
Device params ptrï¼TLVAICåæ°ç»æçå ¥å£æéï¼ä½¿ç¨ç¼ºçåæ°æ¶è®¾ä¸º0x0
Device global data ptrï¼å¿ 须设置为OxO
æ£ç¡®é 置驱å¨ç¨åºå ¥å£åï¼å°±è¦æç §éè¦è®¾ç½®ç¸å ³çåæ°ãä¸é¢å ·ä½è®¨è®ºTLVAICåæ°ç设置ã
TLVAICçåæ°ç»æä½ååå¦ä¸ï¼
typedef struct
å¨ä¸è¬åºç¨ä¸ãä¸è¿°ç»æä½ç大å¤æ°åæ°æ éæ´æ¹ï¼éè¦ä¿®æ¹ç主è¦æ¯aieConfigï¼å®æ¯TLVAICæ§å¶å¯åå¨å¼ï¼éè¦éè¿å®æ¥æ§å¶TLVAICçå·¥ä½æ¨¡å¼ãè¾å ¥/è¾åºéæ©ãéæ ·ççéè¦åæ°ã
é¤äºå¤ä½å¯åå¨å¤ï¼TLVAICå ±æ9个æ§å¶å¯åå¨ï¼æ¯ä¸ªå¯åå¨æ§å¶åé¿ä¸º9bitï¼å°åä½ä¸º7bitï¼å ±æbitãå°åä½ä¸ºé«7ä½èæ§å¶åå¨ä½9ä½ãå ·ä½å¦ä¸ï¼
Register0:左声éè¾å ¥é³éæ§å¶ï¼ç¼ºçå¼ä¸º 0x
Register1:å³å£°éè¾å ¥é³éæ§å¶ï¼ç¼ºçå¼ä¸º 0x
Register 2ï¼å·¦å£°éè¾åºé³éæ§å¶ã缺çå¼ä¸ºOxF9
Register 3ï¼å³å£°éè¾åºé³éæ§å¶ï¼ç¼ºçå¼ä¸ºOxF9
Register 4ï¼æ¨¡æé³é¢éé设置ï¼ç¼ºçå¼ä¸ºOx
Register 5ï¼æ°åé³é¢éé设置ã缺çå¼ä¸º0x
Register 6ï¼èçµæ¨¡å¼æ§å¶ï¼ç¼ºçå¼ä¸º0x
Register 7ï¼æ°åé³é¢æ¥å£æ ¼å¼æ§å¶ï¼ç¼ºçå¼ä¸º0x
Register 8ï¼éæ ·çæ§å¶ï¼ç¼ºç为kHzï¼å¯¹DMEVMæ¿ï¼ç¼ºçå¼ä¸ºOx
Register 9ï¼æ°åé³é¢æ¥å£æ¿æ´»å¼å ³ï¼ç¼ºçå¼ä¸º0x
é常æ åµä¸éè¦ä¿®æ¹çå¯åå¨å æ¬4å·å8å·å¯åå¨ï¼å³éæ©æ¯ç±micè¾å ¥è¿æ¯ç±line inè¾å ¥åæ ¹æ®éè¦éæ©éæ ·çãè¿2个å¯åå¨ç详ç»é ç½®å¦ä¸ï¼
4å·å¯åå¨é ç½®è§è¡¨1ï¼å ¶ä¸ï¼D2ä½ãINSEL(In-put select for ADC)æ¯è¾å ¥éæ©ï¼âOâ为line inï¼âlâ为mic.D1ä½MICM(Microphone mute)æ¯micéé³å¼å ³ï¼ä¸ºâlâ表示éé³ãDOä½MICB(Microphone boost)å¦è®¾ç½®ä¸ºâ1âå°ä¸ºmicè¾å ¥æä¾dBçå¢çã8å·å¯åå¨é ç½®è§è¡¨2ï¼å ¶ä¸ï¼éæ ·çæ§å¶ä½ä¸ºD5~D2çSR[3ï¼O]ã对äºDM EVMæ¿ï¼è®¾ç½®æ¹å¼è§è¡¨3ã
å¯è§ï¼éè¦éè¿4å·å¯åå¨çD2æ¥éæ©è¾å ¥ï¼åæ¶èèDlåDO对micçæ§å¶ï¼éæ ·ççæ§å¶éè¿è®¾ç½®8å·å¯åå¨çSR[3ï¼0]æ¥å®ç°ã
3 TLVAICç驱å¨é ç½®æ¹æ³
å¾å¤åå¦è å¨è¿è¡DM EVMçechoæå ¶ä»é³é¢ä¾ç¨æ¶ï¼æ容æ碰å°çé®é¢æ¯éè¿line inè¾å ¥æ¶æè¾åºï¼èéè¿micè¾å ¥æ¶æ²¡æè¾åºï¼æ´ä¸è¦è¯´æ¹åéæ ·çäºãå³ä½¿åèèµæç¼è¾aic-håemvdm_edma_aicï¼hä¿®æ¹Dcfauhåæ°ä»ç¶æ æ³è§£å³ã
åºç°è¿æ ·çé®é¢æ¶ãé¦å è¦äºè§£TLVAICç模æé³é¢è¾å ¥ä¸ºmicåline inäºéä¸çï¼å ¶æ¬¡è¦ç¥éå¦ä½è½å¤æ£ç¡®é ç½®TLVAICçåæ°ä½¿ä¹æ»¡è¶³ç¹å®åºç¨çéè¦ãå¦æä»ç»åæechoä¾ç¨åå ¶ä»é³é¢ä¾ç¨çè¯ï¼å¯ä»¥åç°åªæå¨echoä¾ç¨ä¸å å«äºaie.håemvdm_edma_aieï¼h 2个头æ件ãå ¶å®å¨echoä¾ç¨ä¸ï¼æå å«çè¿2个头æ件åTLVAICçåå§åè¯å¥å®é 并æªä½¿ç¨ãå¦æå±è½æ对è¿2个头æ件çå å«ä»¥åTLVAICçåå§åè¯å¥ï¼ä¼åç°ç¼è¯åä»ç¶è½å¤æ£å¸¸è¿è¡ãå®é ä¸echoä¾ç¨ä¸çTLVAICåå§åè¯å¥åªæ¯æä¾äºå¯¹â ¡,VAICè¿è¡é ç½®çä¸ç§æ¹æ³è并æªç´æ¥ä½¿ç¨ã该æ¹æ³å¨DDKå çemvdmé¨å说ææ件ä¸ä¹å·²æåã
ç±äºå¨echoä¾ç¨ä¸åå§å驱å¨ç¨åºäººå£åå ¶ä»çé³é¢ä¾ç¨ä¸æ ·ä½¿ç¨äºé»è®¤åæ°ï¼èé»è®¤åæ°æ¯éè¿è°ç¨DDKå ä¸çevmdm_edma_aicï¼åºè·å¾çï¼è¯¥åºä¸ååé ç½®ä¹ä¸åï¼äºæ¯å°±ä¼åºç°ä¸è¿°é®é¢ã
å¨æç¡®äºä»¥ä¸åçåï¼éè¿å®è·µè¯æï¼æ¬ææä¾ç以ä¸ä¸ç§é ç½®æ¹æ³å¯ä»¥éåºåç§åºç¨ã
æ¹æ³ä¸
æ¢ç¶é»è®¤åæ°æ¯éè¿è°ç¨evmdm_edlna_a-icï¼åºè·å¾çï¼é£ä¹èªç¶å¯ä»¥éè¿ä¿®æ¹è¯¥åºæ¥è¾¾å°ä¿®æ¹åæ°çç®çãTIæä¾çDDKå ä¸å å«äºåç§åºçæºä»£ç ï¼è¿ä½¿å¾ä¿®æ¹åºæ件æ为å¯è½ãæ¬æç¨å°çåºçæå·¥ç¨æ¯tiddksrc\audio\evmdmç®å½ä¸çevmdm_edma_mc_ï¼pjtï¼åªéè¦æå¼è¯¥å·¥ç¨ï¼ä¿®æ¹å ¶ä¸aicï¼hä¸çé»è®¤åæ°ï¼éæ°ç¼è¯å°±è½çææ°çåºæ件ãè¿æ ·ï¼ææçé³é¢ä¾ç¨é½ä¼é»è®¤æä¿®æ¹è¿çåæ°è¿è¡ã
è¿ç§æ¹æ³éåTLVAICåæ°é ç½®ç¸å¯¹åºå®çåºç¨åºåãé ç½®å®å ¨éè¿è°ç¨evmdm_ed_ma_aicï¼åºåå§åæ¶è¿è¡ï¼ä¸ç¨å¨åºç¨å·¥ç¨æ件ä¸æ·»å ä»»ä½éå 代ç ï¼ä½¿å¾å·¥ç¨æ件æ´ç®æ´ï¼å¯ç§»æ¤æ§æ´é«ã
æ¹æ³äº
èªå®ä¹ç¬¦åæ åç»æEVMDM_EDMA_Aï¼ICä¸DevParamsçç»æä½ï¼ä¾å¦ï¼
ç¶åå°â_myParmsâä½ä¸ºDevice params ptrå¨æå®äººå£æéæ¶æ¿ä»£é»è®¤ç0x0ãè¿å°±ç¬¦åTIæ¨èçæ¹æ³ï¼å¨echoä¾ç¨ä¸çç¸å ³ä»£ç ä¹è¯´æäºè¿ç§æ¹æ³ã
è¿ç§æ¹æ³è½å¤éåºå ä¹ä»»ä½ä½¿ç¨æ åµï¼åå§ååæ°èªå®ä¹é常æç¡®ï¼ä»£ç æ读æ§è¾é«ãä½æ¯ä¸å»ºè®®åechoä¾ç¨ä¸é£æ ·ç´æ¥å å«é»è®¤åæ°ç头æ件ï¼æ好åç §è¯¥å¤´æ件å®ä¹èªå·±çç»æä½ã
æ¹æ³ä¸
éè¿ä»ç»åæçæevmdm_edma_aicï¼åºçæºä»£ç ï¼å¯ä»¥åç°å¯¹TLVAICå¯åå¨ç设置æ¯éè¿AIC_setParams()å½æ°æ¥å®æçãå¨å¤§å¤æ°æ åµä¸ï¼åªè¦ä¿®æ¹å¯åå¨å¼èä¸å¿ ä¿®æ¹æ åç»æEVMDM_EDMA_AIC_DevParamsç»æä½ä¸çå ¶ä»åéãæ以å¯ä»¥è°ç¨AIC_setParams()å½æ°æ¥å®æ对TLVAICåæ°çé ç½®ãè¿æ ·å°±åªéè¦å®ä¹1个符åæ åçå¯åå¨æ°ç»ï¼å°æ°ç»åä½ä¸ºåæ°æ¥è°ç¨AIC_setParamsf()å½æ°å°±å¯ä»¥è¾¾å°ç®çã
è¿ç§æ¹æ³ä½¿ç¨çµæ´»ï¼ä»£ç é¿åº¦å¾çï¼å«ä¹é常æç¡®ï¼å¯ä»¥ç¨ä¸ååæ°å¤æ¬¡è°ç¨ï¼å°¤å ¶éç¨äºTLVAICåæ°å¯åçç¹æ®åºåã
å¨å®é å·¥ä½åºç¡ä¸å¯¹TLVAICåæ°é ç½®æåºäº3ç§æ¹æ³ï¼åæç¹ç¹ä¸é½ååå®ç¨ãå¨è¿è¡åºäºDDKçTLVAIC驱å¨ç¨åºè®¾è®¡æ¶ï¼å¯ä»¥æ ¹æ®éè¦æ¹ä¾¿å°éç¨ã