linux学习:多媒体开发库SDL+视频、音频、事件子系统+处理yuv视频源
目录
编译和移植
视频子系统
视频子系统产生图像的步骤
api
初始化 SDL 的相关子系统
使用指定的宽、高和色深来创建一个视窗 surface
使用 fmt 指定的格式创建一个像素点编辑
将 dst 上的矩形 dstrect 填充为单色 color编辑
将 src 快速叠加到 dst 上编辑
更新 screen 上的图像元素编辑
api例子
音频子系统
SDL 中默认支持的对 wav 格式 的音频文件的 API
存放音频数据的具体信息
加载 wav 格式的音频文件编辑
启动音频设备编辑
暂停或者继续编辑
api例子
事件子系统
联合体
使用鼠标的实例
处理YUV视频源
sdl是一个跨平台的底层开发库,提供操作诸如音频、 键盘、鼠标、游戏杆以及显卡等硬件的方法,被很多多媒体播放器、模拟器和流行游戏所使 用,SDL 支持 Windows、MacOS、Linux、iOS 以及 Android,也就是说你目所能及的 几乎所有平台它都能运行,并且 SDL 是开源的,完全由 C 语言编写,
编译和移植
- 下载:http://www.libsdl.org/release/SDL-1.2.15.tar.gz
- 解压进入根目录
- ./configure --host=arm-none-Linux-gnueabi --prefix=/usr/local/sdl
- 注意,--host 是指定交叉编译器的前缀,--prefix 是指定 SDL 的安装目录,两者都要根 据你的具体情况来写,不必照抄
- make
- make install
- 将编译后的目录/usr/local/sdl 全部拷贝到开发板中,设置好库目录的环境变量
- 将此目录拷贝到开发板的/usr/local/sdl 中就设置export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/sdl/lib
视频子系统
在屏幕的显示能力,当我们需要显示图片、文字的时候,那就必须使用视频子系统
支持设置视频模式,即创建视频窗口,也支持直接的图像帧缓冲、 支持 Alpha 像素混合、支持窗口管理和图形渲染等
视频子系统产生图像的步骤
- 初始化 SDL 视频子系统
- 设置视频模式(包括宽高、色深等),并创建得到视窗 surface
- 加载一张图像,获得该图像的 surface
- 将图像 surface“放到”视窗 surface 上,同时可以设置你要放置的位置
- 更新视窗 surface,使得图像可
api
初始化 SDL 的相关子系统
使用指定的宽、高和色深来创建一个视窗 surface
使用 fmt 指定的格式创建一个像素点
将 dst 上的矩形 dstrect 填充为单色 color
将 src 快速叠加到 dst 上
更新 screen 上的图像元素
api例子
使用以上 API,结合触摸屏运行库 tslib 来实现移动图片的效果
// 初始化 SDL 视频子系统,并设置视窗 surface 的参数(与 LCD 一致)
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(LCD_WIDTH, LCD_HEIGHT, 0, SDL_ANYFORMAT | SDL_SWSURFACE);// 装载 BMP 图片文件 SDL 表示没压力
image = SDL_LoadBMP(argv[1]);// 1, image_offset 规定了图片要显示的矩形部分
// 2, background_offset 规定了图像要显示在视窗的那个位置,其中:
SDL_Rect image_offset;
SDL_Rect backgroud_offset;
bzero(&image_offset, sizeof(image_offset));
bzero(&backgroud_offset, sizeof(backgroud_offset));
printf("press Ctrl+c to quit.\n");
sem_init(&s, 0, 0);pthread_t tid;
pthread_create(&tid, NULL, read_moving, NULL);// 1, x 和 y 规定了图像要显示的矩形的左上角坐标
// 2, w 和 h 规定了以(x,y)为左上角的矩形的宽和高
image_offset.x = 0;
image_offset.y = 0;
image_offset.w = 400;
image_offset.h = 240;while (1) {// 产生一个 RGB 值为 000(黑色)的像素uint32_t black_pixel = SDL_MapRGB(screen->format, 0, 0, 0);// 将屏幕刷成黑色SDL_FillRect(screen, &screen->clip_rect, black_pixel);// 将图像(image)blit 到屏幕上(screen)long tmp1 = backgroud_offset.x;long tmp2 = backgroud_offset.y;SDL_BlitSurface(image, &image_offset, screen, &backgr_offset);// 显示 screen 上的元素SDL_Flip(screen);// 1,x 和 y 规定了图像 surface 放在视窗的左上角坐标// 2,w 和 h 都是作废的。backgroud_offset.x = tmp1 + xoffset;backgroud_offset.y = tmp2 + yoffset;printf("backgroud_offset.x: %d\n", backgroud_offset.x);printf("backgroud_offset.y: %d\n", backgroud_offset.y);sem_wait(&s);
}
-
要渲染视频流需要结合 FFmpeg 来做
-
图片不是 bmp 格式的,比如 jpeg、png、tiff 等,需要使用第三方扩展库 SDL_image
音频子系统
SDL 中默认支持的对 wav 格式 的音频文件的 API
存放音频数据的具体信息
加载 wav 格式的音频文件
启动音频设备
暂停或者继续
api例子
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_audio.h"
#include "SDL_config.h"struct wave
{SDL_AudioSpec spec;Uint8 *sound; /* 音频数据缓冲区指针 */Uint32 soundlen; /* 音频数据尺寸 */int soundpos; /* 已处理数据大小 */
} wave;// 画进度条
void draw_progress_bar(int left, int len)
{int i;for (i = 0; i < 20; i++)printf("\b");printf("[");int n = ((1 - (float)left / len) * 100) / 10;for (i = 0; i <= n; i++)printf("-");printf(">");for (i = 0; i < 9 - n; i++)printf(" ");printf("] %.1f%%", (1 - (float)left / len) * 100);fflush(stdout);
}// 音频解码回调函数
void deal_audio(void *unused, Uint8 *stream, int len)
{Uint8 *waveptr;int waveleft;waveptr = wave.sound + wave.soundpos;waveleft = wave.soundlen - wave.soundpos;while (waveleft <= len){memcpy(stream, waveptr, waveleft);stream += waveleft;len -= waveleft;waveptr = wave.sound;waveleft = wave.soundlen;wave.soundpos = 0;printf("\n");SDL_CloseAudio();SDL_FreeWAV(wave.sound);SDL_Quit();exit(0);}memcpy(stream, waveptr, len);wave.soundpos += len;draw_progress_bar(waveleft, wave.soundlen);
}int main(int argc, char *argv[])
{// 初始化音频子系统SDL_Init(SDL_INIT_AUDIO);// 加载 WAV 文件SDL_LoadWAV(argv[1], &wave.spec, &wave.sound, &wave.soundlen);// 指定音频数据处理回调函数wave.spec.callback = deal_audio;// 启动音频设备SDL_OpenAudio(&wave.spec, NULL);SDL_PauseAudio(0);printf("\npress Enter to pause and unpause.\n");static int pause_on = 1;while (1){// 按下回车键,暂停或播放getchar();SDL_PauseAudio(pause_on++);if (!(pause_on %= 2))printf("stopped.\n");}return 0;
}
SDL 利用函数 SDL_LoadWAV()将音频数据加载到一个缓冲区中,然后 通过结构体 SDL_AudioSpec 中的 callback 指定回调函数 deal_audio(),该函数会在音 频设备准备好要读取数据的时候被自动调用。 然后,调用 SDL_OpenAudio()启动音频设备,并且调用 SDL_PauseAudio(0)来使 得启动整个流程,此时只要音频设备准备好了,需要数据的时候,就会自动调用 deal_audio 这个函数。回调函数 deal_audio()就像一个搬运工,一旦音频设备准备好可以读取数据了, 他就将音频数据源源不断地搬到音频设备上去播放
音频文件不是 wav 格式的,比如 MP3,MIDI,OGG,MOD 这些,就需要用到 SDL 的第三方扩展库 SDL_Mixer。
事件子系统
- SDL的事件允许程序接收从用户输入的信息,当调用SDL_Init(SDL_INIT_VIDEO)初始化视频子系统时,事件子系统将被连带自动初始化。
- 本质上所有的事件都将被SDL置入一个所谓的“等待队列”中,我们可以使用诸如SDL_PollEvent()或者 SDL_WaitEvent()或者 SDL_PeepEvent()来处理或者检查当前正在等待的事件。
- SDL中处理事件的关键核心,是一个叫SDL_Event的联合体,事实上“等待队列”中储存的就是这些联合体,SDL_PollEvent()或者SDL_WaitEvent()讲这些联合体从队列中读出,然后根据其中的信息作出相应的处理
联合体
囊括了SDL-1.2版本所支持的所有事件
- type事件的类型
- active事件触发
- key键盘
- motion鼠标移动
- button鼠标按键
- jaxis游戏杆摇杆
- jball游戏杆轨迹球
- jhatJoystick游戏杆帽
- jbutton游戏杆按键
- resize窗口大小变更
- expose窗口焦点变更
- quit退出
- user用户自定义事件
- syswm未定义窗口管理事件
使用鼠标的实例
功能
- 使用鼠标左键点击向左小箭头,显示上一张图片
- 使用鼠标左键点击向右小箭头,显示下一张图片
- 使用鼠标右键退出程序
代码
#include <SDL.h>
#include <stdio.h>
#include <stdbool.h>#define WIDTH 800
#define HEIGHT 480
#define BPP 32SDL_Surface* screen;
SDL_Surface* image;
SDL_Surface* left, *right;SDL_Surface* load_image(const char* filename) {return SDL_DisplayFormat(SDL_LoadBMP(filename));
}void show_bmp(const char* filename) {// Fill the screen with black coloruint32_t black_pixel = SDL_MapRGB(screen->format, 0, 0, 0);SDL_FillRect(screen, &screen->clip_rect, black_pixel);// Load the imageimage = load_image(filename);// Set the position of the imagestatic SDL_Rect rect = {0, 0};SDL_BlitSurface(image, NULL, screen, &rect);// Set the positions of the left and right arrowsstatic SDL_Rect left_pos = {100, 200};static SDL_Rect right_pos = {700, 200};SDL_BlitSurface(left, NULL, screen, &left_pos);SDL_BlitSurface(right, NULL, screen, &right_pos);// Refresh the screen to display the imageSDL_Flip(screen);
}int main(int argc, char const* argv[]) {if (argc != 2) {printf("Usage: %s <bmp_directories>\n", argv[0]);exit(0);}SDL_Init(SDL_INIT_EVERYTHING);screen = SDL_SetVideoMode(WIDTH, HEIGHT, BPP, SDL_SWSURFACE);const char* bmp_files[] = {"1.bmp", "2.bmp", "3.bmp", "4.bmp"};chdir(argv[1]);left = load_image("left.bmp");right = load_image("right.bmp");// Blit the image onto the screenSDL_Rect rect = {0, 0};SDL_BlitSurface(image, NULL, screen, &rect);SDL_Rect left_pos = {100, 200};SDL_Rect right_pos = {700, 200};// Set white color as transparentint32_t key = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);SDL_SetColorKey(left, SDL_SRCCOLORKEY, key);SDL_SetColorKey(right, SDL_SRCCOLORKEY, key);// Display the first imageshow_bmp(bmp_files[0]);// Block and wait for mouse clickint i = 0;SDL_Event event;while (1) {SDL_WaitEvent(&event);// Switch to the previous image when the left arrow is clickedif (event.button.type == SDL_MOUSEBUTTONUP &&event.button.button == SDL_BUTTON_LEFT &&event.button.y >= 200 &&event.button.y <= 287) {if (event.button.x >= 100 && event.button.x <= 160) {i = (i == 0) ? 3 : (i - 1);}if (event.button.x >= 700 && event.button.x <= 760) {i = (i + 1) % 4;}// Release the current image resources before displaying another imageSDL_FreeSurface(image);show_bmp(bmp_files[i]);}// Quit the program when the right mouse button is clickedif (event.button.type == SDL_MOUSEBUTTONUP &&event.button.button == SDL_BUTTON_RIGHT) {break;}}return 0;
}
处理YUV视频源
使用V4L2接口获取摄像头数据(YUV格式),然后使用SDL将视频数据显示到LCD显示器上
步骤
- 1.准备好LCD,设置好相应的参数,备用
- 2.准备好摄像头,设置好采集格式等参数,备用
- 3.初始化SDL,并创建YUV层,备用
- 4.启动摄像头,开始捕获YUV数据,并将数据丢给SDL的YUV处理层显示
具体代码
- 1
- 打开LCD设备
- 获取LCD显示器的设备参数
- 申请一块适当跟LCD尺寸一样大小的显存
- 2.
- 打开摄像头设备文件
- 配置摄像头的采集格式
- 设置即将要申请的摄像头缓存的参数
- 使用该参数reqbuf来申请缓存
- 根据刚刚设置的reqbuf.count的值,来定义相应数量的struct v4l2_buffer
- 3.
- 初始化带音视频和定时器子系统的SDL
- 创建基本surface
- 创建一个YUYV格式的surface
- 4.
- 启动摄像头
- 准备好应用层缓冲区参数
- 开始捕获采集数据
- 将数据丢给SDL处理
#include <SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <linux/videodev2.h>#define LCD_WIDTH 800
#define LCD_HEIGHT 480void 打开LCD并分配显存(unsigned int **fb_mem, struct fb_var_screeninfo *lcdinfo) {int lcd = open("/dev/fb0", O_RDWR);ioctl(lcd, FBIOGET_VSCREENINFO, lcdinfo);*fb_mem = mmap(NULL, lcdinfo->xres * lcdinfo->yres * lcdinfo->bits_per_pixel / 8,PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0);
}void 打开摄像头并配置(int *cam_fd, struct v4l2_format *fmt, int *nbuf, struct v4l2_requestbuffers *reqbuf,struct v4l2_buffer *buffer, unsigned char **start) {*cam_fd = open("/dev/video3", O_RDWR);bzero(fmt, sizeof(*fmt));fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt->fmt.pix.width = LCD_WIDTH;fmt->fmt.pix.height = LCD_HEIGHT;fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; // YUYV 格式fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;ioctl(*cam_fd, VIDIOC_S_FMT, fmt);*nbuf = 3;bzero(reqbuf, sizeof(*reqbuf));reqbuf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;reqbuf->memory = V4L2_MEMORY_MMAP;reqbuf->count = *nbuf;ioctl(*cam_fd, VIDIOC_REQBUFS, reqbuf);for (int i = 0; i < *nbuf; i++) {bzero(&buffer[i], sizeof(buffer[i]));buffer[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buffer[i].memory = V4L2_MEMORY_MMAP;buffer[i].index = i;ioctl(*cam_fd, VIDIOC_QUERYBUF, &buffer[i]);start[i] = mmap(NULL, buffer[i].length, PROT_READ | PROT_WRITE,MAP_SHARED, *cam_fd, buffer[i].m.offset);ioctl(*cam_fd, VIDIOC_QBUF, &buffer[i]);}
}int main() {int lcd, cam_fd, nbuf;unsigned int *fb_mem;struct fb_var_screeninfo lcdinfo;struct v4l2_format fmt;struct v4l2_requestbuffers reqbuf;struct v4l2_buffer buffer[3];unsigned char *start[3];// 打开 LCD 并分配帧缓冲区打开LCD并分配显存(&fb_mem, &lcdinfo);// 打开摄像头并配置打开摄像头并配置(&cam_fd, &fmt, &nbuf, &reqbuf, buffer, start);// 初始化 SDL 包括视频、音频和定时器子系统SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);// 创建基本表面SDL_Surface *screen = NULL;screen = SDL_SetVideoMode(LCD_WIDTH, LCD_HEIGHT, 0, 0);// 创建 YUYV 格式的表面SDL_Overlay *bmp = SDL_CreateYUVOverlay(fmt.fmt.pix.width, fmt.fmt.pix.height,SDL_YUY2_OVERLAY, screen);// 启动摄像头enum v4l2_buf_type vtype = V4L2_BUF_TYPE_VIDEO_CAPTURE;ioctl(cam_fd, VIDIOC_STREAMON, &vtype);// 准备应用层缓冲区参数struct v4l2_buffer v4lbuf;bzero(&v4lbuf, sizeof(v4lbuf));v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;v4lbuf.memory = V4L2_MEMORY_MMAP;while (1) {// 捕获数据for (int i = 0; i < nbuf; i++) {v4lbuf.index = i;ioctl(cam_fd, VIDIOC_DQBUF, &v4lbuf);memcpy(bmp->pixels[0], start[i], buffer[i].length);bmp->pitches[0] = fmt.fmt.pix.width;ioctl(cam_fd, VIDIOC_QBUF, &v4lbuf);}// 锁定 YUV 重叠SDL_LockYUVOverlay(bmp);// 解锁 YUV 重叠SDL_UnlockYUVOverlay(bmp);// 显示 YUV 重叠SDL_DisplayYUVOverlay(bmp, NULL);}// 清理munmap(fb_mem, lcdinfo.xres * lcdinfo.yres * lcdinfo.bits_per_pixel / 8);close(lcd);close(cam_fd);return 0;
}
相关文章:

linux学习:多媒体开发库SDL+视频、音频、事件子系统+处理yuv视频源
目录 编译和移植 视频子系统 视频子系统产生图像的步骤 api 初始化 SDL 的相关子系统 使用指定的宽、高和色深来创建一个视窗 surface 使用 fmt 指定的格式创建一个像素点编辑 将 dst 上的矩形 dstrect 填充为单色 color编辑 将 src 快速叠加到 dst 上编辑 更新…...

基于门控的循环神经网络:LSTM
之前我们介绍了循环神经网络的原理以及实现。但是循环神经网络有一个问题,也就是长期依赖问题。我们之前的01序列预测案例中可以看到,当序列长度到达10以上之后错误就会增多,说明简单的RNN记忆容量较小,当长度更大时就不怎么适用了…...
Web常见的攻击方式及其防御策略
随着互联网技术的快速发展,Web应用已成为我们日常生活和工作中不可或缺的一部分。然而,Web应用也面临着各种安全威胁和攻击。了解这些常见的攻击方式,并采取有效的防御策略,对于保护Web应用的安全至关重要。 一、常见的Web攻击方…...

关于SQL
数据库简介: 数据库分类 关系型数据库模型: 优点:易于维护,可以实现复杂的查询 缺点:海量数据 读取写入性能差,高并发下数据库的io是瓶颈 是把复杂的数据结构归结为简单的二元关系(即二维表…...

大模型时代下两种few shot高效文本分类方法
介绍近年(2022、2024)大语言模型盛行下的两篇文本分类相关的论文,适用场景为few shot。两种方法分别是setfit和fastfit,都提供了python的包使用方便。 论文1:Efficient Few-Shot Learning Without Prompts 题目:无需提示的高效少…...

Linux0.11 中全局描述符表(GDT)
在Linux内核中,全局描述符表(Global Descriptor Table,简称GDT)是一个关键的数据结构,主要用于管理处理器的内存段和相关的权限与属性。它属于x86架构中的保护模式特性,允许操作系统对内存访问进行更精细的…...
搜维尔科技:数据手套用于外固定虚拟现实模拟 、外固定增强现实模拟
数据手套用于外固定虚拟现实模拟、外固定增强现实模拟 搜维尔科技:数据手套用于外固定虚拟现实模拟、外固定增强现实模拟...

《三》菜单栏_工具栏_状态栏动作与实现
上期我们创建了辣么多的动作,那么这次我们要是开始实现这些动作,撸起袖子来吧: //菜单动作(ACtion)QAction *newAct;//新建QAction *openAct;//打开QAction *saveAct;//保存QAction *saveAsAct;//另存为QAction *prin…...

基于NTP服务器获取网络时间的实现
文章目录 1 NTP1.1 简介1.2 包结构1.3 UNIX 时间戳和NTP时间戳 2 代码实现2.1 实现步骤2.2 完整代码 3 结果 在某些场景下,单片机需要通过网络获取准确的时间进行数据同步,例如日志记录、定时任务等。然而,单片机本身无法直接获得准确的标准时…...

Web APIs(获取元素+操作元素+节点操作)
目录 1.API 和 Web API 2.DOM导读 DOM树 3.获取元素 getElementById获取元素 getElementsByTagName获取元素 H5新增方法获取 获取特殊元素 4.事件基础 执行事件 操作元素 修改表单属性 修改样式属性 使用className修改样式属性 获取属性的值 设置属性的值 移除…...
Android adb shell关于CPU核的命令
Android adb shell关于CPU核的命令 先使用命令: adb shell 进入控制台。 然后,直接在$后面输入下面命令,针对CPU的命令。 cat /proc/cpuinfo | grep ^processor | wc -l 查看当前手机的CPU是几核的。 cat sys/devices/system/cpu/online …...

基于springboot+mybatis+vue的项目实战之页面参数传递
如图所示,删除操作可以用按钮实现,也可以用超链接来实现。 1、第一种情况,用按钮实现。 html页面相关: <button type"button" click"deleteId(peot.id)">删除</button> <script>new Vue(…...

CSS-浮动
float (浮动) 作用:盒子的顶点是一样的,具备行内块的特征,能设置宽高 属性:float 属性值:left 浮动在网页左边 right 浮动在网页右边 .a{width: 100px;height: 100px;float:left;background-color: red;}.b…...
MFC:字符串处理
例子 //多字节char* szTest "abc多字节";int nLen strlen(szTest);//9//宽字节wchar_t* szTest2 L"abc多字节";int nlen2 wcslen(szTest2);//6//测试项目配置为Unicodewchar_t* szTesz3 TEXT("abcd");//char* -> CStringCString strTes…...

虚拟仿真云平台在教育应用中的优势和意义
虚拟仿真云实验教学平台作为一种新型的教学方法,近年来在高校教育中得到了十分广泛的应用。它通过模拟真实的实验场景和实验操作,让学生在计算机上进行实验操作和数据处理,为学生提供了更加便捷、可靠、有效的实验学习环境。本文,…...
CPU的的处理流程如何快速记忆
为了快速记忆CPU的处理流程,可以将其简化成五个主要阶段,通常称为“冯诺依曼架构”的五个基本步骤,或者是流水线处理的几个阶段。下面是一种便于记忆的简化版本: CPU处理流程的五个阶段: 取指令(Instructi…...

AI视频教程下载:基于OpenAl、LangChain、 Replicate开发AI应用程序
欢迎来到令人兴奋的 AI 应用世界!在这门课程中,你将学习到创建一个能够与用户互动、理解自然语言、处理音频输入,甚至分析图像的真正智能应用所需的技能和技术。 AI 工具和技术 你将获得使用几个知名 AI API 和技术的实际经验。这些行业领先…...

【C++】继承相关(基类与派生类的继承关系以及细节整理)
目录 00.引言 01.继承的定义 02.基类和派生类对象 03.继承中的作用域 04.派生类的默认成员函数 05.友元、静态成员 00.引言 继承是面向对象编程中的一个重要概念,它的作用是创建一个新的类,该类可以从一个已存在的类(父类/基类&#x…...
【Web后端】监听器Listener
1、简介 用来监听Servlet组件对象状态发生变化的组件可以监听的源包括:ServetRequest、HttpSession、ServletContext当监听到事件源状态发生变化时,会有对应的响应行为 2、使用方法 在web.xml文件中配置 <listener> <listener-class>com.coder.util.…...

C/C++ 初级球球大作战练手
效果演示: https://live.csdn.net/v/385490 游戏初始化 #include <stdbool.h> #include<stdio.h> #include<stdlib.h> #include<time.h> #include<graphics.h> #include <algorithm> #include<math.h> #include<mmsy…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...