0.引言
詳解sdl常用技術實戰(1)
示例**的基本功能就是從檔案中讀取yuv資料,然後通過sdl的介面,去40ms重新整理一幀資料。把這個重新整理事件放到執行緒佇列,由主線程去讀取,然後重新整理。本次程式是支援視窗的縮放。捕獲視窗大小變化的事件,然後根據視窗大小的變化,按照一定的比例去縮放就可以了。至於這個縮放後顯示的位置,在以後再講。
介面如下:
1.sdl渲染相關的資料結構
在**定義時,定義了sdl相關的資料結構。示例**如下:
sdl_event event; // 事件 sdl_rect rect; // 矩形 sdl_window *window = null; // 視窗 sdl_renderer *renderer = null; // 渲染 sdl_texture *texture = null; // 紋理 sdl_thread *timer_thread = null; // 請求重新整理執行緒 uint32_t pixformat = yuv_format; // yuv420p,即是sdl_pixelformat_iyuv
2.yuv影象顯示流程通過**演示如何從yuv檔案中讀取資料,然後通過sdl的介面去顯示在視窗。需要經過如下步驟:
(1)sdl_init()
sdl_init(sdl_init_video)
(2)sdl_createwindow()
建立視窗,視窗的大小,預設使用給yuv定義的解析度。示例**如下:
window = sdl_createwindow("******st yuv player", sdl_windowpos_undefined, sdl_windowpos_undefined, video_width, video_height, sdl_window_opengl|sdl_window_resizable);
(3)sdl_createthread()
建立請求重新整理執行緒,例項**如下:
timer_thread = sdl_createthread(refresh_video_timer, null, null);
(4)sdl_createrender()
根據步驟2建立的視窗的基礎上,建立乙個渲染器,示例**如下:
renderer = sdl_createrenderer(window, -1, 0);
(5)sdl_waitevent()
等待事件的發生,主線程在這裡主要是捕獲影象重新整理、視窗大小變化及介面退出事件。示例**如下:
timer_thread = sdl_createthread(refresh_video_timer, null, null);
(6)sdl_createtexture()
根據步驟4建立的渲染器基礎上,建立紋理(需要指定畫素格式和解析度),示例**如下:
texture = sdl_createtexture(renderer, pixformat, sdl_textureaccess_streaming, video_width, video_height);
(7)event.type == refresh_event
如果在主線程裡去判斷是重新整理事件,就去從檔案中讀取資料,然後再更新紋理。注意還需要關注視窗大小的變化。示例**如下:
(8)sdl_updatetexture()
把新的畫素資料放進來,並更新紋理。示例**如下:
sdl_updatetexture(texture, null, video_buf, video_width);
(9)sdl_renderclear()
在準備刷下一幀時,需要清除當前幀。示例**如下:
sdl_renderclear(renderer);
(10)sdl_rendercopy()
將紋理的資料,拷貝給渲染器,去顯示。示例**如下:
sdl_rendercopy(renderer, texture, null, &rect);
(11)sdl_renderpresent()
渲染器,更新。示例**如下:
sdl_renderpresent(renderer);
(12)event.type == sdl_windowevent
視窗變化事件,實時捕獲視窗的大小。示例**如下:
else if(event.type == sdl_windowevent)
(13)event.type == sdl_quit和event.type == quit_event
這裡要捕獲系統退出事件和自定義退出事件,示例**如下:
else if(event.type == sdl_quit) //退出事件 else if(event.type == quit_event)
(14)等待執行緒退出和資源釋放
退出之前一定要釋放資源,等待子執行緒退出,示例**如下:
s_thread_exit = 1; // 保證執行緒能夠退出 // 釋放資源 if(timer_thread) sdl_waitthread(timer_thread, null); // 等待執行緒退出 if(video_buf) free(video_buf); if(video_fd) fclose(video_fd); if(texture) sdl_destroytexture(texture); if(renderer) sdl_destroyrenderer(renderer); if(window) sdl_destroywindow(window); sdl_quit();
3.影象重新整理執行緒本示例**建立了乙個執行緒,由這個執行緒去控制重新整理的時間和退出。重新整理事件控制在40ms重新整理一次。在退出時,由子執行緒打出乙個退出事件給子執行緒,這樣主線程才能正確退出。這背後的邏輯就是ui介面的重新整理一般都是主線程在操作。示例**如下:
int refresh_video_timer(void *data) s_thread_exit = 0;//發出退出事件 //push quit event sdl_event event; event.type = quit_event; sdl_pushevent(&event); return 0;}
4.影象顯示效果
5.總結
YUV420P旋轉演算法
void flip mat yuv420protate.cpp 定義控制台應用程式的入口點。include stdafx.h clockwise 順時針 contrarotate 逆時針旋轉 flip horizontal 映象翻轉 水平翻轉 順時針旋轉90。取元素 從左下方第乙個點開始,從下往上,...
yuv420和yuv420p的區別
yv12和i420的區別 在採集到rgb24資料後,需要對這個格式的資料進行第一次壓縮。即將影象的顏色空間由rgb2yuv。因為,x264在進行編碼的時候需要標準的yuv 4 2 0 但是這裡需要注意的是,雖然yv12也是 4 2 0 但是yv12和i420的卻是不同的,在儲存空間上面有些區別。如下...
詳解YUV420資料格式
1.yuv簡介 yuv定義 分為三個分量,y 表示明亮度 luminance或luma 也就是灰度值 而 u 和 v 表示的則是色度 chrominance或chroma 作用是描述影像色彩及飽和度,用於指定畫素的顏色。yuv格式 有兩大類 planar和packed。對於planar的yuv格式,...