本文主要内容是基于的“Beginning SDL 2.0(3) SDL介绍及BMP渲染”(以下简称BS3)基础上,将BMP加载及渲染修改为YUV420或I420的原始视频格式。阅读完本部分内容相信你可以对SDL2.0中的Renderer机制(支持硬件加速)有一定了解,并可以直接加载显示YUV数据。
SDL 2.0新的支持硬件加速的视频渲染技术——Render
SDL 1.x的版本的视频渲染技术是基于纯软件实现的,效率相对较差,通常很难满足实时渲染的需求。SDL 2.0之后针对这个问题,提供了新的2D加速渲染方案——Renderer。并提供了基于以下类型的机制:
- 单个像素点(point)
- 直线(line)
- 填充矩形(rectangle)
- 纹理图像(texture image)
为了应用新的渲染技术,我们需要修改下BS3中提供的SDLVideoRender基类,主要是添加SDL_Renderer成员函数:
SDL_Renderer * m_sdl_renderer;
在实现文件中修改SDLVideoRender::Init函数中添加初始化代码,用于创建SDL_Renderer对象
m_sdl_renderer = SDL_CreateRenderer(m_sdl_window, -1, SDL_RENDERER_ACCELERATED); if (nullptr == m_sdl_renderer) { return false; }
参数具体函数可以参考SDL_CreateRenderer。(SDL官网上的函数介绍)。
同时在void SDLVideoRender::Deinit()函数中添加反初始化代码,用于销毁SDL_Renderer对象
if (nullptr != m_sdl_renderer) { SDL_DestroyRenderer(m_sdl_renderer); m_sdl_renderer = nullptr; }
YUV图像渲染
首先我们使用YuvRender类来说明,如何实现YUV图像加载及渲染的方法。其定义如下:
#pragma once #include "sdlvideorender.h" class YuvRender :public SDLVideoRender { public: YuvRender(void); ~YuvRender(void); bool Init(HWND show_wnd, RECT show_rect); void Deinit(); // width x height resolution // data[] for Y\U\V, stride is linesize of each raw void Update(int width, int height, unsigned char *data[3], int stride[3]){} bool Render(); private: void FillTexture1(); void FillTexture2(); private: int m_yuv_width; int m_yuv_height; int m_yuv_frame_size; unsigned char * m_yuv_data; SDL_Texture * m_show_texture; };
这里假定要加载的YUV图像分辨率为720x576,构造函数代码如下:
YuvRender::YuvRender(void) : SDLVideoRender() , m_yuv_width(720), m_yuv_height(576) , m_yuv_frame_size(0) , m_yuv_data(nullptr) , m_show_texture(nullptr) {}