【音视频开发】第四章 SDL音视频渲染
【音视频开发】第四章 SDL音视频渲染
文章目录
- 【音视频开发】第四章 SDL音视频渲染
- 一、简介
- 1.什么是 SDL
- 二、Windows 环境搭建
- 三、SDL 子系统
- 四、Window 显示
- 1.SDL 视频显示函数简介
- 2.窗口渲染结构体
- 五、SDL 事件
- 1.通用事件结构体 SDL_Event
- 2.事件类型
- 六、SDL 线程
- 1.常用线程相关 API
- 七、YUV 显示
- 1.代码示例
- 八、PCM 音频播放
- 1.SDL 播放 PCM 音频基本流程
- 2.代码示例
一、简介
1.什么是 SDL
官网:https://www.libsdl.org
SDL(Simple DirectMedia Layer)是一个使用 C 语言开发的开源跨平台开发库,它主要用来直接访问操作系统底层的硬件资源,比如:
- 图形(Graphics)
- 音频(Audio)
- 输入设备(键盘、鼠标、手柄)
- 窗口管理
- 多线程(Threading)
- 文件 IO(File I/O)
典型用途
- 2D 游戏(平台跳跃、射击类)
- 模拟器(NES、SNES、GameBoy 等复古游戏模拟器)
- 图形工具或小型 UI 框架
- 作为大型游戏引擎(如 Unity)或自研引擎的底层组件之一
二、Windows 环境搭建
下载地址:https://github.com/libsdl-org/SDL/releases
创建一个 C 项目
将刚刚下载完成的 SDL 压缩包解压,复制到项目根目录中,并将路径配置到.pro文件
将 SDL2-2.32.4\lib\x64 目录下的 SDL2.dll 文件复制到项目根目录中,编写简单的窗口创建程序
#include <stdio.h>
#include <SDL.h>#undef mainint main()
{printf("Hello SDL World!\n");if (SDL_Init(SDL_INIT_VIDEO) != 0) {printf("SDL_Init Error: %s\n", SDL_GetError());return 1;}SDL_Window *window = SDL_CreateWindow("Basic SDL Window",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,640,480,SDL_WINDOW_SHOWN);if (!window) {printf("Can't create window, err: %s\n", SDL_GetError());SDL_Quit();return 1;}// 添加事件循环,保持窗口直到关闭SDL_Event event;int running = 1;while (running) {while (SDL_PollEvent(&event)) {if (event.type == SDL_QUIT) {running = 0;}}SDL_Delay(16); // 简单的帧延迟}SDL_DestroyWindow(window);SDL_Quit();return 0;
}
三、SDL 子系统
在 SDL(Simple DirectMedia Layer)中,子系统(Subsystem)就是 SDL 提供的某一类功能模块的集合,你可以把它理解成“功能插件”或“功能模块”。这些子系统是独立的,你可以按需开启,避免加载不必要的内容,提升效率。
- SDL_INIT_TIMER:定时器功能(SDL_GetTicks)
- SDL_INIT_AUDIO:音频子系统
- SDL_INIT_VIDEO:视频子系统(窗口、OpenGL、Vulkan)
- SDL_INIT_JOYSTICK:游戏摇杆(Joystick)
- SQL_INIT_HAPTIC:触觉反馈(震动设备)
- SDL_INIT_GAMECONTROLLER:手柄控制器(比 joystick 更高级)
- SDL_INIT_EVENTS:SDL 事件系统(键盘/鼠标等)
- SDL_INIT_SENSOR:传感器(如陀螺仪)
- SDL_INIT_EVERYTHING:初始化所有子系统
四、Window 显示
1.SDL 视频显示函数简介
- SDL_Init():初始化 SDL 系统
- SDL_CreateWindow():创建窗口 SDL_Window
- SDL_CreateRender():创建渲染器 SDL_Renderer
- SDL_CreateTexture():创建纹理 SDL_Texture
- SDL_UpdateTexture():设置纹理的数据
- SDL_RenderCopy():将纹理的数据拷贝给渲染器
- SDL_RenderPresent():显示
- SDL_Delay():工具函数,用于延时
- SDL_Quit():退出 SDL 系统
2.窗口渲染结构体
- SDL_Window:表示一个窗口(由 SDL_CreateWindow() 创建)
- SDL_Render:渲染器,用于在窗口上绘制图形
- SDL_Texture:纹理,加载图像后用于渲染
- SDL_Surface:表示一块像素数据,可用于直接操作图像
- SDL_Rect:表示一个矩形区域(常用于位置和尺寸)
五、SDL 事件
SDL 的事件系统是通过轮询或等待来处理用户输入、窗口变化、系统通知等各种操作的核心机制。
SDL 的所有事件都通过一个统一的 SDL_Event 结构体表示,然后通过 event.type 判断它属于哪种事件类型。
1.通用事件结构体 SDL_Event
SDL_Event event;while(SDL_PollEvent(&event)){switch(event.type){case SDL_QUIT://处理退出break;//其他事件...}
}
2.事件类型
- 退出事件:SDL_QUIT
- 窗口事件:SDL_WINDOWEVENT + event.window.event
- 键盘事件:SDL_KEYDOWN, SDL_KEYUP
- 鼠标事件:SDL_MOUSEMOTION, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SQL_MOUSEWHEEL
- 控制器:SQL_CONTROLLER… 系列
- 自定义事件:SQL_USEREVENT
六、SDL 线程
SDL 提供了跨平台的线程创建与管理接口,让开发者在不同系统下都能一致地创建和管理线程。
1.常用线程相关 API
创建线程
SQL_Thread* SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
- fn:线程函数,函数签名为 int thread_func(void *data)
- name:线程名称
- data:传递给线程函数的参数
- 返回值:成功返回 SDL_Thread*,失败返回 NULL
等待线程结束
void SDL_WaitThread(SDL_Thread* thread, int *status);
等待指定线程结束,并获取其返回值
获取当前线程 ID
SDL_threadID SDL_ThreadID(void);
获取线程名
const char* SDL_GetThreadName(SDL_Thread* thread);
互斥锁(Mutex)
SDL_mutex* SDL_CreateMutex();
void SDL_DestroyMutex(SDL_mutex* mutex);
int SDL_LockMutex(SDL_mutex* mutex);
int SDL_UnlockMutex(SDL_mutex* mutex);
七、YUV 显示
使用 SDL 显示 YUV 图像是视频播放中非常常见的一种技术路径。
1.代码示例
- 读取并显示 .yuv 原始视频文件(YUV420P格式)
- SDL 窗口播放视频帧
- 每秒大约播放 25 帧
#include <SDL2/SDL.h>
#include <stdio.h>// 视频宽度和高度
#define WIDTH 640
#define HEIGHT 480// YUV 文件路径
#define FILE_PATH "test.yuv"// 每帧字节数(YUV420P:Y 占 w*h,U/V 各占 w*h/4)
#define FRAME_SIZE(WIDTH * HEIGHT * 3 / 2)int main(int argc, char* argv[]){// 初始化 SDL 视频系统if(SDL_Init(SDL_INIT_VIDEO) < 0){print("SDL 初始化失败:%s\n", SDL_GetError());return -1;}// 创建 SDL 窗口SDL_Window* window = SDL_CreateWindow("YUV 显示示例", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);if(!window){printf("窗口创建失败:%s\n", SDL_GetError());SDL_Quit();return -1; }// 创建渲染器SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);// 创建 YUV4200P 纹理SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);// 打开 .yuv 文件FILE* file = fopen(FILE_PATH, "rb");if(!file){printf("无法打开文件:%s\n", FILE_PATH);return -1;}// 分配一帧缓冲区Uint8* buffer = (Uint8*)malloc(FRAME_SIZE);if(!buffer){printf("内存分配失败\n");fclose(file);return -1;}SDL_Event event;int quit = 0;// 简单播放循环:直到用户关闭窗口或播放结束while(!quit){// 读取一帧 YUV 数据size_t readBytes = fread(buffer, 1, FRAME_SIZE, file);if(readBytes < FRAME_SIZE){// 播放结束,自动回到文件开头循环播放fseek(file, 0, SEEK_SET);continue;}// 获取 Y/U/V 分量指针Uint8* yPlane = buffer;Uint8* uPlane = buffer + WIDTH * HEIGHT;Uint8* vPlane = buffer + WIDTH * HEIGHT + (WIDTH * HEIGHT) / 4;// 更新纹理数据SDL_UpdateYUVTexture, NULL, yPlane, WIDTH, uPlane, WIDTH / 2, vPlane, WIDTH / 2);// 清空渲染器并复制纹理SDL_RenderClear(renderer);SDL_RenderCopy(renderer, texture, NULL, NULL);SDL_RenderPresent(renderer);// 处理退出事件while(SDL_PollEvent(&event)){if(event.type == SDL_QUIT){quit = 1;}}// 控制帧率(约 25fps)SDL_Delay(40);}// 释放资源free(buffer);fclose(file);SDL_DestroyTexture(texture);SDL_DestroyRenderer(renderer);SDL_DestroyWindow(window);SDL_Quit();return 0;
}
八、PCM 音频播放
使用 SDL 播放 PCM(Pulse Code Modulation,脉冲编码调制) 音频是实现音频播放功能的一种常见方式,尤其适用于原始音频数据(未压缩的 .pcm 文件,例如 16-bit、44100Hz、立体声)
1.SDL 播放 PCM 音频基本流程
- 初始化 SDL 音频系统
- 设置音频参数(采样率、格式、声道数、回调函数等)
- 打开音频设备
- 播放时通过回调函数往缓冲区填充 PCM 数据
- 启动播放并保持主循环
2.代码示例
#include <SDL2/SDL.h>
#include <stdio.h>// 定义音频缓冲区结构
typedef struct {Uint8* pos; //当前播放位置Uint32* len; //剩余字节数
}AudioData;// 音频回调函数:SDL 会周期性调用它来获取音频数据
void audio_callback(void* userdata, Uint8* stream, int len) {AudioData* audio = (AudioData*)userdata;if(audio->len == 0){return; //播放完了}// 播放剩余字节数不足一帧时,只复制剩余部分len = (len > audio->len ? audio->len : len);SDL_memcpy(stream, audio->pos, len);audio->pos += len;audio->len -= len;
}int main(int argc, char* argv[]){// 假设 PCM 文件是 16-bit signed, stereo, 44100Hzconst char* filePath = "test.pcm";// 打开 PCM 文件FILE* file = fopen(filePath, "rb");if(!file){printf("无法打开 PCM 文件:%s\n", filePath);return -1;}// 获取文件大小fseek(file, 0, SEEK_END);Uint32 fileSize = ftell(file);fseek(file, 0, SEEK_SET);// 读取全部 PCM 数据到内存中Uint8* buffer = (Uint8*)malloc(fileSize);fread(buffer), 1, fileSize, file);fclose(file);// 初始化 SDLif(SDL_Init(SDL_INIT_AUDIO) < 0){printf("SDL_Init 错误:%s\n", SDL_GetError());return -1;}// 设置音频格式(必须与 PCM 文件一致)SDL_AudioSpec spec;spec.freq = 44100; //采样率spec.format = AUDIO_S16LSB; //16-bit signed little endianspec.channels = 2; //立体声spec.samples = 4096; //音频缓冲区大小(影响延迟)spec.callback = audio_callback; //设置音频回调AudioData audio = { buffer, fileSize };spec.userdata = &audio;// 打开音频设备if(SDL_OpenAudio(&spec, NULL) < 0){printf("SDL_OpenAudio 错误:%s\n", SDL_GetError());free(buffer);SDL_Quit();return -1; }// 启动播放SDL_PauseAudio(0);// 播放期间阻塞主线程while(audio.len > 0){SDL_Delay(100); //每 100ms 轮询一次 }// 播放完成后清理资源SDL_CloseAudio();free(buffer);SDL_Quit();return 0;
}
相关文章:
【音视频开发】第四章 SDL音视频渲染
【音视频开发】第四章 SDL音视频渲染 文章目录 【音视频开发】第四章 SDL音视频渲染一、简介1.什么是 SDL 二、Windows 环境搭建三、SDL 子系统四、Window 显示1.SDL 视频显示函数简介2.窗口渲染结构体 五、SDL 事件1.通用事件结构体 SDL_Event2.事件类型 六、SDL 线程1.常用线…...
音频基础概念
声音 物体在一定的振动频率下产生了声音。声音可以被分解为不同频率不同强度正弦波的叠加。 声音三要素 声调 音调: 由发声体振动的频率决定,频率越高(振动越快)则音调越高,听起来就越“刺耳”,反之音调越低、听起…...
rust编程学习(二):复合数据类型
复合数据类型是由其他类型组合而成的类型。Rust的复合数据类型有元组、数组、结构体、枚举等, 通过一些简单的例子帮助大家快速了解Rust复合类型。 1 元组类型 元组类型是由一个或多个类型的元素组合成的复合类型,使用小括号“()”把所有元素放在一起。…...
学习笔记十四——一文看懂 Rust 迭代器
🌀 一文看懂 Rust 迭代器 📚 目录导航 什么是迭代器?为什么 Rust 到处都在用它?Rust 迭代器的底层逻辑是什么?适配器 vs 消费者:谁是主角?常见适配器:加工数据的全能工厂常见消费者…...
H.265硬件视频编码器xk265代码阅读 - 帧内预测
源代码地址: https://github.com/openasic-org/xk265 帧内预测具体逻辑包含在代码xk265\rtl\rec\rec_intra\intra_pred.v 文件中。 module intra_pred() 看起来是每次计算某个4x4块的预测像素值。 以下代码用来算每个pred_angle的具体数值,每个mode_i对应…...
贪心算法学习C++
1,跳跃游戏II 题目连接:45. 跳跃游戏 II - 力扣(LeetCode) 【题目描述】 在给定的一个nums数组中,nums[i]表示从当前i位置最多可以向后跳跃nums[i]个位置。问跳跃到最后 数组最后一个元素的最少跳跃次数?…...
Go 语言实现的简单 CMS Web
Go 语言实现的简单 CMS Web 以下是一个使用 Go 语言实现的简单 CMS Web 演示代码示例, 包含基本的内容管理功能: 项目结构 ### 项目结构 cms-demo/ ├── main.go ├── handlers/ ├── models/ ├── views/ │ ├── home.html │ ├─…...
Zookeeper选举机制
一、选举机制的核心原理 ZooKeeper的选举机制基于ZAB协议(ZooKeeper Atomic Broadcast),这是一种为分布式系统设计的原子广播协议。其核心目标是快速选举出Leader节点,并确保数据一致性。以下为关键原理: 1. 选举触发…...
安卓自定义build的apk文件名
android studio打包应用默认生成的apk名称是:app-release.apk 。 如果我们想修改生成的apk文件名,比如想放入版本号,比如想放入渠道号,又比如和打包时间有关联,那我们就需要能自动化生成可自定义的apk文件名ÿ…...
【Web APIs】JavaScript 操作多个元素 ④ ( 表格全选复选框案例 )
文章目录 一、核心要点解析 - 表格全选复选框案例1、案例需求2、复选框设置3、获取 全选复选框 和 普通复选框4、设置 全选复选框 逻辑5、设置 普通复选框 逻辑 二、完整代码示例1、代码示例2、执行结果 一、核心要点解析 - 表格全选复选框案例 1、案例需求 在表格中 , 设置 多…...
Lua 第6部分 函数
在 Lua 语言中,函数( Function )是对语句和表达式进行抽象的主要方式。 函数既可以用 于完成某种特定任务(有时在其他语言中也称为过程 ( procedure )或子例程 ( s ubroutine) ), 也可以只是进行…...
OpenCv高阶(五)——SIFT特征提取
目录 SIFT特征提取 一、原理核心步骤 1. 尺度空间极值检测 2. 关键点定位 3. 方向分配 4. 描述子生成 二、SIFT算法具有的特点 三、SIFT特征提取器的简单使用 1、特征检测器的创建 2、 检测图像中的关键点 3、绘制关键点 4、计算关键点描述符 四、SIFT 算法的优缺点…...
基于Spring MVC的客户端真实IP获取方案解析
文章目录 基于Spring MVC的客户端真实IP获取方案解析概述核心方法解析代码实现工作流程 IP获取优先级策略IP有效性验证异常处理与日志使用场景注意事项扩展建议 基于Spring MVC的客户端真实IP获取方案解析 概述 在Web应用开发中,准确获取客户端真实IP地址是常见的…...
JavaScript爬虫基础篇:HTTP 请求与响应
在互联网的世界里,数据无处不在。无论是新闻资讯、商品信息,还是社交媒体动态,这些数据都以各种形式存储在服务器上。而爬虫,就是我们获取这些数据的得力助手。今天,我们就来聊聊爬虫的基础——HTTP 请求与响应&#x…...
【Java基础】Java集合遍历方式
前言 在Java编程中,集合(Collection)是存储和操作对象的核心工具。遍历集合是开发者最频繁的操作之一,但不同场景下选择合适的遍历方式至关重要。 一、基础遍历方式 1. 基本for循环 适用场景:仅适用于List等有序集…...
KWDB创作者计划—深度解析:AIoT时代的分布式多模型数据库新标杆
在AIoT(人工智能物联网)快速发展的今天,数据的多样性、实时性和复杂性对数据库提出了前所未有的挑战。传统的数据库架构往往难以同时满足时间序列数据的高效处理、关系型数据的复杂查询以及多模型数据的无缝集成需求。而KWDB 2.2.0版本的发布…...
智慧城市大数据整体建设方案,数据中台方案(word)
第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章…...
Nginx:轻量级高性能的Web服务器与反向代理服务器
目录 一.引言 二.Nginx的核心特点 2.1高性能与高并发 2.2低资源消耗 2.3功能丰富 2.4高度扩展性 三.Nginx的应用场景 3.1静态资源服务器 3.2反向代理服务器 3.3API网关 3.4Nginx的配置与使用 四.总结 一.引言 在互联网高速发展的今天,Web服务器的性能与…...
【Pandas】pandas DataFrame pop
Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...
Spring Boot集成MinIO的详细步骤
1. 安装MinIO 使用Docker部署MinIO 拉取MinIO镜像: docker pull minio/minio 这将从Docker Hub中获取最新的MinIO镜像。 创建目录: mkdir -p /home/minio/config mkdir -p /home/minio/data 这些目录将用于持久化MinIO的数据和配置文件 创建MinIO…...
【文献笔记】SatLM: Satisfiability-Aided Language Models Using Declarative Prompting
SatLM: Satisfiability-Aided Language Models Using Declarative Prompting 原文代码 标题翻译:SATLM:使用声明式提示的语言模型SAT辅助 1. 简介 1.1. 研究问题 文章提出了SATLM方式,使用LLM生成声明性任务规范,而不是命令式…...
LRU算法
package LRU缓存;import java.util.Arrays; import java.util.HashMap;//建立一个双向队列 class MyQueueNode{int key;int value;MyQueueNode pre;MyQueueNode next;public MyQueueNode(int key,int value){this.key key;this.valuevalue;} } class MyQueue{MyQueueNode head…...
二进制和docker两种方式部署Apache pulsar(standalone)
#作者:闫乾苓 文章目录 1、二进制安装部署Pulsar(standalone)1.1 安装配置JDK1.2 下载解压pulsar安装包1.3 启动独立模式的Pulsar 集群1.4 创建主题测试1.5 向主题写入消息测试1.6 从主题中读取消息测试 2.docker安装部署Pulsar(standalone)2.1 使用docker 启动Pul…...
【物联网】基于LORA组网的远程环境监测系统设计
基于LORA组网的远程环境监测系统设计 演示视频: 简介: 1.本系统有一个主机,两个从机。 2.一主多从的LORA组网通信,主机和两个从机都配备了STM32F103单片机与 LoRa 模块,主机作为中心设备及WIFI网关,负责接收和发送数据到远程物联网平台和手机APP,两个从机则负责采集数…...
k8s+有状态nacos账户密码安全认证开启+springcloud 配置
nacos 账号密码登录,默认未开启验证权限,不登录也能访问nacos控制台配置文件,生产环境非常不安全。所以需要手动开启安全认证。本地启动nacos的 application.properties配置文件更改如下: ### The auth system to use, currently only nacos …...
《分布式软总线赋能老旧设备高效通信》
在数字化转型的浪潮中,分布式软总线技术成为实现设备互联互通的关键力量。然而,当面对大量老旧设备时,其性能受限的现状对分布式软总线提出了严峻挑战。如何在这些性能瓶颈下,让老旧设备实现高效连接与通信,是亟待解决…...
07-云原生安全深度剖析:从 Kubernetes 集群防护到微服务安全加固
云原生安全深度剖析:从 Kubernetes 集群防护到微服务安全加固 一、云原生时代的安全挑战 1.1 云原生架构的复杂性引入新风险 在云原生架构下,Kubernetes 集群管理着大量动态变化的容器化应用,微服务通过 API 频繁交互,传统安全…...
Object.create(null)`和`{}`创建的对象有什么区别?
在 JavaScript 中,使用 Object.create(null) 和 {} 创建的对象有以下核心区别: 1. 原型链的差异 创建方式原型链([[Prototype]])继承关系const obj {}继承自 Object.prototype拥有 Object 的原型方法const obj Object.create(n…...
Sherpa简介
Sherpa 是一个由 K2-FSA 团队 开发的 开源语音处理框架,旨在解决传统语音识别工具(如 Kaldi)在模型部署和跨平台适配中的复杂性问题。它通过整合现代深度学习技术和高效推理引擎,提供了从语音识别、合成到说话人识别的一站式解决方…...
【MySQL】索引事务
索引 1.索引概念 数据库使用select查询需要将表中所有的数据都遍历一遍筛选出满足where条件的,如果表中数据非常多,遍历一遍就需要O(n)复杂度是非常高的,为此就引入了索引的概念。 索引是查询的优化手段,避免对表进行遍历&…...
STL详解 - list
目录 一、List容器概述 1.1 什么是list? 1.2 核心特点 二、List的定义与初始化 三、List 的基本操作 3.1 插入操作 🌵头插和尾插 🌵指定位置插入 3.2 删除操作 🍋头删和尾删 🍋指定位置删除 四、List 的迭代…...
LinkedList<Integer> 常用方法通俗讲解
LinkedList<Integer> linkedList new LinkedList<>(); 创建了一个整数类型的链表。链表就像一列火车,每节车厢(节点)都连接着下一节车厢。下面我用通俗易懂的方式讲解它的主要方法: 1. 添加元素 add(5) - 在链表末尾添加数字5,…...
[250416] GitHub Action 新升级,支持 Windows on Arm
目录 GitHub Actions 更新:Windows arm64 托管运行器现已推出公共预览版 GitHub Actions 更新:Windows arm64 托管运行器现已推出公共预览版 现在,GitHub 为公共代码仓库免费提供了基于 Windows arm64 架构的托管运行器(Hosted R…...
Spring Boot 整合 Redis 实现点赞功能:从基础到实践
在当今互联网应用开发中,点赞功能几乎成为了各类内容平台的标配。它不仅能增加用户与内容之间的互动,还能直观地反映内容的受欢迎程度。本文将详细介绍如何使用 Spring Boot 整合 Redis 来实现一个简单的文章点赞功能,让你轻松掌握这一实用技…...
深入解析布尔注入:原理、实战与防御
目录 一、布尔注入的原理与核心逻辑 二、布尔注入的实战步骤 三、关键函数与绕过技巧 四、实战案例:获取数据库名称 五、防御策略与最佳实践 六、总结 一、布尔注入的原理与核心逻辑 布尔注入(Boolean-Based Blind SQL Injection)是一种…...
1.2 使用RawInputSharp来取得键盘硬件信息以及虚拟码
RawInputSharp 是一个 C# 库,用于处理 Windows 的原始输入(Raw Input) API,它允许开发者直接访问键盘、鼠标等输入设备的底层数据。 本例介绍如何读取键盘的虚拟码以及键盘硬件信息。效果如下图: 示例中:开始是1键的按下与抬起&am…...
C++23 中的可选扩展浮点类型:std::float{16|32|64|128}_t 和 std::bfloat16_t
文章目录 1. 扩展浮点类型概述2. 如何使用这些类型3. 编译器支持4. 特性测试宏5. 类型转换和重载决议6. 标准库支持7. 应用场景8. 总结 C23 引入了可选的扩展浮点类型,包括 std::float16_t、 std::float32_t、 std::float64_t、 std::float128_t 和 std::bfloa…...
JVM 内存调优
内存调优 内存泄漏(Memory Leak)和内存溢出(Memory Overflow)是两种常见的内存管理问题,它们都可能导致程序执行不正常或系统性能下降,但它们的原因和表现有所不同。 内存泄漏 内存泄漏(Memo…...
数据结构(java)栈与队列
栈:(先进后出) 入栈: 1.普通栈一定要放、最小栈放的原则是: *如果最小栈是空的,那么放 *如果最小栈的栈顶元素没有当前的元素小,则放 2.如果要放的的元素小于等于最小栈栈顶元素可以放吗?放 出栈: 需要…...
医疗大模型落地方案:技术选型、部署策略与调优
医疗大模型的落地应用已成为推动医疗行业数字化转型的重要引擎。本文将从技术选型、部署策略和调优方案三大维度,系统性地解析医疗大模型落地的关键要素,为医疗机构提供可操作的落地指南。随着人工智能技术的快速发展,医疗大模型已在影像诊断…...
JVM:类加载子系统
一、类加载子系统概述 类加载子系统由多个类加载器组成,它们负责从文件系统或者网络中读取二进制形式的字节码(.class)文件,并将其加载进 JVM。字节码文件中关于类的定义、类中属性的定义、类中方法的定义以及类中方法的字节码等…...
独家!美团2025校招大数据题库
推荐阅读文章列表 2025最新大数据开发面试笔记V6.0——试读 我的大数据学习之路 面试聊数仓第一季 题库目录 Java 1.写一个多线程代码 2.写一个单例代码 3.LinkedBlockingQueue原理 4.模板设计模式 5.如何设计一个 生产者-消费者队列 6.堆内存和栈内存 7.ThreadLo…...
Angular 框架详解:从入门到进阶
Hi,我是布兰妮甜 !在当今快速发展的 Web 开发领域,Angular 作为 Google 主导的企业级前端框架,以其完整的解决方案、强大的类型系统和丰富的生态系统,成为构建大型复杂应用的首选。不同于其他渐进式框架,An…...
使用Vue 3与.NET 8.0通过SignalR实现实时通信,并结合JWT身份验证
实时通信是一个非常重要的功能。SignalR是一个强大的库,能够帮助我们轻松实现客户端和服务器之间的实时数据传输。本文将结合你的代码示例,向你展示如何使用Vue 3作为前端框架,ASP.NET Core作为后端框架,通过SignalR实现实时消息通…...
Harmonyos-Navigation路由跳转
Harmonyos-Navigation路由跳转 概述Navigation路由跳转模块内页面路由系统路由表测试页代码创建并配置路由表文件配置创建好的路由表文件跳转页面 自定义路由表 跨模块路由封装库模块路由跳转工具类 概述 Navigation是路由容器组件,一般作为首页的根容器࿰…...
《人工智能应用创新》5天出审稿意见!
期刊简介 《人工智能应用创新(Innovative Applications of AI)》 (ISSN:3078-2147)是由香港修墨信息工程研究院举办,经国际同行评审后收录的学术期刊。本刊共分三个栏目:综述分析、应用示范、前…...
Excel数据自动填充到Word自定义表格
上一份工作在一家国企做软件测试,需求变来变去(3天一小改,5天换版面),xmind要先整理一遍测试用例(版本迭代,该废的废,该加的加),完了细节在禅道里补充&#x…...
Spring Boot一次接口请求涉及的完整执行链路
Spring Boot一次接口请求涉及的完整执行链路 🔁 Spring 项目请求执行链路(简化视图) 客户端请求(浏览器、Postman)↓ Tomcat(Servlet 容器)↓ 【Listener 监听器】↓ 【Filter 过滤器】&#x…...
mapbox基础,加载视频到地图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️raster 栅格图层 api二、🍀加载视频到…...
Android动态化技术优化
Android动态化技术优化 一、WebView优化基础 1.1 WebView性能瓶颈 初始化耗时内存占用高页面加载慢白屏问题 1.2 WebView基本配置 class OptimizedWebView : WebView {init {// 开启硬件加速setLayerType(LAYER_TYPE_HARDWARE, null)// 配置WebSettingssettings.apply {//…...