Mac平台上面的EPlayer播放器的开发已经接近尾声了,基本功能都有了,很多bug已经修复完毕。但是最后到了性能优化阶段发现,视频进行全屏缩放,已经进行鼠标拖动窗口缩放的时候,会发生卡顿问题。
经过分析,基本可以定位在了SDL的输出上了。
最终发现我对SDL2的视频输出调用还是有问题的,首先对于SDL2的视频输出初始化。
if(SDL_Init(SDL_INIT_VIDEO))
{
returnVideo_Render_Err_DeviceErr;
}
m_pSDLWindow = SDL_CreateWindowFrom(pVideoWindow);
m_pSDLRenderer = SDL_CreateRenderer(m_pSDLWindow, -1, 0);
m_pSDLTexture = SDL_CreateTexture(m_pSDLRenderer,
SDL_PIXELFORMAT_IYUV,
SDL_TEXTUREACCESS_STREAMING,
m_nVideoWndWidth, m_nVideoWndHeight);
其中pVideoWindow是一个 UI层传输下来的NSWindow, 以及两个成员变量宽高都很容易理解,当然这部分也是对的。缩放的性能问题并不是这里的代码造成的,因为这部分代码并不参与缩放相关的事情。
接下来就是在窗口进行缩放的时候所进行的代码调用:
SDL_DestroyWindow(m_pSDLWindow);
SDL_DestroyTexture(m_pSDLTexture);
SDL_DestroyRenderer(m_pSDLRenderer);
m_pSDLWindow = SDL_CreateWindowFrom(pWindow);
m_pSDLRenderer = SDL_CreateRenderer(m_pSDLWindow, -1, 0);
m_pSDLTexture = SDL_CreateTexture(m_pSDLRenderer,
SDL_PIXELFORMAT_IYUV,
SDL_TEXTUREACCESS_STREAMING,
m_nVideoWndWidth, m_nVideoWndHeight);
这里首先把SDL_Window 释放掉,然后释放了SDL_Texture, SDL_Renderer,三个输出使用的基本资源,然后紧接着再利用新传输下来的NSWindown 也就是m_pSDLWindow,以及新的宽高再次创建三个视频输出资源,作为新宽高进行视频输出。
视频缩放的卡顿其实就发生在这个地方,其实在这里,重新释放三个资源再次创建,是完全没有必要的,也是对性能的极大浪费。真正应该做的,仅仅是释放掉鱼宽高相关的SDL_Texture,并用新的宽高重新创建即可。所以代码可以简化为:
SDL_DestroyTexture(m_pSDLTexture);
m_pSDLTexture = SDL_CreateTexture(m_pSDLRenderer,
SDL_PIXELFORMAT_IYUV,
SDL_TEXTUREACCESS_STREAMING,
m_nVideoWndWidth, m_nVideoWndHeight);
当然这种情况,是针对原来窗口和新窗口的句柄是一样的,既m_pVideoWindow,也就是用户层传输下来的NSWindow,是同一个窗口,就没问题的。也极大的提高的缩放的速度,性能。
对于真正改变了窗口句柄,窗口的句柄指针发生了变化,那么对于与窗口相关的所有资源,都要进行释放。
当然对于EPlayer在Win32平台上使用的SDL输出,应该是可以借鉴,可以进行优化的了。
嗯,看来win32平台的播放器,可以进一步优化了。