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

网站开发部署长春网络营销公司

网站开发部署,长春网络营销公司,丹东谁家做网站,梭子手做鱼网站【音视频开发】第四章 SDL音视频渲染 文章目录 【音视频开发】第四章 SDL音视频渲染一、简介1.什么是 SDL 二、Windows 环境搭建三、SDL 子系统四、Window 显示1.SDL 视频显示函数简介2.窗口渲染结构体 五、SDL 事件1.通用事件结构体 SDL_Event2.事件类型 六、SDL 线程1.常用线…

【音视频开发】第四章 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 音频基本流程

  1. 初始化 SDL 音频系统
  2. 设置音频参数(采样率、格式、声道数、回调函数等)
  3. 打开音频设备
  4. 播放时通过回调函数往缓冲区填充 PCM 数据
  5. 启动播放并保持主循环

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;
}
http://www.dtcms.com/wzjs/234552.html

相关文章:

  • 阿里去可以做几个网站8大营销工具指的是哪些
  • 东莞网站排名优化公司网站设计公司上海
  • 用wordpress 扒站优化关键词首页排行榜
  • 郑州app开发网站建设网络销售面试问题有哪些
  • 网站下面的公安备案怎么做win7优化大师免安装版
  • 百度推广联盟林云seo博客
  • 北京网站建设企业网站制作微营销推广平台有哪些
  • linux运维是必死之路亚马逊关键词优化软件
  • 怎么做网站相册网络视频营销平台
  • 移动端模板网站建设网络营销做得好的酒店
  • 学习网站大全个人如何在百度上做广告
  • 千年之恋网页制作代码网站排名优化方案
  • seo专业优化公司专注于seo顾问
  • 龙岗网站设计机构网站建设制作教程
  • 网站建设服务是什么意思营销网站建设门户
  • 徐州网站建设要多少钱qq群推广网站
  • 搜索网站入口贵阳网站建设公司
  • 网站下雪代码怎么注册网站平台
  • 手机笑话网站源码电话销售如何快速吸引客户
  • 哈尔滨做网站价格世界新闻
  • 的建站公司巢湖网站制作
  • 外贸网站 建设seo投放是什么意思
  • 邢台建一个网站多少钱肇庆seo按天计费
  • 做淘客需要网站网站按天扣费优化推广
  • 叫别人做网站后怎么更改密码全媒体广告加盟
  • wordpress移动插件谷歌seo服务
  • 免费网站模版 好用的怎样打开网站
  • 网站php环境搭建seo网络排名优化哪家好
  • 齐诺网站建设东莞网站建设做网站百度关键词优化点击 教程
  • 北京网站建设联系电话新浪博客