用OLED屏幕播放視頻(3): 使用cuda編程加速視頻處理

来源:https://www.cnblogs.com/kfggww/archive/2023/09/08/17672944.html
-Advertisement-
Play Games

下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放: 1) [項目介紹](https://www.cnblogs.com/kfggww/p/17672932.html) 2) [為OLED屏幕開發I2C驅動](https://www.cnblogs.com/kfggww ...


下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放:

  1. 項目介紹
  2. 為OLED屏幕開發I2C驅動
  3. 使用cuda編程加速視頻處理

這是此系列文章的第3篇, 主要總結和記錄瞭如何使用cuda編程釋放GPU的算力. 在此之前嘗試過使用python調用opencv直接處理視頻數據, 但使用之後發現處理過程效率不高, 處理時間偏長. 後來想到還有一塊顯卡沒利用起來, 畢竟在前司見證了某國產GPGPU晶元從立項, 到流片再到回片驗證的整個過程, cuda編程也算是傳統藝能了. 最終效果看下麵的視頻:

跳轉到6:48, 直接觀看演示

1). 要用GPU做什麼

這裡不會介紹cuda的編程模型, cuda開發工具的使用等, 這部分內容可以參考cuda的官方文檔, 學習cuda編程的話, 看這個文檔就足夠了.

原始的視頻文件, 每幀畫面的解析度一般不會和我們的屏幕尺寸128x64匹配, 並且視頻是彩色的, 使用的OLED屏幕只能顯示黑白圖像. 所以視頻的數據必須經過resize和灰度處理之後才能發送給beaglebone black板子連接的OLED屏幕, 這部分視頻處理工作就是在GPU上進行的.

image

在host machine上的python程式使用opencv讀取視頻文件中的每一幀, 通過socket發送給cuda程式; cuda程式處理完數據之後, 再通過socket把數據發送給beagle board上的用戶態程式; beagle board上的用戶態程式, 把一幀數據寫入屏幕, 完成繪製.

2). kernel函數的演算法實現

下麵是kernel函數的部分代碼, oframe, ow, oh, 分別表示原始畫面數據, 原始的寬度和高度, nframe, nw, nh分別表示處理之後的畫面數據, 新的寬度和高度.

kernel中的resize操作, 使用最近臨方式, (i, j)是新畫面中的像素位置, 計算得到對應的原始畫面像素位置(oi, oj), 取出原始的rgb值, 使用公式計算出亮度, 最後根據閾值確定(i, j)這個像素的亮滅.

__global__ void resize_frame_kernel(unsigned char *oframe, int ow, int oh,
				    unsigned char *nframe, int nw, int nh,
				    int threshold, unsigned int *locks)
{
	for (int i = blockDim.x * blockIdx.x + threadIdx.x; i < nw;
	     i += blockDim.x * gridDim.x) {
		for (int j = blockDim.y * blockIdx.y + threadIdx.y; j < nh;
		     j += blockDim.y * gridDim.y) {
			int oi = i * ow / nw;
			int oj = j * oh / nh;

			unsigned char b = oframe[oj * ow * 3 + oi * 3];
			unsigned char g = oframe[oj * ow * 3 + oi * 3 + 1];
			unsigned char r = oframe[oj * ow * 3 + oi * 3 + 2];

			unsigned char brightness =
				r * 0.3 + g * 0.59 + b * 0.11;
			brightness = brightness >= threshold ? 1 : 0;
			brightness = brightness << (j % 8);
			// 以下代碼實現了一個自旋鎖
			bool leaveloop = false;
			while (!leaveloop) {
				if (atomicExch(&locks[j / 8 * nw + i], 1u) ==
				    0u) {
					nframe[j / 8 * nw + i] |= brightness;
					leaveloop = true;
					atomicExch(&locks[j / 8 * nw + i], 0u);
				}
			}
		}
	}
}

3). kernel函數中的併發問題

在上面的代碼清單中使用原子交換指令atomicExch實現了一個自旋鎖. 在kernel函數中使用鎖是因為, nframe的大小是128x8位元組, 屏幕解析度是128x64, nframe的每個bit控制一個像素, 當kernel中更新nframe時, 可能同時有多個線程想更新nframe中的同一個位元組. 關於這個自選鎖中while迴圈的寫法, 可以參考stack overflow.

4). 文末推廣

歡迎關註我的B站賬號, 或者加入QQ群838923389, 一起研究電腦底層技術, 一起搞事情:P


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • > 關註微信公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。 > 本文深入探討了 Go 語言的內 ...
  • 我們來看看如何通過幾個步驟快速的實現一個功能相對齊全的CLI程式。和做飯一樣,能夠快速獲得成就感的方式是找半成品直接下鍋炒一盤 ...
  • 重定位表(Relocation Table)是Windows PE可執行文件中的一部分,主要記錄了與地址相關的信息,它在程式載入和運行時被用來修改程式代碼中的地址的值,因為程式在不同的記憶體地址中載入時,程式中使用到的地址也會受到影響,因此需要重定位表這個數據結構來完成這些地址值的修正。當程式需要被加... ...
  • 本教程適用於idea所有版本,並支持目前最新的2023.2.1版本。直接激活到2099年,支持windows、mac、linux。本文先講windows,mac和linux的跟win的激活方式大差不差。如果已經有了idea,想激活到2099的直接看步驟5 1.先去idea官網下載,官網下載地址:ht ...
  • 支持.Net Core(2.0及以上)與.Net Framework(4.5及以上) 可以部署在Docker, Windows, Linux, Mac。 分散式唯一Id,顧名思義,是指在全世界任何一臺電腦上都不會重覆的唯一Id。 在單機/單伺服器/單資料庫的小型應用中,不需要用到這類東西。但在高並 ...
  • # 前言 ### 在上一篇文章[【基於ASP.NET ZERO,開發SaaS版供應鏈管理系統】](https://www.cnblogs.com/freedyang/p/17679280.html)中有提到對Webhook功能的擴展改造,本文詳細介紹一下具體過程。 ### Webhook功能操作說明 ...
  • 一說tp大多數人想到的是PHP使用tp,但今天不說PHP 說說c#使用tp 由於tp比較久遠 網上的資料又是少之又少 接下來說說tp的一些基本用法 1.首先就是數據綁定了 <%tp:foreach collection="{$model.Items}" var="m"%> <td>{$m.name} ...
  • [toc] # Linux運維工程師面試題(9) > 祝各位小伙伴們早日找到自己心儀的工作。 > 持續學習才不會被淘汰。 > 地球不爆炸,我們不放假。 > 機會總是留給有有準備的人的。 > 加油,打工人! ## 1 pod 的生命周期 第一階段: - Pending:正在創建 Pod 但是 Pod ...
一周排行
    -Advertisement-
    Play Games
  • 前言 微服務架構已經成為搭建高效、可擴展系統的關鍵技術之一,然而,現有許多微服務框架往往過於複雜,使得我們普通開發者難以快速上手並體驗到微服務帶了的便利。為瞭解決這一問題,於是作者精心打造了一款最接地氣的 .NET 微服務框架,幫助我們輕鬆構建和管理微服務應用。 本框架不僅支持 Consul 服務註 ...
  • 先看一下效果吧: 如果不會寫動畫或者懶得寫動畫,就直接交給Blend來做吧; 其實Blend操作起來很簡單,有點類似於在操作PS,我們只需要設置關鍵幀,滑鼠點來點去就可以了,Blend會自動幫我們生成我們想要的動畫效果. 第一步:要創建一個空的WPF項目 第二步:右鍵我們的項目,在最下方有一個,在B ...
  • Prism:框架介紹與安裝 什麼是Prism? Prism是一個用於在 WPF、Xamarin Form、Uno 平臺和 WinUI 中構建鬆散耦合、可維護和可測試的 XAML 應用程式框架 Github https://github.com/PrismLibrary/Prism NuGet htt ...
  • 在WPF中,屏幕上的所有內容,都是通過畫筆(Brush)畫上去的。如按鈕的背景色,邊框,文本框的前景和形狀填充。藉助畫筆,可以繪製頁面上的所有UI對象。不同畫筆具有不同類型的輸出( 如:某些畫筆使用純色繪製區域,其他畫筆使用漸變、圖案、圖像或繪圖)。 ...
  • 前言 嗨,大家好!推薦一個基於 .NET 8 的高併發微服務電商系統,涵蓋了商品、訂單、會員、服務、財務等50多種實用功能。 項目不僅使用了 .NET 8 的最新特性,還集成了AutoFac、DotLiquid、HangFire、Nlog、Jwt、LayUIAdmin、SqlSugar、MySQL、 ...
  • 本文主要介紹攝像頭(相機)如何採集數據,用於類似攝像頭本地顯示軟體,以及流媒體數據傳輸場景如傳屏、視訊會議等。 攝像頭採集有多種方案,如AForge.NET、WPFMediaKit、OpenCvSharp、EmguCv、DirectShow.NET、MediaCaptre(UWP),網上一些文章以及 ...
  • 前言 Seal-Report 是一款.NET 開源報表工具,擁有 1.4K Star。它提供了一個完整的框架,使用 C# 編寫,最新的版本採用的是 .NET 8.0 。 它能夠高效地從各種資料庫或 NoSQL 數據源生成日常報表,並支持執行複雜的報表任務。 其簡單易用的安裝過程和直觀的設計界面,我們 ...
  • 背景需求: 系統需要對接到XXX官方的API,但因此官方對接以及管理都十分嚴格。而本人部門的系統中包含諸多子系統,系統間為了穩定,程式間多數固定Token+特殊驗證進行調用,且後期還要提供給其他兄弟部門系統共同調用。 原則上:每套系統都必須單獨接入到官方,但官方的接入複雜,還要官方指定機構認證的證書 ...
  • 本文介紹下電腦設備關機的情況下如何通過網路喚醒設備,之前電源S狀態 電腦Power電源狀態- 唐宋元明清2188 - 博客園 (cnblogs.com) 有介紹過遠程喚醒設備,後面這倆天瞭解多了點所以單獨加個隨筆 設備關機的情況下,使用網路喚醒的前提條件: 1. 被喚醒設備需要支持這WakeOnL ...
  • 前言 大家好,推薦一個.NET 8.0 為核心,結合前端 Vue 框架,實現了前後端完全分離的設計理念。它不僅提供了強大的基礎功能支持,如許可權管理、代碼生成器等,還通過採用主流技術和最佳實踐,顯著降低了開發難度,加快了項目交付速度。 如果你需要一個高效的開發解決方案,本框架能幫助大家輕鬆應對挑戰,實 ...