TDA4与Openvx技术开发示例

TDA4与Openvx技术开发示例
[TI TDA4 J721E]基于TDA4平台 FFmpeg / X264 的ARM平台移植
https://blog.csdn.net/AIRKernel/article/details/121483611
创建了开源的Demo演示案例库,后续会把Demo代码放到这个Gitee库里:
 
TDA4/TI TDA4
https://gitee.com/tda4/ti-tda4
        欢迎大家加入,一起维护这个开源库,给更多的朋友提供帮助。
 
由于需要使用TDA4完成一个推流的工作,在查找各种资料以后,决定移植ffmpeg,进行rtmp的推流工作。下面开始演示移植过程:
 
一、下载源码
1、X264源码(总览:http://download.videolan.org/pub/videolan/x264/snapshots/)
 
博主使用源码版本:
 
http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20191217-2245.tar.bz2
 
2、ffmpeg源码(总览:Index of /releases)
 
博主使用源码版本:http://ffmpeg.org/releases/ffmpeg-4.4.1.tar.bz2
 
二、准备工作
将两个文件拷贝到TDA4的开发板上,使用开发板本身的gcc编译器进行编译,可以省去使用交叉编译链进行编译的步骤,比较方便!(实际上是移植了很久,没搞定,编译总是报错,无奈……)
 
在开发板/home/root/ 目录下新建一个文件夹,命名为ffmpeg
进入ffmpeg文件夹,通过scp将两个下载好的文件拷贝到开发板上来。
(开发板可以联网,关于联网,请查看这篇博客!
 
[TI TDA4 J721E]开发板网络调试功能及开机自动配置网络_AIRKernel的博客-CSDN博客)
 
mkdir ~/ffmpeg
cd ~/ffmpeg
scp ubuntu@192.168.1.100:/home/ubuntu/x264-snapshot-20191217-2245.tar.bz2 ffmpeg-4.4.1.tar.bz2 ~ffmpeg
两个文件要放在同一个目录下进行解压!!!
因为ffmpeg配置的时候,需要使用到x264生成的库(路径!)
 
解压两个源码
 
tar -vxf x264-snapshot-20191217-2245.tar.bz2
tar -vxf ffmpeg-4.4.1.tar.bz2
三、x264配置、编译和安装
进入x264的源码文件夹,分别执行以下命令
 
cd ./x264-snapshot-20191217-2245
./configure --host=arm-linux-gnueabihf --prefix=$PWD/tmp --enable-shared --disable-asm
make -j16 && make install
四、ffmpeg配置、编译和安装
注意!!
编译ffmpeg之前,需要将系统时间设置为当前的时间时间,因为编译会使用到系统时间。
时间格式:月、日、年 时、分、秒
例:date -s "11/20/2021 10:15:05"
 
进入ffmpeg的源码文件夹,分别执行以下指令
 
最后一个编译的过程时间很久,请耐心等待!不要着急!
 
cd ./ffmpeg-4.4.1
 
./configure --enable-shared --enable-pic --disable-static --enable-gpl --enable-nonfree --enable-pthreads --enable-ffmpeg --disable-ffplay --enable-swscale --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-stripping --enable-libx264 --extra-cflags=-I$PWD/../x264-snapshot-20191217-2245/tmp/include --extra-ldflags=-L$PWD/../x264-snapshot-20191217-2245/tmp/lib
 
make -j16 && make install
这一步时间很长……很长……(可能有40分钟左右吧!!)
 
五、示例
1、流推送:(将RTSP流推送到RTMP服务器)
 
ffmpeg -i "rtsp://admin:12345678@192.168.8.154:554/stream2" -an -c:v copy -f flv rtmp://192.168.1.1:554/mystream
2、RTSP流保存成.avi(RTSP流来自局域网内部网络摄像头)
 
ffmpeg -i rtsp://admin:12345678@192.168.8.154:554/stream2 -vcodec copy /home/root/myout.avi
3、USB摄像头流获取并保存成.avi:
 
ffmpeg -f video4linux2 -s 640x480 -i /dev/video1 /home/root/test.avi
4、使用ffmpeg RTMP推流USB摄像头
 
测试成功推流的指令代码:(注意设备名,我这里是video1)
 
ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video1 -f flv -y rtmp://myserver.cn/MINILIVE/mystream
PS:我在实际测试阿里云给的指令的时候出错了,不知道大家能不能成功。
 
Linux下用FFMPEG采集usb摄像头到RTMP-阿里云开发者社区
 
ffmpeg -f video4linux2 -qscale 10 -r 12 -s 640x480 -i /dev/video1 -f alsa -i hw:1 -ab 16 -ar 22050 -ac 1 -f mp3 -f flv rtmp://127.0.0.1/rtmpsvr/rtmp1
测试结束。
                       
原文链接:https://blog.csdn.net/AIRKernel/article/details/121483611
参考文献链接
https://blog.csdn.net/AIRKernel/article/details/121483611
[TI TDA4 J721E](升级版)单屏显示多路摄像头数据(img_mosaic_module节点使用)
https://blog.csdn.net/AIRKernel/article/details/121210285
此篇教程的完整资源在这里下载
 
TITDA4单屏多路显示Demo完整资源ImgMosaic节点的使用教程-C/C++文档类资源-CSDN下载
 
前几天写了一个关于单屏多显示的帖子:
 
[TI TDA4]TIOVX 单屏显示多路摄像头数据(Mosaic节点使用)_AIRKernel的博客-CSDN博客
 
        当时只是研究了其中的一个Demo,这个Demo里面的图像显示还是有点问题,应该是当时作者算法的问题,我也没有详细研究。
 
        这两天重新梳理了以下,发现有一个Node是专门做这个图像镶嵌的工作的,img_mosaic节点。这个imgMosaic Node的主要作用目前看来就是将图像进行镶嵌到一张大图上,进行显示。比如将多个图像区域,内嵌到一个1920*1080尺寸的image上,然后显示出来。(个人理解,如有不同或者错误,欢迎大家指正一下)。
 
        这篇博客就写一下这个节点的移植和实际应用。
 
首先看一下效果图:
 
这里可以设置屏幕显示2个~多个,应该是可以随意分屏的。这个大家可以去试一下,我这里分了9个。另外,我这里只有一个YUV摄像头,如果有多个,大家可以将多个图像替换进去就可以显示不同的图像了,这个替换比较简单,看到代码就应该明白了。
 
一、基于Demo的移植
(基于ti-processor-sdk-rtos-j721e-evm-08_00_00_12下的app_usb_disp_templete)
 
app_usb_disp_templete下载地址如下:
 
TDA4开发板USB摄像头显示NV12图像完整资源-C/C++文档类资源-CSDN下载
 
这个Node的相关操作文件,是从
 
ti-processor-sdk-rtos-j721e-evm-08_00_00_12/vision_apps/apps/dl_demos/app_tidl_avp2路径里面拷贝过来的。
 
1、拷贝一份app_usb_disp_templete,命名为app_usb_disp。
 
2、将两个文件:avp_img_mosaic_module.c avp_img_mosaic_module.h,拷贝到app_usb_disp下。(请忽略encode这两个文件,暂时用不到,还有点问题没有解决,后面会专门处理这个问题)。
 
3、修改concerto.mak内容
 
这里有四个地方需要修改 添加参与编译的源文件、添加头文件路径、添加库路径
 
A、        修改TARGET ,这里可以根据自己的需要进行命名。如:vx_app_usb_disp
B、        CSOURCES += app_img_mosaic_module.c
C、        IDIRS += $(IMAGING_IDIRS)
D、        STATIC_LIBS += $(IMAGING_LIBS)
如图,左边是修改过的,右边是修改前的。大家对照以下(忽略encode相关)
 
 4、main.c中添加头文件
#include "app_img_mosaic_module.h"
在AppObj中添加一个img的对象:ImgMosaicObj imgMosaicObj;
在AppObj中添加一个 graph,用于执行Mosaic节点。
 
5、 分别在app_init / app_create_graph / app_verify_graph / app_run_graph_for_one_frame 中添加关于imgMosaic相关的内容。
app_init中对imgMosaic节点进行初始化操作/添加注册图像处理的kernel。
app_create_graph 中创建 graph。
app_verify_graph  中对 graph进行检查。
app_run_graph_for_one_frame 中执行graph。
分别如下图(对应的函数都在刚刚拷贝的两个文件中):
 
 
 
 
 
 
本工程的工作总体流程是(具体大家还是跟着代码走读一下):
 
A、创建了两个Graph,一个用于执行imgMosaic,一个用于执行Display。
 
B、imgMosaic节点的输入是9个NV12格式的图像组成的array(用户数组),输出是一个1920*1080的image。
 
C、display节点的输入是imgMosaic节点的输出图像。
 
D、首先usb摄像头先工作,生成YUV图像,在内存中以指针形式传递出去。
 
E、将usb摄像头生成的YUV数据,复制到imgMosaic节点的输入数组中。
 
F、执行imgMosaic节点,将输入的数组,生成一个输出的显示图像。
 
G、将输出的显示图像,传递给display节点,然后执行disp_graph,显示出图像。
 
D-G 的过程,每一次都会执行一次,将数组更新,然后显示也会更新。
 
添加完上述这些东西以后,基本上就可以正常编译核运行了。
 
其中有一个函数是我后来添加的:app_running_imgMosaic,位于app_img_mosaic_module.c内,这个函数用于拷贝摄像头生成的数据,到imgMosaic节点的用户数组内。大家可以通过修改这个函数的传入指针,将不同摄像头的数据传入即可得到想要的数据。
 
//动态更新imgMosaic节点内的输入数组的内容
//目前此函数仅支持NV12格式数据的拷贝,大家可以根据自己需要改一下,比如可以拷贝BMP图像的RGB数据等等
vx_status app_running_imgMosaic(vx_object_array *array, char *image)
{
    vx_status status = VX_SUCCESS;
 
    if (status == VX_SUCCESS)
    {
        status = vxGetStatus((vx_reference)(*array));       //查看array状态,如果为空则表示错误
        vx_size arrLen;
        vxQueryObjectArray((*array), VX_OBJECT_ARRAY_NUMITEMS, &arrLen, sizeof(vx_size)); //查询数组内元素的个数
 
        vx_int32 i;
 
        for (i = 0; i < arrLen; i++)        //将数据拷贝到数组中
        {
            vx_rectangle_t rect;
            vx_imagepatch_addressing_t image_addr;
            vx_map_id map_id;
            void *data_ptr;
            vx_uint32 img_width;
            vx_uint32 img_height;
            vx_image in_img;
 
            in_img = (vx_image)vxGetObjectArrayItem((*array), i);                       //获取array内对象的属性,这里是设置为图像格式
 
            vxQueryImage(in_img, VX_IMAGE_WIDTH, &img_width, sizeof(vx_uint32));        //查询图像宽度
            vxQueryImage(in_img, VX_IMAGE_HEIGHT, &img_height, sizeof(vx_uint32));      //查询图像的高度
 
            rect.start_x = 0;
            rect.start_y = 0;
            rect.end_x = img_width;
            rect.end_y = img_height;
            status = vxMapImagePatch(in_img,            //向内核申请图像访问的指针地址,用于拷贝用户数据到vx内核空间
                                     &rect,
                                     0,
                                     &map_id,
                                     &image_addr,
                                     &data_ptr,
                                     VX_WRITE_ONLY,
                                     VX_MEMORY_TYPE_HOST,
                                     VX_NOGAP_X);
 
            memcpy(data_ptr, image, img_width * img_height);    //拷贝数据
 
            vxUnmapImagePatch(in_img, map_id);                  //释放map_id
 
            rect.start_x = 0;
            rect.start_y = 0;
            rect.end_x = img_width;
            rect.end_y = img_height / 2;
            status = vxMapImagePatch(in_img, //向内核申请图像访问的指针地址,用于拷贝用户数据到vx内核空间
                                     &rect,
                                     1,
                                     &map_id,
                                     &image_addr,
                                     &data_ptr,
                                     VX_WRITE_ONLY,
                                     VX_MEMORY_TYPE_HOST,
                                     VX_NOGAP_X);
 
            memcpy(data_ptr, image + img_width * img_height, img_width * img_height / 2); //拷贝数据,这里需要注意拷贝源地址的偏移量
 
            vxUnmapImagePatch(in_img, map_id); //释放map_id
 
            vxReleaseImage(&in_img);//释放临时图像
        }
    }
    return status;
}
 
我会将完整工程放过来,资源上传审核需要时间,链接如下:
 
TITDA4单屏多路显示Demo完整资源ImgMosaic节点的使用教程-C/C++文档类资源-CSDN下载
 
 PS:这个不是广告,我自己在用的笔记软件。给大家推荐一款比较实用的在线云笔记 Notion(免费),下载链接如下:
 
NotionForUbuntu.tar.xz-管理软件文档类资源-CSDN下载
    
                       
原文链接:https://blog.csdn.net/AIRKernel/article/details/125731020
https://blog.csdn.net/AIRKernel/article/details/125731020
参考文献链接
https://blog.csdn.net/AIRKernel/article/details/121210285

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/735694.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

遇到的线上问题之“动态数据源报错-recyle error java.lang.InterruptedException”

Druid出现DruidDataSource - recyle error - recyle error java.lang.InterruptedException: null异常排查与解决 一、线上的代码之前运行的都很平稳,突然就出现了一个很奇怪的问题,看错误信息是第三方框架Druid报出来了,连接池回收连接时出现的问题。[][ERROR][2024-07-01 …

遇到的线上问题之“recyle error java.lang.InterruptedException”

Druid出现DruidDataSource - recyle error - recyle error java.lang.InterruptedException: null异常排查与解决 一、线上的代码之前运行的都很平稳,突然就出现了一个很奇怪的问题,看错误信息是第三方框架Druid报出来了,连接池回收连接时出现的问题。[][ERROR][2024-07-01 …

构建高可用性、高性能和可扩展的Zabbix Server架构

简介 本教程讲解了一下如何设计构建一个高性能、高可靠、高扩展的Zabbix 监控集群。 架构图 架构图PDF下载: https://songxwn.com/file/Zabbix_HA.pdfPigsty 时序数据库集群 Zabbix Server 和 Grafana的数据都是存放在数据库的,而Zabbix性能很大程度取决于数据库。所以要搭建…

[JavaScript]作用域的“生产者”——词法作用域

本篇文章标题即摘要,就不赘述。 如果文中有不妥或不对的,多多交流。【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18252500 出自【进步*于辰的博客】参考笔记二,P43.3、P46.1、P9.3;笔记三,P70、P71。目录先…

NAT类型发现

一、前言之前一篇文章中,提出了一个判断NAT类型的方案。该方案是自己研究设计的,比较粗糙。近期研读了关于STUN的一些协议标准,其中RFC3489中就包含了判断NAT类型的标准方案。与自己设计的方案相比,标准方案有以下优点:1,利用了STUN协议中定义的一些属性,如CHANGE-REQUE…

全网最适合入门的面向对象编程教程:06 类和对象的Python实现-自定义类的数据封装

本文我们主要介绍了数据封装的基本概念和特性,如何设置自定义类的私有属性和私有方法,protect属性的概念和特点。全网最适合入门的面向对象编程教程:06 类和对象的 Python 实现-自定义类的数据封装 摘要: 本文我们主要介绍了数据封装的基本概念和特性,如何设置自定义类的私…

MOS管

MOS管 MOS 管是金属-氧化物半导体场效应晶体管的缩写,是一种重要的半导体器件。它具有以下特点和应用:特点:高输入阻抗:MOS 管的输入阻抗很高,可以减少对前级电路的影响。 开关速度快:MOS 管的导通和截止速度很快,适用于高频电路。 噪声低:MOS 管的噪声较低,适用于对噪…

三极管的作用和原理

目录 目录三极管的类型、作用和工作原理三极管的作用NPN三极管结构和工作原理:PNP三极管结构和工作原理:区别和应用场景三极管的类型、作用和工作原理三极管是一种重要的半导体器件,主要有两种类型:NPN和PNP。它们在结构、工作原理和应用上有显著的区别。三极管的作用 三极…

【Oracle】匹配一个字符中是否存在空格以及回车

【Oracle】匹配一个字符中是否存在空格以及回车 使用REGEXP_LIKE,然后使用[[:space:]] [[:space:]] 是一个 POSIX 字符类,匹配任何空白字符,包括空格、制表符、回车和换行 例子如下 SELECT R1, R2 FROM dual WHERE REGEXP_LIKE(R1, R2, [[:space:]]);您能读到这儿,我呢是发…

[淘宝/天猫/1688/京东]API接口数据采集分享

主流电商平台大数据采集API接口。在当今时代,从数据中挖掘价值的重要性愈发凸显,远超以往任何时期。现代企业渴望在任意设备上,无论身处何地,都能实时获取最新的相关信息。这正是数字化转型的核心所在,它同样适用于供应链的每一个环节。在当今时代,从数据中挖掘价值的重要…

@RequestMapping中的name属性解释

在Spring MVC中,@RequestMapping注解用于映射web请求到特定的处理方法。这个注解有多个属性,其中之一就是name。name属性通常用于为映射提供一个名称,这个名称可以在日志、文档或其他需要引用这个映射的地方使用。 在Spring MVC的上下文中,这允许你为特定的@RequestMapping…

6种Win10关闭自动更新方法介绍!

Win10自动更新 想寻找Win10关闭自动更新方法?Windows 10自动更新功能旨在确保您的系统始终运行最新的安全补丁和功能更新。然而,对于某些用户来说,频繁的更新可能带来不便。有时选择拒绝更新,系统会一直不停的提示系统更新;选择更新了,更新后一些软件或网络打印机等相关设…

【动画进阶】类 ChatGpt 多行文本打字效果

今天我们来学习一个有意思的多行文本输入打字效果,像是这样:这个效果其实本身并非特别困难,实现的方式也很多,在本文中,我们更多的会聚焦于整个多行打字效果最后的动态光标的实现。 也就是如何在文本不断变长,在不确定行数的情况下,让文字的最末行右侧处,一直有一个不断…

解决卡顿发热,超帧技术焕发中重载游戏动力

近几年,中国手游市场规模不断扩大,开发者通过在画面、玩法等方面的持续创新和打磨,推出更加精品化的产品。然而愈发精美的画质和复杂的玩法,也给硬件带来超高的负载,导致玩家在游戏过程中,频繁出现掉帧卡顿、发烫、续航差等体验降低的现象。HarmonyOS SDK 图形加速服务(…

ArchiMate 3 学习

目录ArchiMate 3 学习什么是ArchiMateArchiMate 3.1 规范关系动机元素策略元素业务层应用层技术层物理元素实施和迁移元素复合元素 ArchiMate 3 学习 ArchiMate 3 中文版 什么是ArchiMate ArchiMate 是 The Open Group 为企业架构提供的开放和独立的建模语言,由不同的工具供应…

如何找到并快速上手一个开源项目

以前有写过两篇文章来简单聊过如何做开源的事情,最近我自己组了一个社区里面也有不少朋友对开源感兴趣,于是我便根据自己的经验系统的梳理了一些关于开源的事情。新手如何快速参与开源项目 手把手教你为开源项目贡献代码有兴趣的可以先看看之前这两篇。🔎如何找到自己感兴趣…

WPF在.NET9中的重大更新:Windows 11 主题

WPF在.NET9中的重大更新:Windows 11 主题在2023年的2月20日,在WPF的讨论区,WPF团队对路线的优先级发起了一次讨论。对三个事项发起了投票。 第一个是Windows 11 主题第二个是更新的控件第三个是可空性注释最终Windows 11 主题得票最高,WPF团队2023-2024的工作优先级就是Win…

配置 Swagger + 注释

打开Xml文件生成,右键项目进入属性设置: 取消未进行注释而进行提示的警告: 然后Program.cs增加代码: 代码:builder.Services.AddSwaggerGen(s => {//获取xml文件名称var xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";//包含注释,…

C#winform如何在窗体实现视频播放

1.在Form窗体设计中的左侧工具箱列表中右击鼠标,单击选择项。2.在弹出的对话框中点击COM组件,选择Windows Media Player,点击确定3.接着在工具箱选择Windows Media Player控件,将控件添加到窗体中,并且添加一个OpenFileDialog控件4.接着在工具箱的对话框中将OpenFileDialog…

AI引导学习前端开发

假设你是一位前端技术开发专家,我有几个JavaScript的问题想向你咨询 我想用JavaScript来做微信小程序开发,请以表格的方式输出知识要点 请叙述JavaScript操作浏览器对象的常用接口和方法 把上述表格按照访问对象归类 将上述文字制作一个表格来呈现,要求逻辑清晰描述信息简明…