一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种高效可转码的视频解码方法与流程

2021-11-30 21:59:00 来源:中国专利 TAG:


1.本发明属于linux系统下视频解码技术,特别是一种高效可转码的视频解码方法。


背景技术:

2.hi3559av100是专业的8k ultra hd mobile camera soc,它提供了8k30/4k120广播级图像质量的数字视频录制,支持多路sensor输入,支持h.265编码输出或影视级的raw数据输出,并集成高性能isp处理,同时采用先进低功耗工艺和低功耗架构设计,为用户提供了卓越的图像处理能力。
3.hi3559av100支持业界领先的多路4k sensor输入,多路isp图像处理,支持hdr10高动态范围技术标准,并支持多路全景硬件拼接。在支持8k30/4k120视频录制下,hi3559av100提供硬化的6

dof数字防抖,减少了对机械云台的依赖。
4.pci

express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准,它原来的名称为"3gio",是由英特尔在2001年提出的,旨在替代旧的pci,pci

x和agp总线标准。pcie属于高速串行点对点双通道高带宽传输,所连接的设备分配独享通道带宽,不共享总线带宽,主要支持主动电源管理,错误报告,端对端的可靠性传输,热插拔以及服务质量(qos)等功能。pcie交由pci

sig(pci特殊兴趣组织)认证发布后才改名为"pci

express",简称"pci

e"。它的主要优势就是数据传输速率高,而且还有相当大的发展潜力。
5.但是hi3559av100属于硬解码范畴,在协议帧不完全符合解码协议,或者错误帧比较多的情况下,解码效率比较低下或者不能解码,并且对于带有参数帧的图像信息,硬解码模块无法提取参数信息。另外,在图像数据量比较大的情况下,网络传输占比时间长,严重影响了解码时间。解码后的图像格式在不符合应用层软件需求时,还需要对解码图像进行格式转化。


技术实现要素:

6.本发明解决的技术问题是:克服现有技术的不足,本发明的目的是在linux平台下,针对海思hi3559av100芯片特点,并结合pcie设备属性,设计实现了一种linux系统下一种高效可转码的视频解码方法。利用pcie通道进行数据传输,使用ffmpeg软解码库获取完整帧信息,有效得获取压缩帧参数信息。同时针对协议类型,建立过滤机制筛选错误帧,传送可解码的数据包给海思hi3559av100芯片硬解码模块,从而完成解码和转码过程。
7.本发明的技术解决方案是:
8.一种高效可转码的视频解码方法,包括如下步骤:
9.1)配置ffmpeg的编译属性和参数,将ffmpeg动态库移植到海思平台;
10.2)配置pcie设备,启动pcie通道,制定主设备和从设备传输规则;
11.3)根据通道数为每个通道创建pcie读数据线程,启动pcie读任务获取主机传输的原始图像数据;
12.4)创建ffmpeg获取数据包线程,使用ffmpeg动态库获取含参数帧的完整压缩图像数据包;
13.5)对完整数据包进行过滤,将可解码的数据包发送到硬解码模块;
14.6)获取硬解码模块内的图像;
15.7)将解码后的图像转化为目标格式图像;
16.8)将转码后的图像通过pcie通道发送给主机。
17.可选地,步骤7)所述将解码后的图像转化为目标格式图像,具体为:
18.71)判断历史记录的图像像素宽width和高height以及图像格式format是否与当前图像的宽和高、格式一致,如果一致就说明不需要进行转化,直接进入步骤8),否则进行下一步;
19.72)判断当前通道的转化上下文对象指针img_convert_ctx是否为空,如果不为空,则需要调用sws_freecontext库函数释放该对象指针,清空对该通道转化功能的配置参数;
20.73)将当前图像像素的宽、高和图像格式保存在历史记录标志width、height、format中,作为下次判断是否进行转化操作的参考值;
21.74)使用avpicture_get_size库函数,以一个最大图像像素max_width*max_height为函数参数,获取目标格式图像的字节数numbytes;
22.75)使用av_malloc库函数,以numbytes*sizeof(uint8_t)为参数,申请一个当前通道的存放图像rgb数据数组rgb;
23.76)以当前图像的rgb数据数组rgb、像素宽、高、目标格式为参数,调用avpicture_fill获取填充后的图像帧数组framergb;
24.77)使用当前图像帧的像素宽、高、当前帧格式、填充图像帧数组framergb、目标格式、转化方式为参数,调用sws_getcontex库函数获取当前通道的转化上下文的对象img_convert_ctx;
25.78)使用sws_scale库函数将当前图像格式的图像转化为目标格式的图像,并进行相应的大小缩放,如果转化成功则将转化完的图像保存在framergb数组,如果转化不成功则报错提示并等待下一次图像传输。
26.可选地,步骤1)所述将ffmpeg动态库移植到海思平台,具体为:
27.11)首先,配置ffmpeg编译属性,根据平台类型、cpu类型、编码解码器属性、格式转换属性、交叉编译属性配置参数;
28.12)修改acodec.h文件,增加变量:参数帧长度sei_len和数组sei_buf,根据应用层需求确定其参数帧大小sei_buf_size;
29.13)在hevc_sei.c文件中的decode_nal_sei_prefix函数中添加获取参数帧功能;
30.14)然后,执行configure命令,在配置文件夹的子文件夹lib下将生成的解码库libavcodec、libavformat、libavutil、libswscale;
31.15)最后,将动态库拷贝到解码板卡的/usr/lib路径下。
32.可选地,步骤2)所述主设备和从设备传输规则,具体为:
33.主设备上电后写入握手的规定内容,从设备在上电后检测到相应内容并握手成功;
34.主设备和从设备为每个通道分配读写的pcie地址,并防止读写地址冲突;
35.主设备握手成功后在规定的pcie地址段写入每个通道接收数据的地址内容;
36.主设备通过查询固定地址段的内容长度是否大于0作为判断是否有数据的标准,并在读走数据后将长度清零;
37.从设备在传输数据之前先判断主设备是否已读走上次数据,如果是则写入解码后的图像数据并将长度写入,如果不是则放弃本次写数据任务,等待下一次解码后的数据再传输。
38.可选地,步骤3)所述根据通道数为每个通道创建pcie读数据线程,具体为:
39.31)申请pcie通道的读写互斥锁,对每个通道的读写操作进行保护,不允许同时有多个通道进行读写操作;
40.32)查看主设备是否有新的图像数据可供读取,即在固定地址内的读数据长度是否不为零,同时主机的读地址也不为零;
41.33)根据协议规则再在指定的读地址段读取数据,设置pcie读任务的目的地址为从设备的pcie读地址;设置源地址为主设备的pcie写地址;
42.34)然后,通过ioctl函数对从设备发送读数据任务命令;判断返回值是否成功,如成功则读长度清零,以供主设备进行下次传输数据;
43.35)解锁pcie通道的读写互斥锁,释放资源。
44.可选地,步骤4)所述创建ffmpeg获取数据包线程,具体为:
45.421)获取从pcie通道读取的图像数据数组首地址指针bufptr和长度buflen;
46.422)判断当前的数据长度buflen是否大于0,如果是则继续下一步,如果不是,则退出本次数据的解码过程,等待下次pcie通道传送的图像数据;
47.423)传送数据数组首地址指针bufptr和长度buflen给软解码模块,使用库函数av_parser_parse2对数据按帧进行分割,如果从数组能成功获得一个完整的图像帧数据包则记录继续下一步,如果不是则退出本次解码过程;等待pcie通道传送的图像数据;
48.424)保存本次数据数组中图像帧分割的数据包长度ret,从数据数组总长度buflen剔除本次分割的图像帧数据包长度ret,并向前移动首地址指针bufptr,移动次数为ret;
49.425)将本次分割的图像完整数据包放到待解码队列中。
50.可选地,步骤5)所述对完整数据包进行过滤,具体为:
51.51)判断图像类型,分析不同类型需要的slice个数图像数据包中含p帧的个数,并记录在该通道的数据结构变量pslicenumber;
52.52)判断当前数据包大小是否大于协议帧规定的最大数,如果大于则返回退出本次数据包的过滤过程,待接收到新的图像数据包后返回步骤51),否则进行下一步;
53.53)循环遍历本次数据包内的数据,依次判断当前帧是否符合h265协议帧头,如果符合则进行下一步,如果不符合则跳转到步骤59);
54.54)判断当前帧是否为p帧或者i帧,如果是,则需要增加本通道本次传输的数据包内sllice个数temp_pslicenumber,进入下一步;如果不是则跳转到步骤56);
55.55)如果当前数据包的temp_pslicenumber等于2,则再次判断p_slice是否为0,如果是,则设置p_size为i,并更新记录slice标志p_slice为1;
56.56)判断当前帧类型是否为sps,是sps则置标志top为1并进入步骤57);反之,则直接进入58);
57.57)继续判断当前帧是否为参数帧,如果是则将当前数据包数组ptr内的i位置拷贝到数据结构idr_buf,保存sei帧之前的帧头信息,记录当前保存帧头的数据大小idr_size为i,将首次出现sps标识entryflag为1,并清零top为0;完成后进入步骤58);
58.58)判断当前通道的图像数据是否需要插入i帧,并且entryflag为1,如果上述两个条件成立则判断当前帧类型是否为p帧,如果是p帧则将数据包的帧类型字节内容由0x02改成0x26,即改p帧为i帧;反之则直接进入步骤49);
59.59)继续查看数据包内ptr是否还有其他数据需要遍历查询,如果有就回到步骤53),如果没有就继续下一步;
60.510)判断当前通道的insertidr标志和entryflag是否都为1,如果是则继续下一步,如果不是则进行步骤513);
61.511)判断当前temp_pslicenumber是否等于本通道图像类型应该具备的pslicenumber,如果是则下一步,如果不是则丢弃该数据包,退出该数据包的解码过程;待接收到新的图像数据包后返回步骤51);
62.512)将当前数据包内完整图像帧大小为size的数据,拷贝到idr_buf中,拷贝的位置从idr_buf的idr_size开始,将size的大小增大idr_size,再次将idr_buf的数据拷贝到ptr中,拷贝的数据大小为size;
63.513)判断当前temp_pslicenumber是否等于本通道图像类型应该具备的pslicenumber,如果是则进行下一步,如果不是则进行步骤515);
64.514)判断p_slice是否为1,如果是则将p_size赋值给size,清零p_slice;反之,则直接进入步骤515);
65.515)将当前通道的图像参数帧大小记录在seisize中,同时拷贝当前图像的参数帧到当前通道的待解码图像数据结构体decodearray中,将参数个数seicount作为待解码图像的时间戳u64pts;
66.516)查询当前通道的解码状态,并把状态结构体中的已解码图像帧数保存到u32decodestreamframes;
67.517)获取当前通道待解码图像数据的首地址ptr和数据长度size,时间戳u64pts,并以流形式发送到解码模块;
68.518)循环查询解码器的工作状态,直至获得新的解码图像;
69.519)调用海思库函数查询解码器通道状态;
70.520)判断通道内剩余需解码的字节数是否为0,如果是则进去下一步,如果不是则延时1ms跳转到步骤519);
71.521)解码器通道已经解码后的图像帧数是否与之前保存的u32decodestreamframes不相等,或者该通道的insertidr标识为1,如果是进入下一步,如果不是则到步骤523);
72.522)将insrtidr标识清零,增加参数帧的个数,判断如果seicount大于协议指定大的最大值sei_num,则将参数帧的个数标志seicount清零,进入步骤526);反之,则直接进入下一步;
73.523)复位解码器,进入步骤524);
74.524)判断解码器复位标志resetflag是否为0,如果是则进入下一步,如果不是则继续等待1ms,跳转到步骤523);
75.525)将复位状态resetstate置1,调用库函数停止解码通道的视频流接收任务,销毁解码通道,重启解码通道,将插入i帧的标志insertidr置1,复位状态resetstate置0,进入下一步;
76.526)结束本次过滤过程。
77.可选地,步骤8)所述将转码后的图像通过pcie通道发送给主机,具体为:
78.81)获取pcie通道的读写互斥锁;
79.82)拷贝解码后的图像参数数据到dma虚拟地址空间;
80.83)判断海思平台芯片内的写长度是否被主机清零,如果为0则报错退出,终止图像发送任务,待接收到新的解码后的图像参数数据后返回步骤81);反之则进入步骤84);
81.84)获取给主设备发送数据的目的物理地址,如果为零则报错退出,终止图像发送任务,待接收到新的解码后的图像参数数据后返回步骤81);反之则进入步骤85);
82.85)获取dma传输的物理首地址和协议规定的偏移地址,将两者的和作为dma传输任务的源地址,将主机pcie的物理地址vxworks_phy_addr作为任务的目的地址;
83.86)设置本次任务的传输长度为参数帧数据的长度sei_len;
84.87)判断当前pcie设备的操作句柄是否大于零,如果是则使用系统函数ioctl下达pcie写任务并进入下一步,如果不是则报错退出本次过程,终止图像发送任务,待接收到新的解码后的图像参数数据后返回步骤81);
85.88)判断当前pcie写任务的任务状态是否为完成,如果是则进入下一步,如果不是则报错退出本过程;待接收到新的解码后的图像参数数据后返回步骤81);
86.89)设置第二次dma传输任务的源地址为图像帧数组数据,将主机物理地址vxworks_phy_addr偏移参数帧字节个数sei_len的地址作为任务的目的地址,设置图像帧长度frame_len为第二次任务的传输长度;
87.810)重复步骤87)和步骤88),进入下一步;
88.811)将发送的图像帧长度frame_len写入到协议规定的内存地址,提示主机可以读取数据;
89.812)使用主机读取图像帧数据和参数帧数据,完成回传工作;
90.813)解锁pcie通道的互斥锁,释放pcie通道资源,待接收到新的解码后的图像参数数据后返回步骤81)。
91.第二方面,一种电子设备,包括存储器、处理器及存储在所述存储器上并可在所述处理器上运行的计算机程序,所述处理器执行所述计算机程序时实现第一方面所述的方法的步骤。
92.一种具有处理器可执行的非易失的程序代码的计算机可读介质,所述程序代码使所述处理器执行第一方面所述方法。
93.本发明与现有技术相比的优点在于:
94.本发明利用pcie通道采取dma传输方式对图像大数据进行传输,同时采用ffmpeg解码库获取原始帧中参数帧信息和数据帧信息,获取完整图像帧数据包;建立过滤机制筛
选出错误帧,调整数据包内的帧顺序,传输可解码的完整数据包给硬解码模块,完成解码和转码功能。
附图说明
95.图1为本发明一种高效可转码的视频解码方法实现流程图。
具体实施方式
96.结合图1,为了解决linux系统下视频解码问题,采用基于ffmpeg软解码和海思芯片模块硬解码结合的方法。下面对本发明的内容作进一步描述。
97.1)配置ffmpeg的编译属性和参数,将ffmpeg动态库移植到海思平台
98.首先,配置ffmpeg编译属性。然后,修改ffmpeg源码,使其具备返回参数帧的功能,交叉编译ffmpeg源码。最后,获取ffmpeg解码动态库拷贝到海思开发板。
99.11)首先,配置ffmpeg编译属性,根据平台类型、cpu类型、编码解码器属性、格式转换属性、交叉编译属性配置参数。
100.12)修改acodec.h文件,增加变量:参数帧长度sei_len和数组sei_buf,根据应用层需求确定其参数帧大小sei_buf_size;
101.13)在hevc_sei.c文件中的decode_nal_sei_prefix函数中添加获取参数帧功能:获取函数中的参数size,将size赋值给sei_len,判断size是否小于等于sei_buf_size,如果满足条件则拷贝上下文参数数组gb内数据到sei_buf,拷贝的长度为size,拷贝的sei_buf的数组下标i为gb数组的索引index除以8,即sei_buf[i]=gb_buf[index/8];
[0102]
14)然后,执行configure命令,在配置文件夹的子文件夹lib下将生成的解码库libavcodec、libavformat、libavutil、libswscale。
[0103]
15)最后,将动态库拷贝到解码板卡的/usr/lib路径下;
[0104]
2)配置pcie设备,启动pcie通道,建立与主机通信传输机制;
[0105]
首先,根据传输需求,将海思的pcie配置成从设备,主机的pcie设备为主设备。
[0106]
然后,配置pcie驱动。在海思板卡的系统路径/etc/profile里面自动加载3559驱动文件:hi35xx_dev_slv.ko、irq_map_slv.ko、mcc_drv_slv.ko、mcc_usrdev_slv.ko、pcit_dma_slv.ko。
[0107]
最后,制定主设备和从设备传输规则,规则如下:
[0108]
主设备上电后写入握手的规定内容,从设备在上电后检测到相应内容并握手成功;
[0109]
主设备和从设备为每个通道分配读写的pcie地址,并防止读写地址冲突;
[0110]
主设备握手成功后在规定的pcie地址段写入每个通道接收数据的地址内容;
[0111]
主设备通过查询固定地址段的内容长度是否大于0作为判断是否有数据的标准,并在读走数据后将长度清零;
[0112]
从设备在传输数据之前先判断主设备是否已读走上次数据(即固定地址段长度为0),如果是则写入解码后的图像数据并将长度写入,如果不是则放弃本次写数据任务,等待下一次解码后的数据再传输。
[0113]
3)根据通道数为每个通道创建pcie读数据线程,启动pcie读任务获取主机传输的
原始图像数据
[0114]
首先,创建pcie读数据线程实时查看主机是否有新的图像数据可供读取;然后根据协议规则再在指定的地址段读取数据;最后将读完标志清零,以供主机进行下次传输数据。
[0115]
根据通道数为每个通道创建pcie读数据线程,线程具体操作为:
[0116]
31)申请pcie通道的读写互斥锁,对每个通道的读写操作进行保护,不允许同时有多个通道进行读写操作;
[0117]
32)查看主设备是否有新的图像数据可供读取,即在固定地址内的读数据长度是否不为零,同时主机的读地址也不为零;
[0118]
33)根据协议规则再在指定的读地址段读取数据,具体操作:设置pcie读任务的目的地址为从设备的pcie读地址;设置源地址为主设备的pcie写地址);
[0119]
34)然后,通过ioctl函数对从设备发送读数据任务命令;判断返回值是否成功,如成功则读长度清零,以供主设备进行下次传输数据。
[0120]
35)解锁pcie通道的读写互斥锁,释放资源。
[0121]
4)创建ffmpeg获取数据包线程,使用ffmpeg动态库获取含参数帧的完整压缩图像数据包
[0122]
首先,初始化ffmpeg使用环境。其次,创建获取数据包线程。然后,使用ffmpeg动态库获取压缩图像的含参数帧的完整数据包。
[0123]
41)初始化解码库使用环境
[0124]
首先,设置解码器类型,采用hevc(h265)类型的解码器。然后,初始化解码器上下文环境,动态申请图像帧存储空间。
[0125]
42)创建ffmpeg获取数据包线程,线程具体流程如下:
[0126]
421)获取从pcie通道读取的图像数据数组首地址指针bufptr和长度buflen;
[0127]
422)判断当前的数据长度buflen是否大于0,如果是则继续下一步,如果不是,则退出本次数据的解码过程,等待下次pcie通道传送的图像数据;
[0128]
423)传送数据数组首地址指针bufptr和长度buflen给软解码模块,使用库函数av_parser_parse2对数据按帧进行分割,如果从数组能成功获得一个完整的图像帧数据包则记录继续下一步,如果不是则退出本次解码过程;等待pcie通道传送的图像数据数组;
[0129]
424)保存本次数据数组中图像帧分割的数据包长度ret,从数据数组总长度buflen剔除本次分割的图像帧数据包长度ret,并向前移动首地址指针bufptr,移动次数为ret。
[0130]
425)将本次分割的图像完整数据包放到待解码队列中。
[0131]
5)对完整数据包进行过滤,将可解码的数据包发送到硬解码模块;
[0132]
建立过滤机制,分析数据包内的帧个数和帧类型,针对压缩原理和图像类型分类保存不同图像需要的协议帧个数和帧类型。同时,根据错误类型对图像数据进行再处理,从而组合可解码的数据包给硬解码模块。具体步骤如下:
[0133]
51)判断图像类型,分析不同类型需要的slice个数图像数据包中含p帧的个数),并记录在该通道的数据结构变量pslicenumber。
[0134]
52)判断当前数据包大小是否大于协议帧规定的最大数,如果大于则返回退出本
次数据包的过滤过程,待接收到新的图像数据包后返回步骤51),否则进行下一步;
[0135]
53)循环遍历本次数据包内的数据,遍历从0到(size

3),size为该数据包的大小,依次判断当前帧是否符合h265协议帧头(即具备连续三个字节为00 0001),如果符合则进行下一步,如果不符合则跳转到步骤59);
[0136]
54)判断当前帧是否为p帧或者i帧,如果是,则需要增加本通道本次传输的数据包内sllice个数temp_pslicenumber,进入下一步;如果不是则跳转到步骤56);
[0137]
55)如果当前数据包的temp_pslicenumber等于2,则再次判断当前slice是否为本数据包第一个slice即p_slice是否为0,如果是,则记录当前数据包ptr内遍历字节所在的位置i,即设置p_size为i,并更新记录slice标志p_slice为1,表示已经存在一个slice;
[0138]
56)判断当前帧类型是否为sps,是sps则置标志top为1并进入步骤57);反之,则直接进入58);
[0139]
57)继续判断当前帧是否为参数帧(sei帧),如果是则将当前数据包数组ptr内的i位置拷贝到数据结构idr_buf,保存sei帧之前的帧头信息(vps,pps,sps帧),记录当前保存帧头的数据大小idr_size为i,将首次出现sps标识entryflag为1,并清零top为0;完成后进入步骤58);
[0140]
58)判断当前通道的图像数据是否需要插入i帧(用insertidr标识),并且entryflag为1,如果上述两个条件成立则判断当前帧类型是否为p帧,如果是p帧则将数据包的帧类型字节内容由0x02改成0x26,即改p帧为i帧;反之则直接进入步骤49);
[0141]
59)继续查看数据包内ptr是否还有其他数据需要遍历查询,如果有就回到步骤53),如果没有就继续下一步;
[0142]
510)判断当前通道的insertidr标志和entryflag是否都为1,如果是则继续下一步,如果不是则进行步骤513);
[0143]
511)判断当前temp_pslicenumber是否等于本通道图像类型应该具备的pslicenumber,如果是则下一步,如果不是则丢弃该数据包,退出该数据包的解码过程;待接收到新的图像数据包后返回步骤51);
[0144]
512)将当前数据包内完整图像帧大小为size的数据,拷贝到idr_buf中,拷贝的位置从idr_buf的idr_size开始,将size的大小增大idr_size(即当前数据包大小需要插入之前保存的帧头信息),再次将idr_buf的数据拷贝到ptr中,拷贝的数据大小为size;
[0145]
513)判断当前temp_pslicenumber是否等于本通道图像类型应该具备的pslicenumber,如果是则进行下一步,如果不是则进行步骤515);
[0146]
514)判断p_slice是否为1,如果是则将p_size赋值给size(即只取),清零p_slice;反之,则直接进入步骤515);
[0147]
515)将当前通道的图像参数帧大小记录在seisize中,同时拷贝当前图像的参数帧到当前通道的待解码图像数据结构体decodearray中,将参数个数seicount作为待解码图像的时间戳u64pts;
[0148]
516)查询当前通道的解码状态,并把状态结构体中的已解码图像帧数保存到u32decodestreamframes;
[0149]
517)获取当前通道待解码图像数据的首地址ptr和数据长度size,时间戳u64pts,并以流形式发送到解码模块;
[0150]
518)循环查询解码器的工作状态,直至获得新的解码图像;
[0151]
519)调用海思库函数查询解码器通道状态;
[0152]
520)判断通道内剩余需解码的字节数是否为0,如果是则进去下一步,如果不是则延时1ms跳转到步骤519);
[0153]
521)解码器通道已经解码后的图像帧数是否与之前保存的u32decodestreamframes不相等,或者该通道的insertidr(需要插入i帧)标识为1,如果是进入下一步,如果不是则到步骤523);
[0154]
522)将insrtidr标识清零,增加参数帧的个数(seicount增加1),判断如果seicount大于协议指定大的最大值sei_num,则将参数帧的个数标志seicount清零,进入步骤526);反之,则直接进入下一步;
[0155]
523)复位解码器,进入步骤524);
[0156]
524)判断解码器复位标志resetflag是否为0,如果是则进入下一步,如果不是则继续等待1ms,跳转到步骤523);
[0157]
525)将复位状态resetstate置1,调用库函数停止解码通道的视频流接收任务,销毁解码通道,重启解码通道,将插入i帧的标志insertidr置1,复位状态resetstate置0,进入下一步;
[0158]
526)结束本次过滤过程;
[0159]
6)获取解码器通道内的图像
[0160]
建立获取解码图像任务,实时读取解码器工作状态,调用库函数获取解码通道内解码图像。具体步骤如下:
[0161]
61)创建获取解码图像线程;
[0162]
62)进入图像获取循环;
[0163]
63)查询通道内的复位状态resetstate是否为1,如果是1则延时1ms,继续查询复位状态,如果不是则进行下一步;
[0164]
64)调用库函数hi_mpi_vdec_getframe获取图像存储的内存地址。如果失败则跳转到步骤63),如果成功则进入下一步;
[0165]
65)将复位标志resetflag置1;
[0166]
7)将解码后的图像转化为目标格式图像
[0167]
使用软解码动态库对解码图像进行再处理,创建转化线程任务,将解码图像转化成应用层需要的目标格式和目标像素大小的图像,具体步骤如下:
[0168]
71)判断历史记录的图像像素宽width和高height以及图像格式format是否与当前图像的宽和高、格式一致,如果一致就说明不需要进行转化,直接进入步骤8),否则进行下一步;
[0169]
72)判断当前通道的转化上下文对象指针img_convert_ctx是否为空,如果不为空,则需要调用sws_freecontext库函数释放该对象指针,清空对该通道转化功能的配置参数;
[0170]
73)将当前图像像素的宽、高和图像格式保存在历史记录标志width、height、format中,作为下次判断是否进行转化操作的参考值;
[0171]
74)使用avpicture_get_size库函数,以一个最大图像像素max_width*max_
height为函数参数,获取目标格式图像的字节数numbytes;
[0172]
75)使用av_malloc库函数,以numbytes*sizeof(uint8_t)(uint8_t为无符号8位二进制整型)为参数,申请一个当前通道的存放图像rgb数据数组rgb;
[0173]
76)以当前图像的rgb数据数组rgb、像素宽、高、目标格式为参数,调用avpicture_fill获取填充后的图像帧数组framergb;
[0174]
77)使用当前图像帧的像素宽、高、当前帧格式、填充图像帧数组framergb、目标格式、转化方式为参数,调用sws_getcontex库函数获取当前通道的转化上下文的对象img_convert_ctx;
[0175]
78)使用sws_scale库函数将当前图像格式的图像转化为目标格式的图像,并进行相应的大小缩放,如果转化成功则将转化完的图像保存在framergb数组,如果转化不成功则报错提示并等待下一次图像传输;
[0176]
8)将转码后的图像通过pcie通道发送给主机。
[0177]
获取转码后的目标图像后,将图像数据拷贝到dma传输的内存空间,并启动dma传输任务将图像数据发送到主机端的pcie通道,并将发送长度写入协议规定的地址段通知主机读取数据。具体步骤如下:
[0178]
81)获取pcie通道的读写互斥锁;
[0179]
82)拷贝解码后的图像参数数据到dma虚拟地址空间;
[0180]
83)判断海思平台芯片内的写长度是否被主机清零(即上一帧图像数据已被主设备取走),如果为0则报错退出,终止图像发送任务,待接收到新的解码后的图像参数数据后返回步骤81);反之则进入步骤84);
[0181]
84)获取给主设备发送数据的目的物理地址,如果为零则报错退出,终止图像发送任务,待接收到新的解码后的图像参数数据后返回步骤81);反之则进入步骤85);
[0182]
85)获取dma传输的物理首地址和协议规定的偏移地址,将两者的和作为dma传输任务的源地址,将主机pcie的物理地址vxworks_phy_addr作为任务的目的地址;
[0183]
86)设置本次任务的传输长度为参数帧数据的长度sei_len;
[0184]
87)判断当前pcie设备的操作句柄是否大于零,如果是则使用系统函数ioctl下达pcie写任务并进入下一步,如果不是则报错退出本次过程,终止图像发送任务,待接收到新的解码后的图像参数数据后返回步骤81);
[0185]
88)判断当前pcie写任务的任务状态是否为完成,如果是则进入下一步,如果不是则报错退出本过程;待接收到新的解码后的图像参数数据后返回步骤81);
[0186]
89)设置第二次dma传输任务的源地址为图像帧数组数据,将主机物理地址vxworks_phy_addr偏移参数帧字节个数sei_len的地址作为任务的目的地址,设置图像帧长度frame_len为第二次任务的传输长度;
[0187]
810)重复步骤87)和步骤88),进入下一步;
[0188]
811)将发送的图像帧长度frame_len写入到协议规定的内存地址,提示主机可以读取数据;
[0189]
812)使用主机读取图像帧数据和参数帧数据,完成回传工作;
[0190]
813)解锁pcie通道的互斥锁,释放pcie通道资源,待接收到新的解码后的图像参数数据后返回步骤81)。
[0191]
一种电子设备,包括存储器、处理器及存储在所述存储器上并可在所述处理器上运行的计算机程序,所述处理器执行所述计算机程序时实现上述方法的步骤。
[0192]
一种具有处理器可执行的非易失的程序代码的计算机可读介质,所述程序代码使所述处理器执行上述方法。
[0193]
利用上述技术方案,采用上述操作步骤,本发明可以实现linux系统下视频解码和传输问题,该方法已经经过了算法验证,并进行了实验检验。结果标明,该方案可以为解决图像解码问题,采用软解码方法,组成包含图像帧和参数帧的完整数据包,采用过滤机制,动态筛选不符合协议类型的错误帧,获取可解码的图像数据包,再使用芯片的硬解码模块完成解码和转码过程,有效减少解码时间。另外,使用pcie通道的dma传输方式对图像大数据进行传输,极大地减少了传输时延。
[0194]
在本发明中,步骤1)对板卡进行了解码环境的配置,对其软解码库ffmpeg移植适应海思平台,同时对ffmpeg进行修改,使其返回的图像数据包带有参数帧。
[0195]
步骤2)和步骤3)配置了pcie设备,建立与主机传输过程的规则,启动pcie的dma传输模式,对图像大数据进行接收。
[0196]
步骤7)再次使用pcie回传解码后图像给主机,完成传输任务。
[0197]
步骤3)为ffmpeg创建使用环境,并指定启动要求的解码器,可针对原始数据进行协议分析。同时,从网络接收的数据区循环获取原始数据,调用库函数获取可组合成带有参数帧的完整图像帧的数据包的长度,从网络接收数据区从剔除该长度并循环反复进行直到数据区没有任何数据。
[0198]
步骤4)建立过滤机制,动态筛选出不符合协议规定的错误帧,分析编码规律,调整数据包图像帧顺序,根据编码器特性动态修改帧类型,使其组合成可解码的图像数据包。同时,实时监控解码器状态,根据当前数据包的需求启动复位解码通道操作,使其解码模块持续进行工作。
[0199]
步骤5)创建获取数据线程,根据复位状态启动库函数获取解码通道内的图像,并在数据后修改其复位状态使得步骤4能实时更新解码器工作状态。
[0200]
步骤6)使用硬解码模块内的视频图形子系统对解码后的图像进行格式转化,以任务形式持续处理解码通道内的图像,为应用层显示需要提供支持。
[0201]
本发明虽然已以较佳实施例公开如上,但其并不是用来限定本发明,任何本领域技术人员在不脱离本发明的精神和范围内,都可以利用上述揭示的方法和技术内容对本发明技术方案做出可能的变动和修改,因此,凡是未脱离本发明技术方案的内容,依据本发明的技术实质对以上实施例所作的任何简单修改、等同变化及修饰,均属于本发明技术方案的保护范围。
[0202]
本发明说明书中未作详细描述的内容属本领域专业技术人员的公知技术。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献