OpenHarmony 3.2 Release版本Codec HDI适配过程

2024-04-12 08:04

本文主要是介绍OpenHarmony 3.2 Release版本Codec HDI适配过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

OpenHarmony Codec HDI(Hardware Device Interface)驱动框架基于 OpenMax 实现了视屏硬件编解码驱动,提供 Codec 基础能力接口供上层媒体服务调用,包括获取组件编解码能力、创建组件、参数设置、数据的轮转和控制、以及销毁组件等功能,实现对视频数据的编解码处理。

视频编解码驱动架构

Codec HDI 2.0 接口依赖 OpenMax IL 的标准接口。OMX Wrapper 将 OMX 接口的实现封装成 libOMX_Core.z.so 供 HDI 层调用。如果 codec 驱动为实现 OpenMax 标准接口,则需根据驱动适配实现 OMX Interface 接口。

Codec HDI 2.0 接口列表:

头文件接口名称功能描述
codec_component _manager.hint32_t (*GetComponentNum)();获取 Codec 编解码组件数量
int32_t (*GetComponentCapabilityList)(CodecCompCapability *capList, int32_t count);获取编解码能力集表
int32_t (*CreateComponent)(struct CodecComponentType **component, uint32_t *componentId, char *compName, int64_t appData, struct CodecCallbackType *callbacks);创建 Codec 组件实例
int32_t (*DestroyComponent)(uint32_t componentId);销毁组件实例
codec_component _if.hint32_t (*GetComponentVersion)(struct CodecComponentType *self, struct CompVerInfo *verInfo);获取 Codec 组件版本号
int32_t (*SendCommand)(struct CodecComponentType *self, enum OMX_COMMANDTYPE cmd, uint32_t param, int8_t *cmdData, uint32_t cmdDataLen);发送命令给组件
int32_t (*GetParameter)(struct CodecComponentType *self, uint32_t paramIndex, int8_t *paramStruct, uint32_t paramStructLen);获取组件参数设置
int32_t (*SetParameter)(struct CodecComponentType *self, uint32_t index, int8_t *paramStruct, uint32_t paramStructLen);设置组件需要的参数
int32_t (*GetConfig)(struct CodecComponentType *self, uint32_t index, int8_t *cfgStruct, uint32_t cfgStructLen);获取组件的配置结构
int32_t (*SetConfig)(struct CodecComponentType *self, uint32_t index, int8_t *cfgStruct, uint32_t cfgStructLen);设置组件的配置
int32_t (*GetExtensionIndex)(struct CodecComponentType *self, const char *paramName, uint32_t *indexType);根据字符串获取组件的扩展索引
int32_t (*GetState)(struct CodecComponentType *self, enum OMX_STATETYPE *state);获取组件的状态
int32_t (*ComponentTunnelRequest)(struct CodecComponentType *self, uint32_t port, int32_t tunneledComp, uint32_t tunneledPort, struct OMX_TUNNELSETUPTYPE *tunnelSetup);设置组件 Tunneled 方式通信
int32_t (*UseBuffer)(struct CodecComponentType *self, uint32_t portIndex, struct OmxCodecBuffer *buffer);指定组件端口的 buffer
int32_t (*AllocateBuffer)(struct CodecComponentType *self, uint32_t portIndex, struct OmxCodecBuffer *buffer);向组件申请端口 buffer
int32_t (*FreeBuffer)(struct CodecComponentType *self, uint32_t portIndex, const struct OmxCodecBuffer *buffer);释放 buffer
int32_t (*EmptyThisBuffer)(struct CodecComponentType *self, const struct OmxCodecBuffer *buffer);编解码输入待处理 buffer
int32_t (*FillThisBuffer)(struct CodecComponentType *self, const struct OmxCodecBuffer *buffer);编解码输出填充 buffer
int32_t (*SetCallbacks)(struct CodecComponentType *self, struct CodecCallbackType *callback, int64_t appData);设置 Codec 组件的回调函数
int32_t (*ComponentDeInit)(struct CodecComponentType *self);组件去初始化
int32_t (*UseEglImage)(struct CodecComponentType *self, struct OmxCodecBuffer *buffer, uint32_t portIndex, int8_t *eglImage, uint32_t eglImageLen);使用已在 ELG 中申请的空间
int32_t (*ComponentRoleEnum)(struct CodecComponentType *self, uint8_t *role, uint32_t roleLen, uint32_t index);获取组件角色
codec_callback_if.hint32_t (*EventHandler)(struct CodecCallbackType *self, enum OMX_EVENTTYPE event, struct EventInfo *info);事件上报
int32_t (*EmptyBufferDone)(struct CodecCallbackType *self, int64_t appData, const struct OmxCodecBuffer *buffer);上报输入 buffer 编码或者解码处理完毕
int32_t (*FillBufferDone)(struct CodecCallbackType *self, int64_t appData, const struct OmxCodecBuffer *buffer);上报输出 buffer 填充完毕

Codec HDI 相关目录接口

├── //drivers/peripheral/codec
│   ├── hal
│   │   ├── BUILD.gn
│   │   ├── idl_service
│   │   ├── include
│   │   ├── passthrough             # v2.0到v1.0的转换,v1.0接口已弃用,无需实现
│   │   ├── src
│   │   ├── v1.0                    # codec hdi v1.0接口的实现,已弃用,MediaService已不对接相关接口。
│   │   └── v2.0                    # codec hdi v2.0接口的实现,依赖OpenMax接口,需封装实现libOMX_Core.z.so
│   ├── hdi_service                 # codec_host相关实现
│   │   ├── BUILD.gn
│   │   ├── codec_proxy
│   │   ├── codec_service_stub
│   │   └── common
│   ├── interfaces
│   │   └── include
│   └── test

OMX_Core 相关接口

codec hdi V2.0 的实现依赖 libOMX_Core.z.so,需根据 OpenMax 标准接口封装实现。

参考 drivers/peripheral/codec/hal/v2.0/hdi_impl/include/codec_omx_core.h 的定义调用过程。

typedef OMX_ERRORTYPE (*InitFunc)();
typedef OMX_ERRORTYPE (*DeinitFunc)();
typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)(OMX_STRING, OMX_U32, OMX_U32);
typedef OMX_ERRORTYPE (*GetHandleFunc)(OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *);
typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE);
typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)(OMX_STRING, OMX_U32 *, OMX_U8 **);

HCS 配置

配置 codec_host 服务

./hdf_config/uhdf/device_info.hcs

codec :: host {hostName = "codec_host";priority = 50;gid = ["codec_host", "uhdf_driver", "vendor_mpp_driver"];codec_omx_device :: device {device0 :: deviceNode {policy = 2;priority = 100;moduleName = "libcodec_hdi_omx_server.z.so";serviceName = "codec_hdi_omx_service";deviceMatchAttr = "media_codec_capabilities";}}
}

配置 codec_capabilities

根据 codec::host 中配置的 deviceMatchAttr,配置 hdf.hcs

./hdf_config/uhdf/hdf.hcs

#include "media_codec_capabilitie.hcs"

参考 media_codec_capabilitie.hcs

root {module = "master";codec_config {match_attr = "media_codec_capabilities";use_openmax = true;// capsMask: 0x01, Adaptive playback; 0x02, Secure playback; 0x04, Tunnel playback.// allocateMask: 0x01, Input buffer allocated within the Codec module;// allocateMask: 0x02, Input buffer allocated by an external user;// allocateMask: 0x04, Output buffer allocated within the Codec module;// allocateMask: 0x08, Output buffer allocated by an external user.
​VideoHwEncoders {/* node name explanation -- HDF_video_hw_enc_avc_rk:****    HDF____________video__________________hw____________________enc____________avc_______rk**     |               |                    |                      |              |        |** HDF or OMX    video or audio    hardware or software    encoder or decoder    mime    vendor*/HDF_video_hw_enc_avc_rk {role = 1;type = 1;name = "OMX.rk.video_encoder.avc";supportProfiles = [1, 32768, 2, 32768, 8, 32768];maxInst = 4;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 40000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 16;heightAlignment = 8;minBlockCount = 99;maxBlockCount = 8160;minBlocksPerSecond = 99;maxBlocksPerSecond = 489600;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [28, 24, 20, 12];measuredFrameRate = [320, 240, 165, 165, 720, 480, 149, 149, 1280, 720, 73, 73, 1920, 1080, 18, 18];bitRateMode = [1, 2];minFrameRate = 1;maxFrameRate = 60;}..................}
}

RK3568 的参考适配过程

OMX Wrapper 的封装

根据 gn 文件://drivers/peripheral/codec/BUILD.gn

OMX_IL_PATH = rebase_path("//device/soc/${device_company}/${product_name}/hardware/omx_il")cmd = "if [ -f ${OMX_IL_PATH}/BUILD.gn ]; then echo true; else echo false; fi"HAVE_OMX_IL_PATH =exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value")
​if (HAVE_OMX_IL_PATH) {deps += [ "${OMX_IL_PATH}:lib_omx" ]}

需创建 lib_omx 工程,并封装实现 libOMX_Core.z.so,供 codec hdi 接口调用。

如果 codec 驱动已实现 OpenMax 标准接口,则可直接封装 libOMX_Core 库,否则需要根据私有驱动实现 OpenMax 接口。

参考 RK3568 的适配过程,因 codec 驱动使用 rockchip 的 mpp 平台实现,需根据私有驱动实现 OpenMax 的接口。

参考 gn 文件://device/soc/rockchip/rk3568/hardware/omx_il/BUILD.gn

group("lib_omx") {if (product_name == "rk3568") {deps = ["//device/soc/rockchip/rk3568/hardware/omx_il/component/video/dec:libomxvpu_dec","//device/soc/rockchip/rk3568/hardware/omx_il/component/video/enc:libomxvpu_enc","//device/soc/rockchip/rk3568/hardware/omx_il/core:libOMX_Core","//device/soc/rockchip/rk3568/hardware/omx_il/libOMXPlugin:libOMX_Pluginhw",]}
}

hcs 配置

  • 配置 codec_host 服务
    //vendor/hihope/rk3568/hdf_config/uhdf/device_info.hcs

    codec :: host {hostName = "codec_host";priority = 50;gid = ["codec_host", "uhdf_driver", "vendor_mpp_driver"];codec_omx_device :: device {device0 :: deviceNode {policy = 2;priority = 100;moduleName = "libcodec_hdi_omx_server.z.so";serviceName = "codec_hdi_omx_service";deviceMatchAttr = "codec_component_capabilities";}}
    }
  • 配置 codec hcs
    需根据硬件信息配置编解码组件的配置参数
    //vendor/hihope/rk3568/hdf_config/uhdf/hdf.hcs

    #include "media_codec/codec_component_capabilities.hcs"

    //vendor/hihope/rk3568/hdf_config/uhdf/media_codec/codec_component_capabilities.hcs

    root {module = "master";codec_config {match_attr = "codec_component_capabilities";use_openmax = true;// capsMask: 0x01, Adaptive playback; 0x02, Secure playback; 0x04, Tunnel playback.// allocateMask: 0x01, Input buffer allocated within the Codec module;// allocateMask: 0x02, Input buffer allocated by an external user;// allocateMask: 0x04, Output buffer allocated within the Codec module;// allocateMask: 0x08, Output buffer allocated by an external user.VideoHwEncoders {/* node name explanation -- HDF_video_hw_enc_avc_rk:****    HDF____________video__________________hw____________________enc____________avc_______rk**     |               |                    |                      |              |        |** HDF or OMX    video or audio    hardware or software    encoder or decoder    mime    vendor*/HDF_video_hw_enc_avc_rk {role = 1;type = 1;name = "OMX.rk.video_encoder.avc";supportProfiles = [1, 32768, 2, 32768, 8, 32768];maxInst = 4;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 40000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 16;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 0xFFFFFFFF;maxBlocksPerSecond = 0xFFFFFFFF;blockSizeWidth = 0xFFFFFFFF;blockSizeHeight = 0xFFFFFFFF;supportPixelFmts = [28, 24, 20, 12];measuredFrameRate = [320, 240, 165, 165, 720, 480, 149, 149, 1280, 720, 73, 73, 1920, 1080, 18, 18];bitRateMode = [1, 2];minFrameRate = 0;maxFrameRate = 0;}}VideoHwDecoders {HDF_video_hw_dec_avc_rk {role = 1;type = 0;name = "OMX.rk.video_decoder.avc";supportProfiles = [1, 32768, 2, 32768, 8, 32768];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 4096;maxHeight = 2160;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [320, 240, 617, 617, 720, 480, 559, 559, 1280, 720, 276, 276, 1920, 1080, 164, 164, 3840, 2160, 30, 30];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_mpeg2_rk {role = 0xFFFFFFFF;type = 0;name = "OMX.rk.video_decoder.m2v";supportProfiles = [0, 3, 1, 3];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 8;supportPixelFmts = [24];measuredFrameRate = [];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_v8p_rk {role = 0xFFFFFFFF;type = 0;name = "OMX.rk.video_decoder.vp8";supportProfiles = [];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [320, 180, 500, 500, 640, 360, 387, 387, 1280, 720, 112, 112, 1920, 1080, 77, 77];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_h263_rk {role = 0xFFFFFFFF;type = 0;name = "OMX.rk.video_decoder.h263";supportProfiles = [1, 1, 1, 2, 1, 4, 1, 16, 8, 1, 8, 2, 8, 4, 8, 16];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [176, 144, 600, 600, 352, 288, 600, 600];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_m4v_rk {role = 3;type = 0;name = "OMX.rk.video_decoder.m4v";supportProfiles = [1, 1, 1, 2, 1, 4, 1, 8, 1, 16];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [176, 144, 600, 600];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_flv_rk {role = 0xFFFFFFFF;type = 0;name = "OMX.rk.video_decoder.flv1";supportProfiles = [];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_mjpeg_rk {role = 0;type = 0;name = "OMX.rk.video_decoder.mjpeg";supportProfiles = [];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 10000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 8;heightAlignment = 8;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}HDF_video_hw_dec_hevc_rk {role = 2;type = 0;name = "OMX.rk.video_decoder.hevc";supportProfiles = [1, 1, 1, 4, 1, 16, 1, 64, 1, 256, 1, 1024, 1, 4096, 1, 16384, 1, 65536, 2, 65536];maxInst = 6;isSoftwareCodec = false;processModeMask = [];capsMask = [0x01];minBitRate = 1;maxBitRate = 160000000;minWidth = 176;minHeight = 144;maxWidth = 1920;maxHeight = 1088;widthAlignment = 2;heightAlignment = 2;minBlockCount = 0xFFFFFFFF;maxBlockCount = 0xFFFFFFFF;minBlocksPerSecond = 1;maxBlocksPerSecond = 244800;blockSizeWidth = 16;blockSizeHeight = 16;supportPixelFmts = [24];measuredFrameRate = [352, 288, 700, 700, 720, 480, 700, 700, 640, 360, 980, 980, 1280, 720, 600, 600, 1920, 1080, 130, 130, 3840, 2160, 130, 130];bitRateMode = [];minFrameRate = 0;maxFrameRate = 0;}}VideoSwEncoders {}VideoSwDecoders {}AudioHwEncoders {}AudioHwDecoders {}AudioSwEncoders {}AudioSwDecoders {}}
    }

适配验证

  • 当系统启动后,拉起 codec_host 进程,日志中有加载 hcs 配置的 component 相关组件的 log,则初步判定适配过程正常。

  • 当前系统通过 gstreamer 插件实现视频编解码功能。当未实现硬件编解码时,默认使用 FFmpeg 软件编解码。
    codec hdi 插件加载过程如下:
    ///foundation/multimedia/player_framework/services/engine/gstreamer/plugins/codec/hdi_plugins/hdi_init.cpp

    void HdiInit::AddHdiCap(CodecCompCapability &hdiCap)
    {MEDIA_LOGI("Add codec name %{public}s", hdiCap.compName);CapabilityData codecCap;codecCap.codecName = hdiCap.compName;codecCap.codecType = GetCodecType(hdiCap.type);codecCap.mimeType = GetCodecMime(hdiCap.role);codecCap.isVendor = !hdiCap.isSoftwareCodec;codecCap.alignment = {hdiCap.port.video.whAlignment.widthAlignment, hdiCap.port.video.whAlignment.heightAlignment};codecCap.bitrateMode = GetBitrateMode(hdiCap.port.video);codecCap.width = {hdiCap.port.video.minSize.width, hdiCap.port.video.maxSize.width};codecCap.height = {hdiCap.port.video.minSize.height, hdiCap.port.video.maxSize.height};codecCap.bitrate = {hdiCap.bitRate.min, hdiCap.bitRate.max};codecCap.frameRate = {hdiCap.port.video.frameRate.min, hdiCap.port.video.frameRate.max};codecCap.format = GetCodecFormats(hdiCap.port.video);codecCap.blockPerFrame = {hdiCap.port.video.blockCount.min, hdiCap.port.video.blockCount.max};codecCap.blockPerSecond = {hdiCap.port.video.blocksPerSecond.min, hdiCap.port.video.blocksPerSecond.max};codecCap.blockSize = {hdiCap.port.video.blockSize.width, hdiCap.port.video.blockSize.height};codecCap.measuredFrameRate = GetMeasuredFrameRate(hdiCap.port.video);codecCap.profileLevelsMap = GetCodecProfileLevels(hdiCap);capabilitys_.push_back(codecCap);
    }
    

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

这篇关于OpenHarmony 3.2 Release版本Codec HDI适配过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/896566

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、