有一次老大给我分配个任务,你给我们做个流媒体服务器,将YUV和PCM编码h264和aac,然后复用成一个合适的格式通过服务器转发过去……,说完之后,我发现我根本就听不懂他在说什么?然后再细讲了之后,我还是没弄明白。当时我对视频处理的唯一认识就是——视频是由一张一张图片连续播放形成的。就我这水平,也敢叫我做这个?反正老板让我干,我也只有干了。然后就去各种查阅书籍和网站、博客,最后自己用时5个多月,使用Live555和ffmpeg弄出了一套,真是难。在此期间,要是有人带我入门,我想还能快很多,当时是连们都找不到呀,虽然现在也不弄视频处理了,但还是把期间的感悟记下来,希望能帮助和我一样的小白。我只自学了半年音视频处理,应该还有很多不对的地方,我只是说出我的理解,水平有限,希望大家谅解。
我们先来说音视频是如何制作出来的,首先我们会采集原始的音频数据,然后将音频数据编码成音频流,采集视频原始数据(就是一张张序列图片),然后将视频数据编码成视频流,然后将音频流和视频流复用成一个音视频格式(其实就是按照某种方式将他们放在一起),如flv,mp4,rmvb,avi,ts等,过程大体就是这样的。
介绍一下我理解的音视频处理的的一些概念——
编码:将原始数据变成相关的流的操作,如YUV422变成h264等,PCM变成aac等。
解码:将相关的流变成原始数据的操作。
复用:将流封装成音视频格式,如将h264和aac封装成flv等。
解复用:将音视频格式中的流解出来。
音频介绍——我在工作中,原始的音频数据暂时只接触到PCM数据(不晓得还有没有别的),PCM数据有点像脉冲数据,由于音频数据是使用波来记录的,采集音频数据的时候,我们将它量化,类似下图这样。
所以确定一个音频原始数据的参数有,它的横坐标——采样率(一秒钟内分割的份数),它的纵坐标——采样格式(用多少个单位来衡量纵坐标),以横坐标增长的方向,按顺序写下对应纵坐标的数值,就是音频的原始数据了。在FFMPEG中,采样率对应sample_rate, 采样格式对应AVSampleFormat,由于为了增加立体效果,就是说人的耳朵可以听音确定音频的来源,所以有了声道的概念,一个完整的音频数据有可能不止一个声道,对应channels。所以一个完整的音频数据参数有:采样率,采样格式,声道数。
采样率有22.05KHz、44.1KHz、48KHz等格式,确定了一秒钟内,声音采样的数量;
采样格式有(摘抄至ffmpeg的libavutil\samplefmt.h)
AV_SAMPLE_FMT_NONE = -1,
AV_SAMPLE_FMT_U8, ///< unsigned 8 bits
AV_SAMPLE_FMT_S16, ///< signed 16 bits
AV_SAMPLE_FMT_S32, ///< signed 32 bits
AV_SAMPLE_FMT_FLT, ///< float
AV_SAMPLE_FMT_DBL, ///< double
AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar
AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar
AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar
AV_SAMPLE_FMT_FLTP, ///< float, planar
AV_SAMPLE_FMT_DBLP, ///< double, planar
AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically
他们决定了数据的振幅和数据的存放格式,后缀没有P是非平面型,有P的是平面型,平面型与非平面型只有在多个声道的时候才能有意义,例如有两个声道,A和B,非平面型在一个数据块中放数据是这样的A0A1A2A3.....B0B1B2B3...,而平面型是这样的A0B0A1B1A2B2A3B3.....。
声道数决定了一个音频数据有几个声道,每个声道的采样率和采样格式都应该是一样的。
视频介绍——视频原始数据就是一张一张的序列图,描述原始数据的格式有多种,如RGB系列和YUV系列,他们都是不同的颜色空间,但都差不多,现在只介绍YUV,因为ffmpeg中用的最多。一张图片一般是一个矩形块,有宽和高,分别代表图片在横纵坐标上的像素点的数量,YUV系列中有很多种,如YUV444,YUV422,YUV420等等,它们描述了如何采集数据,我们只介绍YUV444,YUV444代表每个像素点由Y、U、V三个分量来表示,它们所占的分量是一样的。那么视频数据参数就有三个宽,高,采样格式,在ffmpeg中就是width、height和AVPixelFormat。
宽和高定义了图片的大小,决定了图片像素点的数量。
采样格式决定了数据在一个块中的存储格式,它们也分是否为平面型,和音频数据差不多。
现在我们将原始数据编码后变成相应的流数据,在复用成音视频格式,就可以播放了。但是这里有一点,在一个音视频文件中,只有一个视频流,而可以有多个音频流,多个音频流就是音轨的概念了。
在了解这些参数后,我们学习音视频处理,才能更快的理解其中的过程,否则就是知道别人这么做了,却不知道为什么要这样做,学习起来就很慢,我将自己的理解说出来,希望帮助到入门的人。在学习的过程中,没有专门的资料,我就是看源码的例子,看别人的博客,感觉还是很艰辛的,毕竟这个还是太复杂了。最好的资料就是ffmpeg的源码中自带的例子和Live555中自带的例子,推荐一个博客,我就是按照他的博客学来的——雷霄骅,他的ffmpeg系列写的不错。