本文是在“Beginning SDL 2.0(4) YUV加载及渲染”(以下简称BS4)基础上做的功能完善,如果你对之间介绍的内容了解不多,麻烦先阅读之前的内容。
本文主要介绍如何完成一个基于MFC和SDL 2.0的YUV播放器,基本思路是使用Windows的WM_TIMER消息,定期刷新画面。(正规的播放器通常使用一个独立的线程用于做固定帧率的刷新,这里为了简单期间使用系统提供的定时器实现。)
工程创建
使用vs10创建mfc基于对话框的工程,2_sdl_yuv_player,配置好SDL包含路径,同时包含BS4中提供的YuvRender类。如果不想处理unicode字符,建议将工程属性的字符集设置为多字节编码。
并在主对话框中编辑出如下几个控件:一个Static用于YUV视频显示,一个播放按钮用于选择yuv路径,并开启播放,三个输入框分别用于输入视频宽、高及帧率。效果如下:
YuvRender类更新
由于BS4中的YuvRender是读取本地文件目录下的yuv图像,然后显示视频的,这里需要修改下,以支持动态的YUV画面渲染。
具体接口如下:
#pragma once #include "sdlvideorender.h" class YuvRender :public SDLVideoRender { public: YuvRender(void); ~YuvRender(void); // Init use parent impl //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: bool CreateTexture(int width, int height); void FillTexture(unsigned char *data[3], int stride[3]); private: // texture size int m_in_width, m_in_height; SDL_Texture * m_show_texture; };
相比之前的版本这里最大的区别是Update函数不再是空实现,添加了CreateTexture函数,主要考虑我们事先是不知道需要创建Texture的分辨率。
这里Init函数功能,完全可以直接使用父类提供的实现。
下面是Deinit函数实现代码
void YuvRender::Deinit() { if (nullptr != m_show_texture) { SDL_DestroyTexture(m_show_texture); m_show_texture = NULL; } SDLVideoRender::Deinit(); }