鸿蒙(API 12 Beta3版)【时域可分层视频编码】 音视频编码

news2024/9/24 5:24:15

基础概念

时域可分层视频编码介绍

可分层视频编码,又叫可分级视频编码、可伸缩视频编码,是视频编码的扩展标准,目前常用的包含SVC(H.264编码标准采用的可伸缩扩展)和SHVC(H.265编码标准采用的可扩展标准)。

其特点是能一次编码出时域分层、空域分层、质量域分层的码流结构,满足因网络、终端能力和用户需求不同带来的的差异化需求。

时域可分层视频编码, 是指能编码出时域分层码流的视频编码,下图是通过参考关系构建的4层时域分层码流结构。

1

从高到低逐层丢弃部分层级的码流(丢弃顺序L3->L2->L1),能实现不同程度的帧率伸缩,以满足传输和解码能力的变化需求。

如下图所示,是上述4层时域分层码流结构丢弃L3后组成的新的码流结构,能在解码正常的情况下实现帧率减半的效果。其他层的丢弃同理。

2

时域分层码流结构介绍

基础码流是由一个或多个独立图像组(Group Of Pictures,简称GOP)组合而成的。GOP是在编码中一组从I帧开始到I帧结束的连续的可独立解码的图像组。

时域分层码流可以在GOP内继续细分为独立的一个或多个时域图像组(Temporal Group Of Pictures, 简称TGOP),每一个TGOP由一个基本层和后续的一个或多个增强层组合而成,如上述4层时域分层码流结构中的帧0到帧7是一个TGOP。

  • 基本层(Base Layer, 简称BL): 是GOP中的最底层(L0)。在时域分层中,该层用最低帧率进行编码。
  • 增强层(Enhance Layer简称EL): 是BL之上的层级,由低到高可以分为多层(L1,L2,L3)。在时域分层中,最低层的EL依据BL获得的编码信息,进一步编码帧率更高的层级,更高层的EL会依据BL或低层EL,来编码比低层更高帧率的视频。

如何实现时域分层码流结构

时域分层码流结构的实现是依靠参考关系逐帧指定实现的,参考帧按在解码图像缓存区(Decoded Picture Buffer,简称DPB)驻留的时长分为短期参考帧和长期参考帧。

  • 短期参考帧(Short-Term Reference,简称STR): 是不能长期驻留在DPB中的参考帧,更新方式是先进先出,如果DPB满,旧的短期参考帧会被移出DPB。
  • 长期参考帧(Long-Term Reference,简称LTR): 是能长期驻留在DPB中的参考帧,通过标记替换的方式更新,不主动标记替换就不会更新。

虽然STR个数大于1时,也能实现一定的跨帧参考结构,但受限于存在时效过短,时域分层结构支持的跨度有限。LTR则不存在上述问题,也能覆盖短期参考帧跨帧场景。优选使用LTR实现时域分层码流结构。

适用场景

基于上述描述的时域分层编码特点,推荐以下场景使用:

  • 场景1:播放侧无缓存或低缓存的实时编码传输场景,例如视频会议、视频直播、协同办公等。
  • 场景2:有视频预览播放或倍速播放需求的视频编码录制场景。

若开发场景不涉及动态调整时域参考结构,且分层结构简单,则推荐使用[全局时域可分层特性],否则使能[长期参考帧特性]。

约束和限制

  • 不可以混用全局时域可分层特性和长期参考帧特性。

    由于底层实现归一,全局时域可分层特性和长期参考帧特性不能同时开启。

  • 叠加强制IDR配置时,请使用随帧通路配置。

    参考帧仅在GOP内有效,刷新I帧后,DPB随之清空,参考帧也会被清空,因此参考关系的指定受I帧刷新位置影响很大。

    使能时域分层能力后,若需要通过OH_MD_KEY_REQUEST_I_FRAME临时请求I帧,应使用生效时机确定的随帧通路配置方式准确告知框架I帧刷新位置以避免参考关系错乱,参考随帧通路配置相关指导,避免使用生效时机不确定的OH_VideoEncoder_SetParameter方式。

  • 支持OH_AVBuffer回调通路,不支持OH_AVMemory回调通路。

    新特性依赖随帧特性,应避免使用OH_AVMemory回调OH_AVCodecAsyncCallback,应使用OH_AVBuffer回调OH_AVCodecCallback。

  • 支持时域P分层,不支持时域B分层。

    时域可分层编码按分层帧类型分为基于P帧的时域分层和基于B帧的时域编码,当前支持分层P编码,不支持分层B编码。

全局时域可分层特性(Feature_Temporal_Scalability)

接口介绍

全局时域可层特性,适用于编码稳定和简单的时域分层结构,初始配置,全局生效,不支持动态修改。开发配置参数如下:

配置参数语义
OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY全局时域分层编码使能参数
OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE全局时域分层编码TGOP大小参数
OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE全局时域分层编码TGOP参考模式
  • 全局时域分层编码使能参数: 在配置阶段配置,仅特性支持才会真正使能成功。
  • 全局时域分层编码TGOP大小参数: 可选配置,影响时域关键帧之间的间隔,用户需要基于自身业务场景下抽帧需求自定义关键帧密度,可在[2, GopSize)范围内配置,若不配置则使用默认值
  • 全局时域分层编码TGOP参考模式参数: 可选配置,影响非关键帧参考模式。包括相邻参考ADJACENT_REFERENCE和跨帧参考JUMP_REFERENCE。相邻参考相对跨帧参考拥有更好的压缩性能,跨帧参考相对相邻参考拥有更好的丢帧自由度,如不配置则使用默认值。

使用举例1:TGOP=4,相邻参考模式

3

使用举例2:TGOP=4,跨帧参考模式

4

开发指导

基础编码流程请参考[视频编码开发指导],下面仅针与基础视频编码过程中存在的区别做具体说明。

  1. 在初始阶段创建编码实例时,校验当前视频编码器是否支持全局时域可分层特性。
// 1.1 获取对应视频编码器能力句柄,此处以H.264为例
OH_AVCapability *cap = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
// 1.2 通过特性能力查询接口校验是否支持全局时域可分层特性
bool isSupported = OH_AVCapability_isFeatureSupported(cap, VIDEO_ENCODER_TEMPORAL_SCALABILITY);

若支持,则可以使能全局时域可分层特性。

  1. 在配置阶段,配置全局时域分层编码特性参数。
constexpr int32_t TGOP_SIZE = 3; 
// 2.1 创建配置用临时AVFormat
OH_AVFormat *format = OH_AVFormat_Create();
// 2.2 填充使能参数键值对
OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY, 1);
// 2.3 (可选)填充TGOP大小和TGOP内参考模式键值对
OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE, TGOP_SIZE);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE, ADJACENT_REFERENCE);
// 2.4 参数配置
int32_t ret = OH_VideoEncoder_Configure(videoEnc, format);
if (ret != AV_ERR_OK) {
    // 异常处理
}
// 2.5 配置完成后销毁临时AVFormat
OH_AVFormat_Destroy(format);
  1. (可选)在运行阶段输出轮转中,获取码流对应时域层级信息。

    开发者可基于已配置的TGOP参数,按编码出帧数目周期性获取。

    通过配置周期获取示例代码如下:

uint32_t outPoc = 0;
// 通过输出回调中有效帧数,获取TGOP内相对位置,对照配置确认层级
static void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
{
    // 注:若涉及复杂处理流程,建议相关
    struct OH_AVCodecBufferAttr attr;
    (void)buffer->GetBufferAttr(attr);
    // 刷新I帧后poc归零
    if (attr.flags & AVCODEC_BUFFER_FLAG_KEY_FRAME) {
        outPoc = 0;
    }
    // 没有帧码流只有XPS的输出需要跳过
    if (attr.flags != AVCODEC_BUFFER_FLAG_CODEC_DATA) {
        int32_t tGopInner = outPoc % TGOP_SIZE;
        if (tGopInner == 0) {
            // 时域关键帧,后续传输、解码流程不可丢弃
        } else {
            // 时域非关键帧,后续传输、解码流程可以丢弃
        }
        outPoc++;
    }
}
  1. (可选)在运行阶段输出轮转中,使用步骤3获取的时域层级信息,自适应传输或自适应解码。

    基于获取的时域可分层码流和对应的层级信息,开发者可选择需要的层级进行传输,或携带至对端自适应选帧解码。

长期参考帧特性(Feature_Long-Term_Reference)

接口介绍

长期参考帧特性提供帧级灵活的参考关系配置。适用于灵活和复杂的时域分层结构。

配置参数语义
OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT长期参考帧个数参数
OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR当前帧标记为LTR帧
OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR当前帧参考的LTR帧号
  • 长期参考帧个数参数: 在配置阶段配置,应小于等于查询到的最大支持数目,查询方式详见开发指导。
  • 当前帧标记为LTR帧: BL层标记为LTR,被跳跃参考的EL层也标记为LTR。
  • 当前帧参考的LTR帧号: 如当前帧需要跳跃参考前面已被标记为LTR的帧号。

使用举例,实现[时域可分层视频编码介绍]中的4层时域分层结构的配置如下:

  1. 在配置阶段,将OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT 配置为5。

  2. 在运行阶段输入轮转中,按如下表所示随帧配置LTR相关参数,下表中\表示不做配置。

    配置\POC012345678910111213141516
    MARK_LTR10001000100010001
    USE_LTR\\0\0\4\0\8\8\1208

开发指导

基础编码流程请参考[视频编码开发指导],下面仅针与基础视频编码过程中存在的区别做具体说明。

  1. 在初始阶段创建编码实例时,校验当前视频编码器是否支持LTR特性。
constexpr int32_t NEEDED_LTR_COUNT = 5;
bool isSupported = false;
int32_t supportedLTRCount = 0;
// 1.1 获取对应编码器能力句柄,此处以H.264为例
OH_AVCapability *cap = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
// 1.2 通过特性能力查询接口校验是否支持LTR特性
isSupported = OH_AVCapability_isFeatureSupported(cap, VIDEO_ENCODER_LONG_TERM_REFERENCE);
// 1.3 确定支持的LTR数目
if (isSupported) {
    OH_AVFormat *properties = OH_AVCapability_GetFeatureProperties(cap, VIDEO_ENCODER_LONG_TERM_REFERENCE);
    OH_AVFormat_GetIntValue(properties, OH_FEATURE_PROPERTY_KEY_VIDEO_ENCODER_MAX_LTR_FRAME_COUNT, &supportedLTRCount);
    OH_AVFormat_Destroy(properties);
    // 1.4 判断LTR是否满足结构需求
    isSupported = supportedLTRCount >= NEEDED_LTR_COUNT;
}

若支持,且支持的LTR数目满足自身码流结构需求,则可以使能LTR特性。

  1. 在配置之前注册回调时,注册随帧通路回调。

Buffer输入模式示例:

// 2.1 编码输入回调OH_AVCodecOnNeedInputBuffer实现
static void OnNeedInputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
{
    // 输入帧buffer对应的index,送入InIndexQueue队列
    // 输入帧的数据buffer送入InBufferQueue队列
    // 数据处理,请参考:
    // - 写入编码码流
    // - 通知编码器码流结束
    // - 随帧参数写入
    OH_AVFormat *format = OH_AVBuffer_GetParameter(buffer);
    OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR, 1);
    OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, 4);
    OH_AVBuffer_SetParameter(buffer, format);
    // 通知编码器buffer输入完成
    OH_VideoEncoder_PushInputBuffer(codec, index);
}

// 2.2 编码输出回调OH_AVCodecOnNewOutputBuffer实现
static void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
{
    // 完成帧buffer对应的index,送入outIndexQueue队列
    // 完成帧的数据buffer送入outBufferQueue队列
    // 数据处理,请参考:
    // - 释放编码帧
    // - 记录POC和LTR生效情况
}

// 2.3 注册数据回调
OH_AVCodecCallback cb;
cb.onNeedInputBuffer = OnNeedInputBuffer;
cb.onNewOutputBuffer = OnNewOutputBuffer;
OH_VideoEncoder_RegisterCallback(codec, cb, nullptr);

Surface输入模式示例:

// 2.1 编码输入参数回调OH_VideoEncoder_OnNeedInputParameter实现
static void OnNeedInputParameter(OH_AVCodec *codec, uint32_t index, OH_AVFormat *parameter, void *userData)
{
    // 输入帧buffer对应的index,送入InIndexQueue队列
    // 输入帧的数据avformat送入InFormatQueue队列
    // 数据处理,请参考:
    // - 写入编码码流
    // - 通知编码器码流结束
    // - 随帧参数写入
    OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR, 1);
    OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, 4);
    // 通知编码器随帧参数配置输入完成
    OH_VideoEncoder_PushInputParameter(codec, index);
}

// 2.2 编码输出回调OH_AVCodecOnNewOutputBuffer实现
static void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
{
    // 完成帧buffer对应的index,送入outIndexQueue队列
    // 完成帧的数据buffer送入outBufferQueue队列
    // 数据处理,请参考:
    // - 释放编码帧
    // - 记录POC和LTR生效情况
}

// 2.3 注册数据回调
OH_AVCodecCallback cb;
cb.onNewOutputBuffer = OnNewOutputBuffer;
OH_VideoEncoder_RegisterCallback(codec, cb, nullptr);
// 2.4 注册随帧参数回调
OH_VideoEncoder_OnNeedInputParameter inParaCb = OnNeedInputParameter;
OH_VideoEncoder_RegisterParameterCallback(codec, inParaCb, nullptr);
  1. 在配置阶段,配置同时存在LTR最大数目。
constexpr int32_t TGOP_SIZE = 3;
// 3.1 创建配置用临时AVFormat
OH_AVFormat *format = OH_AVFormat_Create();
// 3.2 填充使能LTR个数键值对
OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT, NEEDED_LTR_COUNT);
// 3.3 参数配置
int32_t ret = OH_VideoEncoder_Configure(videoEnc, format);
if (ret != AV_ERR_OK) {
    // 异常处理
}
// 3.4 配置完成后销毁临时AVFormat
OH_AVFormat_Destroy(format);
  1. (可选)在运行阶段输出轮转中,获取码流对应时域层级信息。

    同全局时域分层特性。

    因在输入轮转有配置LTR参数,也可在输入轮转中中记录,输出轮转中找到对应的输入参数。

  2. (可选)在运行阶段输出轮转中,使用步骤4获取的时域层级信息,自适应传输或自适应解码。

    同全局时域分层特性。

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

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

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

相关文章

【JavaEE初阶】线程安全的集合类

📕 引言 我们之前讲过的集合类,,大部分都不是线程安全的. Vector, Stack, HashTable, 是线程安全的(都是自带了synchronized,不建议用), 其他的集合类不是线程安全的。 注意:加锁不能保证线程一定安全,不加锁也不能确定线程一定…

spark-python

前言:本帖子是看了黑马教学视频结合spark八股,记录一下spark的知识. 一.spark介绍 1.1 spark的运行模式 1.2 spark的架构角色 在讨论spark的架构角色时,首先先回顾一下yarn的架构角色. spark架构角色: 二.standalone 运行原理 2.1standalone架构 standalone中有三类进程: m…

AI称重收银一体秤

系统介绍 专门为零售行业的连锁店量身打造的收银系统,适用于常规超市、生鲜超市、水果店、便利店、零食专卖店、服装店、母婴用品、农贸市场等类型的门店使用。同时线上线下数据打通,线下收银的数据与小程序私域商城中的数据完全同步,如商品…

如何在 Windows 11/10/8/7 中恢复已删除和未保存的记事本文本文件

很多原因都会导致未保存的记事本文本文件丢失。这些包括意外关闭、系统崩溃或电源故障等。无论丢失文本文件的原因是什么,相关的焦虑都是一样的。如果您遇到这种情况,可以使用以下有效方法在 Windows 11/10/8/7 中恢复已删除的文本文件。在这篇文章中&am…

NFT Insider #142:Mocaverse 在 The Sandbox 中推出 Mocaland 体验,Azuki 推出新系列动画片

NFT Insider 浓缩每周 NFT 新闻,为大家带来关于 NFT 最全面、最新鲜、最有价值的讯息。每期周报将从 NFT 市场数据,艺术新闻类,游戏新闻类,虚拟世界类,其他动态类,五个角度剖析 NFT 市场现状,了…

从新手到专家:2024年四大电脑录屏软件满足不同需求

电脑录屏是我们记录和分享信息的重要方式。无论是专业领域的技术演示,还是个人爱好的展示,一个好的录屏工具都能让我们的表达更加生动和直观。下面,就让我们一起探索几款市面上备受好评的电脑录屏软件。 福昕REC 链接:www.foxit…

金九银十,全网最详细的软件测试面试题总结

前面看到了一些面试题,总感觉会用得到,但是看一遍又记不住,所以我把面试题都整合在一起,都是来自各路大佬的分享,为了方便以后自己需要的时候刷一刷,不用再到处找题,今天把自己整理的这些面试题…

A股继续震荡盘整,无力回天还是蓄势待发?

今日A股走势十分反常,恐有大事将要发生了,直奔主题,马上告诉给所有人! 1、今天A股走势反常,昨夜外围纳指上涨2.87%,中概股也大涨了。今天亚太股市也在拉升,而A股却冲高回落,再度翻绿…

牛客JS题(二十八)控制动画

注释很详细&#xff0c;直接上代码 涉及知识点&#xff1a; css动态效果前提判断类型判断 题干&#xff1a; 我的答案 <!DOCTYPE html> <html><head><meta charset"utf-8" /><style type"text/css">#rect {width: 100px;he…

面试题(六)

1、等于操作符 “ ” 和全等操作符 “ ” 区别 有类型隐式转换&#xff0c;会先进行类型转换&#xff0c;再确定操作数是否相等&#xff08;若类型比较&#xff09;。 null undefined 结果为 true 没有类型隐式转换&#xff0c;只有两个操作数在不转换的前提下相等&#xff…

如何在 Android 手机/平板电脑上恢复误删除的 DCIM 文件夹

DCIM 文件夹是智能手机和平板电脑上最重要的文件夹之一。许多人报告说他们在 Android 设备上遇到了 DCIM 文件夹为空的问题。实际上&#xff0c;这种情况大多数情况下都会发生&#xff0c;当您意外从 Android 设备中删除 DCIM 文件夹或因病毒攻击、应用程序问题和意外格式化等原…

Android系统安全 — 6.5 Bluetooth安全连接原理

1 蓝牙协议架构和简称 蓝牙协议栈主要分&#xff1a;APPS层&#xff08;应用层&#xff0c;包括音频播放器&#xff0c;蓝牙遥控&#xff0c;智能家居APP等&#xff09;&#xff0c; HOST层&#xff08;中间层协议&#xff0c;包括GAP,SMP,ATT/GATT, L2CAP, AMP Manager&#x…

6自由度机械手DH坐标系建立

一、建立机械臂DH坐标系 Z为转动关节的转轴&#xff0c;Xi垂直于关节轴i和i1所在的平面&#xff0c;则根据上述方法可以建立坐标系如下图&#xff1a; 二、DH参数表 DH参数设定&#xff1a;机器人的每个连杆可以用4个运动学参数表示&#xff0c;DH法建立坐标系&#xff0c;xi-…

『状态模式』

首先创建一个项目 打开项目后复制至3个场景 命名为 创建一个空物体 命名为GameLoop 创建一个脚本GameLoop.cs 编写代码如下 将代码挂载至空物体GameLoop 将三个场景拖拽至Scenes In Build 分析下状态模式的类图 我们创新类图中的代码 编写ISceneState.cs 编写三个状态子类继承构…

Rust学习----Rust安装

如何安装Rust&#xff1f; 1.官网&#xff1a;https://www.rust-lang.org/zh-CN/ 2.Linux or Max: curl https://sh.rustup.rs -sSf | sh 3.Windows按官网指导安装。 4.Windows Subsystem for Linux&#xff1a; curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs…

2024年软件测试八股文(含答案+文档)

1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&…

Redis 数据结构深度解析

在浩瀚的数据存储海洋中&#xff0c;Redis以其卓越的性能和丰富的数据结构脱颖而出&#xff0c;成为众多开发者心中的瑰宝。作为一个高性能的键值存储系统&#xff0c;Redis不仅支持基础的字符串类型&#xff0c;还提供了哈希、列表、集合、有序集合等复杂数据结构&#xff0c;…

Git详细命令大全

一、创建版本库 创建目录&#xff1a;mkdir zzz 目录路径 进入目录&#xff1a;cd zzz 目录路径 查看当前目录路径&#xff1a;pwd 将当前目录变成Git仓库 &#xff1a;git init 二、代码存储 提交 添加文件到暂存区&#xff1a; 当前代码&#xff1a;git add . add与.之间有空…

医疗行业解决方案参考

医疗行业解决方案 互联网医院架构 患者门户&#xff1a;提供患者信息查询、挂号、缴费等基本服务。 预约挂号&#xff1a;允许患者在线预约挂号&#xff0c;减少现场排队等候时间。 挂号查询&#xff1a;患者可以查询挂号状态和相关信息。 院内导诊&#xff1a;提供院内导航…

2-60 基于matlab的时滞系统广义预测控制(GPC)算法仿真

基于matlab的时滞系统广义预测控制&#xff08;GPC&#xff09;算法仿真&#xff0c;不同控制加权矩阵控制效果对比&#xff0c;输入参数预测时域、控制时域、控制加权矩阵、误差加权矩阵。输出对比结果。程序已调通&#xff0c;可直接运行。 2-60 控制加权矩阵 误差加权矩阵 -…