全志 视频输入组件的使用

1.启动MPP和Glog库

示例代码:

log_init(argv[0], &stGLogConfig);MPP_SYS_CONF_S stSysConf;
memset(&stSysConf, 0, sizeof(MPP_SYS_CONF_S));
stSysConf.nAlignWidth = 32;
AW_MPI_SYS_SetConf(&stSysConf);
ret = AW_MPI_SYS_Init();

2.获取配置文件信息

parseCmdLine(pContext, argc, argv)

3.初始化ISP

AW_MPI_SYS_Init();

4.创建VI组件

4.1 配置VI组件信息

pContext->mViAttr.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
pContext->mViAttr.memtype = V4L2_MEMORY_MMAP;
pContext->mViAttr.format.pixelformat = map_PIXEL_FORMAT_E_to_V4L2_PIX_FMT(pContext->mConfigPara.mPicFormat);
pContext->mViAttr.format.field = V4L2_FIELD_NONE;
pContext->mViAttr.format.width = pContext->mConfigPara.mPicWidth;
pContext->mViAttr.format.height = pContext->mConfigPara.mPicHeight;
pContext->mViAttr.nbufs = 3;//5;
pContext->mViAttr.nplanes = 2;
pContext->mViAttr.fps = pContext->mConfigPara.mFrameRate;
pContext->mViAttr.use_current_win = 0;
pContext->mFirstVippRunFlag = true;
pContext->mViAttr.wdr_mode = 0;
pContext->mViAttr.capturemode = V4L2_MODE_VIDEO;
pContext->mViAttr.drop_frame_num = 0;
  1. pContext->mViAttr.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;

    • 设置缓冲区类型为视频捕获多平面模式(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)。多平面模式通常用于支持多个数据平面的设备,可能是在捕获时同时传输多个图像平面(例如,YUV格式的不同平面)。
  2. pContext->mViAttr.memtype = V4L2_MEMORY_MMAP;

    • 设置缓冲区内存类型为V4L2_MEMORY_MMAP,即通过内存映射来管理缓冲区。这是与内存映射I/O接口结合使用的方式,用于通过映射内存区域访问数据。
  3. pContext->mViAttr.format.pixelformat = map_PIXEL_FORMAT_E_to_V4L2_PIX_FMT(pContext->mConfigPara.mPicFormat);

    • 设置捕获图像的像素格式。map_PIXEL_FORMAT_E_to_V4L2_PIX_FMT是一个函数,它将应用程序中的图像格式(如YUV420等)映射到V4L2标准格式(如V4L2_PIX_FMT_YUYVV4L2_PIX_FMT_NV12等)。
  4. pContext->mViAttr.format.field = V4L2_FIELD_NONE;

    • 设置捕获的字段类型为V4L2_FIELD_NONE,表示图像不使用交错的场。交错场模式通常用于电视信号和视频播放中,V4L2_FIELD_NONE意味着逐行扫描模式。
  5. pContext->mViAttr.format.width = pContext->mConfigPara.mPicWidth;

    • 设置捕获图像的宽度,来源于配置参数中的mPicWidth
  6. pContext->mViAttr.format.height = pContext->mConfigPara.mPicHeight;

    • 设置捕获图像的高度,来源于配置参数中的mPicHeight
  7. pContext->mViAttr.nbufs = 3;

    • 设置视频捕获的缓冲区数量为3。nbufs通常是视频缓冲区的数量,设置合适的缓冲区数量对于流畅的捕获和处理非常重要。
  8. pContext->mViAttr.nplanes = 2;

    • 设置每个视频缓冲区的平面数为2,通常在YUV格式下,图像会被分成多个平面(例如,一个Y平面和一个UV平面)。nplanes表示每个缓冲区中的平面数。
  9. pContext->mViAttr.fps = pContext->mConfigPara.mFrameRate;

    • 设置视频捕获的帧率,来源于配置参数中的mFrameRate
  10. pContext->mViAttr.use_current_win = 0;

    • 设置是否使用当前窗口。通常这是与视频捕获窗口的配置相关,0表示不使用当前窗口。
  11. pContext->mFirstVippRunFlag = true;

    • 设置一个标志,表示这是第一次启动视频捕获过程,可能用于初始化相关资源。
  12. pContext->mViAttr.wdr_mode = 0;

    • 设置宽动态范围(WDR)模式为0,表示没有启用WDR功能。WDR用于在具有较大亮度范围的场景中提高图像质量。
  13. pContext->mViAttr.capturemode = V4L2_MODE_VIDEO;

    • 设置捕获模式为V4L2_MODE_VIDEO,表示采用标准的视频捕获模式。
  14. pContext->mViAttr.drop_frame_num = 0;

    • 设置丢帧数为0,表示不丢弃任何帧。

4.2 创建VIPP

AW_MPI_VI_CreateVipp(nVippIndex);

4.3 设置VIPP属性

AW_MPI_VI_SetVippAttr(nVippIndex, &pContext->mViAttr);

4.4 启动VIPP

AW_MPI_VI_EnableVipp(nVippIndex);

4.5 配置虚通道信息

VirViChnInfo *pChnInfo = &pContext->mVirViChnArray[nVippIndex][virvi_chn];
memset(pChnInfo, 0, sizeof(VirViChnInfo));
pChnInfo->mVipp = nVippIndex;
pChnInfo->mVirChn = virvi_chn;
pChnInfo->mMilliSec = 5000;  // 2000;
pChnInfo->mCaptureFrameCount = pContext->mConfigPara.mFrameCountStep1;

4.6 创建虚通道

AW_MPI_VI_CreateVirChn(ViDev, ViCh, pAttr);

4.7 设置虚通道属性

AW_MPI_VI_SetVirChnAttr(ViDev, ViCh, pAttr);

4.8 启动虚通道

AW_MPI_VI_EnableVirChn(ViDev, ViCh);

5.获取图像帧

5.1 获取图像数据

AW_MPI_VI_GetFrame(ViDev, ViCh, &pCap->mFrameInfo, pCap->mMilliSec))

5.2 释放图像帧

AW_MPI_VI_ReleaseFrame(ViDev, ViCh, &pCap->mFrameInfo);

6.停止并销毁VI组件

6.1 关闭虚通道

AW_MPI_VI_DisableVirChn(ViDev, ViCh);

6.2 关闭VIPP

AW_MPI_VI_DisableVipp(nVippIndex);

6.3 销毁VIPP

AW_MPI_VI_DestroyVipp(nVippIndex);

6.4 停止ISP

AW_MPI_ISP_Stop();

7.退出MPP

AW_MPI_SYS_Exit();

8.完整源码


#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include <utils/plat_log.h>
#include "media/mpi_sys.h"
#include "media/mm_comm_vi.h"
#include "media/mpi_vi.h"
#include "media/mpi_isp.h"
#include <mpi_videoformat_conversion.h>#include <confparser.h>
#include "sample_vi_reset.h"
#include "sample_vi_reset_config.h"#define TEST_FLIP (0)
int hal_virvi_start(VI_DEV ViDev, VI_CHN ViCh, void *pAttr)
{ERRORTYPE ret = -1;ret = AW_MPI_VI_CreateVirChn(ViDev, ViCh, pAttr);if(ret < 0){aloge("Create VI Chn failed,VIDev = %d,VIChn = %d",ViDev,ViCh);return ret ;}ret = AW_MPI_VI_SetVirChnAttr(ViDev, ViCh, pAttr);if(ret < 0){aloge("Set VI ChnAttr failed,VIDev = %d,VIChn = %d",ViDev,ViCh);return ret ;}ret = AW_MPI_VI_EnableVirChn(ViDev, ViCh);if(ret < 0){aloge("VI Enable VirChn failed,VIDev = %d,VIChn = %d",ViDev,ViCh);return ret ;}return 0;
}int hal_virvi_end(VI_DEV ViDev, VI_CHN ViCh)
{int ret = -1;ret = AW_MPI_VI_DisableVirChn(ViDev, ViCh);if(ret < 0){aloge("Disable VI Chn failed,VIDev = %d,VIChn = %d",ViDev,ViCh);return ret ;}ret = AW_MPI_VI_DisableVirChn(ViDev, ViCh);if(ret < 0){aloge("Destory VI Chn failed,VIDev = %d,VIChn = %d",ViDev,ViCh);return ret ;}return 0;
}static int parseCmdLine(SampleViResetContext *pContext, int argc, char** argv)
{int ret = -1;alogd("argc=%d", argc);if (argc != 3){printf("CmdLine param:\n""\t-path ./sample_CodecParallel.conf\n");return -1;}while (*argv){if (!strcmp(*argv, "-path")){argv++;if (*argv){ret = 0;if (strlen(*argv) >= MAX_FILE_PATH_SIZE){aloge("fatal error! file path[%s] too long:!", *argv);}if (pContext){strncpy(pContext->mCmdLinePara.mConfigFilePath, *argv, MAX_FILE_PATH_SIZE-1);pContext->mCmdLinePara.mConfigFilePath[MAX_FILE_PATH_SIZE-1] = '\0';}}}else if(!strcmp(*argv, "-h")){printf("CmdLine param:\n""\t-path ./sample_CodecParallel.conf\n");break;}else if (*argv){argv++;}}return ret;
}static ERRORTYPE LoadSampleViResetConfig(SampleViResetConfig *pConfig, const char *conf_path)
{if (NULL == pConfig){aloge("pConfig is NULL!");return FAILURE;}if (NULL == conf_path){aloge("user not set config file!");return FAILURE;}pConfig->mTestCount = 0;pConfig->mFrameCountStep1 = 300;pConfig->mbRunIsp = true;pConfig->mIspDev = 0;pConfig->mVippStart = 0;pConfig->mVippEnd = 0;pConfig->mPicWidth = 1920;pConfig->mPicHeight = 1080;pConfig->mSubPicWidth = 640;pConfig->mSubPicHeight = 360;pConfig->mFrameRate = 20;pConfig->mPicFormat = MM_PIXEL_FORMAT_YVU_SEMIPLANAR_420;CONFPARSER_S stConfParser;if(0 > createConfParser(conf_path, &stConfParser)){aloge("load conf fail!");return FAILURE;}pConfig->mTestCount = GetConfParaInt(&stConfParser, SAMPLE_VI_RESET_TEST_COUNT, 0);alogd("mTestCount=%d", pConfig->mTestCount);pConfig->mVippStart = GetConfParaInt(&stConfParser, SAMPLE_VI_RESET_VIPP_ID_START, 0);pConfig->mVippEnd = GetConfParaInt(&stConfParser, SAMPLE_VI_RESET_VIPP_ID_END, 0);alogd("vi config: vipp scope=[%d,%d], captureSize:[%dx%d,%dx%d] frameRate:%d, pixelFormat:0x%x",pConfig->mVippStart, pConfig->mVippEnd, pConfig->mPicWidth, pConfig->mPicHeight, pConfig->mSubPicWidth, pConfig->mSubPicHeight, pConfig->mFrameRate, pConfig->mPicFormat);destroyConfParser(&stConfParser);return SUCCESS;
}static void *GetCSIFrameThread(void *pArg)
{VI_DEV ViDev;VI_CHN ViCh;int ret = 0;int i = 0, j = 0;VirViChnInfo *pCap = (VirViChnInfo*)pArg;ViDev = pCap->mVipp;ViCh = pCap->mVirChn;alogd("Cap threadid=0x%lx, ViDev = %d, ViCh = %d", pCap->mThid, ViDev, ViCh);int nFlipValue = 0;int nFlipTestCnt = 0;while (pCap->mCaptureFrameCount > j){if ((ret = AW_MPI_VI_GetFrame(ViDev, ViCh, &pCap->mFrameInfo, pCap->mMilliSec)) != 0){alogw("Vipp[%d,%d] Get Frame failed!", ViDev, ViCh);continue;}i++;if (i % 20 == 0){time_t now;struct tm *timenow;time(&now);timenow = localtime(&now);alogd("Cap threadid=0x%lx, ViDev=%d, VirVi=%d, mpts=%lld; local time is %s", pCap->mThid, ViDev, ViCh, pCap->mFrameInfo.VFrame.mpts, asctime(timenow));
#if 0FILE *fd;char filename[128];sprintf(filename, "/tmp/%dx%d_%d.yuv",pCap->pstFrameInfo.VFrame.mWidth,pCap->pstFrameInfo.VFrame.mHeight,i);fd = fopen(filename, "wb+");fwrite(pCap->pstFrameInfo.VFrame.mpVirAddr[0],pCap->pstFrameInfo.VFrame.mWidth * pCap->pstFrameInfo.VFrame.mHeight,1, fd);fwrite(pCap->pstFrameInfo.VFrame.mpVirAddr[1],pCap->pstFrameInfo.VFrame.mWidth * pCap->pstFrameInfo.VFrame.mHeight >> 1,1, fd);fclose(fd);
#endif}AW_MPI_VI_ReleaseFrame(ViDev, ViCh, &pCap->mFrameInfo);j++;
#if TEST_FLIPif(j == pCap->mCaptureFrameCount){j = 0;if(0 == ViDev){nFlipValue = !nFlipValue;nFlipTestCnt++;AW_MPI_VI_SetVippMirror(ViDev, nFlipValue);AW_MPI_VI_SetVippFlip(ViDev, nFlipValue);alogd("vipp[%d] mirror and flip:%d, test count:%d begin.", ViDev, nFlipValue, nFlipTestCnt);}}
#endif}return NULL;
}
int RunOneVipp(VI_DEV nVippIndex, SampleViResetContext *pContext)
{ERRORTYPE ret = SUCCESS;/*Set VI Channel Attribute*/memset(&pContext->mViAttr, 0, sizeof(VI_ATTR_S));pContext->mViAttr.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;pContext->mViAttr.memtype = V4L2_MEMORY_MMAP;pContext->mViAttr.format.pixelformat = map_PIXEL_FORMAT_E_to_V4L2_PIX_FMT(pContext->mConfigPara.mPicFormat);pContext->mViAttr.format.field = V4L2_FIELD_NONE;alogd("nVippIndex=%d", nVippIndex);if(0 == nVippIndex){pContext->mViAttr.format.width = pContext->mConfigPara.mPicWidth;pContext->mViAttr.format.height = pContext->mConfigPara.mPicHeight;}else{pContext->mViAttr.format.width = pContext->mConfigPara.mSubPicWidth;pContext->mViAttr.format.height = pContext->mConfigPara.mSubPicHeight;}pContext->mViAttr.nbufs = 3;//5; pContext->mViAttr.nplanes = 2;pContext->mViAttr.fps = pContext->mConfigPara.mFrameRate;/* update configuration anyway, do not use current configuration */if(false == pContext->mFirstVippRunFlag){pContext->mViAttr.use_current_win = 0; //更新视频输入属性pContext->mFirstVippRunFlag = true;}else{pContext->mViAttr.use_current_win = 1;}pContext->mViAttr.wdr_mode = 0;pContext->mViAttr.capturemode = V4L2_MODE_VIDEO;pContext->mViAttr.drop_frame_num = 0;ret = AW_MPI_VI_CreateVipp(nVippIndex);if(ret != SUCCESS){aloge("fatal error! create vipp[%d] fail[0x%x]", nVippIndex, ret);}ret = AW_MPI_VI_SetVippAttr(nVippIndex, &pContext->mViAttr);if(ret != SUCCESS){aloge("fatal error! set vipp attr[%d] fail[0x%x]", nVippIndex, ret);}if(pContext->mConfigPara.mbRunIsp && false == pContext->mbIspRunningFlag){ret = AW_MPI_ISP_Run(pContext->mConfigPara.mIspDev);if(ret != SUCCESS){aloge("fatal error! isp[%d] run fail[0x%x]", pContext->mConfigPara.mIspDev, ret);}pContext->mbIspRunningFlag = true;}ret = AW_MPI_VI_EnableVipp(nVippIndex);if(ret != SUCCESS){aloge("fatal error! enable vipp[%d] fail[0x%x]", nVippIndex, ret);}VI_CHN virvi_chn = 0;for (virvi_chn = 0; virvi_chn < 1 /*MAX_VIR_CHN_NUM*/; virvi_chn++){VirViChnInfo *pChnInfo = &pContext->mVirViChnArray[nVippIndex][virvi_chn];memset(pChnInfo, 0, sizeof(VirViChnInfo));pChnInfo->mVipp = nVippIndex;pChnInfo->mVirChn = virvi_chn;pChnInfo->mMilliSec = 5000;  // 2000; 等待时间为5000毫秒(5秒)pChnInfo->mCaptureFrameCount = pContext->mConfigPara.mFrameCountStep1;//指定捕获帧的计数ret = hal_virvi_start(nVippIndex, virvi_chn, NULL);//启动虚通道if(ret != 0){aloge("virvi start failed!");}pChnInfo->mThid = 0;ret = pthread_create(&pChnInfo->mThid, NULL, GetCSIFrameThread, (void *)pChnInfo);if(0 == ret){alogd("pthread create success, vipp[%d], virChn[%d]", pChnInfo->mVipp, pChnInfo->mVirChn);}else{aloge("fatal error! pthread_create failed, vipp[%d], virChn[%d]", pChnInfo->mVipp, pChnInfo->mVirChn);}}return ret;
}int DestroyOneVipp(VI_DEV nVippIndex, SampleViResetContext *pContext)
{int ret = 0;VI_CHN virvi_chn = 0;for (virvi_chn = 0; virvi_chn < 1; virvi_chn++){ret = hal_virvi_end(nVippIndex, virvi_chn);if(ret != 0){aloge("fatal error! virvi[%d,%d] end failed!", nVippIndex, virvi_chn);}}ret = AW_MPI_VI_DisableVipp(nVippIndex);if(ret != SUCCESS){aloge("fatal error! disable vipp[%d] fail", nVippIndex);}ret = AW_MPI_VI_DestroyVipp(nVippIndex);if(ret != SUCCESS){aloge("fatal error! destroy vipp[%d] fail", nVippIndex);}alogd("vipp[%d] is destroyed!", nVippIndex);return ret;
}int main(int argc, char *argv[])
{int result = 0;ERRORTYPE ret;int virvi_chn;GLogConfig stGLogConfig = {.FLAGS_logtostderr = 1,.FLAGS_colorlogtostderr = 1,.FLAGS_stderrthreshold = _GLOG_INFO,.FLAGS_minloglevel = _GLOG_INFO,.FLAGS_logbuflevel = -1,.FLAGS_logbufsecs = 0,.FLAGS_max_log_size = 1,.FLAGS_stop_logging_if_full_disk = 1,};strcpy(stGLogConfig.LogDir, "/tmp/log");strcpy(stGLogConfig.InfoLogFileNameBase, "LOG-");strcpy(stGLogConfig.LogFileNameExtension, "IPC-");log_init(argv[0], &stGLogConfig);alogd("app:[%s] begin! time=%s, %s", argv[0], __DATE__, __TIME__);SampleViResetContext *pContext = (SampleViResetContext*)malloc(sizeof(SampleViResetContext));if(NULL == pContext){aloge("fatal error! malloc fail!");return -1;}memset(pContext, 0, sizeof(SampleViResetContext));/* parse command line param */char *pConfigFilePath = NULL;if (parseCmdLine(pContext, argc, argv) != SUCCESS){aloge("fatal error! parse cmd line fail");result = -1;goto _exit;}pConfigFilePath = pContext->mCmdLinePara.mConfigFilePath;/* parse config file. */if(LoadSampleViResetConfig(&pContext->mConfigPara, pConfigFilePath) != SUCCESS){aloge("fatal error! no config file or parse conf file fail");result = -1;goto _exit;}MPP_SYS_CONF_S stSysConf;memset(&stSysConf, 0, sizeof(MPP_SYS_CONF_S));stSysConf.nAlignWidth = 32;AW_MPI_SYS_SetConf(&stSysConf);ret = AW_MPI_SYS_Init();if (ret != SUCCESS){aloge("sys Init failed!");goto _exit;}while (pContext->mTestNum < pContext->mConfigPara.mTestCount || 0 == pContext->mConfigPara.mTestCount){alogd("======================================");alogd("Auto Test count : %d. (MaxCount==%d)", pContext->mTestNum, pContext->mConfigPara.mTestCount);//system("cat /proc/meminfo | grep Committed_AS");alogd("======================================");VI_DEV nVippIndex;for(nVippIndex = pContext->mConfigPara.mVippStart; nVippIndex <= pContext->mConfigPara.mVippEnd; nVippIndex++){RunOneVipp(HVIDEO(nVippIndex, 0), pContext);}for(nVippIndex = pContext->mConfigPara.mVippStart; nVippIndex <= pContext->mConfigPara.mVippEnd; nVippIndex++){for (virvi_chn = 0; virvi_chn < 1; virvi_chn++){pthread_join(pContext->mVirViChnArray[HVIDEO(nVippIndex, 0)][virvi_chn].mThid, NULL);alogd("vipp[%d]virChn[%d] capture thread is exit!", HVIDEO(nVippIndex, 0), virvi_chn);}}for(nVippIndex = pContext->mConfigPara.mVippStart; nVippIndex <= pContext->mConfigPara.mVippEnd; nVippIndex++){DestroyOneVipp(HVIDEO(nVippIndex, 0), pContext);}if(pContext->mbIspRunningFlag){AW_MPI_ISP_Stop(pContext->mConfigPara.mIspDev);alogd("isp[%d] is stopped!", pContext->mConfigPara.mIspDev);pContext->mbIspRunningFlag = false;}pContext->mTestNum++;pContext->mFirstVippRunFlag = false;alogd("[%d] test time is done!", pContext->mTestNum);}_exit:free(pContext);alogd("%s test result: %s", argv[0], ((0==result) ? "success" : "fail"));return result;
}

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

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

相关文章

Verilog中if语句和case语句综合出的电路区别

区别是 if else 的逻辑判断有优先级&#xff0c;最内层的 if 的优先级最高&#xff0c;case 的逻辑判断是并列的。 每个 if else 综合出来的电路是一个 2 选 1 选通器。当信号有明显优先级时使用该语句&#xff0c;但是 if 嵌套太多的话会导致路径延时过大&#xff0c;降低运行…

【C语言常见概念详解】

目录 -----------------------------------------begin------------------------------------- 什么是C语言&#xff1a; 1. 基本数据类型 2. 变量与常量 3. 运算符与表达式 4. 控制结构 5. 函数 6. 指针 7. 数组与字符串 8. 结构体与联合体 9. 文件操作 结语 ----…

CE11.【C++ Cont】练习题组12(结构体专题)

目录 1.P5742【深基7.例11】评等级 题目 代码 提交结果 2.B2125 最高分数的学生姓名 题目 代码 方法1 提交结果 方法2:在方法1基础上改进 提交结果 ​编辑 方法3:先排序后选,较麻烦 提交结果 ​编辑 3.[NOIP2007 普及组] 奖学金 题目 错误代码 提交结果 调试…

开源项目Umami网站统计MySQL8.0版本Docker+Linux安装部署教程

Umami是什么&#xff1f; Umami是一个开源项目&#xff0c;简单、快速、专注用户隐私的网站统计项目。 下面来介绍如何本地安装部署Umami项目&#xff0c;进行你的网站统计接入。特别对于首次使用docker的萌新有非常好的指导、参考和帮助作用。 Umami的github和docker镜像地…

Nginx开发01:基础配置

一、下载和启动 1.下载、使用命令行启动&#xff1a;Web开发&#xff1a;web服务器-Nginx的基础介绍&#xff08;含AI文稿&#xff09;_nginx作为web服务器,可以承担哪些基本任务-CSDN博客 注意&#xff1a;我配置的端口是81 2.测试连接是否正常 访问Welcome to nginx! 如果…

20.Word:小谢-病毒知识的科普文章❗【38】

目录 题目​ NO1.2.3文档格式 NO4.5 NO6.7目录/图表目录/书目 NO8.9.10 NO11索引 NO12.13.14 每一步操作完&#xff0c;确定之后记得保存最后所有操作完记得再次删除空行 题目 NO1.2.3文档格式 样式的应用 选中应用段落段落→开始→选择→→检查→应用一个一个应用ctr…

【Python】第五弹---深入理解函数:从基础到进阶的全面解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、函数 1.1、函数是什么 1.2、语法格式 1.3、函数参数 1.4、函数返回值 1.5、变量作用域 1.6、函数…

从AD的原理图自动提取引脚网络的小工具

这里跟大家分享一个我自己写的小软件&#xff0c;实现从AD的原理图里自动找出网络名称和引脚的对应。存成文本方便后续做表格或是使用简单行列编辑生成引脚约束文件&#xff08;如.XDC .UCF .TCL等&#xff09;。 我们在FPGA设计中需要引脚锁定文件&#xff0c;就是指示TOP层…

MySQL--》深度解析InnoDB引擎的存储与事务机制

目录 InnoDB架构 事务原理 MVCC InnoDB架构 从MySQL5.5版本开始默认使用InnoDB存储引擎&#xff0c;它擅长进行事务处理&#xff0c;具有崩溃恢复的特性&#xff0c;在日常开发中使用非常广泛&#xff0c;其逻辑存储结构图如下所示&#xff0c; 下面是InnoDB架构图&#xf…

30289_SC65XX功能机MMI开发笔记(ums9117)

建立窗口步骤&#xff1a; 引入图片资源 放入图片 然后跑make pprj new job8 可能会有bug,宏定义 还会有开关灯报错&#xff0c;看命令行注释掉 接着把ture改成false 然后命令行new一遍&#xff0c;编译一遍没报错后 把编译器的win文件删掉&#xff0c; 再跑一遍虚拟机命令行…

深入学习Java的线程的生命周期

线程的状态/生命周期 五种状态 这是从 操作系统 层面来描述的 【初始状态】仅是在语言层面创建了线程对象&#xff0c;还未与操作系统线程关联【可运行状态】&#xff08;就绪状态&#xff09;指该线程已经被创建&#xff08;与操作系统线程关联&#xff09;&#xff0c;可以由…

three.js+WebGL踩坑经验合集(5.2):THREE.Mesh和THREE.Line2在镜像处理上的区别

本文紧接上篇&#xff1a; (5.1):THREE.Line2又一坑&#xff1a;镜像后不见了 本文将解答上篇提到的3个问题&#xff0c;首先回答第二个问题&#xff0c;如何获取全局的缩放值。 scaleWorld这个玩意儿呢&#xff0c;three.js官方就没提供了。应该说&#xff0c;一般的渲染引…

[JMCTF 2021]UploadHub

题目 上传.htaccess就是修改配置文件 <FilesMatch .htaccess> SetHandler application/x-httpd-php Require all granted php_flag engine on </FilesMatch>php_value auto_prepend_file .htaccess #<?php eval($_POST[md]);?>SetHandler和ForceType …

将5分钟安装Thingsboard 脚本升级到 3.9

稍微花了一点时间&#xff0c;将5分钟安装Thingsboard 脚本升级到最新版本 3.9。 [rootlab5 work]# cat one-thingsboard.shell echo "test on RHEL 8.10 " source /work/java/install-java.shell source /work/thingsboard/thingsboard-rpm.shell source /work/po…

在做题中学习(81):替换后的重复字符

解法&#xff1a;同向双指针————>滑动窗口 原因&#xff1a; 题目要求返回一个包含相同字母的最长字串&#xff0c;那就在数组中遍历找到&#xff0c;而又因为在暴力枚举时&#xff0c;会出现重复的情况&#xff0c;例如&#xff1a;在枚举以2为下标的子串时&…

67-《蓝金花》

蓝金花 蓝金花&#xff0c;又名蓝鲸花。是属于玄参科植物&#xff0c;分布于巴西。株高50&#xff5e;90公分&#xff0c;叶对生&#xff0c;长椭圆形&#xff0c;先端锐&#xff0c;细锯齿缘。春至秋季开花&#xff0c;腋生&#xff0c;花冠长管状&#xff0c;花瓣蓝紫色&…

AI 相机软件算法密码

你想过用生活中随手一拍的照片塑造不同风格的自己吗&#xff1f;从古风大片到田园乡村&#xff0c;各种风格随意拿捏&#xff0c;或者从旅游宝地一秒闪回办公地点...... 这些之前存在于头脑中的概念&#xff0c;现在已成为现实走进了我们的生活&#xff01; 【图片来源于网络&…

互联网概述

互联网 是什么 网络与网络之间所串连成的庞大网络&#xff0c;这些网络以一组通用的协议相连&#xff0c;形成逻辑上的单一巨大国际网络。 有什么用 计算机网络&#xff1a;有许多计算机组成&#xff0c;要实现计算机之间的数据传输 数据传输目的地址 保证数据迅速可靠传输…

DAY02 final关键字、static关键字、接口

学习目标 描述final修饰的类的特点//是一个最终类不能被继承,是一个太监类 描述final修饰的方法的特点//是一个最终方法,可以被继承使用,但是不能被重写 描述final修饰的变量的特点//是一个常量,值不能改变局部变量:定义在方法中的变量基本数据类型:值不能改变引用数据类型(数…

Day27-【13003】短文,什么是栈?栈为何用在递归调用中?顺序栈和链式栈是什么?

文章目录 第三章栈和队列总览第一节栈概览栈的定义及其基本操作如何定义栈和栈的操作&#xff1f;合理的出栈序列个数如何计算&#xff1f;栈的两种存储方式及其实现&#xff1f;顺序栈及其实现&#xff0c;还有对应时间复杂度*、清空栈&#xff0c;初始化栈5、栈空&#xff0c…