图像间距pitch是什么?(linesize、stride)(指图像中的一行图像数据所占的存储空间的长度)
width
圖像的寬度,就是像素的個數
間距(pitch)
在圖像數據傳輸和顯示的過程中有一個不常用的參數:間距。
它有很多的別名,
- 在使用d3d(Direct3D,是微軟為提高3D游戲在Windows中的顯示性能而開發的顯示程序接口)顯示的時候,它叫pitch;
- 在用ffmpeg解碼的時候,它叫linesize;
- 在用ffmpeg轉換格式的時候,它叫stride。
統一以間距來表示。
這個參數看起來似乎沒什么用,因為它的值和圖像的寬度一樣。但是那是大多數情況下,一旦遇到它和寬度不一樣的時候,如果你不了解它的含義,那么程序肯定要出問題。可是為什么有時候它等于寬度,有時候又不等于呢?這就和它的含義有關了。
我們都知道現在計算機的cpu都是32位或者64位的cpu,他們一次最少讀取4、8個字節,如果少于這些,反而要做一些額外的工作,會花更長的時間。所有會有一個概念叫做內存對齊,將結構體的長度設為4、8的倍數。
間距也是因為同樣的理由出現的。因為圖像的操作通常按行操作的,如果圖像的所有數據都緊密排列,那么會發生非常多次的讀取非對齊內存。會影響效率。而圖像的處理本就是一個分秒必爭的操作,所以為了性能的提高就引入了間距這個概念。
間距就是指圖像中的一行圖像數據所占的存儲空間的長度,它是一個大于等于圖像寬度的內存對齊的長度。這樣每次以行為基準讀取數據的時候就能內存對齊,雖然可能會有一點內存浪費,但是在內存充裕的今天已經無所謂了。
間距的值
所以如果圖像的寬度如果是內存對齊長度的整數倍,那么間距就會等于寬度,而現在的cpu通常一次讀取都是4個字節,而我們通常見到的分辨率都是4的整數倍,所以我們通常發現間距和圖像的寬度一樣(這里通常指rgb32格式或者以通道表示的yuv420p格式的y通道)。但是如果遇到一些少見的分辨率時間距和圖像的寬度就不一樣。
還有一種情況是顯卡,因為顯卡是獨立工作的,所以顯卡可能和cpu的內存對齊位數是不同的,此時間距就可能和cpu上的有很大差別,例如NVIDA顯卡(它的內存對齊位數超大),通常在用d3d顯示的時候會用到間距。所以如果你的d3d顯示程序在Intel的顯卡上顯示正常,而在NVIDA顯卡上顯示不正常,先不要懷疑顯卡驅動,先看看你有沒有正確處理間距的問題。
間距的處理
那么對于間距和寬度不同的時候要如何處理呢?在不同的情況下,處理不同,但是只要把握一個核心—內存對齊,就能理解。
在使用d3d做圖像顯示的時候,在獲取顯示內存空間的時候通常會獲取到一個參數pitch,就是我們的間距。顯卡每次都將pitch長度的數據當做一行。我們將圖像數據復制過去得時候要一行一行復制,每次下一行數據的目的起始位置都是上一行的起始位置加上間距。
如果是yv12這種通道表示的數據,u、v通道要相應的將行距除2。間距導致的空間內容可以不用置空。(?不太理解,可能是我沒有了解過YUV圖像數據格式的原因)
在ffmpeg解碼的時候,解碼后會獲取到一個參數linesize,其實也是間距。從解碼后的數據內存中將數據拷貝出來的時候,需要一行一行拷貝,每一行數據的起始位置都是上一行的起始位置加上間距,一行的真正的圖像數據長度就是圖像寬度(通道類型要相應除倍數)。
在用ffmpeg進行圖像格式轉換的時候,需要傳入一個參數stride,其實也是間距。只不過這次不需要復雜的處理,只需要知道傳入ffmpeg進行轉換的圖像數據使用的間距,然后傳入就行,ffmpeg會自動根據這個值進行相應的處理。
一般視頻、圖像存儲在內存時,圖像的每一行末尾也許包含一些擴展的內容,這些擴展的內容只影響圖像如何存儲在內存中,但是不影響圖像如何顯示出來;
參考文章:圖像Width和Pitch
總結
以上是生活随笔為你收集整理的图像间距pitch是什么?(linesize、stride)(指图像中的一行图像数据所占的存储空间的长度)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言函数strcmp()(比较两个字符
- 下一篇: 为什么要把进程/线程绑定到特定cpu核上