openh264使用指南

概述

目前openh264官网只有一些问答,关键的开发资料全在github页的的wiki页面(https://github.com/cisco/openh264/wiki)

同样官方的二进制库也在github页的release页面上提供下载(https://github.com/cisco/openh264/releases)

此文章所述皆为windows平台,其他平台使用类似。此文章所使用的openh264版本为1.6,openh264没有提供导入库,只能使用动态加载的方式使用。

使用

获取对象

首先使用LoadLibraryGetProcAddressAPI获取到dll提供的函数接口。一共有6个接口

WelsCreateDecoder;
WelsCreateSVCEncoder;
WelsDestroyDecoder;
WelsDestroySVCEncoder;
WelsGetCodecVersion;
WelsGetCodecVersionEx;

调用WelsCreateDecoder接口可以获取解码器对象。
调用WelsCreateSVCEncoder接口可以获取编码器对象。

此节内容并没有在官方文档中写明,所以在此特别说明。

获取到的是一个c++对象指针,通过这个指针,可以调用对象的方法。对象的头文件在源码的codec\api\svc目录下的codec_api.h(官方文档中对此也没有做出说明)。

编码器

通过WelsCreateSVCEncoder接口获取到的对象是ISVCEncoder类型指针。

初始化

首先调用对象的GetDefaultParams方法获取到默认的参数结构,然后覆盖自己的参数,具体值根据实际情况决定,参数的含义参考文档。
其中需要注意的是iSpatialLayerNum,指定要输出几路码流,通常设为1。
然后要将参数中的sSpatialLayers码流参数数组的参数也填为指定码流的参数。数组元素的数量由iSpatialLayerNum决定。

调用对象的InitializeExt方法,传入修改过的参数,初始化编码器对象。
然后调用

int videoFormat = videoFormatI420;
SetOption(ENCODER_OPTION_DATAFORMAT, &videoFormat);

设置传入图像的格式,目前只支持yuv420,所以这句是固定的。
至此编码器参数设置的已经完成。

编码

真正的编码需要调用对象的EncodeFrame方法。方法需要两个参数,一个SSourcePicture指针类型的用来存放待编码的yuv数据,一个SFrameBSInfo指针类型的用来获取编码后的NAL单元数据。
SSourcePicture类型的对象内容如下:
iPicWidth:传入图像宽度。
iPicHeight:传入图像高度。
iColorFormat:传入图像格式,目前只有一种videoFormatI420
iStride:yuv3个通道的行宽数组。
pData:yuv3个通道的数据指针数组。
调用EncodeFrame方法,传入正确填充的SSourcePicture指针类型的参数和置零的SFrameBSInfo指针类型参数。
然后查看返回值,如果返回值为0并且SFrameBSInfo类型参数的eFrameType字段不等于videoFrameTypeSkip说明有数据被编码出来。
数据存放在SFrameBSInfo类型参数的sLayerInfo结构数组中。其中每个结构体中的pBsBuf表示编码得到的数据,
而长度是结构体pNalLengthInByteint数组加起来的和,数组的长度由结构体的iNalCount成员表示。

而编码得到的数据内存不需要释放,编码器每次调用对象的EncodeFrame方法时会重用这块内存,也就是说编码出来的数据的在下次调用对象的EncodeFrame方法前有效。在销毁编码器的时候释放这块内存。

销毁

调用编码器的对象的Uninitialize方法,然后调用WelsDestroySVCEncoder接口,传入之前获得的编码器对象指针。即可销毁对象,释放资源。

解码器

通过WelsCreateDecoder接口获取到的对象是ISVCDecoder类型指针。

初始化

建立一个SDecodingParam类型的空的参数结构体,,具体值根据实际情况决定,参数的含义参考文档。需要特别说明的是bParseOnly字段,便是是否要仅仅解析内容,通常用来测试,所以正常使用的时候设为false

调用解码器对象的Initialize方法,传入填充正确的SDecodingParam类型参数。

解码

真正的解码需要调用解码器对象的DecodeFrameNoDelay方法,此方法需要4个参数,第一个unsigned char指针类型参数表示传入的NAL单元起始的地址,第二个int型参数表示NAL单元的长度。第三个unsigned char指针数组类型参数用来接收解码完的图像数据,需要提前分配好数组空间,但是实际的每个指针指向的内存不用分配。第四个是置空的SBufferInfo指针类型参数,获取解码的数据的一些信息。

调用解码器对象的DecodeFrameNoDelay方法,传入对应的参数,接收返回值,如果返回后等于0并且,SBufferInfo类型参数中的iBufferStatus等于1。就代表成功解码出了数据。

解码出的图像数据按照通道分别存放在传入的第三个参数的指针数组里。SBufferInfo类型参数中的UsrData.sSystemBuffer.iWidth指示图像的宽度,SBufferInfo类型参数中的UsrData.sSystemBuffer.iHeight指示图像的高度,SBufferInfo类型参数中的sDstBufInfo.UsrData.sSystemBuffer.iStride数组指示每个通道的行宽。
根据这3个参数就可以将解码得到数据中的有效的图像数据拿出来。

销毁

调用解码器的对象的Uninitialize方法,然后调用WelsDestroyDecoder接口,传入之前获得的解码器对象指针。即可销毁对象,释放资源。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐