FFMPEG 编码解码独立功能 替代硬件板卡模块记录

9 篇文章 0 订阅

之前公司用的编解码用的是硬件模块 有寒武纪 海康 还有华为的等等,程序调用的是统一的接口 ,因为不用的硬件厂商的API不一样,所以需要做一层抽象封装,这样程序调用的时候可以不用关注到底是哪个硬件。

然后有一个需求 不用硬件板卡 直接用FFMPEG 借助CPU来进行编解码。差不多一周时间实现了记录下 支持WINDOWS  也支持 LINUX:

哦对了 其实是有两个模块 ,

一个是FFMPEG 拉RTSP的流

另一个是FFMPEG 编解码 两个独立 可以单独调用 也可以两个一起用。

先看下文件结构

ICodec.h是 统一调用接口的抽象接口定义 如下 后面程序调用的都是这个接口

然后这个create_codec 和destroy_codec 是创建和销毁ICodec的另一层封装。

 下面来看一下FFMPEG 类的定义

 

继承了基类,然后需要实现基类的虚函数,这也是程序调用的接口

下面是一些内部的私有函数 看名字 就知道意思了

 m_decoder 和 m_encoder 分辨定义解码和编码需要的一些参数

解码的结构体定义如下:

 编码的结构体定义如下:

 不同的操作系统  系统调用的API 不一样 做了区分

m_configInfo 是程序调用的时候传进来的一些编码配置信息(分辨率 码率 等等) 以及编码之后的回调函数 如下图:

 

先看一下程序如何调用的,如下图:

 pFFCodec就是定义的一个ICodec * 指针变量 需要先通过create_codec new 一个对象

之后需要调用init方法 传入的info就是一个configinfo的结构

start之后  没有异常的话就会开始编解码了

通过feed_frame_data 给编解码模块喂数据 就是ffmpeg 拉RTSP 拉出来的H264或者H265裸流

 

销毁的部分如下:

 下面看下代码  create和 destroy很简单 没啥 需要解释的 如下:new 和delete对象

接下来看下实际的实现部分 定义了一个静态变量m_instance 用来记录 编码器的实际创建数量

cpp文件中这个静态变量需要 声明一下 不然 link的时候会报错 我的环境是vs2022

接下来  初始化部分  需要添加一个解码器 一个编码器 

实际上 我们是如果好几路RTSP流是相同的话,只是编出来不同的分辨率 Decoder解码器的部分是可以复用的,也就是一路Decoder对应多路Encoder

但是由于之前我们程序已经成型了 没办法 修改,所以这里 就不能复用了,这里直接一路Decoder对应一路Encoder 

 Init成功之后就是Start了 Start很简单 分别开启解码线程,编码线程 不同的操作系统做了区分

 decode_thread函数主要做的事就是 从解码队列里不断读取feed的raw packet 然后 解码成功之后通过decode_cb回调送入编码队列,实际过程中 feed data的时候的packet是没有pts信息的 ,这里解码的时候需要自己给packet打pts 否则ffmepg解码会有问题 ,这个pts要根据实际的fps 来打 如果25帧就是90000/25*packetcounter++   我没这么做 ,因为 传进来的时候不知道fps是多少

而是取了系统的实时time。这里就不贴出来  给自己留点干货

 看下decode_cb就是 把数据送入队列的操作

解码出来的是AVFrame的数据 这里需要注意下 

 另外之前说的 如果一个解码器对应多个编码器的话 这里 把数据送队列的时候 就用一个for循环 分别送入不用的编码器队列就可以了

接下来是编码线程 

编码线程做的事主要就是从刚刚编码队列中取出 刚刚解码送进来的数据 然后 判断下

编码分辨率是否和源分辨率一样 不一样的话需要调用sws_scale进行yuv图像的缩放

之后调用ffmpeg的api  编码   编码之后将编码出来的rawpacket数据送入回调函数中

至此 大概流程就走完了,

 总的来说 并不是很复杂,这里不涉及到对yuv数据的具体操作,api都帮我们做好了

目前测试没遇到啥问题,后期测试yuv有很多种格式,可能部分格式需要具体处理 ,暂时不需要

实际开发中遇到个问题,如下 下面三行被我注释掉了,不然 会异常  还没时间查为什么,

注释掉,一般也够用了 。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QMCY_jason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值