当前位置: 首页 > news >正文

openh264解码h264视频帧主流程

一 解析一帧的入口

int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur) {

// 解码slice

PDqLayer pCurDqLayer = pCtx->pCurDqLayer;

PFmo pFmo = pCtx->pFmo;

int32_t iRet;

int32_t iNextMbXyIndex, iSliceIdc;

PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer;

PSliceHeaderExt pSliceHeaderExt = &pSlice->sSliceHeaderExt;

PSliceHeader pSliceHeader = &pSliceHeaderExt->sSliceHeader;

int32_t iMbX, iMbY;

const int32_t kiCountNumMb = pSliceHeader->pSps->uiTotalMbCount; //need to be correct when fmo or multi slice

uint32_t uiEosFlag = 0;

PWelsDecMbFunc pDecMbFunc;

pSlice->iTotalMbInCurSlice = 0; //initialize at the starting of slice decoding.

if (pCtx->pPps->bEntropyCodingModeFlag) { //cabac 熵编码

if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag ||

pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag ||

pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag) {

WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,

"WelsDecodeSlice()::::ILP flag exist, not supported with CABAC enabled!");

pCtx->iErrorCode |= dsBitstreamError;

return dsBitstreamError;

}

if (P_SLICE == pSliceHeader->eSliceType) //P Slice帧解析

pDecMbFunc = WelsDecodeMbCabacPSlice;

else if (B_SLICE == pSliceHeader->eSliceType) // B slice解析

pDecMbFunc = WelsDecodeMbCabacBSlice;

else //I_SLICE. B_SLICE is being supported

pDecMbFunc = WelsDecodeMbCabacISlice; // I Slice解析

} else { //

if (P_SLICE == pSliceHeader->eSliceType) {

pDecMbFunc = WelsDecodeMbCavlcPSlice;

} else if (B_SLICE == pSliceHeader->eSliceType) {

pDecMbFunc = WelsDecodeMbCavlcBSlice;

} else { //I_SLICE

pDecMbFunc = WelsDecodeMbCavlcISlice;

}

}

二 解析P slice函数

int32_t WelsDecodeMbCabacPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {

PDqLayer pCurDqLayer = pCtx->pCurDqLayer; //当前解码上下文

PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer; // slice上下文

PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; // slice header

PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0]; //参考帧上下文

uint32_t uiCode;

int32_t iMbXy = pCurDqLayer->iMbXyIndex;

int32_t i;

SWelsNeighAvail uiNeighAvail;

pCurDqLayer->pCbp[iMbXy] = 0; //code block parttern信息

pCurDqLayer->pCbfDc[iMbXy] = 0;

pCurDqLayer->pChromaPredMode[iMbXy] = C_PRED_DC;

pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true;

pCurDqLayer->pTransformSize8x8Flag[iMbXy] = false;

GetNeighborAvailMbType (&uiNeighAvail, pCurDqLayer); //填充邻居mb_type 为当前宏块解码做准备

WELS_READ_VERIFY (ParseSkipFlagCabac (pCtx, &uiNeighAvail, uiCode)); //解析是否为skip块

if (uiCode) {

int16_t pMv[2] = {0};

pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_SKIP;

ST32 (&pCurDqLayer->pNzc[iMbXy][0], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][4], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][8], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][12], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][16], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][20], 0);

pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;

memset (pCurDqLayer->pDec->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);

bool bIsPending = GetThreadCount (pCtx) > 1;

pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[0] && (ppRefPic[0]->bIsComplete

|| bIsPending));

//predict mv

PredPSkipMvFromNeighbor (pCurDqLayer, pMv); //通过周围块的信息,计算得到当前块的mvp

for (i = 0; i < 16; i++) {

ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][i], * (uint32_t*)pMv);

ST32 (pCurDqLayer->pMvd[0][iMbXy][i], 0);

}

//if (!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag) {

// memset (pCurDqLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (int16_t));

//}

//reset rS

pCurDqLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; //??????????????? dqaunt of previous mb 前一个qp,当前

//解码得到 delta + 这里的qp就是实际qp

for (i = 0; i < 2; i++) {

pCurDqLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pCurDqLayer->pLumaQp[iMbXy] +

pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, 51)];

//计算得到chromaqp,和lumaqp有对应关系

}

//for neighboring CABAC usage

pSlice->iLastDeltaQp = 0;

WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));

return ERR_NONE;

}

WELS_READ_VERIFY (WelsDecodeMbCabacPSliceBaseMode0 (pCtx, &uiNeighAvail, uiEosFlag)); //实际解析slice 中MB列表

return ERR_NONE;

三 解析Bslice过程

int32_t WelsDecodeMbCabacBSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {

//解析B slice

PDqLayer pCurDqLayer = pCtx->pCurDqLayer; //当前帧上下文

PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer; //Slice指针

PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; //当前slice头指着

PPicture* ppRefPicL0 = pCtx->sRefPic.pRefList[LIST_0]; //前向参考列表

PPicture* ppRefPicL1 = pCtx->sRefPic.pRefList[LIST_1]; //后向参考列表

uint32_t uiCode; //

int32_t iMbXy = pCurDqLayer->iMbXyIndex;

int32_t i;

SWelsNeighAvail uiNeighAvail;

pCurDqLayer->pCbp[iMbXy] = 0; //

pCurDqLayer->pCbfDc[iMbXy] = 0;

pCurDqLayer->pChromaPredMode[iMbXy] = C_PRED_DC;

pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true;

pCurDqLayer->pTransformSize8x8Flag[iMbXy] = false;

GetNeighborAvailMbType (&uiNeighAvail, pCurDqLayer); //填充周围宏块信息

WELS_READ_VERIFY (ParseSkipFlagCabac (pCtx, &uiNeighAvail, uiCode)); //解析 skip标记

memset (pCurDqLayer->pDirect[iMbXy], 0, sizeof (int8_t) * 16);

bool bIsPending = GetThreadCount (pCtx) > 1;

if (uiCode) {

int16_t pMv[LIST_A][2] = { {0, 0}, { 0, 0 } };

int8_t ref[LIST_A] = { 0 };

pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_SKIP | MB_TYPE_DIRECT;

ST32 (&pCurDqLayer->pNzc[iMbXy][0], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][4], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][8], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][12], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][16], 0);

ST32 (&pCurDqLayer->pNzc[iMbXy][20], 0);

pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;

memset (pCurDqLayer->pDec->pRefIndex[LIST_0][iMbXy], 0, sizeof (int8_t) * 16);

memset (pCurDqLayer->pDec->pRefIndex[LIST_1][iMbXy], 0, sizeof (int8_t) * 16);

pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPicL0[0] && (ppRefPicL0[0]->bIsComplete

|| bIsPending)) || ! (ppRefPicL1[0] && (ppRefPicL1[0]->bIsComplete || bIsPending));

if (pCtx->bMbRefConcealed) {

SLogContext* pLogCtx = & (pCtx->sLogCtx);

WelsLog (pLogCtx, WELS_LOG_ERROR, "Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");

return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);

}

SubMbType subMbType;

if (pSliceHeader->iDirectSpatialMvPredFlag) { //Direct 块类型判断

//predict direct spatial mv

int32_t ret = PredMvBDirectSpatial (pCtx, pMv, ref, subMbType);

if (ret != ERR_NONE) {

return ret;

}

} else {

//temporal direct mode

int32_t ret = PredBDirectTemporal (pCtx, pMv, ref, subMbType);

if (ret != ERR_NONE) {

return ret;

}

}

//reset rS

pCurDqLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; //??????????????? dqaunt of previous mb

for (i = 0; i < 2; i++) {

pCurDqLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pCurDqLayer->pLumaQp[iMbXy] +

pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, 51)];

}

//for neighboring CABAC usage

pSlice->iLastDeltaQp = 0;

WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));

return ERR_NONE;

}

WELS_READ_VERIFY (WelsDecodeMbCabacBSliceBaseMode0 (pCtx, &uiNeighAvail, uiEosFlag)); //实际解析BSlice中的mb

return ERR_NONE;

}

四 解析ISlice过程

int32_t WelsDecodeMbCabacISliceBaseMode0 (PWelsDecoderContext pCtx, uint32_t& uiEosFlag) {

//解析I slice

PDqLayer pCurDqLayer = pCtx->pCurDqLayer; //当前帧解码上下文

PBitStringAux pBsAux = pCurDqLayer->pBitStringAux;

PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer; //slice上下文

PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;

SWelsNeighAvail sNeighAvail;

int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;

int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;

int32_t iMbXy = pCurDqLayer->iMbXyIndex;

int32_t i;

uint32_t uiMbType = 0, uiCbp = 0, uiCbpLuma = 0, uiCbpChroma = 0;

ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);

pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true;

pCurDqLayer->pTransformSize8x8Flag[iMbXy] = false;

pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;

pCurDqLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;

GetNeighborAvailMbType (&sNeighAvail, pCurDqLayer);

WELS_READ_VERIFY (ParseMBTypeISliceCabac (pCtx, &sNeighAvail, uiMbType)); //解析mb类型

if (uiMbType > 25) { //非法的mb类型

return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_TYPE);

} else if (!pCtx->pSps->uiChromaFormatIdc && ((uiMbType >= 5 && uiMbType <= 12) || (uiMbType >= 17

&& uiMbType <= 24))) { //如果没有色度信息,这里mb类型不合法的类型判断

return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_TYPE);

} else if (25 == uiMbType) { //I_PCM

WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "I_PCM mode exists in I slice!");

WELS_READ_VERIFY (ParseIPCMInfoCabac (pCtx)); //解析PCM 信息,cabac

pSlice->iLastDeltaQp = 0;

WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));

if (uiEosFlag) {

RestoreCabacDecEngineToBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux);

}

return ERR_NONE;

} else if (0 == uiMbType) { //I4x4 16个4x4的帧内块

ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);

pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_INTRA4x4;

相关文章:

openh264解码h264视频帧主流程

一 解析一帧的入口int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur) {// 解码slicePDqLayer pCurDqLayer pCtx->pCurDqLayer;PFmo pFmo pCtx->pFmo;int32_t iRet;int32_t iNextMbXyIndex, iSliceIdc;PSlice pSlice &a…...

【个人笔记】C语言位域

一句话解释位域&#xff1a;指定结构体内变量的的位宽&#xff0c;从而节省空间 例子&#xff1a; #include <stdio.h> struct _test {int bit1:3; // 第一个字节0 ~ 2位 int :0; // 空域&#xff1a;表示第一个字节 3~7都为0int bit2:1; // 第二个字节第0位int :3;…...

ROS笔记(1)——ROS的核心概念

目录 节点与管理器 话题通信 服务通信 参数——全局共享字典 节点与管理器 节点——执行单元 &#xff08;1&#xff09;执行具体任务的进程、独立运行的可执行文件 &#xff08;2&#xff09;不同节点可使用不同的编程语言&#xff0c;可分布式运行在不同的主机 &#xff…...

动态SQL使用【JavaEE】

动态SQL使用 1. if 标签 判断一个参数是否有值&#xff0c;如果没值&#xff0c;那么就会隐藏 if 中的 sql 语法&#xff1a; <if test"username!null">username#{username} </if>表达式&#xff1a;username 的参数是否为空 如果结果为 true&#xff0c…...

leetcode刷题

1、stack栈相关 top()&#xff1a;返回一个栈顶元素的引用&#xff0c;类型为 T&。如果栈为空&#xff0c;返回值未定义。 push(const T& obj)&#xff1a;可以将对象副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。 push(T&& obj)&#xff1…...

移动设备安全管理基础指南

什么是移动安全管理 &#xff08;MSM&#xff09; 移动安全管理是指为保护企业中的移动设备和企业数据而采取的行动。这些操作可以进一步被归类为反应性的或主动的&#xff0c;基于该操作是在数据和设备被破坏之前还是之后执行的。除了管理移动设备外&#xff0c;大多数MDM解决…...

【Java|多线程与高并发】 使用Thread 类创建线程的5种方法如何查看程序中的线程

文章目录前言线程创建1.继承Thread类重写run()方法如何查看程序中的线程?2.实现Runnable接口3.使用匿名内部类,继承Thread4.使用匿名内部类,实现Runnable5.⭐使用Lambda表达式,创建线程(重要)Thread 的常见构造方法总结前言 在这里主要补充说明一些问题,方便更好地理解下面的…...

零基础学MySQL(五)-- 详细讲解数据库中的常用函数

目录&#x1f387;一、聚合函数1️⃣count 函数&#xff08;1&#xff09;基本语法&#xff08;2&#xff09;基本练习&#xff08;3&#xff09;注意细节2️⃣sum 函数&#xff08;1&#xff09;基本语法&#xff08;2&#xff09;基本练习&#xff08;3&#xff09;注意细节3…...

第4章 流程控制-if-else,Switch,For循环(循环守卫,循环步长,倒叙打印),While循环,多重循环...

第 4 章 流程控制-if-else,Switch,For循环(循环守卫&#xff0c;循环步长&#xff0c;倒叙打印)&#xff0c;While循环&#xff0c;多重循环 4.1 分支控制 if-else 让程序有选择的的执行&#xff0c;分支控制有三种&#xff1a;单分支、双分支、多分支 4.1.1 单分支 1)基本语法…...

2.4G-WiFi连接路由器过程

一、概述 WiFi的数据通信基于802.11协议进行&#xff0c;无线AP在工作时会定时向空中发送beacon数据包&#xff0c;基站&#xff08;STA&#xff09;从beacon中解析出AP的名称、加密方式等信息&#xff0c;从而发起连接。 二、WiFi连接路由器的详细过程 WiFi连接过程主要可以…...

3. SpringMVC Rest 风格

1. REST 简介 REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换&#xff0c;它是一种软件架构风格。 当要表示一个网络资源的时候&#xff0c;可以使用两种方式&#xff1a; 传统风格资源描述形式 http://localhost/user/getById?…...

Python3简介

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&#xff0c;相比其他语言经常使用英文关键字&#xff0c;其他语言的一些标点符号&#xff0c;它具有比其他语言更有特色语法结构。 Python 是面向对象语言: 这意味着P…...

如何学习PMP?

★基础要打牢 方法&#xff1a;“基础不牢&#xff0c;地动山摇”&#xff0c;如果基础不牢那么就很难拿高分&#xff0c;因为连最基础的题目分都不一定能拿到。 可以在针对基础知识&#xff0c;把PMBOK看一两遍&#xff0c;再次加深印象&#xff0c;再把平时做章节练习、每日5…...

【DSP视频教程】第11期:插补算法,曲线拟合丝滑顺畅,统计函数和基础函数加速实现,汇集SIMD,饱和和MAC乘累加应用实战(2023-02-12)

视频教程汇总帖&#xff1a;https://www.armbbs.cn/forum.php?modviewthread&tid110519 DSP视频教程有段时间没有更新了。 当前DSP库从CMSIS软件包里面独立出来&#xff0c;并且更新非常频繁&#xff0c;所以本期视频教程优先给大家简单介绍下新版DSP&#xff0c; 然后为…...

分类模型评估:混淆矩阵、准确率、召回率、ROC

1. 混淆矩阵 在二分类问题中&#xff0c;混淆矩阵被用来度量模型的准确率。因为在二分类问题中单一样本的预测结果只有Yes or No&#xff0c;即&#xff1a;真或者假两种结果&#xff0c;所以全体样本的经二分类模型处理后&#xff0c;处理结果不外乎四种情况&#xff0c;每种…...

算法 ——世界 一

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。个人爱好: 编程&#xff0c;打篮球&#xff0c;计算机知识个人名言&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石…...

2023年3月AMA-CDGA/CDGP数据治理认证考试这些城市可以报名

目前2023年3月5日CDGA&CDGP开放报名的城市有&#xff1a;北京、上海、广州、深圳、杭州、重庆&#xff0c;西安&#xff0c;成都&#xff0c;长沙&#xff0c;济南&#xff0c;更多考场正在增加中… DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业…...

Java变量和数据类型,超详细整理,适合新手入门

目录 一、什么是变量&#xff1f; 二、变量 变量值互换 三、基本数据类型 1、八种基本数据类型 2、布尔值 3、字符串 四、从控制台输入 一、什么是变量&#xff1f; 变量是一种存储值的容器&#xff0c;它可以在程序的不同部分之间共享&#xff1b;变量可以存储数字、字…...

Echarts 设置折线图拐点的颜色,边框等样式,hover时改变颜色

第014个点击查看专栏目录上一篇文章我们讲到了如何设置拐点大小,图形类型&#xff0c;旋转角度&#xff0c;缩放同比&#xff0c;位置偏移等&#xff0c;这篇文章介绍如何设置拐点的颜色、边框大小颜色等样式。hover轴线时候&#xff0c;拐点的填充颜色改变文章目录示例效果示例…...

做 SQL 性能优化真是让人干瞪眼

很多大数据计算都是用SQL实现的&#xff0c;跑得慢时就要去优化SQL&#xff0c;但常常碰到让人干瞪眼的情况。 比如&#xff0c;存储过程中有三条大概形如这样的语句执行得很慢&#xff1a; select a,b,sum(x) from T group by a,b where …; select c,d,max(y) from T grou…...

SpringBoot(3)之包结构

根据spring可知道&#xff0c;注解之所以可以使用&#xff0c;是因为通过包扫描器&#xff0c;扫描包&#xff0c;然后才能通过注解开发。 那么springboot需要扫描哪里呢&#xff1f; springboot的默认包扫描器&#xff0c;扫描的是自己所在的包和子包&#xff0c;例子如下 我…...

test2

物理层故障分析 一、传输介质故障 a.主要用途简述 传输介质主要分为 导向传输介质和非导向传输介质。前者包括双绞线&#xff08;两根铜线并排绞合&#xff0c;距离过远会失真&#xff09;、同轴电缆&#xff08;铜质芯线屏蔽层&#xff0c;抗干扰性强&#xff0c;传输距离更…...

LoadRunner安装教程

备注&#xff1a;电脑最好安装有IE浏览器或者360极速版浏览器 一、下载安装包 提前下载安装文件&#xff0c;必须下载。 链接: https://pan.baidu.com/s/1blFiMIJcoE8s3uVhAxdzdA?pwdqhpt 提取码: qhpt 包含的文件有&#xff1a; 二、安装loadrunner 注意&#xff0c;以…...

VHDL语言基础-Testbech

目录 VHDL仿真概述: 基本结构: VHDL一般仿真过程: 仿真测试平台文件: 编写测试平台文件的语言: 一个测试平台文件的基本结构如下&#xff1a; 测试平台文件包含的基本语句: 产生激励信号的方式: 时钟信号: 复位信号: 周期信性信号: 使用延迟DELAYD: 一般的激励信号…...

机器学习基础总结

一&#xff0c;机器学习系统分类 机器学习系统分为三个类别&#xff0c;如下图所示: 二&#xff0c;如何处理数据中的缺失值 可以分为以下 2 种情况&#xff1a; 缺失值较多&#xff1a;直接舍弃该列特征&#xff0c;否则可能会带来较大噪声&#xff0c;从而对结果造成不良影…...

linux的三权分立设计思路和用户创建(安全管理员、系统管理员和审计管理员)

目录 一、三权分立设计思路 1、什么是三权 2、三员及权限的理解 3、三员之三权 4、权限划分 5、“三员”职责 6、“三员”配置要求 二、linux三权分立的用户创建 1、系统管理员 2、安全管理员 3、审计管理员 一、三权分立设计思路 1、什么是三权 三权指的是配置、…...

revit中如何创建有坡度的排水沟及基坑?

一、revit中如何创建有坡度的排水沟? 先分享一张有坡度排水沟的族的照片给大家加深一下印象&#xff0c;有了一个粗略的直观认识&#xff0c;小编就来说说做这个族的前期思路吧。 一、前期思路&#xff1a; 1、 用拼接的方式把这个族形状拼出来&#xff0c;先用放样&#xff0…...

Web自动化测试——selenium篇(一)

文章目录一、环境准备二、Web 自动化测试 Demo三、元素定位常用方法四、元素定位失败可能原因五、测试对象操作六、等待操作七、信息打印在学习 Web 自动化测试的过程中&#xff0c;selenium 是其中的常用工具。除了其开源免费&#xff0c;包含丰富的 API 以外&#xff0c;它还…...

认识 CSS pointer-events 属性

pointer-events 的基本信息 pointer-events 属性用来控制一个元素能否响应鼠标操作&#xff0c;常用的关键字有 auto 和 none pointer-events: none; // 让一个元素忽略鼠标操作 pointer-events: auto; // 还原浏览器设定的默认行为 规范定义 条目状态初始值auto可用值适用所…...

【java】springboot和springcloud区别

文章目录1、含义不同2、作用不同3、使用方式不同4、特征不同5、注释不同6、优势不同7、组件不同8、设计目的不同1、含义不同 springboot&#xff1a;一个快速开发框架&#xff0c;它简化了传统MVC的XML配置&#xff0c;使配置变得更加方便、简洁。 springcloud&#xff1a;是…...

杭州网站设计工作室/河北百度seo软件

没有相关的视频教程及相关的学习线路&#xff0c;学起来是一件很费劲的事情&#xff0c;还有很多人从网上及其它渠道购买视频&#xff0c;这些视频资料大多是盗版&#xff0c;上当受骗的人不在少数。为此千锋小编呕心沥血整理了这套零基础全套Linux云计算教程&#xff0c;不管是…...

网站设计 上海/长沙网络推广网站制作

python的类方法和类的静态方法 (2010-03-11 21:27)分类&#xff1a; Pythonpython的类方法和类的静态方法&#xff0c;其实就是一个用classmethod和staticmethod修饰的类中的函数。其中类方法要在定义的时候指出在调用它时隐式赋给他的第一个参数&#xff0c;这个参数一般情况下…...

药品网站建设/百度推广新手入门

&#xff08;1&#xff09;黄金分割法&#xff08;0.618法&#xff09; 基本思想&#xff1a; 它通过对试探点的函数值进行比较&#xff0c;使得包含极小点的区间不断缩短&#xff0c;当区间长度小到精度范围之内时&#xff0c;可以粗略地认为区间上各点的函数值均接近于…...

做网站租用服务器/成都seo优化公司排名

SELECT r.Studentno AS "李"同学学号,studentname AS 姓名,StudentResult AS 成绩 FROM result AS r INNER JOIN student AS s ON r.StudentNos.StudentNo AND studentname LIKE CONCAT(李,%) 转载于:https://www.cnblogs.com/Suaron/p/9781731.html...

为什么要建设学校网站/建材企业网站推广方案

模拟实现C智能指针shared_ptr和weak_ptr 仿写C的shared_ptr和weak_ptr 当强智能指针shared_ptr的引用计数为0时&#xff0c;析构资源 当弱智能指针weak_ptr的引用计数为0时&#xff0c;析构引用计数对象 #include<iostream> #include<new> #include<stdio.h&g…...

山西城乡建设网站/电子商务与网络营销题库

二叉树的中序遍历 题目描述&#xff1a; 给定一个二叉树的根节点 root &#xff0c;返回它的 中序 遍历。提示&#xff1a;树中节点数目在范围 [0, 100] 内-100 < Node.val < 100题目链接 首先需要理解什么是中序遍历&#xff0c;中序遍历就是按照"左-根-右"的…...