Course Introduction-1 多媒体信号处理课程介绍
1
多媒体信号处理
Multimedia Signal Processing
3
课程内容
- M. Bosi,《数字音频编码技术与标准导论》
- I. G. Richardson,《H.264和MPEG-4视频压缩》
- 其他讲义
4
什么是多媒体?
- 多媒体是指使用多种媒体形态的组合内容。
- 多媒体包括文字、音频、静态图像、动画、视频或交互式内容的组合。
- 应用:广告、艺术、教育、娱乐、工程、医学、数学、商业等。
什么是信号处理?
- 信号处理是系统工程、电子工程和应用数学的一个领域,处理或分析模拟和数字化信号,表示时间变化或空间变化的物理量。
- 典型操作和应用:
- 信号获取和重建
- 信号压缩(源编码)
- 特征提取,如图像理解
- 品质改进,如降噪、图像增强等
7
本课程的内容
- 多媒体信号处理和压缩导论
- 音视频容器格式
- 010编辑器
8
数据压缩
- 数据压缩,也称源编码或比特率减少,是使用比原始表示更少的比特来对信息进行编码的过程。
- 无损压缩通过识别和消除统计冗余来减少位。无损压缩不会丢失任何信息。
- 有损压缩通过识别和消除不必要的信息来减少位数。
9
数字容器格式
- 容器或封装格式是一种元文件格式,其规范描述了不同的数据元素和元数据如何在计算机文件中共存。
- 容器文件用于识别和交错不同的数据类型。
- 容器格式可以支持多个音频和视频流、字幕、章节信息和元数据,以及播放各种流所需的同步信息。
10
数字容器格式
- 容器格式的各部分有不同的名称:
- RIFF和PNG中的“块”
- QuickTime/MP4中的“原子”
- MPEG-TS中的“包”(来自通信术语)
- JPEG中的“段”
- 一些容器专用于音频:
- AIFF(广泛用于Mac OS平台的IFF文件格式)
- WAV(广泛用于Windows平台的RIFF文件格式)
- XMF(可扩展音乐格式)
- 其他容器专用于静态图像:
- TIFF(带有相关元数据的Tagged Image File Format静态图像)
11
数字容器格式
- 其他灵活的容器可以装载多种音频和视频,以及其他媒体:
- 3GP(许多移动电话使用;基于ISO基本媒体文件格式)
- ASF(Microsoft WMA 和 WMV的容器)
- AVI(标准Microsoft Windows容器)
- Flash Video(FLV, F4V)(Adobe Systems的视频和音频容器)
- Matroska(MKV)(不限于任何编解码器或系统)
- MJ2 – Motion JPEG 2000文件格式
- QuickTime文件格式(苹果标准QuickTime视频容器)
12
数字容器格式
- 其他灵活的容器可以装载多种音频和视频,以及其他媒体(续):
- MPEG程序流(MPEG-1和MPEG-2基本流的标准容器)
- MPEG-2传输流(又称MPEG-TS)(数字广播和在不可靠媒体上传输的标准容器;在蓝光影碟视频中也使用)
- MP4(MPEG-4多媒体组合的标准音频和视频容器)
- Ogg(Xiph.org音频格式Vorbis和视频格式Theora的标准容器)
- RM(RealMedia; RealVideo和RealAudio的标准容器)
13
010编辑器
- 010 editor是一个具有二进制模板技术的专业文本和十六进制编辑器。
- 文本编辑器:编辑文本文件、XML、HTML、Unicode和UTF-8文件、C/C++源代码等。无限撤销和强大的编辑与脚本工具。
- 十六进制编辑器:无与伦比的二进制编辑性能。编辑任意大小的文件。使用强大的二进制模板技术来理解二进制数据。
- 磁盘编辑器:查找和修复硬盘、内存卡、U盘、CD-ROM等上的程序。
- 进程编辑器:调查和修改进程的内存。
14
010编辑器
15
详细主题
- 压缩简介
- 音频处理与压缩:WAVE、ADPCM、MP3和AAC
- 图像处理与压缩:JPEG、GIF
- 视频处理与压缩:H.264
- 音视频流容器:AVI、MP4等
- 010编辑器
16
- VCD
- DVD
- 数码相机
- 视频录像机
- MP4播放器
- 在线电影
17
音频格式
- 无压缩音频格式
- 无损压缩格式
- FLAC、Monkey’s Audio(APE扩展名)、Shorten、WMA无损
- 有损压缩格式
18
音频格式(续)
19
图像格式
- RAW
- BMP
- JPEG
- JPEG2000
- GIF
- PNG
20
视频格式
- MPEG-1
- MPEG-2
- MPEG-4视觉/AVC
- H.261
- H.263
- H.264
21
视频压缩标准发展历史
标准 发布者 流行实现
1990 H.261 ITU-T 视频会议、视频电话
1993 MPEG-1 part 2 ISO、IEC 视频CD
1995 H.262/MPEG-2 Part 2 ISO、IEC、ITU-T DVD视频、蓝光光盘、数字电视广播
1996 H.263 ITU-T 视频会议、视频电话、移动电话视频(3GP)
1999 MPEG-4 Part 2 ISO、IEC 互联网视频(DivX、Xvid等)
2003 H.264/MPEG-4 AVC ISO、IEC、ITU-T 蓝光、HD DVD数字电视广播
22
音视频容器
- AVI
- MP4
- ASF
- FLV
- SWF
- 3GP
- RMVB
- Quicktime
23
AVI Walk Through-2 AVI文件演练
Windows位图数据
- 数据由表示位图的连续行或扫描线的字节数组组成。
- 每个扫描线由表示扫描线中的像素的连续字节组成,从左到右的顺序。
- 表示一个扫描线的字节数取决于位图的宽度。
Windows位图数据
- 如果需要,扫描线必须用0填充以在32比特边界结束。
- 这意味着宽度为8比特、20比特或30比特的单色位图将具有相同的扫描线大小:32比特。
- 宽度为40比特的单色位图的扫描线大小为64比特。
- 位图中的扫描线从下到上存储。
- 这意味着数组中的第一个字节表示位图左下角的像素,最后一个字节表示右上角的像素。
灰度位图
- 每像素使用8比特(即1字节)
- 每个字节表示256阶灰度。
- 白色是“ff”
- 黑色是“00”
- 中间的数字代表从白色到黑色的几个灰度阶。
24位彩色位图
- 每像素使用24比特(即3字节)
- 回想一下,信息头的biBitCount字段将为24。
- 每个像素有3字节分别表示红色、绿色和蓝色。
- 白色是“ffffff”
- 黑色是“000000”
- 红色是“ff0000”
- 绿色是“00ff00”
- 蓝色是“0000ff”
8位色位图
- 每像素使用8比特。只能有256种颜色
- 使用调色板,称为调色板,来选择要使用的颜色
- 在一个位图中,颜色0可以是“浅橙色”,颜色1可以是“深棕色”
- 在另一个位图中,颜色0可以是“浅黄色”,颜色1可以是“深红色”。
- 颜色表位于信息头和数据之间
颜色表
重新看灰度位图
- 这实际上是8位色位图的特例。
- 存在一个颜色表,其中条目0指向黑色,条目255指向白色,中间的条目指向灰度。
- 对于给定大小的图像,8位灰度位图和8位彩色位图的大小相同。
WAV格式
- WAV文件格式是用于存储数字音频(波形)数据的简单文件格式。
- 它支持各种位分辨率、采样率和音频通道。
- 此格式在Windows平台上很流行,并广泛用于处理数字音频波形的程序中。
WAV格式
- WAV文件是许多不同类型chunk的集合。
- 其中包含必需的格式(“fmt”)chunk,其中包含描述波形的参数,例如其采样率。
- 还需要包含实际波形数据的Data(“data”)chunk。所有其他chunk都是可选的。
WAV格式
- 使用WAV的所有应用程序都必须能够读取2个必需的chunk,并可以选择性地忽略可选的chunk。
- 复制WAV的程序应该复制WAV中的所有chunk,即使它选择不解释这些chunk。
- WAV文件内chunk的顺序没有限制,格式chunk必须在Data chunk之前。
- 注意,格式chunk可能不是第一个chunk。
WAV格式
- 所有数据以8位字节形式存储,以小端格式排列。
- “数据块”与“块数据”不同。
- “数据块”具有“块大小”和一些“块数据”。
- 每个其他chunk也是如此。
AVI格式
- AVI是Microsoft开发的另一种资源互换文件格式(RIFF)。
- 代表音频视频交织
- 该格式在文件中交织视频和音频数据(即视频数据段之后紧跟音频数据段)。
AVI格式
- 数据块可以直接驻留在“movi”列表中,或者它们可能被分组在“rec”列表内。
- 标识每个数据块的FOURCC由两位数的流编号后跟定义块中信息类型的两字符代码组成。
- “db”:未压缩视频帧
- “dc”:压缩视频帧
- “wb”:音频数据
Audio coding basics-3 音频编码基础
编码器?
数字音频编码器是一个装置:
- 将模拟音频信号作为输入
- 将其转换为一个方便的数字表示(编码器)
- 之后,我们可以存储、处理或传输它
- 当我们想要播放音频时,我们将数字数据转换回模拟信号(解码器)
解码
音频编码目标
- 保真度:在音频解码器端最大化感知音质(最小化失真)。
- 数据速率:最小化表示原始音频信号所需的数字数据量。
- 复杂性:最小化计算复杂度。
- 延迟:最小化编码延迟。
4
5
最简单的编码器–PCM
- 量化是有损过程,原始信号中包含的一些信息会丢失。
- 量化过程中使用的离散值数量越高,输出信号将越精确地逼近输入信号。
采样
量化
反量化
插值
6
光盘(CD)
- 在80年代中期由索尼和飞利浦推出。
- 音频信号以立体声信号的形式进行数字表示,样本时间间隔为0.023ms,或采样频率为44.1kHz。
- CD中的每个样本的位数R为16位。这种精度允许使用65536个离散电平来表示音频样本幅值。
- CD的数据速率为:
44.1 * 16 * 2 = 1.4112 Mb/s
7
WAVE格式
- 使用RIFF结构将文件内容分组为独立chunk:
- 每个chunk由头部和数据字节组成。
- 头部指定chunk数据字节的类型和大小。
- 某些类型的chunk可包含子chunk。
- RIFF文件chunk必须字对齐。
8
格式块(WAVEFORMATEX)
- 格式(fmt)块描述波形数据的基本参数,如采样率、比特分辨率和通道数。
typedef struct {
WORD wFormatTag;
WORD wChannels;
DWORD dwSamplesPerSec;
DWORD dwAvgBytesPerSec;
WORD wBlockAlign;
WORD wBitsPerSample;
} FormatChunk;
9
wFormatTag
WAVE_FORMAT_PCM 0x0001
WAVE_FORMAT_ADPCM 0x0002
WAVE_FORMAT_ALAW 0x0006
WAVE_FORMAT_MULAW 0x0007
WAVE_FORMAT_MP3 0x0055
10
数据块
- 数据块包含实际的采样帧(即波形数据的所有通道)。
typedef struct {
char chunkID[4];
DWORD chunkSize;
BYTE waveformData[];
} DataChunk;
11
交错立体声波形样本
- 多通道样本以交错波形数据存储;
- 8位样本使用无符号数据表示,而其他样本使用有符号表示。
13
WAVEFORMATEXTENSIBLE
- 用于具有两个以上通道或高于16位分辨率的音频数据
- wFormatTag = FFFE
- cbSize = 24
typedef struct {
WAVEFORMATEX Format;
WORD wValidBitsPerSample;
DWORD dwChannelMask;
GUID SubFormat;
} WAVEFORMATEXTENSIBLE
14
- wValidBitsPerSample: 信号中精度的有效位数。
- wSamplesPerBlock: 每个压缩音频数据块中包含的样本数。
- dwChannelMask: 指定流中通道分配给扬声器位置的位掩码。
- SubFormat: 为每种波形数据定义ID。
WAVEFORMATEXTENSIBLE
15
dwChannelMask
扬声器位置 标志位
SPEAKER_FRONT_LEFT 0x1
SPEAKER_FRONT_RIGHT 0x2
SPEAKER_FRONT_CENTER 0x4
SPEAKER_LOW_FREQUENCY 0x8
SPEAKER_BACK_LEFT 0x10
SPEAKER_BACK_RIGHT 0x20
16
示例:5.1格式的6个通道
waveFormatPCMEx.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
waveFormatPCMEx.wChannels = 6;
waveFormatPCMEx.dwSamplesPerSec = 48000L;
waveFormatPCMEx.dwAvgBytesPerSec = 864000L;
waveFormatPCMEx.wBlockAlign = 18;
waveFormatPCMEx.wBitsPerSample = 24;
17
示例:5.1格式的6个通道
waveFormatPCMEx.cbSize = 22;
waveFormatPCMEx.wValidBitsPerSample = 20;
waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
19
更复杂的编码器
- 心理音频学研究表明,理想情况下,中频范围(2至5kHz)的音频样本需要18-20位数进行描述。
- 在CD数据速率或更低速率下,我们能否产生感知透明的音质?
22
量化
- 中值型量化器输出为零,非中值型量化器不为零。
- 如果允许R位来表示最大2R个不同的代码/样本,则中值型量化器允许2R-1个不同的代码,而非中值型量化器允许2^R个代码。
- 一般来说,中值型量化器的结果更好。
23
均匀量化
- 将输入幅值的等宽范围映射到每个代码上。
- 为了定义输入范围及量化器本身,需要三个信息:
- 量化器是中值型还是非中值型;
- 最大非过载输入值x_max;
- 描述代码所需的位数。
- 对于非中值型量化器,R位允许我们将输入范围设置为:
- 对于中值型量化器:
24
非中值型量化器
二位均匀非中值型量化器
25
非中值型量化器
量化和反量化过程
26
中值型量化器
27
中值型量化器
量化和反量化过程
28
非均匀量化
- 均匀量化器的最大舍入误差等于箱宽的一半(△/2)。
- 然而,相对于非常低幅值的信号,这个误差可能会很大。
- 由于舍入失真的感知更与相对误差相关,这意味着相对于高功率输入信号,均匀量化器在较低功率输入信号上的表现明显更差。
- 为了克服这个问题,可以使用非均匀量化。
29
非均匀量化
用于非均匀量化的组扩技术
32
舍入误差
- 舍入误差来自将输入信号幅值范围映射到单个代码上。
- 将输入幅值范围映射到单个代码上的范围越宽,舍入误差越大。
- 在均匀量化器和高速率量化的情况下,我们有
33
过载误差
- 过载误差来自于对量化器而言幅值太高的信号。
- 即大于量化器最大幅值x_max的输入幅值引起的误差。
- 过载误差往往以突发的形式出现(削波),其听觉效应非常明显。
- 我们希望x_max足够大以避免削波,然而,这会引入较大的舍入误差。
- 量化器设计需要在减少这两种误差之间实现平衡。
34
无损压缩——熵编码
- 除了量化之外,我们还可以通过熵编码的思想进一步减少比特率。
- 在熵编码中,我们将量化码转换成使用每个代码可变位数的不同符号表示。
- 我们使常见代码变短,以使平均比特率降低。
- 这需要估计每个可能代码的概率。
35
示例
- 考虑一个2比特量化信号,量化码为[00]、[01]、[10]、[11]。
- 假设这些代码的概率分别为70%、15%、10%、5%。
- 考虑使用映射:[00]->[0]、[01]->[10]、[10]->[110]、[11]->[111]。
- 对于该信号,这种新映射的平均比特率更低:
R = 0.71 + 0.152 + 0.15*3 = 1.45 比特/代码
36
熵
- 熵表示编码极限,可以表示为:
- 当我们非常确定接下来会出现哪个代码时,熵将很低。
- 当我们对将出现哪个代码知之甚少时,熵将很高。
37
作为p的函数的熵
- 对于2代码符号,熵等于:
H(x) = -plog2p – (1-p)log2(1-p)
- 当p=0或1时,熵为零。我们可以确定接下来的代码,不需要发送任何比特。
- 当p=0.5时,熵等于1,这意味着需要1比特来区分两个结果。
38
- 对于其他概率,存在这样的编码方案,它们可以在平均每个代码符号上使用少于1比特对单比特代码进行编码。
- 熵的最大值出现在所有代码符号同等可能的情况下。在这种情况下,我们不会从采用熵编码中获得任何节省。
- 示例:2^R个均等可能代码符号的熵。
作为p函数的熵
39
霍夫曼编码
- 霍夫曼编码用于对传真、ASCII文本等数据进行编码或压缩。
- 它是David A. Huffman于1952年提出的“构造最小冗余码的方法”。
- 霍夫曼编码是统计编码的一种形式,是一种最优的无记忆码C,使得C的平均码字长度最小化。
- 码字长度根据使用频率不同而变化,用于更频繁的字符的码字长度更短。
40
霍夫曼编码算法
a) 将两个概率最小的符号合并为一个符号,其概率等于两个最小概率之和。
b) 重复a),直到只剩一个符号。
41
霍夫曼编码算法(续)
c) 将从每个非终端节点发出的两条分支(叶子)标记为0和1。符号xj的码字是从根到对应终端节点的二进制序列。
42
- 霍夫曼编码过程不是唯一的。标记分支的不同方法和合并符号的不同选择会产生不同的前缀码。
- 如果符号分布不均匀,霍夫曼编码可以减少固定位数编码的位数。
- 霍夫曼码中每个样本的平均位数在熵的一个比特之内:
熵 ≤ 霍夫曼 ≤ 熵 + 1
霍夫曼编码算法(续)
43
WAVE MS-ADPCM
44
DPCM
- DPCM或差分PCM:编码器在PCM基线上增加了一些功能,基于对样本信号的预测。
- 在DPCM中,我们不直接传输原始PCM样本,而是传输原始样本与基于之前传输样本的预测值之间的差异,
diff = xn+1 - xp_n+1
例如,xp_n+1 = axn + bxn-1
45
MS-ADPCM
- diff通常很小。为了节省存储和传输空间,我们必须将其表示限制在一定范围内,例如从16位减少到4位。
- 然而,我们不能总是保证差异总是很小,因为传输信号中有时存在明显变化。
- 为了解决这个问题,引入了可变因子iDelta。如果diff很大,iDelta就很大,反之亦然。
- 然后我们定义一个新差异 iErrordata = diff / iDelta。
- 通过这种方式,新差异将变得稳定。
好的,我重新翻译第46页的内容:
46
- iErrordata以4比特保存,称为“半字节”。半字节的取值范围是从-8到7。
- 每次生成新的iErrordata时,iDelta根据自适应表进行调整。
iDelta = iDelta * 自适应表[(unsigned)半字节]/256;
const int 自适应表[] = {
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
47
MS-ADPCM WAVEFORMAT
typedef struct adpcmcoef_tag {
int16 icoef1; // 预测系数
int16 icoef2; // 预测系数
} adpcmcoefset;
typedef struct adpcmwaveformat_tag {
waveformatex wfxx;
word wsamplesperblock; // 每块样本数
word wnumcoef; // 预测系数集数量
adpcmcoefset acoeff[wnumcoef];
} adpcmwaveformat;
48
dwSamplesPerSec wBlockAlign
8k 256
11.025k 256
22.05k 512
44.1k 1024
Wsamplesperblock
= (wBlockAlign-7*wChannels)8/(wbitspersamplewChannels)+2
MS-ADPCM WAVEFORMAT
49
acoeff:预测系数。可以解释为8.8有符号固定点值。
有7个预设系数集,必须以以下顺序出现。
系数集 系数1 系数2
0 256 0
1 512 -256
2 0 0
3 192 64
4 240 0
5 460 -208
6 392 -232
编码软件可以添加更多系数,但前7个必须始终相同。
MS-ADPCM WAVEFORMAT
50
MS-ADPCM WAVEFORMAT
- 在MS-ADPCM波形文件中,除了格式块和数据块之外,还有另一个称为fact块的块,用于存储样本长度。
- 在数据块中,数据以块的形式存储,一个接一个。
- 块有三个部分,头部、数据和填充。
51
块头
typedef struct adpcmblockheader_tag {
byte bpredictor[nchannels];
int16 idelta[nchannels];
int16 isamp1[nchannels];
int16 isamp2[nchannels];
} adpcmblockheader;
字段说明
bpredictor: 索引acoef数组以定义用于编码此块的预测器。
idelta: 使用的初始delta值。
isamp1: 块的第二个样本值。
isamp2: 块的第一个样本值。
52
示例
53
示例
54
编码过程
对每个通道的每个块:
- 确定用于该块的预测器。
- 确定该块的初始idelta。
- 写出块头。
- 编码并写出数据。
55
块头写出
一旦选择了预测器和初始量化值,块头的写入如下:
- 写出每个通道的预测器选择。
- 写出每个通道的初始idelta(量化尺度)。
- 写出每个通道第二个样本(isamp1)的16位PCM值。
- 最后写出每个通道第一个样本(isamp2)的16位PCM值。
然后可以编码块的其余部分。注意,由于头部包含前两个样本,因此第一个编码值将是块中的第3个样本。
56
编码过程
编码块中剩余样本时,使用以下步骤:
- 从前两个样本预测下一个样本。
lpredsamp = ((isamp1 * icoef1) + (isamp2 * icoef2)) / 固定点系数基
- 生成并防止溢出/下溢的4比特有符号误差delta。
ierrordelta = (sample(n) - lpredsamp) / idelta
将ierrordelta削减至[-8, 7]的范围内。
- 然后写出半字节ierrordelta: putnibble(ierrordelta)。
57
编码过程
4) 将“预测误差”加到预测的下一个样本上,并防止溢出/下溢错误。
lnewsamp = lpredsample + (idelta * ierrordelta);
将数据钳制为short类型(16位)
5) 调整用于计算“预测误差”的量化步长。
idelta = idelta * 自适应表[ierrordelta] / 固定点自适应基
如果idelta太小,使其为最小允许值。
6) 更新前一个样本的记录。
isamp2 = isamp1;
isamp1 = lnewsample.