行车记录仪 - 录像 - 文件缓存

news/2025/2/11 19:28:39/

背景

  • 基于ffmpeg实现录像功能,性能不理想,前后路摄像头视频码率相加只有28Mbps加上音频也只有4MB/s左右,使用class 10的sd卡 + 2秒 ringbuffer缓存的情况下,依然出现写卡不及时导致的丢帧现象,class 4 sd卡表现更差。

分析

  • 使用dd命令测试class 10 SD卡在该平台上的读写速度,写速度能达到7~8MB/s,因此丢帧问题不是SD卡写性能不足导致的,是录像逻辑的问题。
  • 通过测试定位到ffmpeg接口av_write_frame(写一帧数据)耗时异常,异常部分log如下:
01-01 00:01:13.064   139   310 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE/2022_01_01_000059_00.MOV]: av_write_frame take [19] ms
01-01 00:01:13.067   139   313 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/2022_01_01_000059_00_b.MOV]: av_write_frame take [23] ms
01-01 00:01:13.170   139   313 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/2022_01_01_000059_00_b.MOV]: av_write_frame take [102] ms
01-01 00:01:13.185   139   310 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE/2022_01_01_000059_00.MOV]: av_write_frame take [119] ms
01-01 00:01:13.187   139   313 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/2022_01_01_000059_00_b.MOV]: av_write_frame take [16] ms
01-01 00:01:13.190   139   310 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE/2022_01_01_000059_00.MOV]: av_write_frame take [4] ms
01-01 00:01:13.194   139   313 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/2022_01_01_000059_00_b.MOV]: av_write_frame take [6] ms
....
01-01 00:18:57.202   139   479 I write_packet@CviMuxer.cpp:577 [/mnt/sd/CARDV/MOVIE_b/2022_01_01_001833_00_b.MOV]: av_write_frame take [2249] ms
  • 异常现象总结
  1. av_write_frame耗时不稳定,普遍耗时几毫秒,和预期缓存未满时写缓存(内存拷贝)耗时较少不符。
  2. 间隔性出现耗时100ms以上,时常出现200、300,甚至500ms以上,偶尔出现耗时1s ~ 2s,一帧I帧视频数据才100KB~200KB,耗时完全不符合预期。

ffmpeg 实现

  • ffmpeg录像写文件操作的代码(libavformat/file.c)是调用的open,write,read,seek等系统接口,使用open接口打开文件是没有应用层缓存,因此需要ffmpeg自己实现缓存机制,在file_open中可以设置URLContext 的min_packet_size和max_packet_size来定义缓存大小,代码(libavformat/aviobuf.c)会根据定义的缓存大小申请内存创建缓存,av_write_frame时会先将数据写入该缓存,缓存满了或者主动调用avio_flush接口会调用write接口将缓存数据传递给linux内核。

文件缓存

  • 定义一定大小的文件缓存可以减少系统接口write的调用频率,以及内存拷贝的次数,以提高性能。
  1. 缓存大小需要是内存页,文件系统块(Block),文件系统IO操作块(IO Block)大小的整倍数,以避免跨页操作
  • 系统读写SD卡都是以块为单位,而不是一个字节一个字节的读写,因此缓存大小如果出现不满一块的余量,系统也要将一整块写入sd卡,并且为了保证存储数据的正确性,系统需要先从sd卡读取出该块中缓存未覆盖到的数据,补充到写入数据中,浪费了一定的性能。
  • 不同文件系统或者同一个文件系统,不同SD卡的IO Block也可能不同,需要注意:
[root]/mnt/usb# stat xxx File: xxxSize: 49        	Blocks: 128        IO Block: 65536  regular file
...
[root]/mnt/usb# stat b.txt File: b.txtSize: 6         	Blocks: 64         IO Block: 32768  regular file
...
# stat testfile              File: `testfile'Size: 102             Blocks: 8          IO Block: 4096   regular file
...
  1. 缓存大小需要根据实际情况进行调整
  • 同步IO情况下,缓存大小也会造成一定的性能影响,需要参考数据量,写文件间隔等因素,例如:视频25fps,写文件间隔40ms,缓存的数据最好保证在40ms内传递给linux内核,耗时多了会阻塞下一帧,一些嵌入式平台会影响帧率,耗时少了会增加write的调用次数。

异常原因

  • 现有代码设置了的ffmpeg缓存大小为32KB,理论上不应该出现问题。
  • 分析自有代码和ffmpeg源码可知上面的异常现象中的间隔性耗时过长应该是缓存满了调用write导致的,av_write_frame普遍耗时几毫秒以及偶发性耗时过长是录像逻辑破坏了缓存机制出现。
  • 缓存机制被破坏
  1. 为满足其它功能,我们修改了ffmpeg源码,在一些条件下会做seek和write操作,这种情况下就会导致缓存机制被破坏。
  2. MOV,MP4文件有固定的头部数据 ftyp 和wide box 再加上mdat box 的HEAD一共36个字节,ffmpeg写完这部分数据后会主动调用avio_flush 先将这部分数据写入SD卡,后续再按缓存大小写数据,虽然写的数据大小是满足块的整倍数,但是已经发生错位和跨页。
源码:libavformat/movenc.c
@@ -6744,7 +6744,7 @@ static int mov_write_header(AVFormatContext *s)}}....avio_flush(pb); //需要注释掉if (mov->flags & FF_MOV_FLAG_ISML)mov_write_isml_manifest(pb, mov, s);...    

修复结果

  • 修复完后测试结果
01-01 08:03:54.641   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [4] ms
01-01 08:03:54.641   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.641   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.641   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.641   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.642   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.642   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.642   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.644   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [1] ms
01-01 08:03:54.644   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.644   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.644   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
01-01 08:03:54.644   139   329 I write_packet@CviMuxer.cpp:575 [/mnt/sd/CARDV/MOVIE_b/1970_01_01_080317_00_b.MOV]: av_write_frame take [0] ms
  • 大部分情况下av_write_frame耗时1ms以下,缓存满时耗时会稍微多点,最高时也不超过20ms。

http://www.ppmy.cn/news/155587.html

相关文章

车载USB DVR(行车记录仪)的源码架构浅析(基于AndroiidM)

基于AndroiidM的USB DVR的源码架构浅析,主要讲述大概流程,以便于分析问题。 APP层 源码路径: AndroidM/vendor/mediatek/proprietary/packages/apps/DVR 主要 DVR操作的两个类 FrontView.java 和 MainActivity.java 1、 FrontView 继承了…

破旧手机改造系列:最牛逼的行车记录仪

又是一篇废旧手机改造系列!最近刚提新车,所以这次我准备把一台不用的手机改造成一台功能超级强大的行车记录仪。你肯定会说,“简单!手机本身就有录像功能,直接打开就是喽“。这样也太low了,而且几乎不具备实…

车载、行车记录仪产品知识汇集

[DESCRIPTION] 经常碰到蓝牙耳机和蓝牙车载(Carkit)问题,蓝牙车载和蓝牙耳机有什么区别? [SOLUTION] 蓝牙耳机:市面上,双声道蓝牙耳机大多数支持HFP(手机音频) 和 A2dp(媒体音频) 和AVRCP(音/视频控制)这三个Profile; …

行车记录仪数据删除如何恢复?

10月,公安部交通管理局权威发布,截至2018年9月,全国机动车保有量达3.22亿辆;机动车驾驶人达4.03亿人。随着机动车和驾驶人数量的增加,交通事故和机动车交通事故责任纠纷案件也在逐年上涨。 部分案件常常因没有目击证人…

画质超清晰的行车记录仪,配置确实很强,盯盯拍Z50上手

行车记录仪是很多车友的必需品,不过和爱车不同,行车记录仪的升级速度很快,早期只要有480P的分辨率就算高清了,如今已经很容易找到有着4K分辨率,还支持语音操作的行车记录仪了,像是我上周新装的这款盯盯拍Z5…

最全行车记录仪方案+主控芯片介绍!

最近在关注行车记录仪,了解了之后 写此文章想让车友们知道什么是行车记录仪的高端标准,什么是好货,因为大部分人都不知道。 看到很多朋友在问,什么是行车记录仪的方案,行车记录仪的主控究竟有什么区别,我该…

汽车行驶记录仪

汽车行驶记录仪(zz) shepherd 发表于 2005-1-7 9:02:00 发信人: sataco (贞 Ashes of Time), 信区: AutoTech标 题: 汽车行驶记录仪(zz)发信站: BBS 水木清华站 (Fri Dec 24 20:18:52 2004), 站内汽车行驶记录仪中国汽车技术研究中心 杜启峰 龚进峰--------------------------…

行车记录仪流量卡你了解吗?

随着人们的生活水平逐渐提高,有车一族也越来越多,而交通安全、碰瓷党也屡见不鲜,如果每辆车都安装行车记录仪,能够记录汽车行驶全过程的视频图像和声音,可为交通事故提供证据,行车记录仪就尤为重要。而记录…