行车记录仪 - 录像 - ffmpeg AVPacket 复用
背景
基于ffmpeg实现录像功能,性能不理想,分析现有流程发现:写每一帧数据都需要生成一个AVPacket变量传递给av_write_frame,流程如下:
av_new_packet函数申请一定大小的内存空间存储媒体数据,av_write_frame执行完后,需要使用av_packet_free释放AVPacket内存空间,在行车记录仪产品大码率(16Mbps),较高帧率(25fps ~ 30fps),长时间持续不断录制的环境下,该循环操作对性能的影响不容忽视,生成AVPacket实测耗时如下:
01-01 08:02:13.393 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [0] ms
01-01 08:02:13.460 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [52] ms
01-01 08:02:13.494 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [2] ms
01-01 08:02:13.503 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [3] ms
01-01 08:02:13.533 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [0] ms
01-01 08:02:13.564 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [2] ms
01-01 08:02:13.571 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [2] ms
01-01 08:02:13.608 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [18] ms
01-01 08:02:13.648 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [8] ms
01-01 08:02:13.978 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [0] ms
01-01 08:02:14.014 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [15] ms
01-01 08:02:14.045 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [12] ms
01-01 08:02:14.060 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [6] ms
01-01 08:02:14.085 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [0] ms
01-01 08:02:14.111 230 478 I get_packet@CviMuxer.cpp:294 [/mnt/sd/CARDV/MOVIE/1970_01_01_080135_00.MOV]: get_packet take [15] ms
- 实测耗时波动较大,最多时耗时200~300ms,优化措施:AVPacket 复用。
AVPacket 复用
先通过av_packet_alloc创建一个AVPacket,后续重复使用该AVPacket,写每一帧数据流程:
AVPacket操作相关接口实现在:libavcodec/avpacket.c中,AVPacket所需内存空间的申请和扩大都封装在相关函数中,APP只需将size传递进去就可以了。
修改后实测耗时几乎所有都是1ms以下,只有非常小概率会超出1ms,如下:
01-01 08:00:36.497 237 462 I get_packet@CviMuxer.cpp:308 [/mnt/sd/CARDV/MOVIE/1970_01_01_080022_00.MOV]: get_packet take [0] ms
....
data内存复用
- AVPacket变量以及内存空间可以复用,但是写每一帧都需要将数据memcpy到AVPacket变量的data内存空间中,当数据量较大时memcpy的耗时也会比较明显,可以通过以下函数减少memcpy的使用次数:
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
- av_packet_from_data函数将参数data指针直接赋值给AVPacket的data指针,不需要做内存拷贝,但是释放AVPacket时av_buffer_unref会释放data指向的内存空间,因此存在一些约束。
行车记录仪 - 录像 - ffmpeg AVPacket 复用相关推荐
- [FFmpeg] AVPacket 的使用记录(初始化、引用、解引用、释放)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.先看下与AVPacket相关的几个重要函数 1.AVPacket *av_packet_alloc(void) 2 ...
- ffmpeg解复用编解码 常用API大全给出详细中文解释
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); 将你给出的条目设置进入你给到的 p ...
- FFMpeg AVPacket 之理解与掌握
---------------------------------------- author:hjjdebug date: 2022-01-23 -------------------------- ...
- 行车记录仪 - 录像 - 文件缓存
背景 基于ffmpeg实现录像功能,性能不理想,前后路摄像头视频码率相加只有28Mbps加上音频也只有4MB/s左右,使用class 10的sd卡 + 2秒 ringbuffer缓存的情况下,依然出现 ...
- FFmpeg AVPacket 剖析以及使用
文章目录 知识准备 重要结构体成员分析 释疑 函数说明 av_init_packet av_packet_unref av_packet_alloc av_packet_free av_packet_ ...
- go 接收 ffmpeg avpacket
c++部分: typedef int(*ByteFunc)(unsigned char*, int); MYLIBDLL int byte_url(char* url, ByteFunc tcallb ...
- ffmpeg - AVPacket内存问题分析(AVFrame一样的)
目录: 1.av_packet_alloc()和av_packet_free() 2.av_init_packet()的问题 3.av_packet_move_ref()的问题 4.av_packet ...
- FFmpeg AVPacket和av_packet_unref函数剖析
描述 AVPacket保存一个NAL单元的解码前数据,该结构本身不直接包含数据,其有一个指向数据域的指针.传递给avcodec_send_packet函数的AVPacket结构体data中的数据前面是 ...
- 【Android FFMPEG 开发】FFMPEG 解码 AVPacket 数据到 AVFrame ( AVPacket-解码器 | 初始化 AVFrame | 解码为 AVFrame 数据 )
文章目录 I . FFMPEG 解码 AVPacket 数据到 AVFrame 前置操作 II . FFMPEG 解码 AVPacket 数据到 AVFrame 流程 III . FFMPEG 发送 ...
最新文章
- Android 获取标题栏的高度
- 15-07-05 语句-跳转语句异常语句
- 需要熟悉的几个调试命令:objdump/pmap/ldd/stace
- android init(system/core/init/init.c)分析
- 2020年第十一届蓝桥杯 - 国赛 - Python大学组 - G.重复字符串
- mysql操作语句now_【MySQL数据库开发之二】MySQL 基础语句的书写与操作!
- 使用tr1的bind函数模板
- php把字符串变成多组,php把字符串变成数组(有分隔符)
- if(!!boolean)两次取反
- Android Ble蓝牙中如何获取RawData ,UUID,Major,Minor,Measured power at 1 meter的数据。
- mocano editor中使用代码比对功能
- python布尔值print_python中的用户输入布尔值
- 部署项目 Failure obtaining db row lock: Table ‘XXX.qrtz_LOCKS‘ doesn‘t exist
- Ubuntu16.04安装x11vnc服务并设置自动启动
- 真正的人品,藏在对弱者的态度里
- mycat连接数据库8.0以上 处理程序连接query_cache_size报错信息 mycat升级数据库踩坑
- EasyNVR查看直播视频流显示黑屏原因排查
- 移动新魔百盒M411A_905L3_5621_语音免拆_卡刷固件包
- [享学Eureka] 一、源生Eureka介绍 --- 基于注册中心的服务发现
- 病毒式营销活动策划书