OpenHarmony平台驱动使用(五),HDMI

OpenHarmony平台驱动使用(五)


HDMI

概述

功能简介

HDMI(High Definition Multimedia Interface),即高清多媒体接口,主要用于DVD、机顶盒等音视频Source到TV、显示器等Sink设备的传输。

HDMI以主从方式工作,通常有一个Source端和一个Sink端。

HDMI接口定义了完成HDMI传输的通用方法集合,包括:

  • HDMI控制器管理:打开或关闭HDMI控制器。

  • HDMI启动/停止传输:启动或停止HDMI传输。

  • HDMI控制器设置:设置音频、视频及HDR属性,设置色彩深度、声音图像消隐等。

  • HDMI读取EDID:读取Sink端原始的EDID数据。

  • HDMI热插拔:注册/注销热插拔回调函数。

基本概念

HDMI是Hitachi、Panasonic、Philips、Silicon Image、Sony、Thomson、Toshiba共同发布的一款音视频传输协议。传输过程遵循TMDS(Transition Minimized Differential Signaling)协议。

  • TMDS(Transition Minimized Differential signal):过渡调制差分信号,也被称为最小化传输差分信号,用于发送音频、视频及各种辅助数据。

  • DDC(Display Data Channel):显示数据通道,发送端与接收端可利用DDC通道得知彼此的发送与接收能力,但HDMI仅需单向获知接收端(显示器)的能力。

  • CEC(Consumer Electronics Control):消费电子控制,该功能应该能够在连接HDMI的发送设备与接收设备之间实现交互操作。

  • FRL(Fixed Rate Link):TMDS 的架构进行讯号传输时,最高带宽可达 18Gbps,而FRL模式的带宽则提升到48 Gbps。

  • HDCP(High-bandwidth Digital Content Protection):即高带宽数字内容保护技术,当用户对高清晰信号进行非法复制时,该技术会进行干扰,降低复制出来的影像的质量,从而对内容进行保护。

  • EDID(Extended Display Identification Data):扩展显示标识数据,通常存储在显示器的固件中,标识供应商信息、EDID版本信息、最大图像大小、颜色设置、厂商预设置、频率范围的限制以及显示器名和序列号的字符串。

运作机制

在HDF框架中,HDMI模块接口适配模式拟采用独立服务模式,如图1所示。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。

独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为:

  • 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。

  • device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。

图 1 HDMI独立服务模式结构图

HDMI独立服务模式结构图

HDMI模块各分层作用:

  • 接口层提供打开HDMI设备、启动HDMI传输、停止HDMI传输、声音图像消隐设置、设置色彩深度、获取色彩深度、设置视频属性、获取视频属性、设置HDR属性、读取Sink端原始EDID数据、注册HDMI热插拔检测回调函数、注销HDMI热插拔检测回调函数、关闭HDMI设备的接口。

  • 核心层主要提供HDMI控制器的打开、关闭及管理的能力,通过钩子函数与适配层交互。

  • 适配层主要是将钩子函数的功能实例化,实现具体的功能。

HDMI的Source端提供+5V和GND,用于DDC和CEC通信。通过DDC通道,Source端可以读取Sink端的各项参数,如接受能力等;CEC为可选通道,用于同步Source端与Sink端的控制信号,改善用户体验。TMDS通道有四组差分信号,TMDS Clock Channel为TMDS提供时钟信号,其余三组传输音视频数据及各种辅助数据;HDP为热插拔检测端口,当有Sink端接入时,Source端会通过中断服务程序进行响应。

HDMI物理连接如图2所示:

图 2 HDMI物理连线示意图

HDMI物理连线示意图

约束与限制

HDMI模块当前仅支持轻量和小型系统内核(LiteOS),暂无实际适配驱动 。

使用指导

场景介绍

HDMI具有体积小,传输速率高,传输带宽宽,兼容性好,能同时传输无压缩音视频信号等优点。与传统的全模拟接口相比,HDMI不但增加了设备间接线的便捷性,还提供了一些HDMI特有的智能化功能,可用于小体积设备进行高质量音视频传输的场景。

接口说明

HDMI模块提供的主要接口如下所示,具体API详见。

表 1 HDMI驱动API接口功能介绍

接口名描述
HdmiOpen打开HDMI控制器
HdmiClose关闭HDMI控制器
HdmiStart启动HDMI传输
HdmiStop停止HDMI传输
HdmiAvmuteSet声音图像消隐设置
HdmiDeepColorSet设置色彩深度
HdmiDeepColorGet获取色彩深度
HdmiSetVideoAttribute设置视频属性
HdmiSetAudioAttribute设置音频属性
HdmiSetHdrAttribute设置HDR属性
HdmiReadSinkEdid读取Sink端原始EDID数据
HdmiRegisterHpdCallbackFunc注册HDMI热插拔检测回调函数
HdmiUnregisterHpdCallbackFunc注销HDMI热插拔检测回调函数

开发步骤

使用HDMI设备的一般流程如图3所示。

图 3 HDMI设备使用流程图

HDMI设备使用流程图

打开HDMI控制器

在进行HDMI通信前,首先要调用HdmiOpen打开HDMI控制器。

DevHandle HdmiOpen(int16_t number);

表 2 HdmiOpen参数和返回值描述

参数参数描述
numberint16_t类型,HDMI控制器号
返回值返回值描述
NULL打开HDMI控制器失败
控制器句柄打开的HDMI控制器句柄

假设系统中存在2个HDMI控制器,编号从0到1,以下代码示例为获取0号控制器:

DevHandle hdmiHandle = NULL;  // HDMI控制器句柄// 打开HDMI控制器
hdmiHandle = HdmiOpen(0);
if (hdmiHandle == NULL) {HDF_LOGE("HdmiOpen: hdmi open fail!\n");return NULL;
}
注册热插拔检测回调函数
int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback);

表 3 HdmiRegisterHpdCallbackFunc参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
callback结构体指针,热插拔回调函数信息
返回值返回值描述
HDF_SUCCESS注册成功
负数注册失败

注册热插拔检测回调函数示例:

// 热插拔检测回调函数定义
static void HdmiHpdHandle(void *data, bool hpd)
{if (data == NULL) {HDF_LOGE("priv data is NULL");return;}if (hpd == true) {HDF_LOGD("HdmiHpdHandle: hot plug");// 调用者添加相关处理} else {HDF_LOGD("HdmiHpdHandle: hot unplug");// 调用者添加相关处理}
}// 热插拔检测回调函数注册示例
struct HdmiHpdCallbackInfo info = {0};
info.data = handle;
info.callbackFunc = HdmiHpdHandle;
ret = HdmiRegisterHpdCallbackFunc(hdmiHandle, info);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiRegisterHpdCallbackFunc: Register hpd callback func fail, ret:%d", ret);return ret;
}
读取EDID
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);

表 4 HdmiReadSinkEdid参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
bufferuint8_t类型指针,数据缓冲区
lenuint32_t类型,数据长度
返回值返回值描述
正整数成功读取的原始EDID数据
负数或0读取失败

读取Sink端的原始EDID数据示例:

int32_t len;
uint8_t edid[HDMI_EDID_MAX_LEN] = {0};len = HdmiReadSinkEdid(hdmiHandle, edid, HDMI_EDID_MAX_LEN);
if (len <= 0) {HDF_LOGE("HdmiReadSinkEdid: hdmi read sink edid fail, len = %d.", len);return HDF_FAILURE;
}
设置音频属性
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);

表 5 HdmiSetAudioAttribute参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
attr结构体指针,音频属性
返回值返回值描述
HDF_SUCCESS设置成功
负数设置失败

设置音频属性示例:

struct HdmiAudioAttr audioAttr = {0};
int32_t ret;audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3;
audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S;
audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16;
audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K;
audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3;
ret = HdmiSetAudioAttribute(handle, &audioAttr);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiSetAudioAttribute: hdmi set audio attribute fail!, ret:%d", ret);return ret;
}
设置视频属性
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);

表 6 HdmiSetVideoAttribute参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
attr结构体指针,视频属性
返回值返回值描述
HDF_SUCCESS设置成功
负数设置失败

设置视频属性示例:

struct HdmiVideoAttr videoAttr = {0};
int32_t ret;videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444;
videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED;
videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL;
ret = HdmiSetVideoAttribute(handle, &videoAttr);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiSetVideoAttribute: hdmi set video attribute fail, ret:%d.", ret);return ret;
}
设置HDR属性
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);

表 7 HdmiSetHdrAttribute参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
attr结构体指针,HDR属性
返回值返回值描述
HDF_SUCCESS设置成功
负数设置失败

设置HDR属性示例:

struct HdmiHdrAttr hdrAttr = {0};
int32_t ret;hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3;
hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY;
hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048;
hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;
hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709;
ret = HdmiSetHdrAttribute(handle, &hdrAttr);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiSetHdrAttribute: hdmi set hdr attribute fail, ret:%d", ret);return ret;
}
设置HDMI声音图像消隐
int32_t HdmiAvmuteSet(DevHandle handle, bool enable);

表 8 HdmiAvmuteSet参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
enable布尔值,使能/去使能avmute
返回值返回值描述
HDF_SUCCESS设置成功
负数设置失败

设置声音图像消隐示例:

int32_t ret;ret = HdmiAvmuteSet(hdmiHandle, true);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiAvmuteSet: hdmi avmute set fail, ret:%d", ret);return ret;
}
设置色彩深度
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color);

表 9 HdmiDeepColorSet参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
color枚举类型,色彩深度
返回值返回值描述
HDF_SUCCESS设置成功
负数设置失败

设置色彩深度示例:

int32_t ret;ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiDeepColorSet: hdmi deep color set fail, ret:%d.", ret);return ret;
}
获取色彩深度
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);

表 10 HdmiDeepColorGet参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
color枚举类型指针,色彩深度
返回值返回值描述
HDF_SUCCESS获取成功
负数获取失败

获取色彩深度示例:

enum HdmiDeepColor color;
int32_t ret;ret = HdmiDeepColorGet(handle, &color);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiDeepColorGet: hdmi deep color get fail, ret:%d", ret);return ret;
}
启动HDMI传输
int32_t HdmiStart(DevHandle handle);

表 11 HdmiStart参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
返回值返回值描述
HDF_SUCCESS启动成功
负数启动失败

启动HDMI传输示例:

int32_t ret;ret = HdmiStart(hdmiHandle);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiStart: start transmission fail, ret:%d", ret);return ret;
}
停止HDMI传输
int32_t HdmiStop(DevHandle handle);

表 12 HdmiStop参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
返回值返回值描述
HDF_SUCCESS停止成功
负数停止失败

停止HDMI传输示例:

int32_t ret;ret = HdmiStop(hdmiHandle);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiStop: stop transmission fail, ret:%d.", ret);return ret;
}
注销热插拔检测回调函数
int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle);

表 13 HdmiUnregisterHpdCallbackFunc参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄
返回值返回值描述
HDF_SUCCESS注销成功
负数注销失败

注销热插拔检测回调函数示例:

int32_t ret;ret = HdmiUnregisterHpdCallbackFunc(hdmiHandle);
if (ret != HDF_SUCCESS) {HDF_LOGE("HdmiUnregisterHpdCallbackFunc:unregister fail, ret:%d.", ret);return ret;
}
关闭HDMI控制器
void HdmiClose(DevHandle handle);

表 14 HdmiClose参数和返回值描述

参数参数描述
handleDevHandle类型,HDMI控制器句柄

关闭HDMI控制器示例:

HdmiClose(hdmiHandle);

使用实例

本例程以操作开发板上的HDMI设备为例,详细展示HDMI接口的完整使用流程。

本例拟在Hi3516DV300开发板上对虚拟驱动进行简单的传输操作:

  • SOC:hi3516dv300。

  • HDMI控制器:使用0号HDMI控制器。

示例如下:

#include "hdmi_if.h"          /* HDMI标准接口头文件 */
#include "hdf_log.h"         /* 标准日志打印头文件 */
#include "osal_time.h"       /* 标准延迟&睡眠接口头文件 *//* 热插拔回调函数 */
static void HdmiHpdHandle(void *data, bool hpd)
{if (data == NULL) {HDF_LOGE("priv data is NULL");return;}if (hpd == true) {HDF_LOGD("HdmiHpdHandle: hot plug");/* 调用者添加相关处理 */} else {HDF_LOGD("HdmiHpdHandle: hot unplug");/* 调用者添加相关处理 */}
}/* 设置HDMI相关属性 */
static int32_t TestHdmiSetAttr(DevHandle handle)
{enum HdmiDeepColor color;struct HdmiVideoAttr videoAttr = {0};struct HdmiAudioAttr audioAttr = {0};struct HdmiHdrAttr hdrAttr = {0};int32_t ret;ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS);if (ret != 0) {HDF_LOGE("HdmiDeepColorSet failed.");return ret;}ret = HdmiDeepColorGet(handle, &color);if (ret != 0) {HDF_LOGE("HdmiDeepColorGet failed.");return ret;}HDF_LOGE("HdmiDeepColorGet successful, color = %d.", color);videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444;videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED;videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL;ret = HdmiSetVideoAttribute(handle, &videoAttr);if (ret != 0) {HDF_LOGE("HdmiSetVideoAttribute failed.");return ret;}audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3;audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S;audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16;audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K;audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3;ret = HdmiSetAudioAttribute(handle, &audioAttr);if (ret != 0) {HDF_LOGE("HdmiSetAudioAttribute failed.");return ret;}hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3;hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY;hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048;hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709;ret = HdmiSetHdrAttribute(handle, &hdrAttr);if (ret != 0) {HDF_LOGE("HdmiSetHdrAttribute failed.");return ret;}return 0;
}/* HDMI例程总入口 */
static int32_t TestCaseHdmi(void)
{DevHandle handle = NULL;int32_t ret;struct HdmiHpdCallbackInfo info = {0};uint8_t data[128] = {0};HDF_LOGD("HdmiAdapterInit: successful.");handle = HdmiOpen(0);if (handle == NULL) {HDF_LOGE("HdmiOpen failed.");return ret;}info.data = handle;info.callbackFunc = HdmiHpdHandle;ret = HdmiRegisterHpdCallbackFunc(handle, &info);if (ret != 0) {HDF_LOGE("HdmiRegisterHpdCallbackFunc failed.");return ret;}ret = HdmiReadSinkEdid(handle, data, 128);if (ret <= 0) {HDF_LOGE("HdmiReadSinkEdid failed.");return ret;}HDF_LOGE("HdmiReadSinkEdid successful, data[6] = %d, data[8] = %d.", data[6], data[8]);ret = TestHdmiSetAttr(handle);if (ret != 0) {HDF_LOGE("TestHdmiSetAttr failed.");return ret;}ret = HdmiStart(handle);if (ret != 0) {HDF_LOGE("HdmiStart failed.");return ret;}OsalMSleep(1000);ret = HdmiStop(handle);if (ret != 0) {HDF_LOGE("HdmiStop failed.");return ret;}ret = HdmiUnregisterHpdCallbackFunc(handle);if (ret != 0) {HDF_LOGE("HdmiUnregisterHpdCallbackFunc failed.");return ret;}HdmiClose(handle);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/82606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Git】Commit Hash vs Change-Id

文章目录 1、Commit 号2、Change-Id 号3、区别与联系4、实际场景示例5、为什么需要两者&#xff1f;6、总结附录——Gerrit 在 Git 和代码审查工具&#xff08;如 Gerrit&#xff09;中&#xff0c;Commit 号&#xff08;Commit Hash&#xff09; 和 Change-Id 号 是两个不同的…

leetcode hot100刷题日记——21.不同路径

和20题一样的思路link 题解&#xff1a; class Solution { public:int dfs(int i,int j,vector<vector<int>>&memo){//超过了边界&#xff0c;return 0if(i<0||j<0){return 0;}//从&#xff08;0&#xff0c;0&#xff09;到&#xff08;0&#xff0c;0…

day2 MySQL表数据操作

一&#xff1a;数据操作 注&#xff1a;在编写MySQL代码时可以不用区分大小写 1.查看表结构 desc 表名; -- 查看表中的字段类型&#xff0c;长度&#xff0c;约束。 2.字段的增加 AFTER table 表名 add 字段名 数据类型; -- 默认末尾添加 after table 表名 add 字段名 …

GitAny - 無需登入的 GitHub 最新倉庫檢索工具

地址&#xff1a;https://github.com/MartinxMax/gitany GitAny - 無需登入的 GitHub 專案搜尋工具 GitAny 是一款基於 Python 的工具&#xff0c;允許你在無需登入的情況下搜尋當天最新的 GitHub 專案。它支援模糊搜尋、條件篩選以及倉庫資料的視覺化分析。 安裝依賴 $ pip…

格恩朗金属管浮子流量计 高精度测量的不二之选​

在流量测量的复杂领域&#xff0c;精度就是生命线&#xff0c;直接关乎生产的稳定性、产品的质量以及资源的合理利用。大连格恩朗品牌的金属管浮子流量计&#xff0c;凭借其卓越的精度表现&#xff0c;成为各行业在流量测量时的最佳之选。​ 格恩朗金属管浮子流量计运用经典的可…

【R语言编程绘图-箱线图】

基本箱线图绘制 使用ggplot2绘制箱线图的核心函数是geom_boxplot()。以下是一个基础示例&#xff0c;展示如何用iris数据集绘制不同物种&#xff08;Species&#xff09;的萼片长度&#xff08;Sepal.Length&#xff09;分布&#xff1a; library(ggplot2) ggplot(iris, aes(…

深度学习能取代机器学习吗?

在人工智能领域&#xff0c;“机器学习”和“深度学习”这两个词经常被混为一谈。很多新手甚至以为只要跟 AI 有关的任务&#xff0c;都该用深度学习。但其实&#xff0c;它们并不是谁强谁弱的关系&#xff0c;而是适合不同场景的工具。 这篇文章就来帮你理清楚&#xff1a; 机…

UPS的工作原理和UPS系统中旁路的作用

UPS&#xff08;不间断电源&#xff09;根据工作原理和适用场景的不同&#xff0c;主要分为以下三种类型&#xff0c;每种类型的特点和适用场景如下&#xff1a; 1. 后备式UPS&#xff08;Offline/Standby UPS&#xff09; 工作原理&#xff1a; 正常供电时&#xff0c;负载直接…

一级菜单401问题

正常代码生成的前后台文件&#xff0c;菜单类型是一级标题&#xff0c; 菜单路径和前端组件的地址都正常写的:/projects/xxx/xxx/xxx/XxxList 其他生成的新列表都能点进去&#xff0c;只有这个点进去就是显示空白的像首页那个页面一样&#xff0c; 问题就出现在我第一次建这…

ROS2 robot控制学习(一)

controller_position.yaml使用说明 ROS 2 的 controller_manager 用途典型工作流程示例关键服务与话题扩展功能JointTrajectoryController 参数详解基本参数轨迹参数插值参数前馈控制代码示例动态参数调试参数ForwardCommandController 概述参数解释`joints``interface``allow_…

LightGBM的python实现及参数优化

文章目录 1. LightGBM模型参数介绍2. 核心优势3. python实现LightGBM3.1 基础实现3.1.1 Scikit-learn接口示例3.1.2 Python API示例 3.2 模型调优3.2.1 GridSearchCV简介3.2.2 LightGBM超参调优3.2.3 GridSearchCV寻优结果 在之前的文章 Boosting算法【AdaBoost、GBDT 、XGBoo…

Map集合(双列集合)

Map结合也称为“键值对集合”&#xff0c;格式&#xff1a;{key1value1&#xff0c;key2value2....} Map集合的特点&#xff1a; 键唯一&#xff1a;在Map集合中&#xff0c;键&#xff08;key&#xff09;是唯一的&#xff0c;不能有重复的键。如果尝试插入一个已经存在的键…

springBoot项目测试时浏览器返回406问题解决方案

1. 如果基于最新版本的SpringBoot官方骨架创建的SpringBoot项目&#xff0c;在勾选了lombok的依赖之后&#xff0c;会在pom.xml中引入如下两个插件&#xff1a; 2. 由于第一个插件 maven-compiler-plugin 的引入导致了这个问题&#xff0c;解决这个问题的方案呢&#xff0c;就是…

21.享元模式:思考与解读

原文地址:享元模式&#xff1a;思考与解读 更多内容请关注&#xff1a;深入思考与解读设计模式 引言 在软件开发中&#xff0c;特别是当你处理大量相似对象时&#xff0c;是否会遇到一个问题&#xff1a;大量的对象会占用大量的内存&#xff0c;而这些对象有许多相同的状态&…

java方法重写学习笔记

方法重写介绍 子类和父类有两个返回值&#xff0c;参数&#xff0c;名称都一样的方法&#xff0c; 子类的方法会覆盖父类的方法。 调用 public class Overide01 {public static void main(String[] args) {Dog dog new Dog();dog.cry();} }Animal类 public class Animal {…

什么是ESLint?它有什么作用?

ESLint 是一个用于 静态代码分析 的工具,专门检测 JavaScript/TypeScript 代码中的潜在问题和风格违规。它通过预定义的规则集帮助开发者保持代码的一致性和质量,是前端工程化的核心工具之一。 一、ESLint 的核心作用 1. 错误检查(Error Detection) 识别语法错误、未定义变…

Docker的网络介绍

网络简单介绍 在介绍 Docker 的网络模式之前&#xff0c;先简单说下我们在使用 Vmware 虚拟机中的网络模式&#xff0c;形成对比&#xff0c;更好理解。 1、Vmware 中的网络模式 1.1、VMnet0&#xff08;桥接模式&#xff09; 虚拟机通过宿主机的物理网卡直接连接到外部网络…

Netty学习专栏(六):深度解析Netty核心参数——从参数配置到生产级优化

文章目录 前言一、核心参数全景解析1.1 基础网络层参数1.2 内存管理参数1.3 水位线控制1.4 高级参数与系统级优化 二、生产级优化策略2.1 高并发场景优化2.2 低延迟场景优化 总结 前言 在分布式系统和高并发场景中&#xff0c;Netty作为高性能网络通信框架的核心地位无可替代。…

计算机网络学习(六)——UDP

一、UDP UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是传输层的一种协议&#xff0c;和 TCP 并列。与 TCP 不同&#xff0c;UDP 是无连接、不可靠、面向报文的协议&#xff0c;它的设计目标是追求更快的数据传输速度和更小的开销。 UDP 为…

vue3文本超出三行显示省略号,点击查看更多显示全部文本

只有一行时&#xff08;不显示展开按钮&#xff09;&#xff1a; 话不多说&#xff0c;上码 ~template <el-col :span"24"><el-form-item :label"$t(warningOrgNames_)"><div class"content-box" ref"contanierRef"…