yuv420p 詳解 詳解SDL常用技術實戰 2

2021-10-14 00:24:14 字數 4497 閱讀 9005

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格式,...