音视频开发之SDL2播放视频

音视频开发之SDL2播放视频

如果熟悉OpenGL,那么SDL来渲染视频就很简单了,Window对象时用来显示的窗口,Renderer是具体渲染的渲染器,Texture可以认为就是一张图像,不断的更新Texture的内容,将其显示在窗口上,这就完成了视频的播放。

创建Window

对于渲染视频来说,首先需要创建一个Window对象,这是与Native渲染体系相关联的一个窗口。

1
2
3
4
5
6
7
8
9
if (borderless)
flags |= SDL_WINDOW_BORDERLESS; // 去掉窗口状态栏
else
flags |= SDL_WINDOW_RESIZABLE; // 窗口是否可缩放
// 创建SDL窗口
// 参数(标题,x, y, w, h, 标记)
window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, default_width,
default_height, flags);

创建Renderer

Renderer负责具体的渲染逻辑

1
2
3
// 创建SDL渲染器,SDL_RENDERER_ACCELERATED 使用硬件加速
// 参数(渲染的Window,渲染驱动索引,标记)
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

创建纹理

像素格式:
YUV、RGB
纹理访问格式:
SDL_TEXTUREACCESS_STATIC : 纹理不经常变更
SDL_TEXTUREACCESS_STREAMING : 纹理经常变更
SDL_TEXTUREACCESS_TARGET : 纹理可作为渲染的target

1
2
3
// 创建纹理 
// 参数(对应的渲染器,像素格式,纹理访问格式设置,w, h)
*texture = SDL_CreateTexture(renderer, new_format,SDL_TEXTUREACCESS_STREAMING, new_width,new_height)

什么是纹理

纹理是显卡中一段连续的内存,可以用来存储图片数据,也可以用来存储计算过程中的中间结果等任意数据。
而视频图像数据则是内存中的像素数组。

狭义地讲,纹理是存在于显存的,可以存放任意数据;是视频图像数据存在于内存的,内容是像素数组。纹理存放的不是真正的像素数据,而是存放的图像的描述信息。

所以可以清楚的明白,为什么要使用纹理,将CPU中的像素数据拷贝到GPU中进行存储,然后在GPU上进行处理后交由显示屏进行显示。

更新纹理

更新YUV格式的纹理数据,就是将YUV三个分量的数据和长度一次传入。

1
2
3
ret = SDL_UpdateYUVTexture(
*tex, NULL, frame->data[0], frame->linesize[0], frame->data[1],
frame->linesize[1], frame->data[2], frame->linesize[2]);

更新RGB格式的纹理数据

1
ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]);

显示纹理

Renderer有一个默认的渲染目标,可以通过SDL_SetRenderTarget来更改。要想将纹理的内容显示在屏幕上,需要先将纹理的内容拷贝到Renderer的默认渲染目标上,然后再通过SDL_RenderPresent来刷新屏幕。

1
2
3
4
// 将纹理上的内容拷贝到渲染器的默认渲染目标上
SDL_RenderCopy(renderer, texture, nullptr, &rect);
// 将渲染目标的内容刷新到屏幕上
SDL_RenderPresent(renderer);

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×