当前位置: 首页 > 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…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...