背景

  • 基于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 复用相关推荐

  1. [FFmpeg] AVPacket 的使用记录(初始化、引用、解引用、释放)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.先看下与AVPacket相关的几个重要函数 1.AVPacket *av_packet_alloc(void) 2 ...

  2. ffmpeg解复用编解码 常用API大全给出详细中文解释

    int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); 将你给出的条目设置进入你给到的 p ...

  3. FFMpeg AVPacket 之理解与掌握

    ---------------------------------------- author:hjjdebug date: 2022-01-23 -------------------------- ...

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

    背景 基于ffmpeg实现录像功能,性能不理想,前后路摄像头视频码率相加只有28Mbps加上音频也只有4MB/s左右,使用class 10的sd卡 + 2秒 ringbuffer缓存的情况下,依然出现 ...

  5. FFmpeg AVPacket 剖析以及使用

    文章目录 知识准备 重要结构体成员分析 释疑 函数说明 av_init_packet av_packet_unref av_packet_alloc av_packet_free av_packet_ ...

  6. go 接收 ffmpeg avpacket

    c++部分: typedef int(*ByteFunc)(unsigned char*, int); MYLIBDLL int byte_url(char* url, ByteFunc tcallb ...

  7. ffmpeg - AVPacket内存问题分析(AVFrame一样的)

    目录: 1.av_packet_alloc()和av_packet_free() 2.av_init_packet()的问题 3.av_packet_move_ref()的问题 4.av_packet ...

  8. FFmpeg AVPacket和av_packet_unref函数剖析

    描述 AVPacket保存一个NAL单元的解码前数据,该结构本身不直接包含数据,其有一个指向数据域的指针.传递给avcodec_send_packet函数的AVPacket结构体data中的数据前面是 ...

  9. 【Android FFMPEG 开发】FFMPEG 解码 AVPacket 数据到 AVFrame ( AVPacket-解码器 | 初始化 AVFrame | 解码为 AVFrame 数据 )

    文章目录 I . FFMPEG 解码 AVPacket 数据到 AVFrame 前置操作 II . FFMPEG 解码 AVPacket 数据到 AVFrame 流程 III . FFMPEG 发送 ...

最新文章

  1. Android 获取标题栏的高度
  2. 15-07-05 语句-跳转语句异常语句
  3. 需要熟悉的几个调试命令:objdump/pmap/ldd/stace
  4. android init(system/core/init/init.c)分析
  5. 2020年第十一届蓝桥杯 - 国赛 - Python大学组 - G.重复字符串
  6. mysql操作语句now_【MySQL数据库开发之二】MySQL 基础语句的书写与操作!
  7. 使用tr1的bind函数模板
  8. php把字符串变成多组,php把字符串变成数组(有分隔符)
  9. if(!!boolean)两次取反
  10. Android Ble蓝牙中如何获取RawData ,UUID,Major,Minor,Measured power at 1 meter的数据。
  11. mocano editor中使用代码比对功能
  12. python布尔值print_python中的用户输入布尔值
  13. 部署项目 Failure obtaining db row lock: Table ‘XXX.qrtz_LOCKS‘ doesn‘t exist
  14. Ubuntu16.04安装x11vnc服务并设置自动启动
  15. 真正的人品,藏在对弱者的态度里
  16. mycat连接数据库8.0以上 处理程序连接query_cache_size报错信息 mycat升级数据库踩坑
  17. EasyNVR查看直播视频流显示黑屏原因排查
  18. 移动新魔百盒M411A_905L3_5621_语音免拆_卡刷固件包
  19. [享学Eureka] 一、源生Eureka介绍 --- 基于注册中心的服务发现
  20. 病毒式营销活动策划书

热门文章

  1. c语言---编写程序找出1000以内的完数
  2. 什么是ZooKeeper?
  3. 如何做好售后服务,减少成本,增加收入
  4. 函数 获得所有英文字母
  5. 天翼杯 web APITest
  6. dede自动排版 php,DedeCMS正文自动一键排版插件,伪原创必备
  7. Category详解
  8. MDI窗体和窗体之间的操作总结
  9. 【TARS】压测工具TarsBenchmark
  10. Elliptic Labs和小米联手打造旗舰智能手机小米Mi 11