在图像数据传输和显示的过程当中有一个不经常使用的参数:间距。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