在圖像數據傳輸和顯示的過程當中有一個不經常使用的參數:間距。ide
間距的名稱:
它有不少的別名,在使用d3d顯示的時候,它叫pitch;在用ffmpeg解碼的時候,它叫linesize;
在用ffmpeg轉換格式的時候,它叫stride。這篇文章中統一以間距來表示。性能
間距爲何出現:
這個參數看起來彷佛沒什麼用,由於它的值和圖像的寬度同樣。可是那是大多數狀況下,一旦遇到它和寬度不同的時候,若是你不瞭解它的含義,那麼程序確定要出問題。但是爲何有時候它等於寬度,有時候又不等於呢?這就和它的含義有關了。
咱們都知道如今計算機的cpu都是32位或者64位的cpu,他們一次最少讀取四、8個字節,若是少於這些,反而要作一些額外的工做,會花更長的時間。全部會有一個概念叫作內存對齊,將結構體的長度設爲四、8的倍數。
間距也是由於一樣的理由出現的。由於圖像的操做一般按行操做的,若是圖像的全部數據都緊密排列,那麼會發生很是屢次的讀取非對齊內存。會影響效率。而圖像的處理本就是一個分秒必爭的操做,因此爲了性能的提升就引入了間距這個概念。spa
間距的含義:
間距就是指圖像中的一行圖像數據所佔的存儲空間的長度,它是一個大於等於圖像寬度的內存對齊的長度。這樣每次以行爲基準讀取數據的時候就能內存對齊,雖然可能會有一點內存浪費,可是在內存充裕的今天已經無所謂了。.net
間距的值:
因此若是圖像的寬度若是是內存對齊長度的整數倍,那麼間距就會等於寬度,而如今的cpu一般一次讀取都是4個字節,而咱們一般見到的分辨率都是4的整數倍,因此咱們一般發現間距和圖像的寬度同樣(這裏一般指rgb32格式或者以通道表示的yuv420p格式的y通道)。可是若是遇到一些少見的分辨率時間距和圖像的寬度就不同。
還有一種狀況是顯卡,由於顯卡是獨立工做的,因此顯卡可能和cpu的內存對齊位數是不一樣的,此時間距就可能和cpu上的有很大差異,例如NVIDA顯卡(它的內存對齊位數超大),一般在用d3d顯示的時候會用到間距。因此若是你的d3d顯示程序在Intel的顯卡上顯示正常,而在NVIDA顯卡上顯示不正常,先不要懷疑顯卡驅動,先看看你有沒有正確處理間距的問題(親生經歷)。3d
間距的處理:
那麼對於間距和寬度不一樣的時候要如何處理呢?在不一樣的狀況下,處理不一樣,可是隻要把握一個核心—內存對齊,就能理解。blog
在使用d3d作圖像顯示的時候,在獲取顯示內存空間的時候一般會獲取到一個參數pitch,就是咱們的間距。顯卡每次都將pitch長度的數據當作一行。咱們將圖像數據複製過去得時候要一行一行復制,每次下一行數據的目的起始位置都是上一行的起始位置加上間距。若是是yv12這種通道表示的數據,u、v通道要相應的將行距除2。間距致使的空間內容能夠不用置空。
在ffmpeg解碼的時候,解碼後會獲取到一個參數linesize,其實也是間距。從解碼後的數據內存中將數據拷貝出來的時候,須要一行一行拷貝,每一行數據的起始位置都是上一行的起始位置加上間距,一行的真正的圖像數據長度就是是圖像寬度(通道類型要相應除倍數)。
在用ffmpeg進行圖像格式轉換的時候,須要傳入一個參數stride,其實也是間距。只不過此次不須要複雜的處理,只須要知道傳入ffmpeg進行轉換的圖像數據使用的間距,而後傳入就行,ffmpeg會自動根據這個值進行相應的處理。內存
---------------------
做者:太上絕情
來源:CSDN
原文:https://blog.csdn.net/bjrxyz/article/details/52690661
版權聲明:本文爲博主原創文章,轉載請附上博文連接!it