2.1. SOPHGO多媒体框架介绍

简介 –

本文档所述多媒体框架的描述对象为算能的算丰BM168x产品系列,目前该产品系列包括BM1682和BM1684两款。其中1)BM1682没有视频编码硬件单元,因此本文中所有关于视频硬件编码的内容均只针对BM1684产品而言;2)本文中提到的PCIE模式,仅针对BM1684产品而言,在B M1682下仅支持soc模式;3)本文中提到的Opencv中的bmcv名字空间下的函数,仅针对BM1684产品而言。

本文档所述多媒体框架的覆盖范围包括BM168x产品系列中的视频解码VPU模块、视频编码VPU模块、图像编码JPU模块、图像解码JPU模块、图像处理模块VPP。这些模块的功能封装到FFMPEG和OPENCV开源框架中,客户可以根据自己的开发习惯,选择FFMPEG API或者OPENCV API。其中图像处理模块,我们还单独提供了算能自有的BMCV API底层接口,这部分接口有专门的文档介绍,可以参考《BMCV User Guide》,本文档不再详细介绍,仅介绍这三套API之间的层级关系及如何互相转换。

OPENCV,FFMPEG和BMCV这三套API在功能上是子集的关系,但有少部分不能全部包含,下面的括号中进行了特别标注。

1)BMCV API包含了所有能用硬件加速的图像处理加速接口(这里图像处理硬件加速,包括硬件图像处理VPP模块加速,以及借用其他硬件模块实现的图像处理功能)

2)FFMPEG API包含了所有硬件加速的视频/图像编解码接口,所有软件支持的视频/图像编解码接口(即所有FFMPEG开源支持的格式),通过bm_scale filter支持的部分硬件加速的图像处理接口(这部分图像处理接口,仅包括用硬件图像处理VPP模块加速的缩放、crop、padding、色彩转换功能)

3)OPENCV API包含了所有FFMPEG支持的硬件及软件视频编解码接口(视频底层通过FFMPEG支持,这部分功能完全覆盖),硬件加速的JPEG编解码接口,软件支持的其他所有图像编解码接口(即所有OPENCV开源支持的图像格式),部分硬件加速的图像处理接口(指用图像处理VPP模块加速的缩放、crop、padding、色彩转换功能),所有软件支持的OPENCV图像处理功能。

这三个框架中,BMCV 专注于图像处理功能,且能用BM168x硬件加速的部分;FFMPEG框架强于图像和视频的编解码,几乎所有格式都可以支持,只是是否能用硬件加速的区别;OPENCV框架强于图像处理,各种图像处理算法最初都先集成到OPENCV框架中,而视频编解码通过底层调用FFMPEG来实现。

因为BMCV仅提供了图像处理接口,因此FFMPEG或者OPENCV框架中,客户一般会选择其中一个作为主框架进行开发。这两个框架,从功能抽象上来说,OPENCV的接口要更加简洁,一个接口就可以实现一次视频编解码操作;从性能上说,这两个的性能是完全一致的,几乎没有差别,在视频编解码上,OPENCV只是对 FFMPEG接口的一层封装;从灵活性上说,FFMPEG的接口更加分离,可插入的操作粒度更细。最重要的,客户还是要根据自己对于某个框架的熟悉程度来做选择,只有深入了解,才能把框架用好。

这三个框架层级关系如图所示

../_images/Multim002.png

图 1 OPENCV/FFMPEG/BMCV与BMSDK之间的层级调用关系

在很多应用场景下,需要用到某个框架下的特殊功能,因此在第4节中给出了三个框架之间灵活转换的方案。这种转换是不需要发生大量数据拷贝的,对性能几乎没有损失。

2.1.1. BM1684硬件加速功能

本节给出了多媒体框架中硬件加速模块能支持的功能。其中硬件加速模块包括视频解码VPU模块,视频编码VPU模块,图像编解码JPU模块,图像处理VPP模块。

需要特别注意,这里只列出能够用硬件加速的能力,以及典型场景下的性能估计值。更详细的性能指标参考BM168x产品规格书。

2.1.1.1. 视频编解码

BM1684产品支持H264(AVC),HEVC视频格式的硬件解码加速,最高支持到4K视频的实时解码。支持H264(AVC), HEVC视频格式的硬件编码,最高支持到HD(1080p)视频的实时编码。

视频解码的速度与输入视频码流的格式有很大关系,不同复杂度的码流的解码速度有比较大的波动,比如码率、GOP结构,分辨率等,都会影响到具体的测试结果。一般来说,针对视频监控应用场景,BM1684产品单芯片可以支持到32路HD高清实时解码。

视频编码的速度与编码的配置参数有很大关系,不同的编码配置下,即使相同的视频内容,编码速度也不是完全相同的。一般来说,BM1684产品单芯片最高可以支持到2路HD高清实时编码。

2.1.1.2. 图像编解码

BM1684产品支持JPEG baseline格式的硬件编/解码加速。注意,仅支持JPEG baseline档次的硬件编解码加速,对于其他图片格式,包括JPEG2000, BMP, PNG以及JPEG标准的progressive, lossless等档次均自动采用软解支持。在opencv框架中,这种兼容支持对于客户是透明的,客户应用开发时无需特别处理。

图像硬件编解码的处理速度和图像的分辨率、图像色彩空间(YUV420/422/444)有比较大的关系,一般而言,对于1920x1080分辨率的图片,色彩空间为YUV420的,单芯片图像硬件编解码可以达到600fps左右。

2.1.1.3. 图像处理

BM1684产品有专门的视频处理VPP单元对图像进行硬件加速处理。支持的图像操作有色彩转换、图像缩放、图像切割crop、图像拼接stitch功能。最大支持到4k图像输入。对于VPP不支持的一些常用复杂图像处理功能,如线性变换ax+b,直方图等, 我们在BMCV API接口中,利用其他硬件单元做了特殊的加速处理。

2.1.2. 硬件内存分类

在后续的讨论中,内存同步问题是应用调试中经常会遇到的,比较隐蔽的问题。我们通常统一用设备内存和系统内存来称呼这两类内存间的同步。根据BM168x产品类型的不同,这两个内存在SOC模式和PCIE模式下分别具有不同的含义。

SOC模式,是指用BM168x芯片中的处理器作为主控CPU,BM168x产品独立运行应用程序。典型的产品有SE5、SM5-soc模组。在这类模式下,采用Linux系统下的ION内存对设备内存进行管理。在SOC模式下,设备内存指ION分配的物理内存,系统内存其实是cache,这里的命名只是为了和PCI E模式保持一致。从系统内存(cache)到设备内存,称为Upload上传(实质是cache flush);从设备内存到系统内存(cache),称为Download下载(实质是cache invalidation)。在SOC模式下,设备内存和系统内存最终操作的其实是同一块物理内存,大部分时间,操作系统会自动对其进行同步,这也导致内存没有及时同步时的现象更加隐蔽和难以复现。

PCIE模式,是指BM168x产品作为PCIE板卡形态插到服务器主机上进行工作,应用程序运行在服务器主机的CPU上。在PCIE模式下,设备内存指PCIE板卡上的物理内存,并不包含在服务器主机内存中;系统内存指服务器主机中的内存。从系统内存到设备内存,称为Upload上传(实质是pcie写数据);从设 备内存到系统内存,称为Download下载(实质是pcie读数据)。在PCIE模式下,设备内存和系统内存是物理上完全独立的两块物理内存,必须通过Download/Upload操作才能保证这两块内存保持同步。

../_images/Multim003.png

图 2 内存同步模型

FFMPEG和OPENCV两个框架都提供了内存同步操作的函数。而BMCV API只面向设备内存操作,因此不存在内存同步的问题,在调用BMCV API的时候,需要将数据在设备内存准备好。

在OPENCV框架中,部分函数的形参中就提供了update的标志位,当标志位设置true的时候,函数内部会自动进行内存同步操作。这部分可以参考后续的第二章第3节的API介绍。用户也可以通过bmcv::downloadMat() 和 bmcv::uploadMat()两个函数,主动控制内存同步。同步的基本原则是:a) opencv原生函数中,yuv Mat格式下设备内存中的数据永远是最新的,RGB Mat格式下系统内存中的数据永远是最新的 b) 当opencv函数向BMCV API切换的时候,根据上一个原则,将最新数据同步到设备内存中;反之,从BMCV API向opencv函数切换的时候,在RGB Mat下将最新数据同步到系统内存中。c) 在不发生框架切换的时候,要尽量减少内存同步的操作。频繁的内存同步操作会明显降低性能。

在常规FFMPEG框架中,有两类称之为软(常规)和硬(hwaccel)的codec API和filter API。这两套API的框架都可以支持BM168x的硬件视频编解码和硬件图像filter,从这个角度上说,所谓的软解码和硬解码在底层性能上是完全一样的,只是在使用习惯上的区别。软codec/filter API的使用方式和通常ffmpeg 内置codec完全一致,硬codec/filter API要用-hwaccel来指定使能bmcodec专用硬件设备。当在软codec API和filter API中,通过av_dict_set传入标志参数“is_dma_buffer”或者”zero_copy”,来控制内部codec或filter是否将设备内存数据同步到系统内存中,具体参数使用可以用ffmpeg -h来查看。当后续直接衔接硬件处理的时候,通常不需要将设备内存数据同步到系统内存中。

在hwaccel codec API和filter API中,内存默认只有设备内存,没有分配系统内存。如果需要内存同步,则要通过hwupload和hwdownload filter来完成。

综上所述,OPENCV和FFMPEG框架都对内存同步提供了支持,应用可以根据自己的使用习惯选择相应的框架,对数据同步进行精准控制。BMCV API则始终工作在设备内存上。

2.1.3. 框架之间转换

在应用开发中,总会碰到一些情况下,某个框架无法完全满足设计需求。这时就需要在各种框架之间快速切换。BM168x多媒体框架对其提供了支持,可以满足这种需求,并且这种切换是不发生数据拷贝的,对于性能几乎没有影响。

2.1.3.1. FFMPEG和OPENCV转换

FFMPEG和OPENCV之间的转换,主要是数据格式AVFrame和cv::Mat之间的格式转换。

当需要FFMPEG和OPENCV配合解决的时候,推荐使用常规非HWAccel API的通路,目前OPENCV内部采用是这种方式,验证比较完备。

FFMPEG AVFrame转到OPENCV Mat格式如下。

1. AVFrame * picture;

2. 中间经过ffmpeg API的一系列处理,比如avcodec_decode_video2 或者 avcodec_receive_frame,然后将得到的结果转成Mat

4. card_id 为进行ffmpeg硬件加速解码的设备序号, 在常规codec API中,通过av_dict_set的sophon_idx指定,或者hwaccel API中,在hwaccel设备初始化的时候指定, soc模式下默认为0

5. cv::Mat ocv_frame(picture, card_id);

6. 或可以通过分步方式进行格式转换

7. cv::Mat ocv_frame;

8. ocv_frame.create(picture, card_id);

9. 然后可以用ocv_frame进行opencv的操作,此时ocv_frame格式为BM168x扩展的yuv mat类型,如果后续想转成opencv标准的bgr mat格式,可以按下列操作。

10. 注意:这里就有内存同步的操作, 如果没有设置,ffmpeg默认是在设备内存中的,如果update=false, 那么转成bgr的数据也一直在设备内存中,系统内存中为无效数据,如果update=true,则设备内存同步到系统内存中。如果后续还是硬件加速处理的话,可以update=false, 这样可以 提高效率,当需要用到系统内存数据的时候,显式调用bmcv::downloadMat()来同步即可。

11. cv::Mat bgr_mat;

12. cv::bmcv::toMAT(ocv_frame, bgr_mat, update);

13. 最后AVFrame *picture会被Mat ocv_frame释放,因此不需要对picture进行av_frame_free()操作。如果希望外部调用av_frame_free来释放picture, 则可以加上card_id = card_id | BM_MAKEFLAG(UMatData::AVFRAME_ATTACHED,0,0), 该标准表明AVFrame的创建和释放由外部管理

14. ocv_frame.release();

15. picture = nullptr;

OPENCV Mat转成FFMPEG AVFrame的情况比较少见,因为几乎所有需要的FFMPEG操作都在opencv中有对应的封装接口。比如:ffmpeg解码在opencv有videoCapture类,ffmpeg编码在opencv中有videoWriter类,ffmpeg的filter操作对应的 图像处理在opencv中有bmcv名字空间下的接口以及丰富的原生图像处理函数。

一般来说,opencv Mat转成FFMPEG AVFrame,指的是yuv Mat。在这种情况下,可以按下进行转换。

1. 创建yuv Mat,如果yuv Mat已经存在,可以忽略此步.card_id为BM168x设备序号,soc模式下默认为0

2. AVFrame * f = cv::av::create(height, width, AV_PIX_FMT_YUV420P,  NULL, 0, -1, NULL, NULL,  AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, card_id);

3. cv::Mat image(f, card_id);

4. do something in opencv

5. AVFrame * frame = image.u->frame;

6. call FFMPEG API

7. 注意:在ffmpeg调用完成前,必须保证Mat image没有被释放,否则AVFrame会和Mat image一起释放。如果需要将两个的声明周期分离开来,则上面的image声明要改成如下格式。

8. cv::Mat image(f, card_id | BM_MAKEFLAG(UMatData::AVFRAME_ATTACHED, 0, 0));

9. 这样Mat就不会接管AVFrame的内存释放工作

2.1.3.2. FFMPEG和BMCV API转换

FFMPEG经常需要和BMCV API搭配使用,因此FFMPEG和BMCV之间的转换是比较频繁的。为此我们专门给了一个例子ff_bmcv_transcode,该例子可以在bmnnsdk2发布包里找到。

ff_bmcv_transcode例子演示了用ffmpeg解码,将解码结果转换到BMCV下进行处理,然后再转换回到ffmpeg进行编码的过程。FFMPEG和BMCV之间的互相转换可以参考ff_avframe_convert.cpp文件中的avframe_to_bm_image()和bm_image_ to_avframe()函数。

2.1.3.3. OPENCV和BMCV API转换

OPENCV和BMCV API之间的转换,专门在opencv扩展的bmcv名字空间下提供了专门的转换函数。

OPENCV Mat转换到BMCV bm_image格式。

1. cv::Mat m(height, width, CV_8UC3, card_id);

2. opencv 操作

3. bm_image bmcv_image;

4. 这里update用来控制内存同步,是否需要内存同步取决于前面的opencv 操作,如果前面的操作都是用硬件加速完成,设备内存中就是最新数据,就没必要进行内存同步,如果前面的操作调用了opencv函数,没有使用硬件加速(后续opencv章节6.2中提到了哪些函数采用了硬件加速),对于bgr mat格式就需要做内存同步。

5. 也可以在调用下面函数之前,显式的调用cv::bmcv::uploadMat(m)来实现内存同步

6. cv::bmcv::toBMI(m, &bmcv_image, update);

7. 使用bmcv_image就可以进行bmcv api调用,调用期间注意保证Mat m不能被释放,因为bmcv_image使用的是Mat m中分配的内存空间. handle可以通过bm_image_get_handle()获得

8. 释放:必须调用此函数,因为在toBMI中create了bm_image, 否则会有内存泄漏

9. bm_image_destroy(bmcv_image);

10. m.release();

由BMCV bm_image格式转换到OPENCV Mat有两种方式,一种是会发生数据拷贝,这样bm_image和Mat之间相互独立,可以分别释放,但是有性能损失;一种是直接引用bm_image内存,性能没有任何损失。

1. bm_image bmcv_image;

2. 调用bmcv API给bmcv_image分配内存空间,并进行操作

3. Mat m_copy, m_nocopy;

4. 下面接口将发生内存数据拷贝,转换成标准bgr mat格式.

5. update控制内存同步,也可以在调用完这个函数后用bmcv::downloadMat()来控制内存同步

6. csc_type是控制颜色转换系数矩阵,控制不同yuv色彩空间转换到bgr

7. cv::bmcv::toMAT(&bmcv_image, m_copy, update, csc_type);

8. 下面接口接口将直接引用bm_image内存 (nocopy标志位true), update仍然按照之前的描述,

9. 选择是否同步内存。 在后续opencv操作中,必须保证bmcv_image没有释放,因为mat的内存

10. 直接引用自bm_image cv::bmcv::toMAT(&bmcv_image, &m_nocopy, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, NULL, -1, update, true);

11. 进行opencv

2.2. SOPHGO OpenCV使用指南

2.2.1. OpenCV简介

BM168x系列芯片中的多媒体、BMCV和NPU硬件模块可以加速对图片和视频的处理:

  1. 多媒体模块:硬件加速JPEG编码解码 和Video编解码操作。

  2. BMCV模块:硬件加速对图片的resize、color conversion、crop、split、linear transform、nms、sort等操作。

  3. NPU模块:硬件加速对图片的split、rgb2gray、mean、scale、int8tofloat32操作。

为了方便客户使用芯片上的硬件模块加速图片和视频的处理,提升应用OpenCV软件性能,算能修改了OpenCV库,在其内部调用硬件模块进行Image和Video相关的处理。

算能当前OpenCV的版本为4.1.0,除了以下几个算能自有的API以外,其它的所有API与OpenCV API都是一致的。

BM168x系列芯片有两种应用环境:SOC模式和PCIE卡模式。在SOC模式下,使用BM168x系列内置的ARM A53 core作为主控CPU,直接对芯片内部资源进行控制分配。PCIE模式下,BM168x系列作为PCIE卡插到主机上,由主机CPU通过PCIE接口对资源进行控制分配。SOPHGO OpenCV接口在两种模式下互相兼容,行为基本一致,只有以下微小的差异:

在SOC模式下,由于硬件限制,OpenCV库的Mat对象中,step值会被自动设置为64bytes对齐,不足64bytes的数据用0补齐。而在PCIE模式下,Mat的step不存在64bytes的对齐限制。例如,一张100*100的图片,每个像素的RGB由3个U8值表示,正常的step值为300,但 是经过64bytes对齐,step值最终为320。如下图所示,Mat对象的data中,每一个step的数据是连续的320个bytes,其中前300个是真实数据,后面20个是自动填充的0值。

../_images/Multim004.png

在SOC模式下,由于填充了多余的0值,Mat对象中存储数据的data变量不能直接传递给BMRuntime库的API做推理,否则会降低模型的准确率。请在最后一次BMCV做变换的时候,将stride设置为非对齐方式,多余的0会被自动清除掉。

2.2.2. 数据结构扩展说明

OpenCV内置标准处理的色彩空间为BGR格式,但是很多情况下,对于视频、图片源,直接在YUV色彩空间上处理,可以节省带宽和避免不必要的YUV和RGB之间的互相转换。因此SOPHGO Opencv对于Mat类进行了扩展。

  1. 在Mat.UMatData中,引入了AVFrame成员,扩展支持各种YUV格式。其中AVFrame的格式定义与FFMPEG中的定义兼容

  2. 在Mat.UMatData中增加了fd,addr(soc模式下)或hid,mem(pcie模式下)的定义,分别表示对应的内存管理句柄和物理内存地址

  3. 在Mat类中增加了fromhardware变量,标识当前的视频、图片解码是由硬件或是软件计算完成的。

2.2.3. API扩展说明

2.2.3.1. bool VideoCapture::get_resampler(int *den, int *num)

函数原型

bool VideoCapture::get_resampler(int *den, int *num)

功能

取视频的采样速率。如den=5, num=3表示每5帧中有2帧被丢弃

输入参数

int *den – 采样速率的分母

int *num – 采样速率的分子

输出参数

返回值

true – 执行成功 false - 执行失败

说明

此接口将废弃。推荐用double VideoCapture::get(CAP_PROP_OUTPUT_SRC)接口。

2.2.3.2. bool VideoCapture::set_resampler(int den, int num)

函数原型

bool VideoCapture::set_resampler(int den, int num)

功能

置视频的采样速率。如den=5, num=3,表示每5帧中有2帧被丢弃。

输入参数

int den – 采样速率的分母

int num – 采样速率的分子

输出参数

返回值

true – 执行成功 false - 执行失败

说明

此接口将废弃。推荐用bool VideoCapture::set(CAP_PROP_OUTPUT_SRC, double resampler)接口。

2.2.3.3. double VideoCapture::get(CAP_PROP_TIMESTAMP)

函数原型

double VideoCapture::get(CAP_PROP_TIMESTAMP)

功能

提供当前图片的时间戳,时间基数取决于在流中给出的时间基数

输入参数

CAP_PROP_TIMESTAMP – 特定的枚举类型指示获取时间戳,此类型由Sophgo定义

出输参数

返回值

Convert return value to “int64_t” type before using it.

0x8000000000000000L-No AV PTS value

other-AV PTS value

2.2.3.4. double VideoCapture::get(CAP_PROP_STATUS)

函数原型

double VideoCapture::get(CAP_PROP_STATUS)

功能

该函数提供了一个接口,用于检查视频抓取的内部运行状态

输入参数

CAP_PROP_STATUS – 枚举类型,此类型由Sophgo定义

出输参数

返回值

在使用返回值前请将转换成int类型

0 视频抓取停止,暂停或者其他无法运行的状态)

1 视频抓取正在进行)

2 视频抓取结束)

2.2.3.5. bool VideoCapture::set(CAP_PROP_OUTPUT_SRC, double resampler)

函数原型

double VideoCapture::get(CAP_PROP_OUTPUT_SRC, double resampler)

功能

设置YUV视频的采样速率。如resampler为0.4,表示每5帧中保留2帧,有3帧被丢弃

输入参数

CAP_PROP_OUTPUT_SRC–枚举类型,此类型由Sophgo定义

double resampler – 采样速率

输出参数

返回值

true 执行成功

false执行失败

2.2.3.6. double VideoCapture::get(CAP_PROP_OUTPUT_SRC)

函 数原型

double VideoCapture::get(CAP_PROP_OUTPUT_SRC)

功能

取视频的采样速率。

输 入参数

CAP_PROP_OUTPUT_SRC 特定的枚举类型,指视频输出,此类型由SOPHGO定义

输 出参数

返回值

采样率数值

2.2.3.7. bool VideoCapture::set(CAP_PROP_OUTPUT_YUV, double enable)

函 数原型

bool VideoCapture::set(CAP_PROP_OUTP UT_YUV, double enable)

功能

开或者关闭YUV格式的frame输出。BM168x系列下YUV格式为I420

输 入参数

CAP_PROP_OUTPUT_YUV 特 定的枚举类型,指YUV格式的视频frame输出,此类型由SOPHGO定义; double enable – 操作码,1表示打开,0表示关闭

输 出参数

返回值

true:执行成功 false:执行失败

2.2.3.8. double VideoCapture::get(CAP_PROP_OUTPUT_YUV)

函 数原型

double VideoCapture::get(CAP_PROP_OUTPUT_YUV)

功能

取YUV视频frame输出的状态。

输 入参数

CAP_PROP_OUTPUT_YUV 特定 的枚举类型,指YUV格式的视频frame输出,此类型由SOPHGO定义。

输 出参数

返回值

YUV视频frame输出的状态。1表示打开,0表示关闭。

2.2.3.9. bm_handle_t bmcv::getCard(int id = 0)

函 数原型

bm_handle_t bmcv::getCard(int id = 0)

功能

取SOPHGO OpenCV内部使用的PCIE卡设备句柄。PCIE模式下有效

输 入参数

int id – PCIE卡序号,SOC下恒定为0

输 出参数

返回值

PCIE卡设备句柄

说明

过toBMI接口转换得到bm_image,在调用bmcv API的时候 会要求创建bm_image时的句柄,本接口可以支持获取得到该句柄。

2.2.3.10. int bmcv::getId(bm_handle_t handle)

函 数原型

int bmcv::getId(bm_handle_t handle)

功能

据PCIE设备句柄查询卡序号

输 入参数

Bm_handle_t handle – PCIE设备句柄

输 出参数

返回值

PCIE卡的序号

2.2.3.11. bm_status_t bmcv::toBMI(Mat &m, bm_image *image, bool update = true)

函 数原型

bm_status_t bmcv::toBMI(Mat &m, bm_image*image, bool date = true)

功能

OpenCV Mat对象转换成BMCV接口中对应格式的bm_image数据对象,本接口直接引用Mat的数据指针,不会发生copy操作。 本接口仅支持1N模式

输 入参数

Mat& m – Mat对象,可以为扩展YUV格式或者标准OpenCV BGR格式; bool update – 是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存

输 出参数

bm_image *image – 对应格式的BMCV bm_image数据对象

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

前支持压缩格式、Gray、NV12、NV16,YUV444P、YUV420P、BGR separate、BGR packed、CV_8UC1的格式转换

2.2.3.12. bm_status_t bmcv::toBMI(Mat &m, Mat &m1, Mat &m2, Mat &m3, bm_image *image, bool update = true)

函 数原型

bm_status_t bmcv::toBMI(Mat &m, Mat &m1, Mat &m2, Mat &m3, _image *image, bool update = true)

功能

OpenCV Mat对象转换成BMCV接口中对应格式的bm_im age数据对象,本接口直接引用Mat的数据指针,不发生copy操作。 本接口针对BMCV的4N模式。要求所有Mat的输入图像格式一致

输 入参数

Mat &m 4N中的第1幅图像,扩展YUV格式或者标准OpenCV BGR格式。; Mat &m1 4N中的第2幅图像,扩展YUV格式或者标准OpenCV BGR格式。; Mat &m2 4N中的第3幅图像,扩展YUV格式或者标准OpenCV BGR格式。; Mat &m3 4N中的第4幅图像,扩展YUV格式或者标准OpenCV BGR格式。; bool update 是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存

输 出参数

bm_image *image 对应格式的BMCV bm_image数据对象,其中包含4个图像数据

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

前支持压缩格式、Gray、NV12、NV16,YUV444P、YUV420P、BGR separate、BGR packed、CV_8UC1的格式转换

2.2.3.13. bm_status_t bmcv::toMAT(Mat &in, Mat &m0, bool update=true)

函 数原型

bm_status_t bmcv::toMAT(Mat &in, Mat &m0, bool date = true)

功能

输入的MAT对象,可以为各种YUV或BGR格式,转换成BGR packet格式的MAT对象输出

输 入参数

Mat &in - 输入的MAT对象,可以为各种YUV格式或者BGR格式; bool update – 是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存

输 出参数

Mat &m0 - 输出的MAT对象,转成标准OpenCV的BGR格式

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

前支持压缩格式、Gray、NV12、NV16,YUV444P、YUV420P、BGR separate、BGR packed、CV_8UC1到BGR packed格式转换。 在YUV格式下,会自动根据AVFrame 结构体中colorspace,color_range信息选择正确的色彩转换矩阵。

2.2.3.14. bm_status_t toMAT(bm_image *image, Mat &m, int color_space, int color_range, void* vaddr = NULL, int fd0 = -1, bool update = true, bool nocopy = true)

函 数原型

bm_status_t bmcv::toMAT(bm_image *image, Mat &m, int lor_space, int color_range, void* vaddr=NULL, int fd0=-1, bool update=true, bool nocopy=true)

功能

输 入的bm_image对象,当nocopy为true时,直接复用设备内存转成M at格式,当nocopy为false时,行为类似3.13otMAT接口,1N模式。

输 入参数

bm_image *image - 输入的bm_image对象,可以为各种YUV格式或者BGR格式; Int color_space – 输入image的色 彩空间,可以为AVCOL_SPC_BT709或AVCOL_SPC_BT470,详见FFMPEG pixfmt.h定义; Int color_range – 输入image的色彩动态 范围,可以为AVCOL_RANGE_MPEG或AVCOL_RANGE_JPEG,详见FFMPEG pixfmt.h定义; Void* vaddr – 输出Mat的系统虚拟内存指针,如果已分配,输出Mat直接 使用该内存作为Mat的系统内存。如果为NULL,则Mat内部自动分配; Int fd0 – 输出Mat的物理内存句柄,如果为负,则使用bm_image内的设备内存句柄,否则使用fd0给定的句柄来mmap设备内存; bool update -是否需要同步cache或内存。如果 为true,则转换完成后同步cache或者PCIE卡设备内存到系统内存中; bool nocopy – 如果时true, 则直接引用bm_image的设备内存,如果为false,则转换成标准BGR Mat格式

输 出参数

Mat &m - 输出的MAT对象,当nocopy为true时,输出标准BGR格式或扩展的 YUV格式的Mat;当nocopy为false时,转成标准OpenCV的BGR格式。

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

no copy方式只支持1N模式,4N模式因为内存排列方式,不能支持引用 2. 在nocopy为false的情况下,会自动根据参数colo rspace,color_range信息选择正确的色彩转换矩阵进行色彩转换。 3. 如果系统内存vaddr来自于外部,那么 外部需要来管理这个内存的释放,Mat释放的时候不会释放该内存

2.2.3.15. bm_status_t bmcv::toMAT(bm_image *image, Mat &m0, bool update = true, csc_type_t csc = CSC_MAX_ENUM)

函 数原型

bm_status_t bmcv::toMAT(bm_image *image, Mat &m0, bool date=true, csc_type_t csc=CSC_MAX_ENUM)

功能

输入的bm_image对象, 可以为各种YUV或BGR格式,转换成BGR格式的MAT对象输出,1N模式

输 入参数

bm_image *image 输入的bm_image对象,可以为各种YUV格式或者BGR格式; bool update -是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存; csc_type_t csc – 色彩转换矩阵,默认为YPbPr2RGB_BT601

输 出参数

Mat &m0 - 输出的MAT对象,转成标准OpenCV的BGR格式

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

2.2.3.16. bm_status_t bmcv::toMAT(bm_image *image, Mat &m0, Mat &m1, Mat &m2, Mat &m3, bool update=true, csc_type_t csc=CSC_MAX_ENUM)

函 数原型

bm_status_t bmcv::toMAT(bm_image *image, Mat &m0, Mat 1, Mat &m2, Mat &m3, bool update=true, csc_type_t csc=CSC_MAX_ENUM)

功能

输入的bm_image对象, 可以为各种YUV或BGR格式,转换成BGR格式的MAT对象输出,4N模式

输 入参数

bm_image *image - 输入的4N模式下的bm_image对象,可以为各种YUV格式或者BGR格式; bool update -是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存; csc_type_t csc – 色彩转换矩阵,默认为YPbPr2RGB_BT601

输 出参数

Mat &m0 - 输出的第一个MAT对象,转成标准OpenCV的BGR格式; Mat &m1 - 输出的第二个MAT对象,转成标准OpenCV的BGR格式; Mat &m2 - 输出的第三个MAT对象,转成标准OpenCV的BGR格式; Mat &m3 - 输出的第四个MAT对象,转成标准OpenCV的BGR格式

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

2.2.3.17. bm_status_t bmcv::resize(Mat &m, Mat &out, bool update = true, int interpolation= BMCV_INTER_NEAREST)

函 数原型

bm_status_t bmcv::resize(Mat &m, Mat &out, bool update = true, int interpolation)

功能

输入的MAT对象,缩放到输 出Mat给定的大小,输出格式为输出Mat指定的色彩空间,因为MAT 支持扩展的YUV格式,因此本接口支持的色彩空间并不仅局限于BGR packed。

输 入参数

Mat &m - 输入的Mat对象,可以为标准BGR packed格式或者扩展YUV格式; bool update - 是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存; int interpolation – 缩放算法,可为NEAREST或者LINEAR算法

输 出参数

Mat &out - 输出的缩放后的Mat对象

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

支持Gray、YUV444P、YUV420P、BGR/RGB separate、BGR/RGB packed、ARGB packed格式缩放

2.2.3.18. bm_status_t bmcv::convert(Mat &m, Mat &out, bool update=true)

函 数原型

bm_status_t bmcv::convert(Mat &m, Mat &out, bool update = true)

功能

现两个mat之间的色彩转 换,他与toMat接口的区别在于toMat只能实现各种色彩格式到BGR packed的色彩转换,而本接口可以支持BGR packed或者YUV格式到BGR packed或YUV之间的转换。

输 入参数

Mat &m - 输入的Mat对象,可以为扩展的YUV格式或者标准BGR packed格式; bool update -是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存

输 出参数

Mat &out - 输出的色彩转换后的Mat对象,可以为BGR packed或者YUV格式。

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

2.2.3.19. bm_status_t bmcv::convert(Mat &m, std::vector<Rect> &vrt, std::vector<Size> &vsz, std::vector<Mat> &out, bool update= true, csc_type_t csc=CSC_YCbCr2RGB_BT601, csc_matrix_t *matrix = nullptr, bmcv_resize_algorithm algorithm= BMCV_INTER_LINEAR)

函 数原型

bm_status_t bmcv::convert(Mat &m, std::vector<Rect> &vrt, d::vector<Size> &vsz, std::vector<Mat> &out, bool cached = true, csc_type_t csc=CSC_YCbCr2RGB_BT601, csc_matrix_t *matrix=nullptr, bmcv_resize_algorithm algorithm = BMCV_INTER_LINEAR)

功能

接口采用内置的VPP硬件加速单元,集crop,res ize和csc于一体。按给定的多个rect框,给定的多个缩放size,将 输入的Mat对象,输出到多个Mat对象中,输出为OpenCV标准的BGR pack格式或扩展YUV格式

输 入参数

Mat &m - 输入的Mat对象,可以为扩展的YUV格式或者标准BGR packed格式; std::vector<Rect> &vrt - 多个 rect框,输入Mat中的ROI区域。矩形框个数和resize个数应该相同; std::vector<Size> &vsz - 多个resize大小,与vrt的矩形框一一对应; bool update -是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存; csc_type_t csc – 色彩转换矩阵,可以根据颜色空间指定合适的色彩转换矩阵; csc_matrix_t *matrix – 当色 彩转换矩阵不在列表中时,可以给出外置的用户自定义的转换矩阵; bmcv_resize_algorithm algorithm – 缩放算法,可以为Nearest或者Linear算法

输 出参数

std::vector<Mat> &out - 输出的缩放、crop以及色彩转换后的标准BGR pack格式或YUV格式的Mat对象。

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

接口可以将resize,crop,csc三种操作在一步之内完 成,效率最高。在可能的情况下,要尽可能的使用该接口提高效率

2.2.3.20. bm_status_t bmcv::convert(Mat &m, std::vector<Rect> &vrt, bm_image *out, bool update= true)

函 数原型

bm_status_t bmcv::convert(Mat &m, std::vector<Rect> &vrt, _image *out, bool update= true)

功能

接口采用内置 的VPP硬件加速单元,集crop,resize和csc于一体。按给定的多个 rect框,按照多个bm_image中指定的size,将输入的Mat对象,输 出到多个bm_image对象中,输出格式由bm_image初始化值决定。注 意,bm_image必须由调用者初始化好,并且个数和vrt一一对应。

输 入参数

Mat &m - 输入的Mat对象,可以为扩展的YUV格式或者标准BGR packed格式; std::vector<Rect> &vrt - 多个 rect框,输入Mat中的ROI区域。矩形框个数和resize个数应该相同; bool update -是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存

输 出参数 输

bm_image *out - 的缩放、crop以及色彩 转换后的bm_image对象,输出色彩格式由bm_image初始化值决定。 同时该参数初始化的size、色彩信息也作为输入信息,用于处理。

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

2.2.3.21. void bmcv::uploadMat(Mat &mat)

函 数原型

void bmcv::uploadMat(Mat &mat)

功能

ache同步或者设备内存 同步接口。当执行此函数时,cache中内容会flush到实际内存中( SOC模式),或者host内存同步到PCIE卡设备内存(PCIE模式)。

输 入参数

Mat &mat - 输入的需要内存同步的mat对象

输 出参数

返回值

说明

理调用本接 口,可以有效控制内存同步的次数,仅在需要的时候调用。这在PC IE模式下更为重要,因为每次PCIE设备内存的同步时间耗时较大。

2.2.3.22. void bmcv::downloadMat(Mat &mat)

函 数原型

void bmcv::downloadMat(Mat &mat)

功能

ache同步或者设备内存同步接口。当执行此函数时,cache中 内容会invalidate(SOC模式),或者PCIE卡设备内存同步到host 内存中(PCIE模式)。本接口的内存同步方向与3.21接口正好相反

输 入参数

Mat &mat - 输入的需要内存同步的mat对象

输 出参数

返回值

说明

理调用本接 口,可以有效控制内存同步的次数,仅在需要的时候调用。这在PC IE模式下更为重要,因为每次PCIE设备内存的同步时间耗时较大。

2.2.3.23. bm_status_t bmcv::stitch(std::vector<Mat> &in, std::vector<Rect>& srt, std::vector<Rect>& drt, Mat &out, bool update = true, bmcv_resize_algorithm algorithm = BMCV_INTER_LINEAR)

函 数原型 s

bm_status_t bmcv::stitch(std::vector<Mat> &in, d::vector<Rect> &src, std::vector<Rect> &drt, Mat &out, bool update=true, bmcv_resize_alogrithm algorithm=BMCV_INTER_LINEAR)

功能

像拼 接,将输入的多个Mat按照按照给定的位置缩放并拼接到一个Mat中

输 入参数

std::vector<Mat> &in – 多个输入的Mat对象,可以为扩展的YUV格式或者标准BGR pack格式; std::vector<Rect> &src – 对应每个Mat对象的显示内容框; std::vector<Rect> &drt – 对应每个显示内容在目标Mat中的显示位置; bool update -是否需要同步cache 或内存。如果为true,则转换完成后同步cache或者PCIE卡设备内存; bmcv_resize_algorithm algorithm – 缩放算法, 可以为Nearest或者Linear算法

输 出参数

Mat &out – 输出拼接后的Mat对象,可以为BGR packed或者YUV格式

返回值

BM_SUCCESS(0):执行成功 其他:执行失败

说明

2.2.3.24. void bmcv::print(Mat &m, bool dump = false)

2.2.3.25. void bmcv::print(bm_image *image, bool dump)

2.2.3.26. void bmcv::dumpMat(Mat &image, const String &fname)

2.2.3.27. void bmcv::dumpBMImage(bm_image *image, const String &fname)

2.2.3.28. bool Mat::avOK()

2.2.3.29. int Mat::avCols()

函 数原型

int Mat::avCols()

功能

取YUV扩展格式的Y的宽

输 入参数

输 出参数

返回值

返回扩展的YUV格式的Y的宽,如果为标准OpenCV Mat格式,返回0

2.2.3.30. int Mat::avRows()

函 数原型

int Mat::avRows()

功能

取YUV扩展格式的Y的高

输 入参数

输 出参数

返回值

返回扩展的YUV格式的Y的高,如果为标准OpenCV Mat格式,返回0

2.2.3.31. int Mat::avFormat()

函 数原型

int Mat::avFormat()

功能

取YUV格式信息

输 入参数

输 出参数

返回值

返回扩展的YUV格式信息,如果为标准OpenCV Mat格式,返回0

2.2.3.32. int Mat::avAddr(int idx)

函 数原型

int Mat::avAddr(int idx)

功能

取YUV各分量的物理地址

输 入参数

int idx – 指定YUV plane的序号

输 出参数

返回值

返回指定的plane的物理首地址,如果为标准OpenCV Mat格式,返回0

2.2.3.33. int Mat::avStep(int idx)

函数原型

int Mat::avStep(int idx)

功能

取YUV格式中指定plane的line size

输入参数

int idx – 指定YUV plane的序号

输出参数

返回值

指定的plane的line size,如果为标准OpenCV Mat格式,返回0

2.2.3.34. AVFrame* av::create(int height, int width, int color_format, void *data, long addr, int fd, int* plane_stride, int* plane_size, int color_space = AVCOL_SPC_BT709, int color_range = AVCOL_RANGE_MMPEG, int id = 0)

函数原型

AVFrame* av::create(int height, int width, int clor_format, void *data, long addr, int fd, int* plane_stride, int* plane_size, int color_space = AVCOL_SPC_BT709, int color_range = AVCOL_RANGE_MMPEG, int id = 0)

功能

VFrame的创建接口,允许外部创建系统内存和物理内存,创建的格式与FFMPEG下的AVFrame定义兼容

输入参数

int height – 创建图像数据的高; int width – 创建图像数据的宽; int color_format – 创建图像数据的格式,详见FFMPEG pixfmt.h定义; void *data – 系统内存地址,当为null时,表示该接口内部自己创建管理; long addr – 设备内存地址; int fd – 设备内存地址的句柄。如果为-1,表示设备内存由内部分配,反之则由addr参数给出。在pcie模式下,如果设备内存由外部给出,该值可以设为0,在soc模式下,该值应该为ion内存的句柄。 int* plane_stride – 图像数据每层的每行stride数组; int* plane_size – 图像数据每层的大小; int color_space – 输入image的色彩空间,可以为AVCOL_SPC_BT709或AVCOL_SPC_BT470,详见FFMPEG pixfmt.h定义,默认为AVCOL_SPC_BT709; int color_range – 输入image的色彩动态范围,可以为AVCOL_RANGE_MPEG或AVCOL_RANGE_JPEG,详见FFMPEG pixfmt.h定义,默认为AVCOL_RANGE_MPEG; int id –指定设备卡号以及HEAP位置的标志,详见5.1,该参数默认为0

输出参数

返回值

AVFrame结构体指针

说明

本接口支持创建以下图像格式的AVFrame数据结构:AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, AV_PIX_FMT_YUV422P horizontal, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NV16 2.当设备内存和系统内存均有外部给出时,在soc模式下外部要保证两者地址的匹配,即系统内存是设备内存映射出来的虚拟地址;当设备内存由外部给出,系统内存为null时,该接口内部会自动创建系统内存;当设备内存没有给出,系统内存也为null时,本接口内部会自动创建 ;当设备内存没有给出,系统内存由外部给出时,本接口创建失败

2.2.3.35. AVFrame* av::create(int height, int width, int id = 0)

函 数原型

AVFrame* av::create(int height, int width, int id = 0)

功能

VFrame的简易创建接口,所有内存均由内部创建管理, 仅支持YUV420P格式

输 入参数

int height – 创建图像数据的高; int width – 创建图像数据的宽; int id –指定设备卡号以及HEAP位置的标志,详见5.1,该参数默认为0

输 出参数

返回值

AVFrame结构体指针

说明

本接口仅支持创建YUV420P格式的AVFrame数据结构

2.2.3.36. int av::copy(AVFrame *src, AVFrame *dst, int id)

函 数原型

int av::copy(AVFrame *src, AVFrame *dst, int id)

功能

VFrame的深度copy函数,将src的有效图像数据拷贝到dst中

输 入参数

AVFrame *src – 输入的AVFrame原始数据指针; int id – 指定设备卡号,详见5.1

输 出参数

AVFrame *dst – 输出的AVFrame目标数据指针

返回值

返回copy的有效图像数据个数,为0则没有发生拷贝

说明

本接口仅支持同设备卡号内的图像数据拷贝,即id相同 2. 函数中的id仅需要指定设备卡号,不需要其他标志位

2.2.3.37. int av::get_scale_and_plane(int color_format, int wscale[], int hscale[])

函 数原型

int av::get_scale_and_plane(int color_format, int wcale[], int hscale[])

功能

取指定图像格式相对于YUV444P的宽高比例系数

输 入参数

int color_format – 指定图像格式,详见FFMPEG pixfmt.h定义

输 出参数

int wscale[] – 对应格式相对于YUV444P每一层的宽度比例; int hscale[] - 对应格式相对于YUV444P每一层的高度比例

返回值

返回给定图像格式的plane层数

说明

2.2.3.38. cv::Mat(AVFrame *frame, int id)

函 数原型

cv::Mat(AVFrame *frame, int id)

功能

增的Mat构造接口。根据AVFrame指针信息构造扩展的YUV Mat数据

输 入参数 输

AVFrame *frame – AVFrame数据,可以来自FFMPEG或者cv::av下方法创建; int id – 指定PCIE设备卡号以及AVFRAME_ATTACHED标志,详见5.1

输 出参数

构造的扩展Mat数据类型

返回值

说明

当 AVFRAME_ATTACHED标志位为1时,表示frame由外部创建并释放,不 需要Mat来管理;反之则在释放Mat的同时释放frame指向的内存块

2.2.3.39. cv::Mat(int height, int width, int total, int _type, const size_t* _steps, void* _data, unsigned long addr, int fd, SophonDevice device=SophonDevice())

函 数原型

cv::Mat(int height, int width, int total, int _type, const size_t* _steps, void* _data, unsigned long addr, int fd, SophonDevice device=SophonDevice())

功能

增的Mat构造接口。可以创建opencv 标准格式或扩展的YUV Mat格式,并且系统内存和设备内存都允许通过外部分配给定

输 入参数

int height – 输入图像数据的高; int width – 输入图像数据的宽; int total – 内存 大小,该内存可以为内部待分配的内存,或外部已分配内存的大小; int _type – Mat类型,本接口只支持CV_8UC1或CV_8UC3,扩展的YUV Mat的格式_type类型一律为CV_8UC1; const size_t *steps – 所创建的图像数据的step信息,如果该指针为null,则为AUTO_STEP; void *_data – 系统内存指针,如果为null,则内部分配该内存; unsigned long addr – 设备物理内存地址,任意值均被认为有效的物理地址; int fd – 设备 物理内存对应的句柄。如果为负,则设备物理内存在内部分配管理; SophonDevice device –指定设备卡号以及HEAP位置的标志,详见5.1,该参数默认为0

输 出参数

构造的标准BGR或扩展YUV的Mat数据类型

返回值

说明

SophonDevice是为了避免C++隐含类 型匹配造成函数匹配失误而引入的类型,可以用SophonDevice(int id)直接从5.1节的ID转换过来 2. 当设备内存 和系统内存均有外部给出时,在soc模式下外部要保证两者地址的 匹配,即系统内存是设备内存映射出来的虚拟地址;当设备内存由 外部给出,系统内存为null时,该接口内部会自动创建系统内存; 当设备内存没有给出,系统内存也为null时,本接口内部会自动创 建;当设备内存没有给出,系统内存由外部给出时,本接口创建的 Mat在soc模式下只有系统内存,在pcie模式下会自动创建设备内存

2.2.3.40. Mat::Mat(SophonDevice device)

函 数原型

Mat::Mat(SophonDevice device)

功能

增的Mat构造接口,指定该Mat的后续操作在给定的device设备上

输 入参数

SophonDevice device- 定设备卡号以及HEAP位置的标志,详见5.1

输 出参数

声明Mat数据类型

返回值

说明

本构造函数仅初始化Mat内部的设备index,并不实际创建内存 2. 本构造函数的最大作用是对于某些内部cr eate内存的函数,可以通过这个构造函数,提前指定创建内存的设 备号和HEAP位置,从而避免将大量的内存分配在默认的设备号0上

2.2.3.41. void Mat::create(AVFrame *frame, int id)

函 数原型

void Mat::create(AVFrame *frame, int id)

功能

at分配内存的接口,根据AVFrame指针信息构造扩展的开辟YUV Mat内存

输 入参数 输

AVFrame *frame – AVFrame数据,可以来自FFMPEG或者cv::av下方法创建; int id –指定PCIE设备卡号以及AVFRAME_ATTACHED标志,详见5.1

输 出参数

返回值

说明

当AVFRAME_ATTACHED标志位为1时,表示frame由外部创建并释放,不 需要Mat来管理;反之则在释放Mat的同时释放frame指向的内存块 2.当原来的Mat已经分配了内存的话,如果该内存满足AVFra me的要求,则复用该内存,反之则会自动释放原内存,并重新分配

2.2.3.42. void Mat::create(int height, int width, int total, int _type, const size_t* _steps, void* _data, unsigned long addr, int fd, int id = 0)

函 数原型

void Mat::create(int height, int width, int total, int type, const size_t* _steps, void* _data, unsigned long addr, int fd, int id = 0)

功能

at分配内存接口,该接口系统内存和设备内存都允许通过外部分配给定,也可内部分配。

输 入参数

int height – 输入图像数据的高; int width – 输入图像数据的宽; int total – 内存 大小,该内存可以为内部待分配的内存,或外部已分配内存的大小; int _type – Mat类型,本接口只支持CV_8UC1或CV_8UC3,扩展的YUV Mat的格式_type类型一律为CV_8UC1; const size_t *steps – 所创建的图像数据的step信息,如果该指针为null,则为AUTO_STEP; void *_data – 系统内存指针,如果为null,则内部分配该内存; unsigned long addr – 设备物理内存地址,任意值均被认为有效的物理地址; int fd – 设备 物理内存对应的句柄。如果为负,则设备物理内存在内部分配管理; int id –指定设备卡号以及HEAP位置的标志,详见5.1,该参数默认为0

输 出参数

返回值

说明

扩展的内存分配接口,主要改 进目的是允许外置指定设备物理内存,当设备或者系统内存由外部 创建的时候,则外部必须负责该内存的释放,否则会造成内存泄漏 2. 当设备内存 和系统内存均有外部给出时,在soc模式下外部要保证两者地址的 匹配,即系统内存是设备内存映射出来的虚拟地址;当设备内存由 外部给出,系统内存为null时,该接口内部会自动创建系统内存; 当设备内存没有给出,系统内存也为null时,本接口内部会自动创 建;当设备内存没有给出,系统内存由外部给出时,本接口创建的 Mat在soc模式下只有系统内存,在pcie模式下会自动创建设备内存

2.2.3.43. void VideoWriter::write(InputArray image, char *data, int *len)

函 数原型

void VideoWriter::write(InputArray image, char *data, int len)

功能

增的视频编码接口。与OpenCV标准VideoWriter::write接口不 同,他提供了将编码视频数据输出到buffer的功能,便于后续处理

输 入参数

InputArray image – 输入的图像数据Mat结构

输 出参数

char *data – 输出的编码数据缓存; int *len – 输出的编码数据长度

返回值

2.2.3.44. virtual bool VideoCapture::grab(char *buf, unsigned int len_in, unsigned int *len_out);

函 数原型

bool VideoCapture::grab(char *buf, unsigned int len_in, usigned int *len_out);

功能

增的收流解码接口。与OpenCV标准VideoWriter: :grab接口不同,他提供了将解码前的视频数据输出到buf的功能。

输 入参数

char *buf – 外部负责分配释放内存。; unsigned int len_in – buf空间的大小。

输 出参数

char *buf – 输出解码前的视频数据。; int *len_out – 输出的buf的实际大小。

返回值

true 表示 收流解码成功;false表示收流解码失败。

2.2.3.45. virtual bool VideoCapture::read_record(OutputArray image, char *buf, unsigned int len_in, unsigned int *len_out);

函 数原型

bool VideoCapture::read_record(OutputArray image, char buf, unsigned int len_in, unsigned int *len_out);

功能

增的读取码流视频接口。他提供了将解 码前的视频数据输出到buf的功能,将解码后的数据输出到image。

输 入参数

char *buf – 外部负责分配释放内存。; unsigned int len_in – buf空间的大小。

输 出参数

OutputArray image – 输出解码后的视频数据。; char *buf – 输出解码前的视频数据。; int *len_out – 输出的buf的实际大小。

返回值

true 表示 收流解码成功;false表示收流解码失败。

2.2.4. 硬件JPEG解码器的OpenCV 扩展

在BM168x系列芯片中,提供JPEG硬件编码解码模块。为使用这些硬件模块,SDK软件包中,扩展了OpenCV中与JPEG图片处理相关的API函数,如:cv::imread()、 cv::imwrite()、cv::imdecode()、cv::imencode() 等。您在使用这些函数做JPEG编解码的时候,函数内部会自动调用底层的硬件加速资源,从而大幅度提高了编解码的效率。如果您想保持这些函数原始的OpenCV API使用习惯,可以略过本节介绍;但如果你还想了解一下我们提供的简单易用的扩展功能,这节可能对您非常有帮助。

2.2.4.1. 输出yuv格式的图像数据

OpenCV原生的cv::imread()、cv::imdecode() API函数执行JPEG图片的解码操作,返回一个Mat结构体,该Mat结构体中保存有BGR packed格式的图片数据,算能扩展的API函数功能可以返回JPEG图片解码后的原始的YUV格式数据。用法如下:

当这两个函数的第二个参数flags被设置成cv::IMREAD_AVFRAME时,表示解码后返回的Mat结构体out中保存着YUV格式的数据。具体是什么格式的YUV数据要根据JPEG文件的image格式而定。当flags被设置成其它值或者省略不设置时,表示解码输出OpenCV原生的BGR packed格式的Mat数据。解码器输入输出扩展数据格式说明如下表所示:

输入Image格式

输入YUV格式

FFMPEG对应格式

I400

I400

AV_PIX_FMT_GRAY8

I420

NV12

AV_PIX_FMT_NV12

I422

NV16

AV_PIX_FMT_NV16

I444

I444 planar

AV_PIX_FMT_YUV444P

可以通过Mat::avFormat()扩展函数,得到当前数据所对应的具体的FFmpeg格式。可以通过Mat::avOK()扩展函数,得知cv::imdecode(buf, cv::IMREAD_AVFRAME, &out)解码返回的out,是否是算能扩展的Mat数据格式。

另外在这两个接口中的flags增加cv::IMREAD_RETRY_SOFTDEC标志时会在硬件解码失败的情况下尝试切换软件解码,也可以通过设置环境变量OPENCV_RETRY_SOFTDEC=1实现此功能。

2.2.4.2. 支持YUV格式的函数列表

目前算能Opencv已经支持YUV Mat扩展格式的函数接口列表如下:

  • 视频解码类接口

    • VideoCapture类的成员函数

这类成员函数如read, grab,对于常用的HEVC, H264视频格式都使用了BM168x系列的硬件加速,并支持YUV Mat扩展格式。

  • 视频编码类接口

    • VideoWriter类的成员函数

这类成员函数如write,对于常用的HEVC,H264视频格式已经使用了BM168x系列的硬件加速,并支持YUV Mat扩展格式。

  • JPEG编码类接口

  • JPEG解码类接口

    • Imread

    • Imwrite

    • Imdecode

    • Imencode

以上接口在处理JPEG格式的时候,已经使用了BM168x系列的硬件加速功能,并支持YUV Mat扩展格式。

  • 图像处理类接口

    • cvtColor

    • resize

这两个接口在BM168x系列 SOC模式下支持YUV Mat扩展格式,并使用硬件加速进行了优化。尤其需要注意的是cvtColor接口,只在YUV转换成BGR或者GRAY输出的时候支持硬件加速和YUV Mat的格式,即只支持输入为YUV Mat格式,并进行了硬件加速,输出不支持YUV Mat格式。

在PCIE模式下,考虑到服务器的CPU性能较强,仍然采用原来的opencv原生处理方式,并不支持YUV扩展格式。

  • line

  • rectangle

  • circle

  • putText

以上四个接口均支持YUV扩展格式。注意,这四个接口并没有采用硬件加速,而是使用CPU对YUV Mat扩展格式进行的支持。

  • 基本操作类接口

    • Mat类部分接口

      • 创建释放接口:create,release,Mat声明接口

      • 内存赋值接口:clone,copyTo, cloneAll,copyAllTo,assignTo, operator =,

      • 扩展AV接口:avOK, avComp, avRows, avCols, avFormat, avStep, avAddr

以上接口均支持YUV扩展格式,尤其是copyTo, clone接口都采用硬件进行了加速。

  • 扩展类接口

    • Bmcv接口: 详见opencv2/core/bmcv.hpp

    • AvFrame接口: 详见opencv2/core/av.hpp

以上算能扩展类接口,均支持YUV Mat扩展格式,并均针对硬件加速处理进行了优化。

注意:支持YUV Mat扩展格式的接口并不等价于使用了硬件加速,部分接口是通过CPU处理来实现。这点需要特别注意。

2.2.5. 指定PCIE设备运行硬件加速

本节内容适用于VideoCapture, 图像编解码的Imread, Imwrite等接口。

2.2.5.1. ID参数的定义

ID参数为32位整型,它定义了pcie设备卡以及部分内存扩展标志信息,具体定义如下:

Bit位域

描述

Bit0-7

描述了PCIE设备的卡号,宏定义BM_CARD_ID(id)可以获取这信息

Bit8-10

描述对应PCIE卡上的HEAP内存位置。 Bit8为1表示硬件内存分配在 heap0上; Bit9为1表示硬件内存内存分配在 heap1上; Bit10为1表示硬件内存内存分配在 heap2上; Bit8-10全为0默认分配在 heap1上; Heap0/1/2的内存位置详见BMLIB API手册。宏定义BM_CARD_HEAP(id)可获取该信息

Bit11-20

描述了Mat的内存扩展标志。 B11-B18为opencv标准定义,见MemoryFlag枚举类型B19-为扩展的DEVICE_MEM_ATTACHED,标志该设备内存为外部管理,不需要Opencv来管理释放 B20-为扩展的AVFRAME_ATTACHED,标志创建YUV Mat的AVFrame为外部管理,不需 要Opencv来管理释放。宏定义BM_CARD_MEMFLAG(id)可获取该信息

B21-31

扩展保留

说明: 宏定 义BM_MA KEFLAG(attach,heap,card)可用 来生成 完整的I D定义, 其中att ach对应 B11-20,heap对应 B8-10,card对 应B0-7

2.2.5.2. 利用ID参数指定PCIE设备

在PCIE模式下,多设备情况下需要指定在特定卡上运行硬件加速功能。为了满足这个需要,SOPHGO OpenCV对VideoCapture::Open, imread, imdecode以及mat.create接口进行了扩展,增加了int id参数。

bool VideoCapture::open(const String& filename, int apiPreference, int id)

Mat imdecode(InputArray _buf, int flags, int id )

Mat imread(const String& filename, int flags, int id )

void Mat::create(int d, const int* _sizes, int _type, int id)

通过指定id,可以指定视频解码、图片解码运行在指定PCIE设备上,并且解码出来的Mat输出记录了该PCIE卡设备的序号。后续的硬件加速操作会继续在该指定PCIE设备上运行。

对于输入是Mat的大部分接口来说,因为Mat在调用create接口分配内存的时候已经指定了设备号,就不需要额外增加参数来指定PCIE卡设备。可以根据Mat内置的设备号在对应的设备上进行加速处理。

2.2.6. OpenCV与BMCV API的调用原则

BMCV API充分发挥了BM168x系列芯片中的硬件单元的加速能力,能提高数据处理的效率。而OpenCV软件提供了非常丰富的图像图形处理能力,将两者有机的结合起来,使客户开发既能利用OpenCV丰富的函数库,又能在硬件支持的功能上获得加速,是本节的主要目的。

在BMCV API和OpenCV函数以及数据类型的切换过程中,最关键是要尽量避免数据拷贝,使得切换代价最小。因此在调用流程中要遵循以下原则。

  1. 由OpenCV Mat到BMCV API的切换,可以利用toBMI()函数,该函数以零拷贝的方式,将Mat中的数据转换成了BMCV API调用所需的bm_image类型。

2) 当BMCV API需要切换到OpenCV Mat的时候,要将最后一步的操作通过OpenCV中的bmcv函数来实现。这样既完成所需的图像处理操作,同时也为后续OpenCV操作完成了数据类型准备。因为一般OpenCV都要求BGR Pack的色彩空间,所以一般用toMat()函数作为切换前的最后一步操作。

  1. 一般神经网络处理的数据为不带padding的RGB planar数据,并且对于输入尺寸有特定的要求。因此建议将resize()函数作为调用神经网络NPU接口前的最后一步操作。

  2. 当crop、resize、color conversion三个操作是连续的时候,强烈建议客户使用convert()函数,这可以在带宽优化和速度优化方面都获得理想的收益。即使后续可能还需要做一次拷贝,但因为拷贝发生在缩放之后的图像上,这种代价也是值得的。

2.2.7. OpenCV中GB28181国标接口介绍

SOPHGO复用OpenCV原生的Cap接口,通过对于url定义进行扩展,提供GB28181国标的播放支持。因此客户并不需要重新熟悉接口,只要对扩展的url定义进行理解,即可像播放rtsp视频一样,无缝的播放GB28181视频。

注意:国标中的SIP代理注册步骤,需要客户自己管理。当获取到前端设备列表后,可以直接用url的方式进行播放。

2.2.7.1. 国标GB28181支持的一般步骤 :name: 国标gb28181支持的一般步骤

  • 启动SIP代理(一般客户自己部署或者平台方提供)

  • 客户的下级应用平台注册到SIP代理

  • 客户应用获取前端设备列表,如下所示。其中,34010000001310000009等为设备20位编码。

{“devidelist”:

[{“id”: “34010000001310000009”}

{“id”: “34010000001310000010”}

{“id”: “34020000001310101202”}]}

  • 组织GB28181 url直接调用OpenCV Cap接口进行播放

2.2.7.2. GB28181 url格式定义

2.2.7.2.1. UDP实时流地址定义

gb28181://34020000002019000001:123456@35.26.240.99:5666?deviceid
=34010000001310000009#localid=12478792871163624979#localip=172.
10.18.201#localmediaport=20108:
gb28181://34020000002019000001:123456@35.26.240.99:5666?deviceid
=34010000001310000009#localid=12478792871163624979#localip=172.
10.18.201#localmediaport=20108:

注释*

34020000002019000001:123456@35.26.240.99:5666:

sip服务器国标编码:sip服务器的密码@sip服务器的ip地址:sip服务器的port

deviceid:

前端设备20位编码

localid:

本地二十位编码,可选项

localip:

本地ip,可选项

localmediaport:

媒体接收端的视频流端口,需要做端口映射,映射两个端口(rtp:11801, rtcp:11802),两个端口映射的in和out要相同。同一个核心板端口不可重复。

2.2.7.2.2. UDP回放流地址定义

gb28181_playback://34020000002019000001:123456@35.26.240.99:5666?deviceid
=35018284001310090010#devicetype=3#localid=12478792871163624979#localip=
172.10.18.201#localmediaport=20108#begtime=20191018160000#endtime
=20191026163713:
gb28181_playback://34020000002019000001:123456@35.26.240.99:5666?deviceid
=35018284001310090010#devicetype=3#localid=12478792871163624979#localip=
172.10.18.201#localmediaport=20108#begtime=20191018160000#endtime
=20191026163713:

注释*

34020000002019000001:123456@35.26.240.99:5666:

sip服务器国标编码:sip服务器的密码@sip服务器的ip地址:sip服务器的port

deviceid:

前端设备20位编码

devicetype:

录像存储类型

localid:

本地二十位编码,可选项

localip:

本地ip,可选项

localmediaport:

媒体接收端的视频流端口,需要做端口映射,映射两个端口(rtp:11801, rtcp:11802),两个端口映射的in和out要相同。同一个核心板端口不可重复。

begtime:

录像起始时间

endtime:

录像结束时间

2.2.7.2.3. TCP实时流地址定义

gb28181://34020000002019000001:123456@35.26.240.99:5666?deviceid
=35018284001310090010#localid=12478792871163624979#localip=172.10.18.201:
gb28181://34020000002019000001:123456@35.26.240.99:5666?deviceid
=35018284001310090010#localid=12478792871163624979#localip=172.10.18.201:

注释*

34020000002019000001:123456@35.26.240.99:5666:

sip服务器国标编码:sip服务器的密码@sip服务器的ip地址:sip服务器的port

deviceid:

前端设备20位编码

localid:

本地二十位编码,可选项

localip:

本地ip,可选项

2.2.7.2.4. TCP回放流地址定义

gb28181_playback://34020000002019000001:123456@35.26.240.99:5666?deviceid
=35018284001310090010#devicetype=3#localid=12478792871163624979#localip=
172.10.18.201#begtime=20191018160000#endtime=20191026163713:
gb28181_playback://34020000002019000001:123456@35.26.240.99:5666?deviceid
=35018284001310090010#devicetype=3#localid=12478792871163624979#localip=
172.10.18.201#begtime=20191018160000#endtime=20191026163713:

注释*

34020000002019000001:123456@35.26.240.99:5666:

sip服务器国标编码:sip服务器的密码@sip服务器的ip地址:sip服务器的port

deviceid:

前端设备20位编码

devicetype:

录像存储类型

localid:

本地二十位编码,可选项

localip:

本地ip,可选项

begtime:

录像起始时间

endtime:

录像结束时间

2.2.8. PCIE模式下BMCPU OPENCV加速

2.2.8.1. 概念介绍

Opencv有大量的图像处理函数在host cpu上实现,这样在PCIE环境下,就造成了host和板卡device设备之间交换同步内存的需求,而这种内存同步的速度要远远慢于内存cache的数据同步速度,从而给PCIE环境下的应用开发造成了瓶颈。而我们在的BM168x板卡上的每颗SOC都有强大的ARM Cortex A53处理器资源,目前在PCIE环境下处于闲置状态,因此BMCPU Opencv试图将Host Opencv和Device Opencv之间的功能函数映射起来,将Host Opencv的操作实际用Device Opencv的操作来实现,保证所有的数据都在Device Memory中进行,无需通过PCIE和host发生交换,从而一方面降低对Host CPU的压力,降低CPU处理器的处理性能要求,另一方面提高运行速度,消除PCIE带宽所带来的瓶颈。

BMCPU OPENCV的函数用法与原生OPENCV完全一致,只是为了区别在前面加上”bmcpu_”前缀。

2.2.8.2. 使用说明

说明1. 凡是用BMCPU OPENCV改造过的接口,最新数据都位于device memory中。

这点与之前的opencv cache管理策略有不同。之前在YUV Mat中,最新数据都位于device memory中,而在RGB Mat中,最新数据都位于host memory中。经过BMCPU OPENCV引入后,后续当函数支持到足够数目的时候,我们将在PCIE模式下,无论RGB Mat还是YUV Mat都以device memory为准,这样所有的pcie opencv操作的内存都移到了device memory上,不占用host memory。在达到这个目的之前,为了兼容原有opencv函数的调用,保留原函数,然后统一加上”bmcpu_”前缀的方式,重命名已修改的函数。可以查询我们的已完成函数列表来做对应操作。

对于列表中的函数,无论yuv Mat还是RGB Mat最新数据都在device memory中。当客户需要将其同步到host memory中的时候,需要手动调用bmcv::downloadMat()接口,当需要将host memory中的数据同步到device memory中时,需要调用bmcv::uploadMat()接口。

这点尤其重要,在调用改造过的函数前,如果最新数据在host memory中,就需要将其同步到device memory。这在当Mat采用Scalar::all(),Zeros(), Ones()等函数初始化的时候尤其容易忽略,这时候要记得调用bmcv::uploadMat()将初始化同步到设备内存中。反之,当函数结束,后续处理需要在host memory中进行的时候,就需要调用bmcv::downloadMat()下载下来。

当输入输出Mat没有device内存的时候,函数会自动同步到host内存中,并且释放内部开辟的device内存。

说明2. 参数传递的时候,要求与Mat有关的参数放在最前面。因为Mat的内存结构是提前分配好的,只能修改,不能重新分配。

说明3. 已完成函数列表

已完成函数接口

修改后函数

说明

cv::calcOpticalFlowPyrLK()

cv::bmcpu_calcOp ticalFlowPyrLK()

稀疏光流函数,支持标准BGR Mat格式

cv::calcOpticalFlowFarneback()

cv:: bmcpu_calcOptica lFlowFarneback()

稠密光流函数,支持标准BGR Mat格式

cv::gaussianBlur()

cv::bmcp u_gaussianBlur()

支持BGR Mat格式

cv::bilateralFilter()

cv::bmcpu_b ilateralFilter()

支持BGR Mat格式

cv::boxFilter()

cv::b mcpu_boxFilter()

支持BGR Mat格式

cv::calcHist()

cv:: bmcpu_calcHist()

c alcHist函数共有三个函数类型,除了S parseMat不支持外,其他两个均支持。

cv::warpAffine()

cv::bm cpu_warpAffine()

支持BGR Mat格式

cv::sobel()

c v::bmcpu_sobel()

支持BGR Mat格式

cv::erode()

c v::bmcpu_erode()

支持BGR Mat格式

cv::dialet()

cv ::bmcpu_dialet()

支持BGR Mat格式

cv::morphologyEx

cv::bmcp u_morphologyEx()

支持BGR Mat格式

cv::line()

cv::bmcpu_line()

Open cv中的画线函数,可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

cv::putText()

cv: :bmcpu_putText()

可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

cv::rectangle()

cv::b mcpu_rectangle()

可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

cv::circle()

cv ::bmcpu_circle()

可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

cv::ellipse()

cv: :bmcpu_ellipse()

1,对应opencv中的函数:void ellipse (InputOutput

Array _img, Point center, Size axes,double angle,double start_angle,double end_angle,const Scalar & color,int thickness,int line_type,int shift)

2, 可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

cv::ellipse()

cv:: bmcpu_ellipse2()

1,对应opencv中的函数:void ellipse(InputOutput

Array _img, const RotatedRect& box, const Scalar & color,int thickness, int lineType)

2,可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

cv::polylines()

cv::b mcpu_polylines()

可同时支持YUV和RGB Mat两种类型。YUV支持YUV420P格式

FreeType2::loadFontData()

cv::bmcp u_loadFontData()

对应FreeType2类加载字库

cv::bmcpu_unloadFontData()

释放字库资源,与bmcpu_loadFontData成对调用

FreeType2::setSplitNumber()

cv::bmcpu_setSplitNumber()

Ft2类接口

FreeType2::getTextSize()

cv::bmc pu_getTextSize()

Ft2类接口

FreeType2::putText()

cv::bmc pu_ft2_putText()

可同时支持YUV和RGB Mat

2.2.9. 代码实例

代码实例见bmnnsdk2软件包中的examples/multimedia。

2.3. SOPHGO FFMPEG使用指南

2.3.1. 前言

BM168x系列芯片中,有一个8核的A53处理器,同时还内置有视频、图像相关硬件加速模块。在SOPHGO提供的FFMPEG SDK开发包中,提供了对这些硬件模块的接口。其中,通过这些硬件接口,提供了如下模块:硬件视频解码器、硬件视频编码器、硬件JPEG解码器、硬件JPEG编码器、硬件scale filter、hwupload filter、hwdownload filter。

FFMPEG SDK开发包符合FFMPEG hwaccel编写规范,实现了视频转码硬件加速框架,实现了硬件内存管理、各个硬件处理模块流程的组织等功能。同时FFMPEG SDK也提供了与通常CPU解码器兼容的接口,以匹配部分客户的使用习惯。这两套接口我们称之为HWAccel接口和常规接口,他们底层共享BM168x硬件加速模块,在性能上是相同的。区别仅在于1)HWAccel需要初始化硬件设备 2)HWAccel接口只面向设备内存,而常规接口同时分配了设备内存和系统内存 3)他们的参数配置和接口调用上有轻微差别。

下面描述中,如非特殊说明,对常规接口和HWAccel接口都适用。

2.3.2. 硬件视频解码器

BM168x系列支持H.264和H.265硬件解码。硬件解码器性能详情如下表所述。

Standard

Profile

Level

Max R esolution

Min R esolution

Bit rate

H.264/AVC

BP/CBP/MP/HP

4.1

8192x4096

16x16

50Mbps

H.265/HEVC

Main/Main10

L5.1

8192x4096

16x16

N/A

在SophGo的FFMPEG发布包中,H.264硬件视频解码器的名字为h264_bm,H.265硬件视频解码器的名字为hevc_bm。可通过如下命令, 来查询FFMPEG支持的编码器。

$ ffmpeg -decoders | grep _bm

2.3.2.1. 硬件视频解码器支持的选项

FFMPEG中,BM168x系列的硬件解码器提供了一些额外选项,可以通过如下命令查询。

$ ffmpeg -h decoder=h264_bm

$ ffmpeg -h decoder=hevc_bm

这些选项可以使用av_dict_set API来设置。在设置之前,需要对对这些选项有正确的理解。下面详细解释一下这些选项。

output_format:

  • 输出数据的格式。

  • 设为0,则输出线性排列的未压缩数据;设为101,则输出压缩数据。

  • 缺省值为0。

  • 推荐设置为101,输出压缩数据。可以节省内存、节省带宽。输出的压缩数据,可以调用后面介绍的scale_bm filter解压缩成正常的YUV数据。具体可参考应用示例中的示例1。

cbcr_interleave:

  • 硬件视频解码器解码输出的帧色度数据是否是交织格式。

  • 设为1,则输出为semi-planar yuv图像,譬如nv12;设为0,则输出planar yuv图像,譬如yuv420p。

  • 缺省值为1。

extra_frame_buffer_num:

  • 硬件视频解码器额外提供硬件帧缓存数量。

  • 缺省值为5。最小值为1。

skip_non_idr:

  • 跳帧模式。0,关闭;1,跳过Non-RAP帧;2,跳过非参考帧。

  • 缺省值为0。

handle_packet_loss

  • 出错时,对H.264, H.265解码器使能丢包处理。0, 不做丢包处理;1,进行丢包处理。

  • 缺省值为0。

sophon_idx:

  • PCIE模式下的sophon设备的编号。与/dev/bm-sophon的设备编号一致。

  • 缺省值为0。

zero_copy:

  • 将设备上的帧数据直接拷贝到AVFrame的data[0]-data[3]所自动申请的系统内存里。1,关闭拷贝;0,使能拷贝。

  • 缺省值为1。

2.3.3. 硬件视频编码器

从BM1684开始首次添加了硬件视频编码器。 支持H.264/AVC和H.265/HEVC视频编码。

BM1684硬件编码器设计的能力为: 能够实时编码一路1080P30的视频。具体指标如下:

H.265编码器:

  • Capable of encoding HEVC Main/Main10/MSP(Main Still Picture) Profile @ L5.1 High-tier

H.264编码器:

  • Capable of encoding Baseline/Constrained Baseline/Main/High/High 10 Profiles Level @ L5.2

通用指标

  • 最大分辨率 : 8192x8192

  • 最小分辨率 : 256x128

  • 编码图像宽度须为8的倍数

  • 编码图像高度宽度须为8的倍数

在SophGo的FFMPEG发布包中,H.264硬件视频编码器的名字为h264_bm,H.265硬件视频编码器的名字为h265_bmhevc_bm。可通过如下命令, 来查询FFMPEG支持的编码器。

$ ffmpeg -encoders

2.3.3.1. 硬件视频编码器支持的选项

FFMPEG中, 硬件视频编码器提供了一些额外选项,可以通过如下命令查询。

$ ffmpeg -h encoder=h264_bm

$ ffmpeg -h encoder=hevc_bm

BM1684硬件视频编码器支持如下选项:

preset: 预设编码模式。推荐通过enc-params设置。

  • 0 - fast, 1 - medium, 2 - slow。

  • 缺省值为2。

gop_preset: gop预设索引值。推荐通过enc-params设置。

  • 1: all I, gopsize 1

  • 2: IPP, cyclic gopsize 1

  • 3: IBB, cyclic gopsize 1

  • 4: IBPBP, cyclic gopsize 2

  • 5: IBBBP, cyclic gopsize 4

  • 6: IPPPP, cyclic gopsize 4

  • 7: IBBBB, cyclic gopsize 4

  • 8: random access, IBBBBBBBB, cyclic gopsize 8

qp:

  • 恒定量化参数的码率控制方法

  • 取值范围为0至51

perf:

  • 用于指示是否需要测试编码器性能

  • 取值范围为0或1。

enc-params:

  • 用于设置视频编码器内部参数。

  • 支持的编码参数:preset,gop_preset,qp,bitrate,mb_rc,delta_qp,min_qp,max_qp,bg,nr,deblock,weightp

  • 编码参数preset:取值范围为fast, medium, slow或者是0,1,2

  • 编码参数gop_preset:gop预设索引值。参考上面已有详细解释。

1: all I, gopsize 1

2: IPP, cyclic gopsize 1

3: IBB, cyclic gopsize 1

4: IBPBP, cyclic gopsize 2

5: IBBBP, cyclic gopsize 4

6: IPPPP, cyclic gopsize 4

7: IBBBB, cyclic gopsize 4

8: random access, IBBBBBBBB, cyclic gopsize 8

  • 编码参数qp:恒定量化参数,取值范围为[0, 51]。当该值有效时,关闭码率控制算法,用固定的量化参数编码。

  • 编码参数bitrate:用于编码所指定的码率。单位是Kbps,1Kbps=1000bps。当指定改参数时,请不要设置编码参数qp。

  • 编码参数mb_rc:取值范围0或1。当设为1时,开启宏块级码率控制算法;当设为0时,开启帧级码率控制算法。

  • 编码参数delta_qp:用于码率控制算法的QP最大差值。该值太大影响视频主观质量。太小影响码率调整的速度。

  • 编码参数min_qp和max_qp:码率控制算法中用于控制码率和视频质量的最小量化参数和最大量化参数。取值范围[0, 51]。

  • 编码参数bg:是否开启背景检测。取值范围0或1。

  • 编码参数nr:是否开启降噪算法。取值范围0或1。

  • 编码参数deblock:是否开启环状滤波器。有如下几种用法:

    • 关闭环状滤波器“deblock=0”或“no-deblock”。

    • 简单开启环状滤波器,使用缺省环状滤波器参数”deblock=1”。

    • 开启环状滤波器并设置参数,譬如”deblock=6,6”。

  • 编码参数weightp:是否开启P帧、B帧加权预测。取值范围0或1。

sophon_idx: 仅适用于PCIE模式

  • 用于指出要使用的Sophon设备的编号。与/dev/bm-sophon的编号一致。

  • 最小值为0, 最大值为Sophon设备数量减1

  • 仅适用于常规接口。

is_dma_buffer:

  • 用于提示编码器,输入的帧缓存是否为设备上的连续物理内存地址。

  • 在PCIE模式时,值0表示输入的是系统内存虚拟地址;在SoC模式,值0表示输入的是设备内存的虚拟地址。值1表示,输入的是设备上的连续物理地址。

  • 缺省值为1。

  • 仅适用于常规接口。

2.3.4. 硬件JPEG解码器

在BM168x系列芯片中,硬件JPEG解码器提供硬件JPEG图像解码输入能力。这里介绍一下,如何通过FFMPEG来实现硬件JPEG解码。

在FFMPEG中, 硬件JPEG解码器的名称为 jpeg_bm。可以通过如下命令, 来查看FFMPEG中是否有jpeg_bm解码器。

$ ffmpeg -decoders | grep jpeg_bm

2.3.4.1. 硬件JPEG解码器支持的选项

FFMPEG中, 可以通过如下命令, 来查看jpeg_bm解码器支持的选项

$ ffmpeg -h decoder=jpeg_bm

解码选项的说明如下。硬件JPEG解码器中这些选项, 可以使用 av_dict_set() API 函数对其进行重置。

bs_buffer_size: 用于设置硬件JPEG解码器中输入比特流的缓存大小(KBytes)。

  • 取值范围(0到INT_MAX)

  • 缺省值5120

cbcr_interleave: 用于指示JPEG解码器输出的帧数据中色度数据是否为交织的格式。

  • 0: 输出的帧数据中色度数据为plannar的格式

  • 1: 输出的帧数据中色度数据为interleave的格式

  • 缺省值为0

num_extra_framebuffers: JPEG解码器需要的额外帧缓存数量

  • 对于Still JPEG的输入, 建议该值设为0

  • 对于Motion JPEG的输入, 建议该值至少为2

  • 取值范围(0到INT_MAX)

  • 缺省值为2

sophon_idx: 仅适用于PCIE模式。

  • 用于指出要使用的Sophon设备的编号。 与/dev/bm-sophon的编号一致

  • 最小值为0, 最大值为Sophon设备数量减1

  • 仅适用于常规接口。

zero_copy:

  • 将设备上的帧数据直接拷贝到AVFrame的data[0]-data[3]所自动申请的内存里。0,关闭拷贝;1,使能拷贝。

  • 缺省值为1。

  • 仅适用于旧接口的PCIE模式。新接口提供hwdownload filter,可以显式地把数据从设备内存下载到系统内存。

2.3.5. 硬件JPEG编码器

在BM168x系列芯片中,硬件JPEG编码器提供硬件JPEG图像编码输出能力。这里介绍一下,如何通过FFMPEG来实现硬件JPEG编码

在FFMPEG中,硬件JPEG编码器的名称为 jpeg_bm。可以通过如下命令,来查看FFMPEG中是否有jpeg_bm编码器。

$ ffmpeg -encoders | grep jpeg_bm

2.3.5.1. 硬件JPEG编码器支持的选项

FFMPEG中,可以通过如下命令, 来查看jpeg_bm编码器支持的选项

$ ffmpeg -h encoder=jpeg_bm

编码选项的说明如下。硬件JPEG编码器中这些选项, 可以使用 av_dict_set() API 函数对其进行重置。

sophon_idx: 仅适用于PCIE模式

  • 用于指出要使用的Sophon设备的编号。 与/dev/bm-sophon的编号一致。

  • 最小值为0, 最大值为Sophon设备数量减1

  • 仅适用于常规接口。

is_dma_buffer:

  • 用于提示编码器,输入的帧缓存是否为设备上的连续物理内存地址。

  • 在PCIE模式时,值0表示输入的是系统内存虚拟地址;在SoC模式,值0表示输入的是设备内存的虚拟地址。值1表示,输入的是设备上的连续物理地址。

  • 缺省值为1。

  • 仅适用于常规接口。

2.3.6. 硬件scale filter

BM168x系列硬件scale filter用于将输入的图像进行”缩放/裁剪/补边”操作。譬如,转码应用。在将1080p的视频解码后,使用硬件scale缩放成720p的,再进行压缩输出。

内容

最大分辨率

最小分辨率

放大倍数

硬件限制

4096 * 4096

8*8

32

在FFMPEG中,硬件scale filter的名称为 scale_bm

$ ffmpeg -filters | grep bm

2.3.6.1. 硬件scale filter支持的选项

FFMPEG中,可以通过如下命令, 来查看scaler_bm编码器支持的选项

$ ffmpeg -h filter=scale_bm

scale_bm选项的说明如下:

w:

  • 缩放输出视频的宽度。 请参考ffmpeg scale filter的用法。

h:

  • 缩放输出视频的高度。 请参考ffmpeg scale filter的用法。

format:

  • 缩放输出视频的像素格式。 请参考ffmpeg scale filter的用法。

  • 输入输出支持的格式详见附表7.1。

  • 缺省值”none”。 即输出像素格式为系统自动。输入为yuv420p,输出为yuv420p; 输入为yuvj420p,输出为yuvj420p。输入为nv12时,缺省输出为yuv420p。

  • 在HWAccel框架下:支持nv12到yuv420p、nv12到yuvj420p、yuv420p到yuvj420p、yuvj422p到yuvj420p、yuvj422p到yuv420p的格式转换。在不启用HWAccel框架的正常模式下支持情况见附表7.1。

输入

出 是否

持缩放 是

色转换

GRAY8

GRAY8

NV12(压缩) YU

420P 是

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

NV12(非压缩) YUV

20P 是

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

YUV420P

YUV420P

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

YUV422P

YUV420P

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

YUV444P

YUV420P

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

BGR、RGB

YUV420P

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

RGBP、BGRP

YUV420P

YUV422P

YUV444P

BGR

RGB

RGBP

BGRP

图7.1 scale_bm像素格式支持列表

opt:

  • 缩放操作 (from 0 to 2) (default 0)

  • 值0 - 仅支持缩放操作。缺省值。

  • 值1 - 支持缩放+自动裁剪操作。命令行参数中可用crop来表示。

  • 值2 - 支持缩放+自动补黑边操作。命令行参数中可用pad来表示。

flags:

  • 缩放方法 (from 0 to 2) (default 2)

  • 值0 - bilinear滤波器。命令行参数中,可用bilinear来表示。

  • 值1 - nearest滤波器。命令行参数中,可用nearest来表示。

  • 值2 - bicubic滤波器。命令行参数中,可用bicubic来表示。

sophon_idx:

  • 设备ID , 从0开始。

zero_copy:

  • 值0 - 表示scale_bm的输出AVFrame将同时包含设备内存和主机内存指针,兼容性最好,性能稍有下降。 缺省为0

  • 值1 - 表示scale_bm的输出到下一级的AVFrame中将只包含有效设备地址,不会对数据进行从设备内存到系统内存的同步。建议对于下一级接使用SOPHGO的编码/filter的情况,可以选择设置为1,其他建议设置为0。

  • 缺省为0

2.3.7. AVFrame特殊定义说明

遵从FFMPEG的规范, 硬件解码器是通过AVFrame来提供输出的,硬件编码器是通过AVFrame来提供输入的。因此,在通过API方式,调用FFMPEG SDK、进行硬件编解码处理时,需要注意到AVFrame的如下特殊规定。AVFrame是线性YUV输出。在AVFrame中,data为数据指针, 用于保存物理地址,linesize为每个平面的线跨度。

2.3.7.1. 硬件解码器输出的avframe接口定义

2.3.7.1.1. 常规接口

data数组的定义

下标

说明*

0

Y的虚拟地址

1

cbcr_interleave=1 时CbCr的虚拟地址; cbcr_interleave=0 时Cb的虚拟地址

2

cbcr_interleave=0 时Cr的虚拟地址

3

未使用

4

Y的物理地址

5

cbcr_interleave=1 时CbCr的物理地址; cbcr_interleave=0 时Cb的物理地址

6

cbcr_interleave=0 时Cr的物理地址

7

未使用

linesize数组的定义

下标

说明*

0

Y的虚拟地址的跨度

1

cbcr_interleave=1时CbCr的虚拟地址的跨度; cbcr_interleave=0时Cb的虚拟地址的跨度

2

cbcr_interleave=0时Cr的虚拟地址的跨度

3

未使用

4

Y的物理地址的跨度

5

cbcr_interleave=1时CbCr的物理地址的跨度; cbcr_interleave=0时Cb的物理地址的跨度

6

cbcr_interleave=0时Cr的物理地址的跨度

7

未使用

2.3.7.1.2. HWAccel接口

data数组的定义

下 标

未压缩格式说明

压缩格式明

0

Y的物理地址

压缩的亮度数据的物理地址

1

cbcr_interleave=1 时CbCr的物理地址; cbcr_interleave=0 时Cb的物理地址

压缩的色度数据的物理地址

2

cbcr_interleave=0 时Cr的物理地址

亮度数据的偏移量表的物理地址

3

保留

度数据的偏移量表的物理地址

4

保留

保留

linesize数组的定义

下 标

未压缩格式说明

压缩格式说明

0

Y的物理地址的跨度

亮度数据的跨

1

cbcr_interle ave=1时CbCr的物理地址的跨度; cbcr_int erleave=0时Cb的物理地址的跨度

色度数据的跨度

2

cbcr_int erleave=0时Cr的物理地址的跨度

亮度偏移量表的大小

3

未使用 色

偏移量表的大小

2.3.7.2. 硬件编码码器输入的avframe接口定义

2.3.7.2.1. 常规接口

data数组的定义

下标

说明*

0

Y的虚拟地址

1

Cb的虚拟地址

2

Cr的虚拟地址

3

保留

4

Y的物理地址

5

Cb的物理地址

6

Cr的物理地址

7

未使用

linesize数组的定义

下标

说明*

0

Y的虚拟地址的跨度

1

Cb的虚拟地址的跨度

2

Cr的虚拟地址的跨度

3

未使用

4

Y的物理地址的跨度

5

Cb的物理地址的跨度

6

Cr的物理地址的跨度

7

未使用

2.3.7.2.2. HWAccel接口

data数组的定义

下标

说明*

0

Y的物理地址

1

Cb的物理地址

2

Cr的物理地址

3

保留

4

保留

linesize数组的定义

下标

说明*

0

Y的物理地址的跨度

1

Cb的物理地址的跨度

2

Cr的物理地址的跨度

3

未使用

2.3.7.3. 硬件filter输入输出的AVFrame接口定义

  1. 在不启用HWAccel加速功能时,AVFrame接口定义采用常规接口的内存布局。

data数组的定义

下标

说明*

0

Y的虚拟地址

1

Cb的虚拟地址

2

Cr的虚拟地址

3

保留

4

Y的物理地址

5

Cb的物理地址

6

Cr的物理地址

7

未使用

linesize数组的定义

下标

说明*

0

Y的虚拟地址的跨度

1

Cb的虚拟地址的跨度

2

Cr的虚拟地址的跨度

3

未使用

4

Y的物理地址的跨度

5

Cb的物理地址的跨度

6

Cr的物理地址的跨度

7

未使用

  1. HWAccel接口下AVFrame接口定义

data数组的定义

下标

说明* **

缩格式的输入接口**

0

Y的物理地址 压缩的

度数据的物理地址

1

Cb物理地址 压缩

色度数据的物理地址

2

Cr物理地址 亮度

据的偏移量表的物理地址

3

保留

度数据的偏移量表的物理地址

4

保留

linesize数组的定义

下标

说明* **

缩格式的输入接口**

0

Y物理地址的跨度 亮度数据的

1

Cb物理地址的跨度 色度数据的

2

Cr物理地址的跨度 亮度偏移量

的大小

3

未使用 色

偏移量表的大小

2.3.8. 硬件加速在FFMPEG命令中的应用示例

下面同时给出常规模式和HWAccel模式对应的FFMPEG命令行参数。

为便于理解,这里汇总说明:

  • 常规模式下,bm解码器的输出内存是否同步到系统内存上,用zero_copy控制,默认为1。

  • 常规模式下,bm编码器的输入内存在系统内容还是设备内存上,用is_dma_buffer控制,默认值为1。

  • 常规模式下,bm滤波器会自动判断输入内存的同步,输出内存是否同步到系统内存,用zero_copy控制,默认值为0。

  • HWAccel模式下,设备内存和系统内存的同步用hwupload和hwdownload来控制。

  • 常规模式下,用sophon_idx来指定设备,默认为0;HWAccel模式下用hwaccel_device来指定。

2.3.8.1. 示例 1

使用设备0。解码H.265视频,输出compressed frame buffer,scale_bm解压缩compressed frame buffer并缩放成CIF,然后编码成H.264码流。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:zero_copy=1” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale.264

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale.264

2.3.8.2. 示例 2

使用设备0。解码H.265视频,按比例缩放并自动裁剪成CIF,然后编码成H.264码流。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=crop:zero_copy=1” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale_crop.264

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=crop” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale_crop.264

2.3.8.3. 示例 3

使用设备0。解码H.265视频,按比例缩放并自动补黑边成CIF,然后编码成H.264码流。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=pad:zero_copy=1” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale_pad.264

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=pad” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale_pad.264

2.3.8.4. 示例 4

演示视频截图功能。使用设备0。解码H.265视频,按比例缩放并自动补黑边成CIF,然后编码成jpeg图片。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=pad:format=yuvj420p:zero_copy=1” \

-c:v jpeg_bm -vframes 1 \

-y wkc_100_cif_scale.jpeg

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=pad:format=yuvj420p” \

-c:v jpeg_bm -vframes 1 \

-y wkc_100_cif_scale.jpeg

2.3.8.5. 示例 5

演示视频转码+视频截图功能。使用设备0。硬件解码H.265视频,缩放成CIF,然后编码成H.264码流;同时缩放成720p,然后编码成JPEG图片。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-filter_complex “[0:v]scale_bm=352:288:zero_copy=1[img1];[0:v]scale_bm=1280:720:format= \

yuvj420p:zero_copy=1[img2]” -map ‘[img1]’ -c:v h264_bm -b:v 256K -y img1.264 \

-map ‘[img2]’ -c:v jpeg_bm -vframes 1 -y img2.jpeg

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-filter_complex “[0:v]scale_bm=352:288[img1];[0:v]scale_bm=1280:720:format=yuvj420p[img2]” \

-map ‘[img1]’ -c:v h264_bm -b:v 256K -y img1.264 \

-map ‘[img2]’ -c:v jpeg_bm -vframes 1 -y img2.jpeg

2.3.8.6. 示例6

演示hwdownload功能。硬件解码H.265视频,然后下载存储成YUV文件。

Filter hwdownload专门为HWAccel接口服务,用于设备内存和系统内存的同步。在常规模式中,这步可以通过codec中指定zero_copy选项来实现,因此不需要hwdownload滤波器。

常规模式:

$ ffmpeg -c:v hevc_bm -cbcr_interleave 0 -zero_copy 0 \

-i src/wkc_100.265 -y test_transfer.yuv

HWAccel模式

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -cbcr_interleave 0 -i src/wkc_100.265 \

-vf “hwdownload,format=yuv420p bmcodec” \

-y test_transfer.yuv

2.3.8.7. 示例7

演示hwdownload功能。硬件解码H.265视频,缩放成CIF格式,然后下载存储成YUV文件。

在常规模式中, scale_bm会自动根据filter的链条判定是否同步内存,因此不需要hwdownload。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288,format=yuv420p” \

-y test_transfer_cif.yuv

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288,hwdownload,format=yuv420p bmcodec” \

-y test_transfer_cif.yuv

2.3.8.8. 示例8

演示hwupload功能。使用设备0。上传YUV视频,然后编码H.264视频。

Filter hwupload专门为HWAccel接口服务,用于设备内存和系统内存的同步。在常规模式中,这步可以通过编码器中指定is_dma_buffer选项来实现,因此不需要hwupload滤波器。

常规模式:

$ ffmpeg -s 1920x1080 -pix_fmt yuv420p -i test_transfer.yuv \

-c:v h264_bm -b:v 3M -is_dma_buffer 0 -y test_transfer.264

HWAccel模式:

$ ffmpeg -init_hw_device bmcodec=foo:0 \

-s 1920x1080 -i test_transfer.yuv \

-filter_hw_device foo -vf “format=yuv420p bmcodec,hwupload” \

-c:v h264_bm -b:v 3M -y test_transfer.264

这里foo为设备0的别名。

2.3.8.9. 示例9

演示hwupload功能。使用设备1。上传YUV视频,并缩放成CIF,然后编码H.264视频。

常规模式:

$ ffmpeg -s 1920x1080 -i test_transfer.yuv \

-vf “scale_bm=352:288:sophon_idx=1:zero_copy=1” \

-c:v h264_bm -b:v 256K -sophon_idx 1 \

-y test_transfer_cif.264

说明:1)这里不指定-pix_fmt yuv420p是因为默认输入为yuv420p格式

2)常规模式下,bm_scale filter, decoder,encoder通过参数sophon_idx来指定使用哪个设备

HWAccel模式:

$ ffmpeg -init_hw_device bmcodec=foo:1 \

-s 1920x1080 -i test_transfer.yuv \

-filter_hw_device foo \

-vf “format=yuv420p bmcodec,hwupload,scale_bm=352:288” \

-c:v h264_bm -b:v 256K -y test_transfer_cif.264

说明:这里foo为设备1的别名,HWAccel模式下通过init_hw_device来指定使用具体的硬件设备。

2.3.8.10. 示例10

演示hwdownload功能。硬件解码YUVJ444P的JPEG视频,然后下载存储成YUV文件。

常规模式:

$ ffmpeg -c:v jpeg_bm -zero_copy 0 -i src/car/1920x1080_yuvj444.jpg \

-y car_1080p_yuvj444_dec.yuv

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v jpeg_bm -i src/car/1920x1080_yuvj444.jpg \

-vf “hwdownload,format=yuvj444p bmcodec” \

-y car_1080p_yuvj444_dec.yuv

2.3.8.11. 示例11

演示hwupload功能。使用设备1。上传YUVJ444P图像数据,然后编码JPEG图片。

常规模式:

$ ffmpeg -s 1920x1080 -pix_fmt yuvj444p -i car_1080p_yuvj444.yuv \

-c:v jpeg_bm -sophon_idx 1 -is_dma_buffer 0 \

-y car_1080p_yuvj444_enc.jpg

HWAccel模式:

$ ffmpeg -init_hw_device bmcodec=foo:1 \

-s 1920x1080 -pix_fmt yuvj444p -i car_1080p_yuvj444.yuv \

-filter_hw_device foo -vf ‘format=yuvj444p bmcodec,hwupload’ \

-c:v jpeg_bm -y car_1080p_yuvj444_enc.jpg

这里foo为设备1的别名。

2.3.8.12. 示例12

演示软解码和硬编码混合使用的方法。使用设备2。使用ffmpeg自带的h264软解码器,解码H.264视频,上传解码后数据到芯片2,然后编码H.265视频。

常规模式:

$ ffmpeg -c:v h264 -i src/1920_18MG.mp4 \

-c:v h265_bm -is_dma_buffer 0 -sophon_idx 2 -g 256 -b:v 5M \

-y test265.mp4

HWAccel模式:

$ ffmpeg -init_hw_device bmcodec=foo:2 \

-c:v h264 -i src/1920_18MG.mp4 \

-filter_hw_device foo -vf ‘format=yuv420p bmcodec,hwupload’ \

-c:v h265_bm -g 256 -b:v 5M \

-y test265.mp4

这里foo为设备2的别名。

2.3.8.13. 示例13

演示使用enc-params设置视频编码器的方法。使用设备0。解码H.265视频,缩放成CIF,然后编码成H.264码流。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:zero_copy=1” \

-c:v h264_bm -g 50 -b:v 32K \

-enc-params “gop_preset=2:mb_rc=1:delta_qp=3:min_qp=20:max_qp=40” \

-y wkc_100_cif_scale_ipp_32Kbps.264

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288” \

-c:v h264_bm -g 50 -b:v 32K \

-enc-params “gop_preset=2:mb_rc=1:delta_qp=3:min_qp=20:max_qp=40” \

-y wkc_100_cif_scale_ipp_32Kbps.264

2.3.8.14. 示例14

使用设备0。解码H.265视频,使用bilinear滤波器,按比例缩放成CIF,并自动补黑边,然后编码成H.264码流。

常规模式:

$ ffmpeg -c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=pad:flags=bilinear:zero_copy=1” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale_pad.264

HWAccel模式:

$ ffmpeg -hwaccel bmcodec -hwaccel_device 0 \

-c:v hevc_bm -output_format 101 -i src/wkc_100.265 \

-vf “scale_bm=352:288:opt=pad:flags=bilinear” \

-c:v h264_bm -g 256 -b:v 256K \

-y wkc_100_cif_scale_pad.264

2.3.9. 通过调用API方式来使用硬件加速功能

examples/multimedia/ff_bmcv_transcode/例子演示了使用ffmpeg做编解码,用bmcv做图像处理的整个流程。

examples/multimedia/ff_video_decode/例子演示了使用ffmpeg做解码的流程。

examples/multimedia/ff_video_encode/例子演示了使用ffmpeg做编码的流程。

2.3.10. 硬件编码支持roi编码

参考examples/multimedia/ff_video_encode/例子。设置roi_enable既可启用roi编码。

Roi编码数据通过av_frame side data传递。

Roi数据结构定义为

../_images/Multim005.png

字段说明:

  • QP Map

H264下QP以宏块16x16为单位给出。HEVC下QP以sub-ctu(32x32)为单位给出。QP对应的就是video编码中的Qstep,取值范围为0-51.

  • Lamda Map

lamda是用来控制和调节IP内部的RC计算公式

cost = distortion + lamda * rate

这个调节参数仅在HEVC下有效,允许以32x32 sub-CTU模块为单位控制。

  • Mode Map

这个参数用来指定模式选择。 0 – 不适用 1 – skip mode 2- intra mode。H264下以宏块16x16为单位控制,HEVC下以CTU 64x64为单位控制。

  • Zero-cut Flag

仅在HEVC下有效。将当前CTU 64x64残差系数全部置为0,从而节省出更多的比特给其他更重要的部分。

2.4. SOPHGO LIBYUV使用指南

2.4.1. 简介

BM168x系列芯片中的各种硬件模块,可以加速对图片和视频的处理。颜色转换方面,采用专用硬件来加速速度很快。

但在有些场合,也会存在一些专用硬件覆盖不到的特殊情况。此时采用经过SIMD加速优化的软件实现, 成为专用硬件有力的补充。

SOPHGO增强版libyuv,是随同SDK一同发布的一个组件。目的是充分利用BM168x系列芯片提供的8核A53处理器,通过软件手段为硬件的局限性提供补充。

除了libyuv提供的标准函数之外,针对AI的需求,在SOPHGO增强版libyuv中补充了27个扩展函数。

注意:这里说的是运行在BM168x系列的A53处理器上,而不是host的处理器。这从设备加速的角度是可以理解的。这样可以避免占用host的CPU。

2.4.2. libyuv扩展说明

新增了如下增强AI应用方面的API。

2.4.2.1. fast_memcpy

void* fast_memcpy(void *dst, const void *src, size_t n)

功能

CPU SI MD指令实 现memcpy 功能。从 内存区域 src拷贝 n个字节 到内存区 域dst。

参数

src

内存区域

n

需要拷贝的字节数

dst

目的内存区域

返回值 返

一 个指向dst的指针

2.4.2.2. RGB24ToI400

int RGB24ToI400(const uint8_t* src_rgb24, int src_stride_rgb24, uint8_t* dst_y, int dst_stride_y, int width, int height);

功能

一帧BGR数据转 换成BT.601灰度数据

参数

rc_rgb24

acked BGR图像数据所在的内存虚地址

src_stride_rgb24

内存中每行BGR图像实际跨度

dst_y

灰度图像虚拟地址

dst_stride_y

内存中每行灰度图像实际跨度

width

每行BGR图像数据中packed BGR的数量

height

BGR图像数据的有效行数

返回值 0

正常结束; 非0, 参数异常。

2.4.2.3. RAWToI400

int RAWToI400(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_y, int dst_stride_y, int width, int height);

功能

一帧RGB数据转换 成BT.601灰度数据

参数

rc_raw

acked RGB图像数据所在的内存虚地址

src_stride_raw

内存中每行RGB图像实际跨度

dst_y

灰度图像虚拟地址

dst_stride_y

内存中每行灰度图像实际跨度

width

每行RGB图像数据中packed RGB的数量

height

RGB图像数据的有效行数

返回值 0

正常结束; 非0,参数异常。

2.4.2.4. I400ToRGB24

int I400ToRGB24(const uint8_t* src_y, int src_stride_y, uint8_t* dst_rgb24, int dst_stride_rgb24, int width, int height);

功能

一帧BT.601灰度 数据转换成BGR数据

参数

rc_y

度图像虚拟地址

src_stride_y

内存中每行灰度图像实际跨度

dst_rgb24

packed BGR图像数据所在的内存虚地址

dst_stride_rgb24

内存中每行BGR图像实际跨度

width

每行BGR图像数据中packed BGR的数量

height

BGR图像数据的有效行数

返回值 0

正常结束;非0, 参数异常。

2.4.2.5. I400ToRAW

int I400ToRAW(const uint8_t* src_y, int src_stride_y, uint8_t* dst_raw, int dst_stride_raw, int width, int height);

功能

一 帧BT.601灰度数 据转换成RGB数据

参数

rc_y

度图像虚拟地址

src_stride_y

内存中每行灰度图像实际跨度

dst_raw

packed RGB图像数据所在的内存虚地址

dst_stride_raw

内存中每行RGB图像实际跨度

width

每行RGB图像数据中packed RGB的数量

height

RGB图像数据的有效行数

返回值 0

正常结束; 非0, 参数异常。

2.4.2.6. J400ToRGB24

int J400ToRGB24(const uint8_t* src_y, int src_stride_y, uint8_t* dst_rgb24, int dst_stride_rgb24, int width, int height);

功能

一帧BT.601 full range灰度 数据转换成BGR数据

参数

rc_y

度图像虚拟地址

src_stride_y

内存中每行灰度图像实际跨度

dst_rgb24

packed BGR图像数据所在的内存虚地址

dst_stride_rgb24

内存中每行BGR图像实际跨度

width

每行BGR图像数据中packed BGR的数量

height

BGR图像数据的有效行数

返回值 0

正常结束;非0, 参数异常。

2.4.2.7. RAWToJ400

int RAWToJ400(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_y, int dst_stride_y, int width, int height);

功能

一帧RGB 数据转换成BT.601 full range灰度数据

参数

rc_raw

acked RGB图像数据所在的内存虚地址

src_stride_raw

内存中每行RGB图像实际跨度

dst_y

灰度图像虚拟地址

dst_stride_y

内存中每行灰度图像实际跨度

width

每行RGB图像数据中packed RGB的数量

height

RGB图像数据的有效行数

返回值 0

正常结束;非0, 参数异常。

2.4.2.8. J400ToRAW

int J400ToRAW(const uint8_t* src_y, int src_stride_y, uint8_t* dst_raw, int dst_stride_raw, int width, int height);

功能

一帧BT.601 full range灰度数 据转换成RGB数据

参数

rc_y

度图像虚拟地址

src_stride_y

内存中每行灰度图像实际跨度

dst_raw

packed RGB图像数据所在的内存虚地址

dst_stride_raw

内存中每行RGB图像实际跨度

width

每行RGB图像数据中packed RGB的数量

height

RGB图像数据的有效行数

返回值 0

正常结束;非0, 参数异常。

2.4.2.9. RAWToNV12

int RAWToNV12(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_y, int dst_stride_y, uint8_t* dst_uv, int dst_stride_uv, int width, int height);

功能

一帧YCbCr 4 00图像数据转换 成semi-plannar YCbCr 420 数据可用于full range, 也可 以用于limited r ange的。不涉及 颜色空间转换, 可灵活使用。

参数

rc_y

图像Y分量的虚拟地址

src_stride_y

内存中每行Y分量数据的实际跨度

src_u

源图像Cb分量的虚拟地址

src_stride_u

内存中每行Cb分量数据的实际跨度

src_v

源图像Cr分量的虚拟地址

src_stride_v

内存中每行Cr分量数据的实际跨度

dst_y

目的图像Y分量的虚拟地址

dst_stride_y

内存中每行Y分量数据的实际跨度

dst_uv

目的图像CbCr分量的虚拟地址

dst_stride_uv

内存中每行CbCr分量数据的实际跨度

width

每行图像数据中像素的数量

height

图像数据像素的有效行数

返 回值

0, 常结束;非0, 参数异常。