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音频。视频发送通过静态彩条生成,经过编码、串化及驱动增强后,vscode查询源码插件通过SDI接口输出至显示器。
该设计在Vivado.2版本下实现,提供了一套完整的工程源码,供用户移植及开发使用。同时,作者还提供了相关的GT高速接口解决方案,包括基于A7系列FPGA的GTP方案、K7或ZYNQ系列FPGA的GTX方案、KU或V7系列FPGA的GTH方案及KU+系列FPGA的GTY方案。
为了帮助用户更好地理解和应用该设计,作者在文章末尾提供了获取完整工程源码及技术支持的方式。请注意,由于代码文件较大,无法通过邮箱发送,而是采用百度网盘链接方式提供下载。请耐心阅读至文章结尾,按照指引获取资源。店家网支付源码
特别提醒:本工程及其源码仅供个人学习和研究使用,禁止用于商业用途。如在使用过程中遇到问题或有任何疑问,请随时联系博主或关注官方渠道,获取技术支持。本设计及源码包含了作者和网络资源的贡献,若有冒犯之处,请私信博主批评指正。
使用protobuf实现序列化与反序列化
protobuf是用来干嘛的?
protobuf是一种用于对结构数据进行序列化的工具,从而实现数据存储和交换。(主要用于网络通信中收发两端进行消息交互。所谓的“结构数据”是指类似于struct结构体的数据,可用于表示一个网络消息。当结构体中存在函数指针类型时,直接对其存储或传输相当于是“浅拷贝”,而对其序列化后则是“深拷贝”。)
序列化:将结构数据或者对象转换成能够用于存储和传输的代码在线校对源码格式。 反序列化:在其他的计算环境中,将序列化后的数据还原为数据结构和对象。
从“序列化”字面上的理解,似乎使用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驱å¨ç¨åºè®¾è®¡æ¶ï¼å¯ä»¥æ ¹æ®éè¦æ¹ä¾¿å°éç¨ã