javaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操作?

JavaCV入门指南系列:

JavaCV入门指南:序章(看完本章后,不想看原理的小伙伴可直接跳转到《快速上手篇》)

JavaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操作

JavaCV入门指南:调用opencv原生API和JavaCV是如何封装了opencv的图像处理操作

JavaCV入门指南:帧抓取器(FrameGrabber)的原理与应用

JavaCV入门指南:帧录制器/推流器(FrameRecorder)的原理与应用

JavaCV入门指南:帧过滤器(FrameFilter)的原理与应用

JavaCV入门指南:FrameConverter转换工具类及CanvasFrame图像预览工具类

《快速上手篇》(为了区别,单独划分):

JavaCV入门指南之快速上手篇:快速上手视频拉流、推流、录制文件、录屏、截图和编解码复用解复用等常用音视频处理操作

通过“javaCV入门指南:序章 ”大家知道了处理音视频流媒体的前置基本知识,基本知识包含了像素格式、编解码格式、封装格式、网络协议以及一些音视频专业名词,专业名词不会赘述,自行搜索即可。

本章将正式开始javaCV之旅,还没听说过JavaCV得可以先看一下官方文档里的介绍https://github.com/bytedeco/javacpp。

通过github得项目地址可以知道javaCV封装了这么多库,也不啰嗦了,直接开始吧。

一、什么是JavaCPP

大家知道FFmpeg是C语言中著名的音视频库(注意,不是c++。使用c++调用ffmpeg库的性能损失与Java方式调用损耗相差并不大)。

JavaCV利用JavaCPP在FFmpeg和Java之间构建了桥梁,我们通过这个桥梁可以方便的调用FFmpeg,当然这并不是没有损失的,性能损失暂且不提,最主要问题在于调用ffmpeg之于jvm是native方法,所以通过ffmpeg创建的结构体实例与常量、方法等等都是使用堆外内存,都需要像C那样手动的释放这些资源(jvm并不会帮你回收这部分),以此来保证不会发生内存溢出/泄露等风险。

Javapp在Java内部提供了对本地C++的高效访问,这与一些C/C++编译器与汇编语言交互的方式不同。不需要发明新的语言,比如SWIG、SIP、C++、CLI、Cython或Rython。相反,类似于CPpyy为Python所做的努力,它利用了Java和C++之间的语法和语义相似性。因为使用JNI,因此除了RoboVM之外,它还适用于Java SE的所有实现

二、javaCPP直接调用FFmpeg的API

我们通过《视频拉流解码成YUVJ420P,并保存为jpg图片》作为实例来阐述,实例地址:

javacpp-FFmpeg系列之1:视频拉流解码成YUVJ420P,并保存为jpg图片_eguid-CSDN博客_ffmpeg yuvj420p

这部分内容主要是如何调用FFmpeg的API,本系列作为JavaCV入门不会讲解FFmpeg的具体用法,如果想要深入学习FFmpeg部分,可以选择通过查看FFmpeg的API手册ffmpeg.org,或者访问雷霄骅的博客详细学习FFmpeg的使用。

三、JavaCV是如何封装了FFmpeg的音视频操作?

JavaCV通过JavaCPP调用了FFmpeg,并且对FFmpeg复杂的操作进行了封装,把视频处理分成了两大类:“帧抓取器”(FrameGrabber)和“帧录制器”(又叫“帧推流器”,FrameRecorder)以及用于存放音视频帧的Frame(FrameFilter暂且不提)。

整体结构如下:

视频源---->帧抓取器(FrameGabber) ---->抓取视频帧(Frame)---->帧录制器(FrameRecorder)---->推流/录制---->流媒体服务/录像文件

1、帧抓取器(FrameGrabber)

封装了FFmpeg的检索流信息,自动猜测视频解码格式,音视频解码等具体API,并把解码完的像素数据(可配置像素格式)或音频数据保存到Frame中返回。

帧抓取器详细剖析:帧抓取器(FrameGrabber)的原理与应用

2、帧录制器/推流器(FrameRecorder)

封装了FFmpeg的音视频编码操作和封装操作,把传参过来的Frame中的数据取出并进行编码、封装、发送等操作流程。

帧录制器/推流器详细剖析:帧录制器/推流器(FrameRecorder)的原理与应用

3、过滤器(FrameFilter)

FrameFilter的实现类其实只有FFmpegFrameFilter,因为只有ffmpeg支持音视频的过滤器操作,主要封装了简单的ffmpeg filter操作。

过滤器详细剖析:帧过滤器(FrameFilter)的原理与应用

4、Frame

用于存放解码后的视频图像像素和音频采样数据(如果没有配置FrameGrabber的像素格式和音频格式,那么默认解码后的视频格式是yuv420j,音频则是pcm采样数据)。

里面包含解码后的图像像素数据,大小(分辨率)、音频采样数据,音频采样率,音频通道(单声道、立体声等等)等等数据

Frame里面的一个字段opaque引用AVFrame、AVPacket、Mat等数据,也即是说,如果你是解码后获取的Frame,里面存放的属性找不到你需要的,可以从opaque属性中取需要的AVFrame原生属性。

例如:

Frame frame = grabber.grabImage();//获取视频解码后的图像像素,也就是说这时的Frame中的opaque存放的是AVFrame

AVFrame avframe=(AVFrame)frame.opaque;//把Frame直接强制转换为AVFrame
 long lastPts=avframe.pts();
 System.err.println("显示时间:"+lastPts);

补充:

FFmpeg中两个重要的结构体:AVPacketAVFrame。

AVPacket是ffmpeg中存放解复用(未解码)的音视频帧的结构体,视频只有可能是一帧,大小不定(分为关键帧/I帧、P帧和B帧三种视频帧)。AVPacket属性除了包含音视频帧以外,还包含:pts(显示时间)dts(解码时间)、duration(持续时长)、stream_index(表示音视频流的通道,音频和视频一般是分开的,通过stream_index来区分是视频帧还是音频帧)、flags(AV_PKT_FLAG_KEY(值是1):关键帧,2-损坏数据,4-丢弃数据)、pos(在流媒体中的位置)、size

某些情况下,使用AVPacket直接推流(不经过转码)的过程称之为:转封装。

AVFrame是ffmpeg中存放解码后的音视频图像像素或音频采样数据的结构体,大部分属性是与Frame相同的,多了像素格式、pts、dts和音频布局等等属性。

AVPakcet和AVFrame的使用流程如下图所示:

解复用得到AVPakcet和解码得到AVFrame流程图

下一章:JavaCV入门指南:调用opencv原生API和JavaCV是如何封装了opencv的图像处理操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

eguid_1

感谢支持eguid原创技术文章

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

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

打赏作者

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

抵扣说明:

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

余额充值