【鸿蒙实战开发】音视频解码-获取支持的编解码能力

前言

因来源不同、编解码器协议不同以及设备在编解码能力部署上的不同,在不同设备上开发者可用的编解码器及其能力是有差异的。

为确保编解码行为符合预期,开发者应提前通过音视频编解码能力系列接口查询系统支持的音视频编解码器及其关联的能力参数,找到符合开发场景需求的编解码器,并正确配置编解码参数。

通用开发指导

  1. 在CMake脚本中链接动态库。
target_link_libraries(sample PUBLIC libnative_media_codecbase.so)
  1. 添加头文件。
#include <multimedia/player_framework/native_avcapability.h>
#include <multimedia/player_framework/native_avcodec_base.h>
  1. 获得音视频编解码能力实例。

    支持两种获取音视频编解码能力实例的方式:

方式一:通过OH_AVCodec_GetCapability获取框架推荐的音视频编解码器能力实例。与OH_XXX_CreateByMime系列接口框架推荐策略一致。

   // 获取系统推荐的音频AAC解码器能力实例
OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, false);

方式二:通过OH_AVCodec_GetCapabilityByCategory获取指定软件或硬件的编解码能力实例。

// 获取指定硬件的视频AVC编码器能力实例
OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true, HARDWARE);

若获取能力实例成功,则可继续向下执行。开发者无需关注该实例的回收问题,框架会自行回收。

  1. 按需调用相应查询接口,详细的API说明请参考API文档。

场景化开发指导

基于开发者可能遇到特定场景,举例说明能力查询接口使用方法。

创建指定名称的编解码器

如系统内存在相同MIME类型的多个编码器或多个解码器。使用OH_XXX_CreateByMime系列接口只能创建系统推荐的特定编解码器。若需创建其他编解码器,开发者可先获取编解码器名称,再通过OH_XXX_CreateByName系列接口创建指定名称的编解码器。

接口 功能描述
OH_AVCapability_GetName 获取能力实例对应编解码器的名称

H.264软件解码器和H.264硬件解码器共存时,创建H.264软件解码器示例:

// 1. 获取H.264软件解码器能力实例
OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE);
if (capability != nullptr) {
   // 2. 获取H.264软件解码器名称
   const char *codecName = OH_AVCapability_GetName(capability);
   // 3. 创建H.264软件解码器实例
   OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(codecName);
}

针对软硬件类别差异化配置编解码器参数

软件编解码器和硬件编解码器定义如下:

  • 软件编解码器: 指在CPU上进行编解码工作的编解码器,能力可灵活迭代,相比硬件编解码器具有更好的兼容性,更好的协议和规格扩展能力。

  • 硬件编解码器: 指在专有硬件上进行编解码工作的编解码器,其特点是已在硬件平台硬化,能力随硬件平台迭代。相比软件编解码器具有更好的功耗、耗时和吞吐表现,同时能降低CPU负载。

基于上述软件编解码器和硬件编解码器的特点,在硬件编解码器满足要求的时候,优先使用硬件编解码器,否则使用软件编解码器。开发者可基于软件还是硬件类别差异化配置编解码参数。

接口 功能描述
OH_AVCapability_IsHardware 确认能力实例对应的编解码器是否是硬件的

视频编码,软硬件差异化配置帧率示例:

// 1. 确认推荐的H.264编码器的软硬件类别
OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
bool isHardward = OH_AVCapability_IsHardware(capability);
// 2. 基于软硬件类别差异化配置
OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080);
double frameRate = isHardward ? 60.0 : 30.0;
if (!OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate)) {
   // 异常处理
}
if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) {
   // 异常处理
}
OH_AVFormat_Destroy(format);

创建多路编解码器

部分业务场景涉及创建多路编解码器,基于各类资源的限制,某一编解码器的实例数是有限的,不能无限制创建。

接口 功能描述
OH_AVCapability_GetMaxSupportedInstances 获取能力实例对应编解码器可同时运行的最大实例数,实际能成功创建的数目还受系统其他资源的约束

优先创建硬件解码器实例,不够时再创建软件解码器实例,示例如下:

constexpr int32_t NEEDED_VDEC_NUM = 8;
// 1. 创建硬件解码器实例
OH_AVCapability *capHW = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, HARDWARE);
int32_t vDecNumHW = min(OH_AVCapability_GetMaxSupportedInstances(capHW), NEEDED_VDEC_NUM);
int32_t createdVDecNum = 0;
for (int i = 0; i < vDecNumHW; i++) {
   OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(OH_AVCapability_GetName(capHW));
   if (videoDec != nullptr) {
      // 维护在videoDecVector中
      createdVDecNum++;
   }
}
if (createdVDecNum < NEEDED_VDEC_NUM) {
   // 2. 不够时,创建软件解码器实例
   OH_AVCapability *capSW = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE);
   int32_t vDecNumSW = min(OH_AVCapability_GetMaxSupportedInstances(capSW), NEEDED_VDEC_NUM - createdVDecNum);
   for (int i = 0; i < vDecNumSW; i++) {
      OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(OH_AVCapability_GetName(capSW));
      if (videoDec != nullptr) {
         // 维护在videoDecVector中
         createdVDecNum++;
      }
   }
}

控制编码质量

当前提供三种码控模式供开发者选用,分别是恒定码率(CBR)码控模式、动态码率(VBR)码控模式,以及恒定质量(CQ)码控模式。对于CBR和VBR码控模式,编码质量由码率参数决定。对于CQ码控模式,编码质量由质量参数决定。

接口 功能描述
OH_AVCapability_IsEncoderBitrateModeSupported 确认当前编解码器是否支持给定的码控模式
OH_AVCapability_GetEncoderBitrateRange 获取当前编解码器支持的码率范围,在CBR和VBR码控模式下使用
OH_AVCapability_GetEncoderQualityRange 获取当前编解码器支持的质量范围,在CQ码控模式下使用

CBR和VBR码控模式示例如下:

OH_BitrateMode bitrateMode = BITRATE_MODE_CBR;
int32_t bitrate = 3000000;
OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
if (capability == nullptr) {
   // 异常处理
}
// 1. 确认待配置码控模式是否支持
bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode);
if (!isSupported) {
   // 异常处理
}
// 2. 获取码率范围,判断待配置码率参数是否在范围内
OH_AVRange bitrateRange = {-1, -1};
int32_t ret = OH_AVCapability_Ge
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值