SDL顯示YUV視頻

文章目錄

      • 1. **宏定義和初始化**
      • 2. **全局變量**
      • 3. **`refresh_video_timer` 函數**
      • 4. **`WinMain` 函數**
      • 主要功能及工作流程:
      • 總結:


1. 宏定義和初始化

#define REFRESH_EVENT   (SDL_USEREVENT + 1)     // 請求畫面刷新事件
#define QUIT_EVENT      (SDL_USEREVENT + 2)     // 退出事件
  • REFRESH_EVENTQUIT_EVENT 是自定義的事件類型,用來觸發畫面刷新和退出操作。

2. 全局變量

int s_thread_exit = 0;  // 退出標志
  • s_thread_exit 標志用于控制視頻播放線程的退出。

3. refresh_video_timer 函數

int refresh_video_timer(void *data)
{while (!s_thread_exit){SDL_Event event;event.type = REFRESH_EVENT;SDL_PushEvent(&event); // 觸發刷新事件SDL_Delay(40); // 約每40ms觸發一次}s_thread_exit = 0;//push quit eventSDL_Event event;event.type = QUIT_EVENT;SDL_PushEvent(&event);return 0;
}
  • refresh_video_timer 函數是一個線程函數,每隔 40 毫秒觸發一次 REFRESH_EVENT,用于請求刷新畫面。線程會一直運行,直到 s_thread_exit 被設置為 1。
  • 當播放完畢后,觸發 QUIT_EVENT 以結束程序。

4. WinMain 函數

int WinMain(int argc, char* argv[])
{// 初始化 SDLif (SDL_Init(SDL_INIT_VIDEO)){fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());return -1;}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; // YUV格式// 視頻文件路徑const char *yuv_path = "H:/SDL/SDL_test/yuv420p_320x240.yuv";FILE *video_fd = NULL;uint8_t *video_buf = NULL; // 存儲視頻數據uint32_t y_frame_len = video_width * video_height;uint32_t u_frame_len = video_width * video_height / 4;uint32_t v_frame_len = video_width * video_height / 4;uint32_t yuv_frame_len = y_frame_len + u_frame_len + v_frame_len;// 創建窗口window = SDL_CreateWindow("Simplest YUV Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, video_width, video_height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);if (!window){fprintf(stderr, "SDL: could not create window, err:%s\n", SDL_GetError());goto _FAIL;}// 創建渲染器和紋理renderer = SDL_CreateRenderer(window, -1, 0);texture = SDL_CreateTexture(renderer, pixformat, SDL_TEXTUREACCESS_STREAMING, video_width, video_height);// 分配內存用于存儲 YUV 數據video_buf = (uint8_t*)malloc(yuv_frame_len);if (!video_buf){fprintf(stderr, "Failed to allocate YUV frame space!\n");goto _FAIL;}// 打開 YUV 文件video_fd = fopen(yuv_path, "rb");if (!video_fd){fprintf(stderr, "Failed to open YUV file\n");goto _FAIL;}// 創建請求刷新線程timer_thread = SDL_CreateThread(refresh_video_timer, NULL, NULL);while (1){SDL_WaitEvent(&event);  // 等待事件if (event.type == REFRESH_EVENT) // 畫面刷新事件{video_buff_len = fread(video_buf, 1, yuv_frame_len, video_fd);if (video_buff_len <= 0){fprintf(stderr, "Failed to read data from YUV file!\n");goto _FAIL;}// 更新紋理數據SDL_UpdateTexture(texture, NULL, video_buf, video_width);// 設置顯示區域的矩形(縮放保持比例)rect.x = 0;rect.y = 0;float w_ratio = win_width * 1.0 / video_width;float h_ratio = win_height * 1.0 / video_height;rect.w = video_width * w_ratio;rect.h = video_height * h_ratio;// 清除當前渲染內容并渲染新幀SDL_RenderClear(renderer);SDL_RenderCopy(renderer, texture, NULL, &rect);SDL_RenderPresent(renderer);}else if (event.type == SDL_WINDOWEVENT){// 如果窗口大小改變,更新窗口尺寸SDL_GetWindowSize(window, &win_width, &win_height);printf("SDL_WINDOWEVENT win_width:%d, win_height:%d\n", win_width, win_height);}else if (event.type == SDL_QUIT)  // 退出事件{s_thread_exit = 1;}else if (event.type == QUIT_EVENT)  // 退出視頻播放{break;}}_FAIL: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();return 0;
}

主要功能及工作流程:

  1. SDL 初始化:

    • SDL_Init(SDL_INIT_VIDEO) 初始化 SDL 的視頻模塊。
    • 創建一個窗口 (SDL_CreateWindow)、一個渲染器 (SDL_CreateRenderer) 和一個紋理 (SDL_CreateTexture) 來渲染 YUV 數據。
  2. 讀取 YUV 數據:

    • 打開 YUV 文件并讀取 YUV 數據到緩沖區 video_buf
    • YUV 數據根據視頻的分辨率和 YUV420P 格式計算出每一幀的長度。
  3. 視頻幀渲染:

    • 每次讀取一幀數據后,使用 SDL_UpdateTexture 將 YUV 數據更新到紋理。
    • 通過渲染器 SDL_Renderer 渲染紋理到窗口。
  4. 刷新和退出事件:

    • 創建了一個獨立的線程定時觸發 REFRESH_EVENT,控制視頻的刷新頻率。
    • 如果讀取到文件結尾或退出事件,程序會退出。
  5. 窗口大小調整:

    • 在窗口大小變化時,程序會自動調整渲染區域的比例,保持視頻的寬高比。
  6. 資源釋放:

    • 在退出程序時,確保釋放所有分配的資源,包括 SDL 相關的資源(窗口、渲染器、紋理)以及 YUV 數據緩沖區。

總結:

這個程序通過 SDL2 創建一個視頻播放窗口,讀取并顯示 YUV 文件的每一幀視頻數據。它通過一個單獨的線程來周期性觸發視頻幀的刷新,保持視頻播放的流暢。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75068.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75068.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75068.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AnimateCC基礎教學:隨機抽取花名冊,不能重復

一.核心代碼: this.btnStartObj.addEventListener("click", switchBtn); this.btnOkObj.addEventListener("click", oKBtn); createjs.Ticker.addEventListener("tick", updateRandom); var _this this; var nameArr ["張三", &quo…

軟考 系統架構設計師系列知識點 —— 設計模式之抽象工廠模式

本文內容參考&#xff1a; 軟考 系統架構設計師系列知識點之設計模式&#xff08;2&#xff09;_系統架構設計師中考設計模式嗎-CSDN博客 https://baike.baidu.com/item/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/2361182 特此致謝&#xff01; Abstract Fac…

P2040 打開所有的燈

題目背景 pmshz在玩一個益(ruo)智(zhi)的小游戲&#xff0c;目的是打開九盞燈所有的燈&#xff0c;這樣的游戲難倒了pmshz。。。 題目描述 這個燈很奇(fan)怪(ren)&#xff0c;點一下就會將這個燈和其周圍四盞燈的開關狀態全部改變。現在你的任務就是就是告訴pmshz要全部打開…

漢得企業級 PaaS 平臺 H-ZERO 1.12.0 發布!四大維度升級,構建企業數字化新底座

漢得企業級 PaaS 平臺&#xff08;以下簡稱"H-ZERO"&#xff09;是一款基于微服務架構的企業級數字化 PaaS 平臺&#xff0c;可支持企業各類系統搭建、產品研發&#xff0c;幫助企業快速構架技術中臺。 H-ZERO于2025年3月底正式發布 V1.12.0 &#xff0c;此次發布聚…

ReplicaSet、Deployment功能是怎么實現的?

在Kubernetes中&#xff0c;ReplicaSet 和 Deployment 是用于管理 Pod 副本的關鍵對象。它們各自的功能和實現機制如下&#xff1a; 1. ReplicaSet 功能 管理 Pod 副本&#xff1a;確保指定數量的 Pod 副本一直在運行。如果有 Pod 副本崩潰或被刪除&#xff0c;ReplicaSet 會…

物聯網外設管理服務平臺

1 開發目標 1.1 架構圖 操作系統&#xff1a;基于Linux5.10.10源碼和STM32MP157開發板&#xff0c;完成tf-a(FSBL)、u-boot(SSBL)、uImage、dtbs的裁剪&#xff1b; 驅動層&#xff1a;為每個外設配置DTS并且單獨封裝外設驅動模塊。其中電壓ADC測試&#xff0c;采用linux內核…

PyTorch教程:如何讀寫張量與模型參數

本文演示了PyTorch中張量&#xff08;Tensor&#xff09;和模型參數的保存與加載方法&#xff0c;并提供完整的代碼示例及輸出結果&#xff0c;幫助讀者快速掌握數據持久化的核心操作。 1. 保存和加載單個張量 通過torch.save和torch.load可以直接保存和讀取張量。 import to…

持續集成:GitLab CI/CD 與 Jenkins CI/CD 的全面剖析

一、引言 在當今快速迭代的軟件開發領域,持續集成(Continuous Integration,CI)已成為保障軟件質量、加速開發流程的關鍵實踐。通過頻繁地將代碼集成到共享倉庫,并自動進行構建和測試,持續集成能夠盡早發現并解決代碼沖突和缺陷。而 GitLab CI/CD 和 Jenkins CI/CD 作為兩…

Python 序列構成的數組(序列的增量賦值)

序列的增量賦值 增量賦值運算符 和 * 的表現取決于它們的第一個操作對象。簡單起 見&#xff0c;我們把討論集中在增量加法&#xff08;&#xff09;上&#xff0c;但是這些概念對 * 和其他 增量運算符來說都是一樣的。 背后的特殊方法是 iadd &#xff08;用于“就地加法”&…

GEO, TCGA 等將被禁用?!這40個公開數據庫可能要小心使用了

GEO, TCGA 等將被禁用&#xff1f;&#xff01;這40個公開數據庫可能要小心使用了 最近NIH公共數據庫開始對中國禁用的消息鬧得風風火火&#xff1a; 你認為研究者上傳到 GEO 數據庫上的數據會被禁用嗎&#xff1f; 單選 會&#xff0c;畢竟占用存儲資源 不會&#xff0c;不…

【如何自建MCP服務器?從協議原理到實踐的全流程指南】

文章目錄 如何自建MCP服務器&#xff1f;從協議原理到實踐的全流程指南一、MCP協議是什么&#xff1f;核心架構 二、為什么要自建MCP服務器&#xff1f;1. 突破LLM的固有局限2. 實現個性化功能擴展3. 確保數據隱私安全 三、手把手搭建MCP服務器&#xff08;Python示例&#xff…

鴻蒙開發_ARKTS快速入門_語法說明_渲染控制---純血鴻蒙HarmonyOS5.0工作筆記012

然后我們再來看渲染控制 首先看條件渲染,其實就是根據不同的狀態,渲染不同的UI界面 比如下面這個暫停 開啟播放的 可以看到就是通過if 這種條件語句 修改狀態變量的值 然后我們再來看這個, 下面點擊哪個,上面橫線就讓讓他顯示哪個 去看一下代碼 可以看到,有兩個狀態變量opt…

【Java設計模式】第3章 軟件設計七大原則

3-1 本章導航 學習開辟原則(基礎原則)依賴倒置原則單一職責原則接口隔離原則迪米特法則(最少知道原則)里氏替換原則合成復用原則(組合復用原則)核心思想: 設計原則需結合實際場景平衡,避免過度設計。設計模式中可能部分遵循原則,需靈活取舍。3-2 開閉原則講解 定義 軟…

JVM即時編譯(JIT)

JVM基礎回顧 Java 作為一門高級程序語言&#xff0c;由于它自身的語言特性&#xff0c;它并非直接在硬件上運行&#xff0c;而是通過編譯器(前端編譯器)將 Java 程序轉換成該虛擬機所能識別的指令序列&#xff0c;也就是字節碼&#xff0c;然后運行在虛擬機之上的&#xff1b;…

剛體碰撞檢測與響應(C++實現)

本文實現一個經典的物理算法&#xff1a;剛體碰撞檢測與響應。這個算法用于檢測兩個剛體&#xff08;如矩形或圓形&#xff09;是否發生碰撞&#xff0c;并在碰撞時更新它們的速度和位置。我們將使用C來實現這個算法&#xff0c;并結合**邊界框&#xff08;Bounding Box&#x…

常用的國內鏡像源

常見的 pip 鏡像源 阿里云鏡像&#xff1a;https://mirrors.aliyun.com/pypi/simple/ 清華大學鏡像&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 中國科學技術大學鏡像&#xff1a;https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣鏡像&#xff1a;https://pypi.doub…

鴻蒙小案例-京東登錄

效果 代碼實現 Entry Component struct Index {build() {Column() {Row() {Image($r(app.media.jd_cancel)).width(20)Text(幫助).fontSize(16).fontColor(#666)}.width(100%).justifyContent(FlexAlign.SpaceBetween)Image($r(app.media.jd_logo)).height(250).width(250)// …

《 Scikit-learn與MySQL的深度協同:構建智能數據生態系統的架構哲學》

在機器學習工程實踐中&#xff0c;數據存儲與模型訓練的割裂始終是制約算法效能的關鍵瓶頸。Scikit-learn作為經典機器學習庫&#xff0c;其與MySQL的深度協同并非簡單的數據管道連接&#xff0c;而是構建了一個具備自組織能力的智能數據生態系統。這種集成突破了傳統ETL流程的…

華為AI-agent新作:使用自然語言生成工作流

論文標題 WorkTeam: Constructing Workflows from Natural Language with Multi-Agents 論文地址 https://arxiv.org/pdf/2503.22473 作者背景 華為&#xff0c;北京大學 動機 當下AI-agent產品百花齊放&#xff0c;盡管有ReAct、MCP等框架幫助大模型調用工具&#xff0…

關于軟件bug描述

軟件缺陷&#xff08;Defect&#xff09;&#xff0c;常常又被叫做Bug。 所謂軟件缺陷&#xff0c;即為計算機軟件或程序中存在的某種破壞正常運行能力的問題、錯誤&#xff0c;或者隱藏的功能缺陷。缺陷的存在會導致軟件產品在某種程度上不能滿足用戶的需要。IEEE729-1983對缺…