音视频从入门到精通——超简单的基于FFMPEG+SDL的视频播放器(一)
音视频从入门到精通——超简单的基于FFMPEG+SDL的视频播放器(二)
Simple DirectMedia Layer is a cross-platform development library designed
to provide low level access to audio, keyboard, mouse, joystick, and graphics
hardware via OpenGL and Direct3D. It is used by video playback software,
emulators, and popular games including Valve’s award winning catalog
and many Humble Bundle games.
SDL(Simple DirectMedia Layer)是一个向外提供C接口的跨平台开发库。不只是初学C/C++,即使学过一段时间的程序员也会认为C/C++没有较好可移植性,因为它把系统级API和内存对象的布局直接暴露给了开发人员!C/C++的确无法做到在系统级API层跨平台,这里使用的是把那部分代码提取出来形成个轻量级SDK,即SDL库,SDL处理系统级API差异,然后向上层提供统一API。SDL是轻量级库,只提供基本的画图、播放声音、处理输入事件。
官方明确支持的操作系统包括Windows、Mac OS X、Linux、iOS和Android,在源码树中还可发现其它平台代码,但那些代码可能是未经严格测试的。为支持更多功能,像蓝牙,基于最新版SDL作了修改,也就是左上角提供的“Leagor SDL”。
SDL有广义和狭义之分,狭义SDL就指SDL库,广义还包括SDL_mixer、SDL_image、SDL_ttf和SDL_net。这些库还涉及到众多开源库。但Rose网络模块基于Webrtc,因而不使用SDL_net。
SDL将功能分成下列数个子系统(subsystem):
SDL_INIT_TIMER:定时器
SDL_INIT_AUDIO:音频
SDL_INIT_VIDEO:视频
SDL_INIT_JOYSTICK:摇杆
SDL_INIT_HAPTIC:触摸屏
SDL_INIT_GAMECONTROLLER:游戏控制器
SDL_INIT_EVENTS:事件
SDL_INIT_EVERYTHING:包含上述所有选项
SDL视频显示函数简介
SDL_Init():初始化SDL系统
SDL_CreateWindow():创建窗口SDL_Window
SDL_CreateRenderer():创建渲染器SDL_Renderer
SDL_CreateTexture():创建纹理SDL_Texture
SDL_UpdateTexture():设置纹理的数据
SDL_RenderCopy():将纹理的数据拷贝给渲染器
SDL_RenderPresent():显示
SDL_Delay():工具函数,用于延时
SDL_Quit():退出SDL系统
SDL数据结构简介
SDL_Window 代表了一个“窗口”
SDL_Renderer 代表了一个“渲染器”
SDL_Texture 代表了一个“纹理”
SDL_Rect 一个简单的矩形结构
存储RGB和存储纹理的区别:
比如一个从左到右由红色渐变到蓝色的矩形,
用存储RGB的话就需要把矩形中每个点的具体颜色值存储下来;
而纹理只是一些描述信息,比如记录了矩形的大小、起始颜色、终止颜色等信息,
显卡可以通过这些信息推算出矩形块的详细信息。
所以相对于存储RGB而已,存储纹理占用的内存要少的多。
SDL事件
函数
SDL_WaitEvent():等待一个事件
SDL_PushEvent():发送一个事件
SDL_PumpEvents():将硬件设备产生的事件放入事件队列,用于
读取事件,在调用该函数之前,必须调用SDL_PumpEvents搜集
键盘等事件
SDL_PeepEvents():从事件队列提取一个事件
数据结构
SDL_Event:代表一个事件
SDL线程创建:SDL_CreateThread
SDL线程等待:SDL_WaitThead
SDL互斥锁:SDL_CreateMutex/SDL_DestroyMutex
SDL锁定互斥:SDL_LockMutex/SDL_UnlockMutex
SDL条件变量(信号量):SDL_CreateCond/SDL_DestoryCond
SDL条件变量(信号量)等待/通知:SDL_CondWait/SDL_CondSingal
在Visual Studio 2022中配置 SDL(Simple DirectMedia Layer)
平台visual studio 2022,SDL版本为SDL2-devel-2.24.0-VC,本程序主要是演示sdl如何显示一个窗口。
#define SDL_MAIN_HANDLED
//需要加上这句话,否则会出错
//显示 :无法解析的外部符号 _main,该符号在函数 "int __cdecl invoke_main(void)" (? invoke_main@@YAHXZ) 中被引用
#include
#include "SDL.h"
using namespace std;
#pragma comment(lib,"SDL2.lib")
//由于SDL内部重新定义了main,因此main函数需要写成如下形式
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window;
SDL_Renderer* renderer;
window = SDL_CreateWindow(
"SDL2 Draw Window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
500, // width, in pixels
300, // height, in pixels
SDL_WINDOW_SHOWN // flags - see below
);
if (window == NULL) {
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
renderer = SDL_CreateSoftwareRenderer(SDL_GetWindowSurface(window));
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 15, 23, 44, 255);
SDL_RenderDrawPoint(renderer, 10, 10);
SDL_RenderPresent(renderer);
SDL_UpdateWindowSurface(window);
bool quit = false;
SDL_Event event;
while (!quit) {
SDL_WaitEvent(&event);
switch (event.type) {
case SDL_QUIT://退出事件
SDL_Log("quit");
quit = true;
break;
default:
SDL_Log("event type:%d", event.type);
}
}
//destory renderer
if (renderer) {
SDL_DestroyRenderer(renderer);
}
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
}
输出
—sdl介绍—
SDL2源代码分析5:更新纹理(SDL_UpdateTexture())
SDL2源代码分析6:复制到渲染器(SDL_RenderCopy())
—最简单的基于FFmpeg的视频播放器系列文章列表—
100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)
最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)
最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)
最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器
最简单的基于FFMPEG的Helloworld程序
—其它—