現象:
使用MFC及C#控件進行視頻流或錄像文件的播放app,
問題:
1.對控件進行放大縮小後,界面不刷新。
2.當對運行APP的系統進行鎖屏再解鎖後或遠程連接或切換用戶後,相應的圖像控件界面不刷新。-嚴重
方法:
問題1:控件縮放刷新問題,SDL_SetWindowPosition函數不起作用,是窗口渲染器和紋理後不再匹配,此時需要重新創建再進行繪製更新。SDL_CreateRenderer(),SDL_CreateTexture()再次創建。
問題2:
- 簡單的方法是監聽解鎖後的消息,調用 控件縮放接口進行刷新,但由於監聽此消息不容易,所以沒有進行相應的測試。
- 複雜方法。修改的地方較多,最重要的是對相應的渲染器及紋理創建時的參數進行理解。
修改參數後,總是報內存訪問衝突,有些什麼D3D11.PDB ,D3D9.pdb 什麼文件的無法打開衝突的總是,頭都的了,查看了鎖沒有問題,偶爾查看到 https://www.jianshu.com/p/18c2f9f8716a裏面有說SDL圖像在指定的控件上進行播放,此時相應的SDL是Window的消息映射到SDL。此時兩個地方均接收到消息,此時懷疑是兩個消息的原因。通過消息進行相應的屏蔽一個,不在報衝突。但是在對圖像顯示的時候偶爾會有總是,惱火,(半路進入SDL的我頭都大了)。
此時情況爲在刷新圖像線程中每次重新創建渲染器和紋理進行圖像更新,因爲考慮是界面刷新的問題,所以每次重新創建。
但是 m_sdlRenderer = SDL_CreateRenderer(m_psdlscreen, -1, 0);很大概率會在此位置出現衝突異常。
用日誌文件printf("SDL: could not create window - exiting:%s\n", SDL_GetError());打出錯誤消息,結果有時會出現不能找到渲染器的問題。特別是在系統解屏幕鎖後第一次爲創建m_sdlRenderer失敗,後面一次有時會成功。
思考排查,查看SDL_CreateRenderer(),第三個參數的意思,都沒有說的特別清楚,挨個試,還是會出現,但是SDL_RENDERER_ACCELERATED和SDL_RENDERER_SOFTWARE效果明顯,也試了兩個一起,也不行,但是SDL_RENDERER_SOFTWARE效果好些。結果還不行,
繼續向下排查SDL_CreateTexture(),各參數的意思,第三個參數有三種:
typedef enum
{
SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */
SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */
SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */
} SDL_TextureAccess;
常用的均爲第二種,SDL_TEXTUREACCESS_STREAMING,也沒有查到具體怎樣選擇,試試第三個SDL_TEXTUREACCESS_TARGET做爲一個整體,
結果OK啦。
最終版本修改位置:
①改變窗口大小時重新創建Renderer和exture,且參數注意第三個參數的選擇。
②更新線程只做SDL_UpdateTexture(m_sdlTexture, NULL, cashFrame, nWidthStep);//設置紋理數據,將圖像顯示到窗口
SDL_RenderClear(m_sdlRenderer);//清空渲染器
SDL_RenderCopy(m_sdlRenderer, m_sdlTexture, NULL, NULL);//紋理複製給渲染器
③創建窗口時,注意屏蔽部分消息。SDL_EventState(SDL_WINDOWEVENT, SDL_IGNORE);