音视频开发入门基础知识(视频入门篇)

2023-05-16

RTSP实时音视频开发实战课程:<RTSP实时音视频开发实战>

音视频开发入门基础知识(音频入门篇)

目录

一、前言

二、视频采集和显示

三、视频常见的格式

四、RGB转YUV和YUV转RGB

五、视频的压缩编码

一、前言

       当前随着科技的进步和人们生活水平的不断提高,现在人们在茶余饭后都会使用手机、电脑等这类产品,来看一些有趣的视频,来娱乐自己;而这些都离不开音视频技术的支持。本文开始介绍视频开发中最基本的技术知识,比如视频采集和显示、视频常见的格式、视频压缩编码等。

       首先要知道我们是如何通过视频来看到他人的;如下图所示,视频/声音通过摄像头/麦克风采集后(捕捉)将视频/声音通过网络发送出去,其他人通过网络接收后将视频显示到屏幕上,声音在扬声器播放,比如我们通过抖音、朋友圈视频等,都是拍摄视频上传,通过网络传输,之后在通过网络接收来播放视频和声音;另外视频/声音通过摄像头/麦克风采集后(捕捉)将视频/声音保存为文件存储后,通过播放器选择文件来播放,将视频画面显示到屏幕上,声音通过扬声器播放,比如我们手机通过相机拍摄后就是保存在手机中,然后通过手机自带播放器来播放视频和声音。

dc0f1b2418c240ca9c9b8ab8b474a9eb.png

二、视频采集和显示

    人们要想看到自然界中的景象就需要光,通过光的传递将自然界的景象传递给人眼。我们手机/相机对景象的采集也是通过光。如下图是视频/图像采集的一个过程;通常自然界的人物和景象通过光电转换将光信号转换为电信号,常见的光电转换就是摄像头感光元器件;电信号经过处理器转为数字信号,程序就可以将数字信号进行处理存储为文件。

5883f2c3a1dd445c94fa275b3fba91f6.png

      那么显示器是如何显示数字图像的呢?如下图是显示数字图像的过程;处理器将数字信号转为电信号,电信号通过电光转换器后转换为光信号,就可以被人眼观察到;通常电信号转为光信号的有发光二极管、液晶显示器等。cd8473880bd143eebbf425889349477e.png

      上面介绍了图像的显示过程,那么视频和图像什么关系呢?我们都知道一张图像里面的画面是静止,而视频里面的画面是可以动态的,所以视频和图像最大差异在于视频是动态而图像是静态的。其实视频是由若干张图像组成(注意这里的若干个图像是存在差异的,即不同时刻拍摄的运动物体/景象);当物体在运动过程中通过快速的连续不断的拍摄若干张图像组合在一起就构成了一个视频,这就是视频拍摄的过程。如下图绿荫场上的小球从高抛的过程,通过相机连续不断的拍摄出多个静态图像经过组合就可以得到一个小球高抛的运动状态的视频出来。       

三、视频常见的格式

    任何一个视频或者一个图像都有一个像素格式,而像素是指在数字图像/视频中一个最小的颜色单位,在图像/视频中按照水平+垂直的方向进行排列,通过像素的位置和颜色就可以呈现真实景象的样子。如下图是一副图像,下图的一个格子就可以认为是一个像素(实际进行了放大)。水平和垂直方向的数字520和280就是这个图像的大小,也叫图像的宽度和高度,通常也叫分辨率520x280,也就是图像的宽度是520,高度是280,单位就是像素。

cf93f6ea0f4944c9b6ded087aa73d433.png

      经过摄像头/处理器得到的视频/图像的像素格式通常有RGB、YUV等格式,在这里我们重点介绍RGB和YUV。

      什么是RGB?RGB格式也叫RGB色彩,就是常说的光学三原色,R代表Red(红色),G代表Green(绿色),B代表Blue(蓝色);自然界中肉眼所能看到的任何色彩都可以由这三种色彩混合叠加而成。在RGB格式的图像中一个像素包含了R、G、B三个颜色,其中每个颜色占8bit,也就是一个字节,三个颜色就是24bit(3个字节),由于一个R、G或者B占用8bit那么其所表达的数字范围就是0-255,所以单个颜色所能表示的颜色范围只有256中。通常为了方便图像的存取,RGB格式的图像其三个颜色是交叉存储的,如下图,一个像素的RGB值存储完之后存下一个像素的RGB值。一副分辨率为520x280的RGB格式的图像其大小为520x280*3=436800字节=426.5625KB。

0d62a0307d3c40738aac8ae2cf07fe0c.png

      此外对于RGB图像格式不同可能每个像素大小不同,除了RGB格式还有其他格式比如RGBA格式,ARGB格式、BGR格式等、对于RGBA格式和ARGB格式是在RGB颜色上多了一个Alpha,也通常指图像的透明度,也占用一个字节;对于ARGB和RGBA格式的图像来说每一个像素占32bit(4个字节),一副分辨率为520x280的ARGB/RGBA格式的图像其大小为520x280*4=582400字节=568.75KB。BGR图像格式和RGB的格式像素大小都是24bit仅仅是RGB的存储顺序不同,RGB是先存储Red颜色,BGR是先存储Blue颜色。另外还有些更高bit的RGB格式存在,比如10bit的RGB甚至16bit的RGB,10bit和16bit的RGB和8bit的RGB相比大小会明显增大,此外10bit和16bit由于单个像素的bit数增加那么所表达的颜色范围也会增加,比如10bitRGB单个颜色值的范围为0-1023,所以10bitRGB可以表示的颜色有1024种,比8bitRGB高出4倍。

      什么是YUV?YUV是是一种颜色编码方法,通常是对RGB进行颜色转换得到YUV。Y通常是颜色中的亮度信息(灰度信息),UV是颜色中的彩色信息。通常人眼对事物颜色的亮度和彩色信息的敏感程度不同,大多是对亮度敏感度较高,对彩色信息敏感度较低,所以将颜色的亮度和彩色信息分离表示可以有助于图像的编码。通常YUV的格式有YUV444、YUV422、YUV420;YUV444表示的YUV图像中亮度和彩色信息所占空间大小是1:1:1(Y:U:V);YUV422表示的YUV图像中亮度和彩色信息所占空间大小是2:1:1(Y:U:V),即彩色信息量和亮度信息量相比较降低了一半的信息和存储空间;YUV420表示的YUV图像中亮度和彩色信息所占空间大小是4:1:1(Y:U:V),即彩色信息量和亮度信息量相比较降低了3/4的信息和存储空间,YUV格式通常是减少彩色信息量来降低存储空间大小的一种格式;YUV420的存储空间结构举例可以如下图所示,先存储32个Y,在存帧8个U和8个V。

88e41d1e0ab845a0930fee3683e0f624.png

      在实际的视频和图像编码中使用的YUV格式大多是YUV420的。可以发现上图YUV420的存储结构的三个分量(Y/U/V)是单独存储的,除了上面的单独存储格式外还有UV交织存储的YUV420格式,比如NV21,NV12,这两种也是比较常见的YUV420格式。NV21通常是V在前U在后的存储方式,NV12是U在前V在后的存储方式.,如下图左侧是NV12,右侧是NV21.

d75876ddb2e843959a42c93807052a3b.png

      YUV图像格式通常一个像素由Y分量和U、V分量表示,三个分量通常都是占8bit(一个字节),对于YUV420(NV21/NV12)的图像来说一个像素需要1.5个字节(一个字节的Y和0.25字节的U+0.25字节的V)表示;一副520x280的YUV420图像大小为520x280x1.5=218400字节=213.28KB,可以看到YUV420的格式图像比同分辨率的RGB的大小降低了一半。和RGB一样,YUV不仅有8bit的数据也有10bit、12bit表示的,对于Y(亮度)10bit的数据可以表示0-1023范围的亮度,UV10bit的数据可以表示0-1023范围的色度。

四、RGB转YUV和YUV转RGB

     通常情况下RGB格式的图像其大小比较大,占用较大的存储空间,所示需要对RGB格式进行压缩,通常RGB压缩为YUV(通常是YUV420),RGB压缩为YUV的过程也就是RGB转YUV的公式如下,下面的公式是BT709色域空间下的RGB转YUV的公式。

BT709
Y = 0.183*R + 0.614*G + 0.062*B + 16;
U = 0.439*B - 0.339*G - 0.101*R + 128;
V = 0.439*R - 0.399*G - 0.040*B + 128;

下面的公式是BT601色域空间下的RGB转YUV的公式。

BT601
Y = 0.257*R + 0.504*G + 0.098*B + 16;
U = 0.439*B - 0.291*G - 0.148*R + 128;
V = 0.439*R - 0.368*G - 0.071*B + 128;

关于BT709和BT601是国际标准中不同的两种色域(也就是表示红绿蓝颜色的范围)。

      另外在显示图像数据的时候通常都是按照RGB数据格式进行显示像素点,所以实际显示YUV数据的时候还需要将YUV转RGB,下面的公式是BT709色域空间下的YUV转RGB的公式。

BT709
R = 1.164*(Y-16) + 1.792*(V-128);
G = 1.164*(Y-16) - 0.213*(U-128) - 0.534*(V-128);
B = 1.164*(Y-16) + 2.114*(U-128);

下面的公式是BT601色域空间下的YUV转RGB的公式。

BT601
R = 1.164*(Y-16) + 1.596*(V-128);
G = 1.164*(Y-16) - 0.392*(U-128) - 0.812*(V-128);
B = 1.164*(Y-16) + 2.016*(U-128);

五、视频的压缩编码

     上面的RGB和YUV的介绍中我们可以知道,一副格式为YUV420,分辨率为520x280的图像占用213.28KB,如果是格式为YUV420,分辨率为520x280,时常为1秒,帧率为30帧每秒的视频其大小为520x280x1.5x30=6398.4375KB=6.25MB,如果视频分辨率是高清也就是1920x1080,则视频的大小为1920x1080x1.5x30=91125KB=88.99MB,如果你要从网上看格式为YUV420,分辨率1920x1080,帧率30帧每秒的视频则需要的网速是88.99MB*8=711.9Mb每秒,这种网速一般人根本达不到。如果你要是录制格式为YUV420,分辨率1920x1080,帧率30帧每秒,时常为1小时的视频则大小是:1920x1080x1.5*30*60*60=320364MB=312.8GB,这么大的存储空间,一部256G内存的手机根本不够用,所以需要对YUV格式的视频进一步压缩才能满足我们日常视频拍摄,浏览的需求。

      目前视频压缩编码算法标准比较多,通常使用较多的是H264(也叫AVC)和H265(也叫HEVC);使用H264对YUV420的图像进行压缩,压缩率可以达到100倍-200倍,而且不影响视频的观看,H265编码算法可以达到300倍的压缩率,而且不影响视频的观看。下图是H264的编码框图。

a682d11dd82945d6a1c4a48256f4ae61.png

下图是H265的编码框图。

 ad93e94f06364292ac9da4fa2fd630ff.png

      根据H264和H265的编码框图看出H265编码算法更加复杂。实际上H265的压缩效率比H264的要高,但是同时H265的编码器实现更加困难,目前开源的H265编码器X265比H264开源的X264编码器速度要慢上很多。

     下图是视频采集到编码的数据流程图。3096d7bafd0a4fb0ab9178ed2bce7db0.png

     下图是视频解码到显示的数据流程。

871f525ac6344829940910aa536ca4e1.png

     H264和H265编码器对YUV进行压缩,主要过程是对视频YUV进行编码,将YUV数据编码为IDR帧、P帧、B帧;

IDR帧(Instantaneous Decoding Refresh),即时解码刷新,是视频的关键帧,IDR帧的解码不需要依赖其他视频帧。解码器遇到这个帧会将之前的解码信息清空,根据当前的IDR帧解码生成新的解码信息。视频编码帧中可以有多个IDR帧。

P帧 是前向预测编码的视频帧,它的解码只能参考它前面的P帧或者IDR帧。

B帧 是双向预测编码的视频帧,它的解码需要参考前面的P帧或者IDR帧,也需要参考它后面的P帧或者IDR帧。

       通常IDR帧采用帧内压缩方式,只消除空域上的内容冗余,压缩率比较低;P帧采用帧内和帧间的压缩方式不仅消除空间上的冗余也可以消除时间上的冗余,压缩效率比较高;B帧也采用帧间帧内和帧间的压缩方式,也会消除空间和时间上的冗余,其采用双向预测编码可以进一步降低时间冗余。因此视频压缩的目的是降低视频内容的冗余,使用更少的数据量来保存图像信息。

 下图是H264/H265视频编码帧结构图。

bdf3d79e4add417b814c26e4368e1f95.png

有关H264和H265视频码流的分析如下文章:

H264视频码流结构分析

H265视频码流结构分析

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

音视频开发入门基础知识(视频入门篇) 的相关文章

  • 判断两个IP地址(ipv4)是否在同一个网段

    我们通常会遇到的ip地址是这样的 xff1a ip地址 xff1a 192 168 227 205 子网掩码 xff1a 255 255 255 0 ip地址 xff1a 192 168 226 202 子网掩码 xff1a 255 255
  • 局域网搭建Linux镜像源

    前言 一般情况在企业的局域网内 xff0c 是不连接外网的 xff0c 所以像阿里云这样的在线的镜像源就用不了 xff0c 我相信大家个人在虚拟机里面连的就是阿里云镜像源了 xff0c 而且局域网内服务器较多的话 xff0c 本地挂载镜像源
  • ubuntu22.04 server安装

    目录 1 安装首页2 选择安装语言3 安装器4 选择键盘布局5 选择安装类型6 设置网络连接7 配置镜像源地址8 磁盘分区9 创建登录用户10 配置安装openssh server11 配置安装其他额外的软件12 开始安装系统13 重启系统
  • linux安装OceanBase数据库

    1 下载OceanBase数据库安装包 OceanBase官网下载页面 2 解压安装包并安装 tar xzf oceanbase all in one 4 0 0 0 beta 100120221102135736 el7 x86 64 t
  • linux下安装mysql客户端client

    1 下载mysql客户端 MySQL的Linux客户端官网下载地址 根据Linux的系统版本选择下载对应的rpm安装包 xff08 如下所示 xff09 xff0c 这里选择的是mysql8 0 27版本的redhat8系列的MySQL客户
  • linux下mysql的三种安装方法

    目录 1 离线安装 xff08 tar gz安装包 xff09 2 离线安装 xff08 rpm安装包 xff09 3 在线安装 xff08 yum安装 xff09 前言 安装环境 Redhat Enterprise Linux 8 1 离
  • linux+window+macos下的JDK安装

    1 Linux中安装JDK xff08 1 xff09 下载Linux版本的jdk压缩包 xff08 2 xff09 解压 tar zxvf 压缩包名 例如 xff1a tar zxvf jdk 8u251 linux x64 tar gz
  • bootstrap-table源码函数解读-sprintf

    var sprintf 61 function str var args 61 arguments flag 61 true i 61 1 str 61 str replace s g function var arg 61 args i
  • openGauss数据库的使用

    目录 前言1 启动 停止 重启数据库 xff08 1 xff09 极简版启动 停止 重启命令 xff08 2 xff09 企业版启动 停止 重启命令 2 登录数据库 xff08 1 xff09 登录数据库时的基本连接参数 xff08 2 x
  • openGauss数据库的安装(2.0.0极简版安装)

    目录 前言1 安装环境准备2 创建用户和用户组3 正式安装4 启动数据库实例并测试 前言 这里主要结合官网的文档 xff0c 安装系统环境是官网推荐的openEuler 20 03LTS openGauss数据库版本是openGauss 2
  • openGauss数据库安装(2.0.0企业版安装)

    目录 1 准备环境2 预安装3 正式安装4 启动并登录数据库 前言 此次数据库的系统安装环境仍然是openEuler20 03LTS openGauss安装版本是2 0 0版本 xff0c 相对于极简版安装 xff0c 确实多了一些工具 x
  • openEuler22.03安装

    目录 1 安装2 登录3 修改登录密码输错限制次数 1 安装 如果在此时没有设置网络 xff0c 那么需要在登录后可以编辑 etc sysconfig network scripts ifcfg ens160文件 xff0c 如下红框部分所
  • Linux查看日志常用命令

    第一种 xff1a 查看实时变化的日志 比较吃内存 最常用的 xff1a tail f app log 默认最后10行 xff0c 相当于增加参数 n 10 tail 200f app log 最后200行 xff0c 某一时刻往前推 Ct
  • ubuntu查看文件和文件夹大小

    在实际使用ubuntu时候 xff0c 经常要碰到需要查看文件以及文件夹大小的情况 有时候 xff0c 自己创建压缩文件 xff0c 可以使用 ls hl 查看文件大小 参数 h 表示Human Readable xff0c 使用GB MB
  • NLTK下载错误的终极解决办法

    Downloading package brown to C Users Ken AppData Roaming nltk data Error downloading 39 brown 39 from lt https raw githu
  • Tensorboard 不显示数据的问题

    No dashboards are active for the current data set Probable causes You haven 39 t written any data to your event files Te
  • Pytorch学习(2)——训练词向量的代码

    教程 xff1a https www bilibili com video BV1vz4y1R7Mm p 61 2 span class token keyword import span torch span class token ke
  • Windows 在不修改主题色的情况下将标题栏修改为黑色

    有些软件使用深色模式之后标题栏仍然是白色的 xff0c 很不美观 如果在 Windows 10 的设置中 xff0c 将个性化 颜色 在以下区域显示主题色 标题栏和窗口边框 选中 xff0c 那么标题栏可以带颜色 此时如果将主题色改为彩色
  • 解决debian(jessie)没有声音的问题

    先检查系统声卡驱动 lspci grep Audio 00 1b 0 Audio device Intel Corporation 82801I ICH9 Family HD Audio Controller rev 03 说明系统已经识别

随机推荐

  • 笔记类软件总结

    我大致把笔记类软件分为三类 xff1a 传统文档 思维导图 专业软件 1 传统文档 Typora 最经典的本地软件应该是 Typora 支持 Markdown 的实时预览 xff0c 界面简洁美观 使用基于 Chromium 浏览器的 El
  • Golang Map 基本原理

    Go 语言中的 map 即哈希表 哈希表把元素分到多个桶里 xff0c 每个桶里最多放8个元素 在访问元素时 xff0c 首先用哈希算法根据 key 和哈希表种子获得哈希值 暂将其命名为 h xff0c 然后利用 h 的低 b b b 位得
  • Go 汇编器指南

    A Quick Guide to Go s Assembler Go汇编器指南 This document is a quick outline of the unusual form of assembly language used b
  • [golang] 什么情况下reflect.IsValid 返回 false?

    https stackoverflow com questions 39011295 when does reflect isvalid return false 总结成一句话 xff1a IsValid 表示是否 Value 是否 wra
  • IPv6的DNS,设置DNS

    来自下一代互联网国家工程中心的最新消息 xff0c 该中心正式宣布推出IPv6公共DNS xff1a 240c 6666 xff0c 这是面向全球免费提供的公共DNS服务 同时 xff0c 还有一个备用DNS xff1a 240c 6644
  • MongoDB 查询包含某字符串的记录

    34 key 34 regex 广东
  • Anaconda使用conda连接网络出现错误(CondaHTTPError: HTTP 000 CONNECTION FAILED for url)

    进入 HOMEPATH 目录 编辑其中的 condarc 文件 删除 default 将 https 改成 http 转载自 Anaconda使用conda连接网络出现错误 CondaHTTPError HTTP 000 CONNECTIO
  • Win10 EFI启动文件被删的修复办法

    首先确保EFI分区存在 没有的话可以进入PE创建 首先是不成功的办法 xff1a 用PE里的EFI分区修复 xff0c 成功把Win7变成了EFI启动 xff08 以前梦寐以求的 xff09 xff0c 但是Win10一直修复失败 xff0
  • 关于UITabBarController的UITabBar隐藏问题

    最开始的时候我用的 void hideTabBar if self tabBarController tabBar hidden 61 61 YES return UIView contentView if self tabBarContr
  • NSAttributedString宽高计算小技巧

    通常对于CoreText之类自己实现绘制的控件来说 xff0c 计算富文本的宽高其实需要依赖CTFramesetterSuggestFrameSizeWithConstraints这个方法 但有些时候 xff0c 我们可能只是使用UILab
  • 拦截器获取HttpServletRequest里body数据

    一 问题 通过在拦截器中获取request中的json数据 xff0c 我们可以实现对参数进行校验和改写 问题是参数只能在拦截器里获取一次 xff0c 往后在controller层就无法获取数据 xff0c 提示body为空 在网上查找资料
  • iOS开发小技巧之--WeakSelf宏的进化

    我们都知道在防止如block的循环引用时 xff0c 会使用 weak关键字做如下定义 xff1a span class hljs keyword weak span typeof span class hljs keyword self
  • 用JavaScriptCore做android和iOS都兼容的JS-NativeSDK

    最近在给公司做一个JS Native的SDK xff0c 就是用于JS和原生之间的交互 使用场景上主要还是webView xff0c 那么原先的url拦截的方式已经不再考虑 xff0c 我们使用了iOS7之后的JavaScriptCore
  • 关于Xcode8 iOS10下模拟器NSLog不输出的问题

    昨天升级了Xcode8beta版 xff0c 兴高采烈的打开工程启动模拟器后发现自己的NSLog输出在console中看不到了 xff0c 查阅Xcode8 release note后发现官方的中有这么一段 When debugging a
  • ShareSDK 3.4.0 isWXAppInstalled 返回NO

    升级到3 4 0版本的ShareSDK之后 xff0c 发现 WXApi isWXAppInstalled 方法一直返回false xff0c 无法正常使用 初步怀疑是ShareSDK自己的bug 查找资料后发现 xff0c 解决方案居然是
  • iOS网络诊断功能 ping traceroute

    最近工作中总是遇到需要排查移动客户端网络状况的情况 xff0c 可能由于某些地区网络运营商的问题 xff0c 导致客户端某些功能不正常 xff0c 现在的做法也是非常麻烦的 xff1a 某用户反馈某一功能不能用由运营联系到该用户运营指导该用
  • macOS10.12下如何丝滑的使用appium?

    appium是一个自动化测试的跨平台解决方案 xff0c 这篇文章针对最新版的xcode 8 2和mac OS 10 12给出基本完成的部署过程 xff0c 值得一看 实际操作过程中 xff0c 有几个地方需要注意 xff1a 不要忘记启动
  • iOS如何在页面销毁时优雅的cancel网络请求

    大家都知道 xff0c 当一个网络请求发出去之后 xff0c 如果不管不顾 xff0c 有可能出现以下情况 xff1a 进入某个页面 xff0c 做了某种操作 xff08 退出页面 切换某个tab等等 xff09 导致之前的请求变成无用请求
  • glibc源码解读——malloc

    通过宏定义的展开 xff0c 找到malloc的函数地址 xff1a define C SYMBOL NAME name name define ASM LINE SEP void libc malloc size t bytes libc
  • 音视频开发入门基础知识(视频入门篇)

    RTSP实时音视频开发实战课程 xff1a lt RTSP实时音视频开发实战 gt 音视频开发入门基础知识 xff08 音频入门篇 xff09 目录 一 前言 二 视频采集和显示 三 视频常见的格式 四 RGB转YUV和YUV转RGB 五