在图像数据传输和显示的过程中有一个不常用的参数:间距。

间距的名称:

它有很多的别名,在使用d3d显示的时候,它叫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。间距导致的空间内容可以不用置空。
在ffmpeg解码的时候,解码后会获取到一个参数linesize,其实也是间距。从解码后的数据内存中将数据拷贝出来的时候,需要一行一行拷贝,每一行数据的起始位置都是上一行的起始位置加上间距,一行的真正的图像数据长度就是是图像宽度(通道类型要相应除倍数)。
在用ffmpeg进行图像格式转换的时候,需要传入一个参数stride,其实也是间距。只不过这次不需要复杂的处理,只需要知道传入ffmpeg进行转换的图像数据使用的间距,然后传入就行,ffmpeg会自动根据这个值进行相应的处理。

本文转自:

图像处理、显示中的行宽(linesize)、步长(stride)、间距(pitch)

最新文章

  1. 关于编写性能高效的javascript事件的技术
  2. Erlang垃圾回收机制的二三事
  3. android 开发之 百度地图的使用
  4. C# vs C++ Performance
  5. Bank homework 10 2016 4 25
  6. 爆搜 + 模拟 --- codeforces 475C
  7. PHP - 获取和设置include_path .
  8. linux信号量之进程间同步
  9. Python Thread
  10. Linux 服务器如何禁止 ping 以及开启 ping
  11. UIMenuController/UIPasteboard(2) UITableView上实用剪贴板
  12. 将 SQL Server 实例设置为自动启动(SQL Server 配置管理器)
  13. 对比Cassandra、 Mongodb、CouchDB、Redis、Riak、 Membase、Neo4j、HBase
  14. Javaoop 遇到的问题
  15. C语言中数组使用负数值的标记
  16. PHP7.1安装xdebug
  17. vue--vConsole
  18. Redis 5.0 集群搭建
  19. 线程守护进程与GIL
  20. 2-7 R语言基础 数据框

热门文章

  1. window下的计划任务
  2. python数据结构之quick_sort
  3. BZOJ-1- 4868: [Shoi2017]期末考试-三分
  4. llinux其他权限
  5. 【C#】Convert.ToInt32、(int)和int.Parse三者的区别
  6. Word技巧【转载】
  7. 通过ipmitool找回遗忘的iDrac地址
  8. Java笔记(十五) 并发包
  9. python基础一 ------如何统计一个列表元素的频度
  10. tomcat端口被占用的问题