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

间距的名称:

它有很多的别名,在使用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)

转:图像处理、显示中的行宽(linesize)、步长(stride)、间距(pitch)的更多相关文章

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

    在图像数据传输和显示的过程中有一个不常用的参数:间距. 间距的名称:它有很多的别名,在使用d3d显示的时候,它叫pitch:在用ffmpeg解码的时候,它叫linesize: 在用ffmpeg转换格式 ...

  2. Notepad++中如何设置自动换行以及行宽

    view-->word wrap; setting->preference-->vertical edge settings; Notepad++中如何设置自动换行以及行宽 http ...

  3. WinForm------GridControl显示每行的Indicator中的行号

    1.修改Indicator的行宽 2.添加CustomDrawRowIndicator事件 private void AdminCardView_CustomDrawRowIndicator(obje ...

  4. JavaScript中的各种宽高以及位置总结

    JavaScript中的各种宽高以及位置总结 在javascript中操作dom节点让其运动的时候,常常会涉及到各种宽高以及位置坐标等概念,如果不能很好地理解这些属性所代表的意义,就不能理解js的运动 ...

  5. html中的行内元素和块级元素小结

    一.首先我们总结下行内元素和块级元素有哪些: 行内元素: <a>标签可定义锚<abbr>表示一个缩写形式<acronym>定义只取首字母缩写<b>字体加 ...

  6. Tools下的mdscongiguer 文件中 43行 oracle 配置 发现需要连接库 -lclntsh libclntsh.so 库是个什么东西呢?

    Tools下的mdscongiguer     文件中 43行  oracle 配置      发现需要连接库 -lclntsh      libclntsh.so 库是个什么东西呢? 分想一个知乎网 ...

  7. Linux 显示文本指定行内容

    主要采用sed.head和tail命令 如果文本中使用了 \n 这类符号,cat命令会把它当成换行符,结果会出错 $ sed -n "10p" move.sh   # 显示第10行 ...

  8. 【数据库】数据库的锁机制,MySQL中的行级锁,表级锁,页级锁

    转载:http://www.hollischuang.com/archives/914 数据库的读现象浅析中介绍过,在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数 ...

  9. 在Windows cmd中计算行数

    本文主体来自这篇外文文章的翻译.原文中有一个副标题:"如何简单地用Windows自带的FIND在CMD.exe中计算行数" 当我们在命令行环境中工作时,能计算其它工具输出内容的行数 ...

随机推荐

  1. fdisk

    fdisk管理分区 参数                 作用                                   m                                 ...

  2. Jmeter测试http+JSON配置相关

    1.添加HTTP信息头管理器 Content-Type application/json Accept application/json 2.添加http请求(方法.编码.路径.body)

  3. 深入理解arguments.callee

    在函数内部,有两个特殊的对象:arguments 和 this.其中, arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 a ...

  4. BZOJ.1178.[APIO2009]会议中心(贪心 倍增)

    BZOJ 洛谷 \(Description\) 给定\(n\)个区间\([L_i,R_i]\),要选出尽量多的区间,并满足它们互不相交.求最多能选出多少个的区间以及字典序最小的方案. \(n\leq2 ...

  5. JavaScript基础笔记(三) 引用类型

    引用类型 引用类型的值(对象)是引用类型的一个实例. 一.Object类型 创建Object实例: //方法一:通过new操作符创建 var a = new Object(); a.neme = &q ...

  6. go 单元测试时读取配置文件

    在go项目中读取配置文件时,如果使用的是相对路径,在执行run test时也会在test文件所在的目录下去读取配置文件,如果文件没在此目录下会报错:“open env1.json: The syste ...

  7. React Native小白入门学习路径——一

    前言 过去这段时间一直忙着实验室考核任务,拼尽全力完成了自己的任务之后.正准备开始高强度的实验室的学习的时候,实验室组织了新老生交流会,这也应该是头一次这么近距离的面对大四前辈交流想法.感觉自己受益颇 ...

  8. linux上下载安装mysql,并使用

    一:官网找mysql的安装包 可参考https://blog.csdn.net/a18852867035/article/details/81610611, 我是在https://dev.mysql. ...

  9. sench touch 页面跳转

    下面是我做的一个简单的登录页面登录成功后跳转页面 首页要在app.js 里面添加 1.视图层   登录页面 Ext.define('MyApp.view.Login', { extend: 'Ext. ...

  10. mvc中AntiForgeryToken的实现方式--看Mvc源码

    通过 AntiForgeryWorker的GetHtml()方法生成html --input hide元素--value=要验证的值,并生成cookie--用于保存需要验证的值. 类中的AntiFor ...