1.接口设计
2.窗口渲染器和材质初始化
3.渲染Draw并测试渲染YUV
4.渲染画面随窗口大小自动缩放并抗锯齿
5.清理接口和接收窗口退出事件
1.接口设计:原则
主要的实现步骤:
main的流程:
1 | 打开文件 | yuv_file.open("400_300_25.yuv", ios::binary); | |
2 | 定义和创建 实例指针 | static XVideoView* view = nullptr; | |
3. | 初始化视图 | view->Init(sdl_width, sdl_height, XVideoView::YUV420P); | |
4. | 定时器读图画图 | startTimer(10) |
接口设计注意事项:
1.为什么 virtual bool Draw(const char* data, int linesize = 0) = 0; | |||
2.线程安全指的是?init初始化时,Draw更改 | 互斥锁 | ||
3.私有成员命名加 后缀 width_ | |||
4.头文件中不引入命名空间,因为不知道在什么环境中运行。 |
基类:class XVideoView 不写任何定义,只是虚函数。
成员函数 | ||||
创建 | static XVideoView* Create(RenderType type=SDL); | 关键词 virtual | ||
初始化 | virtual bool Init(int w, int h, Format fmt = RGBA, void* win_id = nullptr) = 0; | 1.返回值需要添加0 | ||
画图 | virtual bool Draw(const char* data, int linesize = 0) = 0; | 2.用nullptr 而不是null |
成员变量 | ||||
材质的宽高 | int width_ = 0;int height_ = 0; | |||
像素 | Format fmt_ = RGBA; | |||
线程安全 | std::mutex mtx_; | 不能在头文件中写命名空间 | ||
派生类:class XSDL :public XVideoView
struct SDL_Window; //窗口
struct SDL_Renderer; //渲染器
struct SDL_Texture; //材质
成员变量 | ||||
SDL_Window* win_ = nullptr; | ||||
SDL_Renderer* render_ = nullptr; | ||||
SDL_Texture* texture_ = nullptr; | ||||
成员函数 | |||||
初始化 | bool Init(int w, int h, Format fmt = RGBA, void* win_id = nullptr) override; | 关键词 函数最后override; | |||
画图 | bool Draw(const char* data, int linesize = 0) override; | ||||
Init 实现步骤:
锁定线程 | unique_lock<mutex> sdl_lock(mtx_); | |||
初始化SDL 视频库 | SDL_Init | |||
解决锯齿问题,线性插值算法 | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); | |||
创建窗口 | SDL_CreateWindow | |||
创建渲染器 | SDL_CreateRenderer | |||
创建材质 | SDL_CreateTexture | |||
draw画的步骤:
锁定线程 | unique_lock<mutex> sdl_lock(mtx_); | |||
设定格式 | case XVideoView::RGBA: | |||
复制内存到显显存 | SDL_UpdateTexture | |||
清空屏幕 | SDL_RenderClear | |||
材质复制到渲染器 | SDL_RenderCopy | |||
显示 | SDL_RenderPresent |
4.渲染画面随窗口大小自动缩放并抗锯齿
基类接口定义添加:
窗口显示缩放 | int scale_w_ = 0; int scale_h_ = 0; | |||
void Scale(int w, int h) | ||||
重构大小 | 重载QWidget里的resizeEvent | SdlQtRGB:: public QWidget | 具体事件不清楚,但是一定要加override.回调函数 | 1.ui.label要resize 2.移到左上角 3.自适应 | ui.label->resize(size()); ui.label->move(0, 0); view->Scale(width(), height()); | |
实现类draw
材质复制到渲染器 | if (scale_w_ <= 0)scale_w_ = width_; if (scale_h_ <= 0)scale_h_ = height_; | |||
渲染的宽高,可缩放 | rect.w = scale_w_;//渲染的宽高,可缩放 rect.h = scale_h_; | |||
业务逻辑
void SdlQtRGB::resizeEvent(QResizeEvent* ev)
{
view->Scale(width(), height());
}
5.清理接口和接收窗口退出事件