针对FFMPEG6在HEVC解码时内存占用的优化

低成本方案往往在对客户需求实现时的技术方面的难点,会让人掉光头发。 这里是基于FFMPEG 6.1版本的改动,也顺带优化了264的占用,在分辨率288×352,FPS30 / GOP 60的情况下内存占用由默认的21~25MB降至6~9MB。特此记录分享。 diff –git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index 46925e09ef..c682bf2fb1 100644 — a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -239,7 +239,9 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup) if (err < 0) av_log(avctx, AV_LOG_ERROR, “hardware … “针对FFMPEG6在HEVC解码时内存占用的优化”

Read More

君正T41平台的FFMPEG 6的构建参数调优

多年来主流的多媒体处理平台就俩,ARM以及X86。ARM因为IOS和Android的缘故被FFMPEG这此平台频繁迭代优化,而MIPS都离开Android多少年了,可想而知FFMPEG对于MIPS平台的优化有多缺。 并且君正在T41系列上并没有支持MIPS标准的MSA指令,所以毫不意外,用默认参数编译的FFMPEG库在T41NQ用君正推荐的主频跑,这种软解码下,288*352分辨率下的H265仅能解码到23帧。 周末研究了大半天MIPS平台相关的编译参数以及FFMPEG 6版本相关的编译选项,终于是找到一组能提升到30帧的解码能力的编译参数,特此分享。 后续能改进的地方应该是对FFMPEG添加君正芯片的MXU指令集支持,这就是水磨功夫了。 ./configure –arch=mips –cpu=mips32r5 \ –cc=${CMAKE_C_COMPILER} \ –ar=${CMAKE_C_COMPILER_AR} \ –cxx=${CMAKE_CXX_COMPILER} \ –strip=${CMAKE_STRIP} \ –sysroot=${CMAKE_SYSROOT} \ –prefix=${PROJECT_BINARY_DIR}/ffmpeg-install \ –disable-all –disable-asm –disable-inline-asm –disable-demuxers \ –disable-ffmpeg –disable-ffprobe –disable-ffplay –disable-symver \ –disable-doc –disable-htmlpages –disable-manpages –disable-podpages … “君正T41平台的FFMPEG 6的构建参数调优”

Read More

君正T41平台下LVGL 8的FB刷新推送改为异步模式

没想到君正T41平台给的kernel用 SPI 屏幕刷新的时候,即便是双FrameBuffer的模式,依旧存在撕裂,并且LVGL在调用ioctl去刷新屏幕时的接口居然是阻塞的,真的是万万没想到。 本来在跑业务时,CPU资源被抢占,解码能力就差,再来君正的垃圾kernel和LVGL这么搞两下,真心累。 没办法,问题还是要解决的,只能给LVGL 8的lv_drivers仓库的fbdev.c里相关的接口改造了下,改成异步推送模式:当有刷新请求过来时若发现FB的数据还未推送完毕,则不再等待,放弃当前刷新请求,直接开始下一次渲染。 特此记录,分享。 diff –git a/display/fbdev.c b/display/fbdev.c index f649703..86e970a 100644 — a/display/fbdev.c +++ b/display/fbdev.c @@ -16,6 +16,7 @@ #include <fcntl.h> #include <sys/mman.h> #include <sys/ioctl.h> +#include <sys/prctl.h> #if USE_BSD_FBDEV #include <sys/fcntl.h> @@ … “君正T41平台下LVGL 8的FB刷新推送改为异步模式”

Read More

LVGL简单模拟Android的页面栈跳转与返回

给带屏产品做UI交互,因为平台资源有限所以就选了LVGL。 简单使用了下,发现这玩意缺失一个现代UI开发最关键的功能,即页面栈;搜了下,居然都没人提过,有些诧异。 就像我们日常用的Android与IOS,打开app后首页进入,然后可以点击某按钮进入下一级页面,按返回键则返回上一级页面并将当前页面销毁,其实就是模拟栈功能。 于是为了后续开发方便,我在LVGL 8.3的版本上简单实现了此功能。 首先定义一个队列,用于存放页面栈的入栈队列,队列直接用kernel里的<queue.h>头文件。 #include <queue.h> typedef void (*ui_action_hdl_t)(lv_obj_t *src_obj, void *user_data); #define act_id int ///< 页面 id struct ui_action_node_t { act_id id;///< 页面ID,单调递增 ui_action_hdl_t hdl; ///< 页面的回调函数句柄 struct timespec create; ///< 页面创建时间 … “LVGL简单模拟Android的页面栈跳转与返回”

Read More

使用CMake拉取gSoap并生成Onvif依赖的模板代码

Onvif这种带有早期浓烈Java语言处理风格的XML格式的协议,在嵌入式解析起来很不方便,但没办法,它已经成为主流了。 网上有很多写基于gSoap工具生成Onvif库的方式,大多都是属于下载后直接把生成的库添加到代码的,其实不优雅,因为这是基于在线协议用工具生成的模板代码,毫无意义,还不如添加协议文件。 我这里直接用CMake的FetchContent模块来实现自动下载库,唯一的前提是需要安装代码生成工具soapcpp2与wsdl2h。 下载gSoap。 include(FetchContent) FetchContent_Declare(gsoap URL https://sourceforge.net/projects/gsoap2/files/gsoap_2.8.125.zip DOWNLOAD_EXTRACT_TIMESTAMP false TIMEOUT 240 OVERRIDE_FIND_PACKAGE ) FetchContent_MakeAvailable(gsoap) set(gsoap_PREFIX ${gsoap_SOURCE_DIR}/gsoap) message(STATUS “gsoap prefix –: ${gsoap_PREFIX} “) find_program(GSOAP_SOAPCPP2 NAMES soapcpp2 HINTS ${gsoap_PREFIX}/src REQUIRED DOC “The gsoap bin directory for … “使用CMake拉取gSoap并生成Onvif依赖的模板代码”

Read More

使用mdbook提供在线接口文档并支持导出PDF

在给客户实现API使用文档的时候,想到了以下问题。 以往在拿到SDK,里面都会由使用文档,按传统的做法一般是Word或PDF文档,当有新版本的时候,里面的文档也是一同更新。 这里就会有个痛点,即文档的变更管控其实并不直观,即便你提交的了文档到仓库但git其实并不能识别除基础文本外的格式,也就会当作二进制文件处理,并不能用git diff处理。 并且客户拿到新文档后,对于新变更的地方也不明确,往往需要再次通读;甚至有的客户仅拿到了新版SDK却没同步收到对应的新版文档。 这种传统的方式对提供方和接收方都不友好,甚至无形中增加了对接的门槛。 所以现在出现了不少工具解决这些问题,其中较为优秀的如Swagger/ApiDocs/Doxygen等,这些工具几乎都能支持目前较为流行的编程语言,以注释的形式能做到代码既文档,支持导出传统的文件,方便管控。 但如果是老项目且规模较大,那引入这种工具就非常耗费时间,且改造难度高;如果要引入到现有项目则通常是项目规模较小或者项目重构的时候比较合适。 所以还是得手写,而我又偏好在线形式的文档,因此决定使用gitbook或mdbook生成在线文档后,再使用插件将其导出为PDF,这样客户拿到SDK后不用担心文档丢失或者过时,还能查看文档的变更记录,直观看出新老版本的变动差异,甚好。 gitbook的离线生成是基于nodejs装环境且官方已经放弃维护,所以我用的mdbook,不过提交到GitHub后在线生成的文档是白嫖gitbook的服务。 导出PDF的插件用的是mdbook-pdf。 不过由于使用了gitbook的在线服务,我这用的是gitbook2pdf这个工具,具体安装使用说明放到我们项目的公开文档里了。

Read More

Go中crypto包的AES加解密使用备忘

因为MES需要对接公司内部一些其他服务的接口,其中对接的几个服务接口要求交互的数据使用AES加密,因此备忘下go中AES算法相关接口的使用. 已同步到gist package main import ( “bytes” “crypto/aes” “crypto/cipher” “crypto/rand” “encoding/base64” “encoding/hex” “io” “io/ioutil” “log” ) func main() { origData := []byte(“jiamisuanface12345sdfasdfasdf1a1”) // data to be encrypted ioutil.WriteFile(“aa”, origData, 0600) key := []byte{0xa0, 0xb0, 0x01, … “Go中crypto包的AES加解密使用备忘”

Read More

Arm平台的Docker运行要求

公司其他部门要求在搭载公司自研PU的ARM设备上运行要Docker,让我们BSP这边提供支持,其他组员不常接触Docker于是便由我这边来处理。查阅一番网上的资料后简单记录一下。 Docker服务对于运行系统的要求颇为简单,仅特别要求64位的系统,Kernel不低于3.10,有iptables且内核启用cgroup;其他便是常用的ps与xz等常用命令工具以及内核中文件系统与网络模块的支持如IPVS与Netfilter等特性。 而官方也早就提供了一键检测脚本,下载后用管理员权限运行即可导出当前系统下已支持与未支持的具体项,然后在构建kernel的配置文件中逐一开启未支持的项即可,如: CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_KMEM=y CONFIG_CGROUPS=y CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_WRITEBACK=y CONFIG_BLK_CGROUP=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_FAIR_GROUP_SCHED=y … … … … 然后是在Kernel引导命令cmdline中指定开启对应特性,如cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1等。

Read More

DinD模式的GitLab Runner自动化构建

去年底开始实现自研的MES系统,开发语言基于Go。Go自带完善的单元测试支持,非常契合目前流行自动化的构建与测试系统。 公司的代码库基于GitLab,且支持了完全功能的CI/CD,因此去官网研究了一番GitLab的CI/CD与Runner相关的文档后,实现了一套目前使用较为便捷的方案,故记录分享。 配置 Runner 公司的GitLab服务其实已经接入了K8S的Runner集群,但由于项目是要将服务打包成Docker Image且为了避免对物理机器的环境依赖,我选择了使用Docker方式的持久化Runner,具体操作如下。 新建一个Group,项目相关的repo应该放在该Group内。 在此Group的Settings内CI/CD配置页获取当前Group Runners的准入token,执行gitlab-runner register指令获取自动生成的config.toml,然后编写Runner的config.toml配置。 config.toml示例如下: # 具体项说明参考官方指导 https://docs.gitlab.com/runner/configuration/advanced-configuration/ concurrent = 3 [[runners]] name = “your-runner-name” url = “https://your.gitlab.address/” # register时自动生成的token,不是CI/CD页面的那个 token = “your-group-token” executor = “docker” [runners.docker] tls_verify = … “DinD模式的GitLab Runner自动化构建”

Read More

OpenWrt 19.07构建速度优化

长时间在基于OpenWrt 19.07版本上开发我们项目的固件,一些设备固件全量编译近十分钟,但一些项目设备的固件可以到二十多分钟,虽然整体的增量编译仅需三四分钟,但我们固件发布时的构建默认走全量编译,因此探索了一番,发现了点可以加速构建的地方,记录分享。 完善全核并行构建时,某些项目因依赖未写全而导致的编译报错。这是最关键的一点。 改为默认利用全核并行构建(这条可有可无,默认给的参数就是全核并行),修改include/host-build.mk文件: — a/include/package.mk +++ b/include/package.mk @@ -22,7 +22,8 @@ MAKE_J:=$(if $(MAKE_JOBSERVER),$(MAKE_JOBSERVER) $(if $(filter 3.% 4.0 4.1,$(MAK ifeq ($(strip $(PKG_BUILD_PARALLEL)),0) -PKG_JOBS?=-j1 +PKG_JOBS?=-j$(shell grep ^processor /proc/cpuinfo | wc -l) else -PKG_JOBS?=$(if $(PKG_BUILD_PARALLEL),$(MAKE_J),-j1) +ALL_CORES?=-j$(shell grep … “OpenWrt 19.07构建速度优化”

Read More