RK3588移植-ffmpeg交叉编译

news/2024/5/4 17:27:12/文章来源:https://blog.csdn.net/weixin_44866921/article/details/128136621

文章目录

    • 1.下载ffmpeg
    • 2.交叉编译
    • 3.修改cmakelist.txt
    • 4.将lib文件复制到install目录下的lib目录
    • 5.测试文件
    • 6.运行测试样例
    • 7.错误
    • n.测试文件源码

1.下载ffmpeg

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg

2.交叉编译

进入下载目录,将ffmpeg编译成arm64平台的版本,编译后的文件存放于./instal_arm64中。

sudo ./configure --prefix=./instal_arm64 --enable-shared --disable-static --enable-cross-compile --arch=arm64 --disable-stripping --target-os=linux --cc=aarch64-linux-gnu-gcc

验证:进入instal_arm64/lib文件夹,使用file命令查看文件格式,若显示为ARM aarch64即成功。
在这里插入图片描述

3.修改cmakelist.txt

需要将交叉编译好的lib/include 文件夹导入项目中,修改cmakelist.txt如下图所示。
在这里插入图片描述
在这里插入图片描述
为方便复制这里将改动内容的文字贴在下面,路径需要改成自己的下载路径

#ffmpeg
# 设置ffmpeg依赖库及头文件所在目录,并存进指定变量
set(ffmpeg_libs_DIR /home/yi/Downloads/ffmpeg/instal_arm64/lib)
set(ffmpeg_headers_DIR /home/yi/Downloads/ffmpeg/instal_arm64/include)
add_library( avcodec SHARED IMPORTED)
add_library( avfilter SHARED IMPORTED )
add_library( swresample SHARED IMPORTED )
add_library( swscale SHARED IMPORTED )
add_library( avformat SHARED IMPORTED )
add_library( avutil SHARED IMPORTED )
#指定所添加依赖库的导入路径
set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavcodec.so )
set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavfilter.so )
set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswresample.so )
set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswscale.so )
set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavformat.so )
set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavutil.so )
# 添加头文件路径到编译器的头文件搜索路径下,多个路径以空格分隔
include_directories(${ffmpeg_headers_DIR})
link_directories(${ffmpeg_libs_DIR})--------省略若干字。。。。。----------------------target_link_libraries(rknn_yolov5_demo${RKNN_RT_LIB}${RGA_LIB}${OpenCV_LIBS}${ffmpeg_libs_DIR}avcodec avformat avutil swresample swscale swscale avfilter
)

4.将lib文件复制到install目录下的lib目录

这里也许可以只复制项目中需要的lib文件.
sudo cp ~/Downloads/ffmpeg/instal_arm64/lib/* install/rknn_yolov5_demo_Linux/lib/

5.测试文件

这里用一个ffpeg解析rtsp流的案例来测试是否成功。因为源码篇幅过长,放到本文最后。程序大意是:读取rtsp流,将rtsp流解析成帧,并且输入到输出文件,同时统计帧数。

6.运行测试样例

sudo ./build-rk3588…
adb push …
这里省略
最终可得到如图所示的结果,表示编译运行成功。
在这里插入图片描述

7.错误

运行时出现了Failed to resolve hostname …无法解析域名的错误。
在这里插入图片描述
解决方案:
有两种可能的原因,1.没有配置域名服务器114.114.114.114 。2.开发板没有网络。

  1. 配置域名服务器
    在这里插入图片描述
  2. 连接网络
    可以尝试ping www.baidu.com,若没有问题的话,则不是网络问题。
    1、安装nmcli
    sudo apt-get install nmcli
    2、查看网络设备
    sudo nmcli dev
    3、开启wifi
    sudo nmcli r wifi on
    4、扫描wifi
    sudo nmcli dev wifi
    5、连接wifi
    sudo nmcli dev wifi connect “wifi名” password “密码”

n.测试文件源码

案例源码:

#ifndef INT64_C 
#define INT64_C(c) (c ## LL) 
#define UINT64_C(c) (c ## ULL) 
#endif extern "C" {/*Include ffmpeg header file*/
#include <libavformat/avformat.h> 
#include <libavcodec/avcodec.h> 
#include <libswscale/swscale.h> #include <libavutil/imgutils.h>  
#include <libavutil/opt.h>     
#include <libavutil/mathematics.h>   
#include <libavutil/samplefmt.h>
}#include <iostream>
using namespace std;int main(void)
{AVFormatContext* ifmt_ctx = NULL, * ofmt_ctx = NULL;const char* in_filename, * out_filename;//in_filename = "rtsp://admin:WY@123456@192.168.0.64/h264/ch1/main/av_stream";in_filename="rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4";out_filename = "output.flv";avformat_network_init();AVDictionary* avdic = NULL;char option_key[] = "rtsp_transport";char option_value[] = "tcp";av_dict_set(&avdic, option_key, option_value, 0);char option_key2[] = "max_delay";char option_value2[] = "5000000";av_dict_set(&avdic, option_key2, option_value2, 0);AVPacket pkt;AVOutputFormat* ofmt = NULL;int video_index = -1;int frame_index = 0;int i;//打开输入流int ret;if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, &avdic)) < 0){cout<<"Could not open input file."<<endl;goto end;}if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0){cout<<"Failed to retrieve input stream information"<<endl;goto end;}//nb_streams代表有几路流for (i = 0; i < ifmt_ctx->nb_streams; i++) {if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){//视频流video_index = i;cout << "get videostream." << endl;break;}}av_dump_format(ifmt_ctx, 0, in_filename, 0);//打开输出流avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);if (!ofmt_ctx){printf("Could not create output context\n");ret = AVERROR_UNKNOWN;goto end;}ofmt = ofmt_ctx->oformat;for (i = 0; i < ifmt_ctx->nb_streams; i++){AVStream* in_stream = ifmt_ctx->streams[i];AVStream* out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);if (!out_stream){printf("Failed allocating output stream.\n");ret = AVERROR_UNKNOWN;goto end;}//将输出流的编码信息复制到输入流ret = avcodec_copy_context(out_stream->codec, in_stream->codec);if (ret < 0){printf("Failed to copy context from input to output stream codec context\n");goto end;}out_stream->codec->codec_tag = 0;if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;}av_dump_format(ofmt_ctx, 0, out_filename, 1);if (!(ofmt->flags & AVFMT_NOFILE)){ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);if (ret < 0){printf("Could not open output URL '%s'", out_filename);goto end;}}//写文件头到输出文件ret = avformat_write_header(ofmt_ctx, NULL);if (ret < 0){printf("Error occured when opening output URL\n");goto end;}//while循环中持续获取数据包,不管音频视频都存入文件while (1){AVStream* in_stream, * out_stream;//从输入流获取一个数据包ret = av_read_frame(ifmt_ctx, &pkt);if (ret < 0)break;in_stream = ifmt_ctx->streams[pkt.stream_index];out_stream = ofmt_ctx->streams[pkt.stream_index];//copy packet//转换 PTS/DTS 时序pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));//printf("pts %d dts %d base %d\n",pkt.pts,pkt.dts, in_stream->time_base);pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);pkt.pos = -1;//此while循环中并非所有packet都是视频帧,当收到视频帧时记录一下if (pkt.stream_index == video_index){printf("Receive %8d video frames from input URL\n", frame_index);frame_index++;}//将包数据写入到文件。ret = av_interleaved_write_frame(ofmt_ctx, &pkt);if (ret < 0){if (ret == -22) {continue;}else {printf("Error muxing packet.error code %d\n", ret);break;}}//av_free_packet(&pkt); //此句在新版本中已deprecated 由av_packet_unref代替av_packet_unref(&pkt);}//写文件尾av_write_trailer(ofmt_ctx);end:av_dict_free(&avdic);avformat_close_input(&ifmt_ctx);//Close inputif (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))avio_close(ofmt_ctx->pb);avformat_free_context(ofmt_ctx);if (ret < 0 && ret != AVERROR_EOF){cout<<"Error occured."<<endl;return -1;}return 0;
}

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

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

相关文章

【LeetCode每日一题:1779. 找到最近的有相同 X 或 Y 坐标的点~~~模拟遍历+曼哈顿距离】

题目描述 给你两个整数 x 和 y &#xff0c;表示你在一个笛卡尔坐标系下的 (x, y) 处。同时&#xff0c;在同一个坐标系下给你一个数组 points &#xff0c;其中 points[i] [ai, bi] 表示在 (ai, bi) 处有一个点。当一个点与你所在的位置有相同的 x 坐标或者相同的 y 坐标时&…

Go1.9.3跑GinDemo

Gin 1. 简介 1.1. 介绍 Gin是一个golang的微框架&#xff0c;封装比较优雅&#xff0c;API友好&#xff0c;源码注释比较明确&#xff0c;具有快速灵活&#xff0c;容错方便等特点 对于golang而言&#xff0c;web框架的依赖要远比Python&#xff0c;Java之类的要小。自身的n…

实验(六):定时器实验

一、实验目的与任务 实验目的&#xff1a; 1&#xff0e;掌握定时/计数器的中断法工作原理&#xff1b; 2&#xff0e;熟悉C51编程与调试方法。 任务&#xff1a; 1. 运行Keil开发环境&#xff0c;完成定时器软件编程&#xff1b; 2. 建立Proteus仿真模型&#xff1b; 3&#x…

Flink系列之Flink流式计算引擎基础理论

声明&#xff1a; 文章中代码及相关语句为自己根据相应理解编写&#xff0c;文章中出现的相关图片为自己实践中的截图和相关技术对应的图片&#xff0c;若有相关异议&#xff0c;请联系删除。感谢。转载请注明出处&#xff0c;感谢。 By luoyepiaoxue2014 B站&#xff…

mapbox地图动画一键飞行

最近&#xff0c;Mapbox GL JS 从 v2.9 开始支持将地图显示为 3D 地球。 话不多说&#xff0c;马上看看效果怎么样&#xff1a; mapbox地图动画我们通过设置投影属性projection&#xff1a;globe&#xff0c;即可将地图更改为地球 const map new mapboxgl.Map({container: m…

【Linux初阶】操作系统概念与定位 | 操作系统管理硬件方法、系统调用和库函数概念

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;操作系统的基础概念、设计OS的目的&#xff0c;操作系统的定位&#xff0c;操作系统管理硬件方法&#xff0c;…

荣誉!InterSystems被独立研究机构Forrester评为“事务分析型数据平台领导者”

2022 年 12 月 1 日&#xff0c;中国&#xff0c;北京——致力于帮助客户解决最关键的可扩展性、互操作性和速度问题的创新数据技术提供商 InterSystems 今天宣布&#xff0c;在Forrester日前公布的《The Forrester Wave™&#xff1a;事务分析型数据平台(2022年第4季度)》报告…

硬件学习路线调研

学习路线 《Verilog传奇》、《Verilog HDL高级数字设计》或者是《用于逻辑综合的VHDL》。不看书也能写出个三段式状态机就可以进入下一阶段了。 此外&#xff0c;你手上必须准备Verilog或者VHDL的官方文档&#xff0c;《verilog_IEEE官方标准手册-2005_IEEE_P1364》、《IEEE …

科研绘图配色方案

科研绘图配色方案 在撰写论文的时候&#xff0c;美观&#xff0c;大气&#xff0c;上档次的图表能够很好地给自己的论文加分。但是在绘制图表的时候往往会面临色彩搭配的问题&#xff0c;选择合适的色彩搭配能够有效地展示自己的方法&#xff0c;但是色彩搭配选择不当的话往往…

2021-02-01

oracle设置定期修改密码 --通过如下sql查询用户密码有效期配置 SELECT username,PROFILE FROM dba_users; --上述sql查询结果一般为default --使用如下sql可以查询到default的默认值 select * from dba_profiles where profile DEFAULT and resource_name PASSWORD_LI…

Express 7 指南 - 开发中间件

Express Express 中文网 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录Express7 指南 - 开发中间件7.1 概述7.2 例子7.2.1 中间件函数 myLogger7.2.2 中间件函数 requestTime7.2.3 中间件函数 validateCookies7.3 可配置的中间件7 指南 - 开发…

数据结构与算法 -二叉树

二叉树相关算法 1. 二叉树基本知识 &#xff08;1&#xff09;二叉树结构 public class Node {V value;Node left;Node right; }left和right只能往下指&#xff0c;没有节点就为空。 &#xff08;2&#xff09;创建二叉树 对于一个完全二叉树&#xff0c;父节点为i, 左子节点…

Unity3d bounds包围盒 和collider碰撞器区别

Bounds 外包围盒 Bounds 叫作外包围盒、边界框、外扩矩形.是struct 结构体。而我们获得Bounds的主要途径有三种&#xff1a;Render,Collider,Mesh。 Render.bounds 世界坐标 Collider.bounds 世界坐标 Mesh.bounds 本地坐标 var m GetComponent<MeshFilter>().bound…

【数据结构】图的实现

文章目录图1.图的基本概念2.图的存储结构3.邻接矩阵3.1邻接矩阵的优缺点3.2邻接矩阵的实现4.邻接表4.1邻接表的实现5.图的遍历5.1广度优先遍历5.2深度优先遍历5.3如何遍历不连通的图&#xff1f;图 1.图的基本概念 图是由顶点集合及顶点间的关系组成的一种数据结构&#xff1…

BERT-of-Theseus

最近了解到一种称为"BERT-of-Theseus"的BERT模型压缩方法&#xff0c;源自论文《BERT-of-Theseus: Compressing BERT by Progressive Module Replacing》。这是一种以"可替换性"为出发点所构建的模型压缩方案&#xff0c;相比常规的剪枝、蒸馏等手段&#…

streptavidin-PEG-6-FAM 链霉亲和素-聚乙二醇-6-羧甲基荧光素

产品名称&#xff1a;链霉亲和素-聚乙二醇-6-羧甲基荧光素 英文名称&#xff1a;streptavidin-PEG-6-FAM 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体&#xff0c;取决于分子量 PEG分子量可选&#xff1a;350、550、75…

自助建站工具

每用一次自助建站工具&#xff0c;就有一个程序员失业。 作为企业老板的你&#xff0c;要为公司的获客&#xff0c;企业推广发愁&#xff0c;但是预算有限&#xff0c;招人也很困难&#xff0c;不仅要面试程序员&#xff0c;后续还要检验这个程序员的功力&#xff0c;实在是太…

谷歌浏览器

引言&#xff1a;众所周知&#xff0c;一个好的浏览器可以提高我们的工作效率&#xff0c;那么今天教大家如何安装超 nice 的浏览器 —— 谷歌浏览器 文章目录一、安装谷歌浏览器二、修改谷歌浏览器搜索引擎三、修改谷歌浏览器默认下载位置一、安装谷歌浏览器 打开&#x1f5b…

GJB 5000B二级-II实施基础

本实践域为新增实践域   思想:以GJB5000A的共用过程域中不乏实践为基础进行提炼并提升,结合各个行业的优秀实践和行业特点,坚持问题导向,使标准更具有指导性和可操作性;充分借鉴GJB9001C中:“4组织环境”、“7支持”的相关内容,形成实施基础实践域。本实践域强调突出重…

0111 栈与队列Day1

剑指offer09.用两个栈实现队列 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#x…