音视频方案,音视频扩展内容 4(笔记)

视频方案,雷霄骅的专栏- http://blog.csdn.net/leixiaohua1020

  在Windows平台下的视频播放技术主要有以下三种:GDI,Direct3D和OpenGL;音频播放技术主要是DirectSound。在Windows平台下视频的播放显示主要可以使用以下两种技术:Direct3D和OpenGL。以上两种显示技术是最好的。除了以上两种之外,还有其他的选择。比如说DirectDraw或者GDI。但是微软已经停止了对DirectDraw的支持。而GDI也并不是主要用于视频显示领域(主要用于软件开发)
  三种视频显示技术:GDI,Direct3D,OpenGL。其中Direct3D包含简单和复杂的两种显示方式:使用Surface和使用Texture;OpenGL也包含简单和复杂的两种显示方式:直接画像素和使用Texture。

-- GDI播放视频的技术

 图形设备接口(Graphics Device Interface或Graphical Device Interface,缩写GDI),是微软公司视窗操作系统(Microsoft Windows)的三大核心部件(另外两个是kernel、user)之一。GDI是微软视窗系统表征图形对象及将其传送给诸如显示器、打印机之类输出设备的标准。其他系统也有类似GDI的东西,比如Macintosh的Quartz(传统的QuickDraw),和GTK的GDK/Xlib。
 GDI用来完成一些和绘制有关的工作,像直线或曲线的绘制,文字渲染,调色板控制。它最大的好处是它有可以直接访问硬件设备的能力。通过GDI可以非常容易的在不同类型的设备上绘制图形,像显示屏和打印机或类似的显示设备。这些能力是微软Windows系统“所见即所得”程序的核心。
 视频显示的输入数据一般情况下是非压缩的RGB/YUV数据。像H.264这些压缩码流是不能用于显示的。非压缩的RGB/YUV数据在我们电脑里并不常见,因为它的体积实在是太大了。像素格式必须转换为RGB(即不能是YUV)才能使用GDI画上去。因为BMP存储像素是RGB格式的。
 我们日常生活中比较常见的存储非压缩的RGB像素数据的格式就是BMP。它的文件体(除去文件头)中存储的是RGB数据。很容易发现,BMP文件明显大于JPEG等压缩格式的文件。
 大端模式(Big Endian),是指数据的低字节(注意是整个字节)保存在内存的高地址中,而数据的高字节,保存在内存的低地址中。其实这是一个更符合人类习惯的存储方式。小端模式(Little Endian),是指数据的低字节保存在内存的低地址中,而数据的高字节保存在内存的高地址中。
 大部分用户的操作系统(如Windows,FreeBsd,Linux)是Little Endian的。少部分,如MAC OS是Big Endian 的。此外,网络字节序是Big Endian的。BMP文件的存储规定是Little Endian。

-- Direct3D(简称D3D)播放视频的技术
 视频播放只是Direct3D的“副业”,它主要用于3D游戏制作。使用Direct3D可以用两种方式渲染视频:Surface和Texture。使用Surface相对来说比使用Texture要简单一些,但是不如使用Texture灵活。鉴于使用Surface更加容易上手.
 Direct3D(简称:D3D)是微软公司在Microsoft Windows系统上开发的一套3D绘图API,是DirectX的一部份,目前广为各家显示卡所支援。
 Direct3D的抽象概念包括:Devices(设备),Swap Chains(交换链)和Resources(资源)。Device(设备)用于渲染3D场景。例如单色设备就会渲染黑白图片,而彩色设备则会渲染彩色图片。Direct3D API定义了一组Vertices(顶点), Textures(纹理), Buffers(缓冲区)转换到屏幕上的流程。这样的流程称为Rendering Pipeline(渲染流水线)。
 在Direct3D中经常会出现“三角形”这个概念。这是因为在3D图形渲染中,所有的物体都是由三角形构成的。因为一个三角形可以表示一个平面,而3D物体就是由一个或多个平面构成的。
  使用Direct3D中的Texture(纹理)渲染视频。渲染与纹理。其实Ditect3D中的很多概念并不是出自于视频领域,而是出自于3D制作。在3D制作过程中,如果单靠计算机绘制生成3D模型,往往达不到很真实的效果。

 Direct3D使用一个纹理坐标系统,它是由用水平方向的u轴和竖直方向v轴构成。注意v轴是向下的(OpenGL的v轴是向上的)。需要注意的是,纹理坐标的取值范围是0-1,而不是像普通坐标那样以像素为单位。它代表了一种图像映射的关系。例如纹理坐标是(0.5,0.0),就是把2D纹理横向二分之一处的点映射到随后定义的物体顶点上去。

 纹理(Texture)和表面(Surface)的区别与联系:
 Surfaces是一个存储2D图像的内存。
 Textures是一张贴图。Texture的图像数据存储于它的Surface中。一个Texture可以包含多个Surface。

 纹理,如果可以把一张2D图片“贴”到3D模型的表面上,则不但节约了计算机绘图的计算量,而且 也能达到更真实的效果。纹理就是这张“贴图”。
 渲染就是从模型生成图像的过程,通常是3D制作的最后一步。如在经过纹理贴图之后,形成了一个“木箱”模型。但是只有把它作为2D图像输出到屏幕上之后,它才能被我们的看见。这个输出的过程就是渲染。我们也可以调整这个“木箱模型”的参数,达到不同的渲染结果。比如说改变观察角度等等。

-- OpenGL播放视频的技术
 OpenGL是一个和Direct3D同一层面的技术。相比于Direct3D,OpenGL具有跨平台的优势。尽管在游戏领域,DirectX的影响力已渐渐超越OpenGL并被大多数PC游戏开发商所采用,但在专业高端绘图领域,OpenGL因为色彩准确,仍然是不能被取代的主角。在高端的图形设备和专业应用方面OpenGL占据着统治地位(Direct3D目前还不支持)。开放源码社区(尤其是Mesa项目)一直致力于提供OpenGL支持。

 - Display List(显示列表)
 显示列表是一组OpenGL命令,被存储(编译)起来用于后续的执行。所有数据,几何(顶点)数据和像素数据都可以存入显示列表。数据和命令缓存到显示列表中可以提高性能。
 - Vertex Operation(顶点处理)
 顶点坐标和法线坐标经过模式视图矩阵从物体坐标系(object coordinates)转换为观察坐标系(eye coordinates)。若启用了光照,对转换后的定点和法线坐标执行光照计算。光照计算更新了顶点的颜色值。
Primitive Assembly(图元装配)
顶点处理之后,基本图元(点、线、多边形)经过投影矩阵变换,再被视见体裁剪平面裁剪,从观察坐标系转换为裁剪坐标系。之后,进行透视除法(除以w)和视口变换(viewport transform),将3d场景投影到窗口坐标系。
 - Pixel Transfer Operation(像素操作)
像素从客户内存中解包出来之后,要经过缩放、偏移、映射、箝拉(clamping)。这些处理即为像素转换操作。转换的数据存在纹理内存或直接经过光栅化转为片段(fragment)。
 - Texture Memory(纹理内存)
纹理图像载入到纹理内存中,然后应用到几何对象上。 
 - Raterization(光栅化)
 光栅化就是把几何(顶点坐标等)和像素数据转换为片段(fragment)的过程,每个片段对应于帧缓冲区中的一个像素,该像素对应屏幕上一点的颜色和不透明度信息。片段是一个矩形数组,包含了颜色、深度、线宽、点的大小等信息(反锯齿计算等)。如果渲染模式被设置为GL_FILL,多边形内部的像素信息在这个阶段会被填充。
 - Fragment Operation(片段操作)
 这是将片段转为帧缓冲区中的像素要进行的最后处理。首先是纹理单元(texel)生成。一个纹理单元由纹理内存中的数据生成,然后应用到每个片段上。之后进行雾计算。 雾计算完成后,还要按序进行若干片段测试,依次为蒙板(scissor)测试,alpha测试,模版(stencil)测试,深度测试。最后,执行混合,抖动,逻辑操作和遮蔽操作,最终的像素存入framebuffer。

 输入的YUV420P像素数据通过一个普通的函数转换为RGB数据后,传送给OpenGL播放。也就是像素的转换是通过CPU完成的。
 输入的YUV420P像素数据通过Shader转换为YUV数据,传送给OpenGL播放。像素的转换是通过显卡上的GPU完成的。

 OpenGL的着色器有.fsh和.vsh两个文件。这两个文件在被编译和链接后就可以产生可执行程序与GPU交互。.vsh 是Vertex Shader(顶点着色器),用于顶点计算,可以理解控制顶点的位置,在这个文件中我们通常会传入当前顶点的位置,和纹理的坐标。.fsh 是Fragment Shader(片元着色器),在这里面我可以对于每一个像素点进行重新计算。Vertex Shader是作用于每一个顶点的,如果Vertex有三个点,那么Vertex Shader会被执行三次。Fragment Shader是作用于每个像素的,一个像素运行一次。
 Vertex Shader(顶点着色器)主要是传入相应的Attribute变量、Uniforms变量、采样器以及临时变量,最后生成Varying变量,以及gl_Posizion等变量。Fragment Shade(片元着色器)可以执行纹理的访问、颜色的汇总、雾化等操作,最后生成gl_FragColor变量。有高手总结如下:“vsh负责搞定像素位置,填写gl_Posizion;fsh负责搞定像素外观,填写 gl_FragColor。

-- DirectSound播放PCM
 DirectSound是Windows下最常见的音频播放技术。目前大部分的音频播放应用都是通过DirectSound来播放的。DirectSound是微软所开发DirectX的组件之一,可以在Windows 操作系统上录音,并且记录波形音效(waveform sound)。目前DirectSound 是一个成熟的API ,提供许多有用的功能,例如能够在较高的分辨率播放多声道声音。
 DirectSound3D(DS3D)最早是1993年与 DirectX 3 一起发表的。DirectX 8以后的DirectSound和DirectSound3D的(DS3D)被合称DirectX Audio。

-- SDL播放视频的技术
 实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API。在Windows平台下,SDL封装了Direct3D这类的API用于播放视频;封装了DirectSound这类的API用于播放音频。因为SDL的编写目的就是简化视音频播放的开发难度,所以使用SDL播放视频(YUV/RGB)和音频(PCM)数据非常的容易。
 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。

 关于音频各种参数:
freq:音频数据的采样率。常用的有48000,44100等。
format:音频数据的格式。举例几种格式:
AUDIO_U16SYS:Unsigned 16-bit samples
AUDIO_S16SYS:Signed 16-bit samples
AUDIO_S32SYS:32-bit integer samples
AUDIO_F32SYS:32-bit floating point samples
channels:声道数。例如单声道取值为1,立体声取值为2。
silence:设置静音的值。
samples:音频缓冲区中的采样个数,要求必须是2的n次方。
padding:考虑到兼容性的一个参数。
size:音频缓冲区的大小,以字节为单位。
callback:填充音频缓冲区的回调函数。

userdata:用户自定义的数据。

-- 最简单的视频编码器:编译(libx264,libx265,libvpx)
 x264,x265,vpx这三个开源的视频编码器可以说是当今“最火”的视频编码器。x264现在占据着H.264视频编码器的半壁江山;x265则是目前实现H.265标准最好的开源视频编码器,并且在未来可能接替x264;而vpx则是Google推出的开源视频编码器,它提出的VP9编码标准的性能也不错。

 最简单的视频编码器:基于libx264(编码YUV为H.264)
 “轻量级”的编码器。因为它不再包含FFmpeg的代码,直接调用libx264完成编码。因此项目的体积非常小巧。该编码器可以将输入的YUV数据编码为H.264码流文件。

 最简单的视频编码器:基于libx265(编码YUV为H.265),H.265(HEVC)
 “轻量级”的编码器。因为它不再包含FFmpeg的代码,直接调用libx265完成编码。因此项目的体积非常小巧。该编码器可以将输入的YUV数据编码为H.265码流文件。
 
 最简单的视频编码器:基于libvpx(编码YUV为VP8),基于libvpx的VP8视频编码器
  与H.264不同,VP8的裸流(即不包含封装格式的纯视频数据流)是不能播放的。换言之,VP8的裸流必须存放在容器中才可以播放。官方示例代码中存储VP8视频流的封装格式是IVF。

-- 最简单的基于librtmp的示例:接收(RTMP保存为FLV),RTMPDump
 最简单的基于librtmp的示例:发布(FLV通过RTMP发布).使用librtmp发布RTMP流的可以使用两种API:RTMP_SendPacket()和RTMP_Write()。

  与RGB每个像素点的每个分量取值范围为0-255不同(每个分量占8bit),YUV取值范围有两种:
(1)以Rec.601为代表(还包括BT.709 / BT.2020)的广播电视标准中,Y的取值范围是16-235,U、V的取值范围是16-240。FFmpeg中称之为“mpeg”范围。
(2)以JPEG为代表的标准中,Y、U、V的取值范围都是0-255。FFmpeg中称之为“jpeg” 范围。

  最简单的基于libVLC的视频播放器。VLC Media Player是一款优秀的播放器,但是由于它的源代码编译的难度比较大,一直没有深入研究过它的开发方面的技术。最简单的基于libVLC的视频播放器(图形界面版)。最简单的基于libVLC的推流器。

  DirectShow的视频播放器。DirectShow是一个庞大的框架,可以在Windows下实现多种多样的视频处理需求。

  -- DVB数字电视系统简介(DVB-C,DVB-S,DVB-T)
  视音频编解码这些技术都是属于“信源”的技术,而《通信原理》研究的范围正好是它的补集,属于“信道”方面的技术。
  数字视频广播(英语:Digital Video Broadcasting,缩写:DVB),是由“DVB Project”维护的一系列为国际所承认的数字电视公开标准。“DVB Project”是一个由300多个成员组成的工业组织,它是由欧洲电信标准化组织(European Telecommunications Standards Institute, ETSI)、欧洲电子标准化组织(European Committee for Electrotechnical Standardization, CENELEC)和欧洲广播联盟(European Broadcasting Union, EBU)联合组成的“联合专家组”(Joint Technical Committee, JTC)发起的。
  DVB标准中描述的系统可以概括成图5所示的结构。根据所属的层次不同从上层到底层可以分为:音视频编码层,服务信息层,基带传输层,信道编码层,射频层。这些层次完成的工作可以概括如下:
 1.音视频编码层:使用MPEG1、2等多项标准对模拟音视频信号进行采样和压缩。
 2.服务信息层:使用DVB SI标准产生PSI、SI和EPG等信息服务。
 3.基带传输层:使用ASI(异步串行)、SPI(同步并行)、SSI(同步串行)接口。
 4.信道编码层:使用各种DVB-S、DVB-C、DVB-T信道编码。
 5.射频层:使用卫星、CATV(有线电视网)、SFN(单频网)、Internet等进行信号传送。

  DVB-C系统中QAM调制与解调仿真,DVB-C(Cable,数字有线电视)系统。DVB系列标准是数字电视领域最重要的标准,它是一个完整的数字广播解决方案,涉及数字电视广播的方方面面。DVB 规范了数字电视的系统结构和信号处理方式,各厂商可以开发各自的 DVB设备,只要该设备能够正确接收和处理信号并满足规范中所规定的性能指标就可以了。我国的卫星数字电视采用了DVB-S标准,地面广播数字电视采用了自主的DTMB标准,有线数字电视传输标准采用了DVB-C 标准。
 DVB-C 标准描述了有线数字电视的帧结构,信道编码和调制。主要用于传送电视中的视频和音频信号。
 有线前端每个部分的功能:
(1)基带接口:该单元将数据结构与信号源格式匹配,帧结构应与包含同步字节的 MPEG-2 TS 流一致。
(2)SYNC1反转和随机化。该单元将依据 MPEG-2 帧结构转换 SYNC1字节;同时为了频谱成形,对数据流进行随机化。
(3)RS编码器。将每一个TS包送入RS编码器进行RS(204,188)信道编码。
(4)卷积交织器。完成深度 I=12 的卷积交织信道编码。
(5)字节变换到 m 比特符号。将字节变换为 QAM 符号。
(6)差分编码。为了获得旋转不变星座图,将每符号两个最高有效位进行差分编码。
(7)基带成形。将差分编码的符号映射到I、Q分量。此外对 I 和 Q 信号进行平方根升余弦滚降滤波。
(8)QAM 调制和物理接口。完成 QAM 调制。之后,它将 QAM 已调制信号连接到有线射频信道。

接收端的功能不再详细叙述。接收端只要按照前端的处理顺序进行逆处理就可以得到基带信号。

 基于Flash的RTMP播放器/推流器才能算得上是RTMP技术中的“正规军”。RTMP本身设计出来就是用于Flash平台之间通信的,而且RTMP最大的优势——“无插件直播”,也是得益于广泛安装在客户端的Flash Player。
  基于Flash的网页播放器相比于其他网页播放器来说最大的优势就是“免插件安装”了,这一点可以很大的提高用户的体验质量。早些时候网络视频(尤其是直播)一般都使用ActiveX控件作为视频播放器,而这些控件并不普及,所以终端用户必须下载相关的插件才能收看节目,因而对很多不熟悉电脑的用户造成了很大的障碍。直到Flash网页播放器的出现,这一障碍才得到了解决。

 -- RTMP Sample Player VideoJS,Video.js官网:http://www.videojs.com/
 注:Video.js是一个基于JavaScript的HTML5视频播放器,本身是开源的。

  RTMP Sample Player VideoJS是基于Video.js的RTMP播放器。其中包含两个播放器:
1.Sample Player VideoJS:HTTP点播网页播放器
2.RTMP Sample Player VideoJS:RTMP网页播放器

 -- RTMP Sample Player Flowplayer,FlowPlayer官网:http://flash.flowplayer.org/
注:FlowPlayer有两个版本:HTML5版本和Flash版本,本文中使用的是Flash版本。

  RTMP Sample Player Flowplayer是基于FlowPlayer的网页播放器。其中包含两个播放器:
Sample Player Flowplayer:HTTP点播网页播放器
RTMP Sample Player Flowplayer:RTMP网页播放器

 -- RTMP Sample Player JWPlayer,JW Player官网:http://www.jwplayer.com
 注:最新版的JW Player似乎不能免费使用RTMP播放功能了,这里使用的是旧版的JW Player

  RTMP Sample Player JWPlayer是基于JW Player的RTMP播放器。其中包含两个播放器:
Sample Player JWPlayer:HTTP点播网页播放器
RTMP Sample Player JWPlayer:RTMP网页播放器

 视频特性TI(时间信息)和SI(空间信息)的计算工具:TIandSI-压缩码流版。基于YUV视频数据的TI和SI计算工具:一个图形界面工具和一个命令行工具。
 目前的TIandSI项目中一共包含4个项目:
TIandSI : 计算YUV数据的TI和SI-图形界面版。
TIandSIcmd : 计算YUV数据的TI和SI-命令行版。
TIandSIpro : 计算压缩码流数据的TI和SI-图形界面版。
TIandSIprocmd : 计算压缩码流数据的TI和SI-命令行版。

 每一帧图像的TI(Temporal perceptual Information)信息和SI(Spatial perceptual Information)信息。TI和SI两个指标取自于ITU BT.1788标准。TI越大,代表视频运动剧烈(时间上变化大);SI越大,代表视频内容复杂(空间上纹理多)。

 1.我的开源视音频项目汇总- https://blog.csdn.net/leixiaohua1020/article/details/42658139
完整的视频处理流程,从外部协议接收下来的数据依次经过解协议,解封装,解码,像素转换,编码,封装:
 协议层(Protocol Layer):该层处理的数据为符合特定流媒体协议规范的数据,例如http,rtmp,file等。
 封装层(Format Layer):该层处理的数据为符合特定封装格式规范的数据,例如mkv,mp4,flv,mpegts,avi等。
 编码层(Codec Layer):该层处理的数据为符合特定编码标准规范的数据,例如h264,h265,mpeg2,mpeg4等。
 像素层(Pixel Layer):该层处理的数据为符合特定像素格式规范的数据,例如yuv420p,yuv422p,yuv444p,rgb24等。

 分辨率:分辨率指的是视频的尺寸。例如常见的分辨率有3840x2160 (4K), 1920x1080 (HD), 1280x720 (720P), 640x360 (360P)等。
 码率:码率是影响视频质量最主要的参数之一。其它条件形同的情况下,码率越大,视频质量越好。例如一个640x360的1Mbps的的视频的质量肯定好于一个640x360的500kbps的视频。但是不同分辨率的视频码率差别很大。例如我们很难断定一个1280x720的1Mbps的视频的质量是否高于一个640x360的500kbps的视频。

  YUV/RGB播放器,既支持YUV又支持RGB的播放器
原版项目地址:https://sourceforge.net/projects/raw-yuvplayer/
修改版源码地址:https://github.com/leixiaohua1020/YUVplayer

猜你喜欢

转载自blog.csdn.net/shareus/article/details/80757971
今日推荐