笔记说明

这是 USTC 软件学院 - 苏州 2023 秋季学期课程笔记(互联网版本)。本着藏着掖着发霉不如对外分享发光的精神,现将其公布。原本的笔记 是卡片式的,为了便于互联网传播与收藏,现整合到同一篇文章当中。

这篇笔记的特点在于:

  • 有机涵盖 PPT 内容,精心编排,存在本人的理解消化过程
  • 有重点标识、考点标识、实际考察标识
  • 存在一些习题以供复习
  • 部分图片为作者手工制作,便于知识的理解和掌握

本笔记存在以下的符号定义:

  • 🔺表示老师经常在课上提,为考试重点。
  • 红色字体部分 实际考察内容(指的是 2023 秋季学期考试)。

本笔记的内容来源:

  • 主要来源:课程 PPT。注意,笔记的章节顺序是经过梳理调整的,顺序不一定与 PPT 讲授过程相符。
  • 参考补充:秃头学长的笔记,补充了一些练习题。

笔记共分为 12 个章节。由于作者水平、精力与时间有限,「时频映射」的两个 Slices 以及「H.264」的 PPT 仅记录部分关键内容,内容也较粗糙(打上了「落叶🍂」标记)。由于当时考试不考「MP4」,所以笔记里也不包含这个章节。

临考前老师列出了多媒体信号处理课程知识点(详看 本课知识点 小节)。在后续的章节中这些知识点将以「考点」标注,如下示例:

考点 X:[考点内容]

如果你有以下需求:

  • 查看笔记源码
  • 想导入到自己的双向笔记库中
  • 习惯在 Github 上阅读
  • 为笔记做贡献

可以访问 本项目

Readme Card

任何贡献都 Welcome!🎉🎉如果你有更新本笔记的想法(或者仅仅是纠错)可以通过邮件或评论区联系我!同时也期待你的 star~


导论(格式概览)

什么是多媒体?包括文字、视频、静态图像、动画、交互内容。应用于广告、艺术、教育

什么是信号处理?

  • 系统工程、电子工程和应用数学领域
  • 操作、分析模拟信号和数字信号
  • 代表时空变化的物理量
  • 典型的操作和应用:信号获取与重构、信号压缩、特征提取、质量提升(降噪,图像增强等)

🔺 数据压缩

无损压缩:识别并消除统计冗余,无信息丢失

  • LZW、Huffman coding(哈夫曼编码)、Arithmetic coding(算数编码)

有损压缩:识别并移除不重要的信息

  • Quantization(量化)、JPEG

数字容器格式 Digital Container Format

考点 1:音频、图像和视频的格式与容器

容器文件用做识别并交织不同数据形式。

容器格式部件的不同名称:

  • RIFF、PNG:chunks 块
  • QuickTime/MP4:atoms 原子
  • MPEG-TS:packets 包 (来自通信术语)
  • JPEG:段

🎵 音频独有的容器:

  • AIFF(IFF 文件格式,在 Mac OS 平台上广泛使用)
  • WAV(RIFF 文件格式,在 Windows 平台上广泛使用)
  • XMF(可扩展音乐格式)

🖼 静态图像独有的容器:

  • TIFF (Tagged Image File Format,标记图像文件格式) 静止图像和关联的元数据。

其他可以接纳多种音视频类型或其他媒体的容器:

  • 3GP (在许多手机中使用;基于 ISO 基本媒体文件格式,是 MP4 的变种)
  • ASF(Microsoft WMA 和 WMV 的容器)
  • AVI(标准的 Microsoft Windows 容器)
  • Flash Video (FLV, F4V) (来自 Adobe Systems 的视频和音频容器)
  • Matroska (MKV) (不限于任何编解码器或系统)
  • MJ2-Motion JPEG 2000 文件格式.
  • QuickTime File Format(Apple 的标准 QuickTime 视频容器)
  • MPEG program stream (standard container for MPEG-1 and MPEG-2 elementary streams)
  • MPEG-2 transport stream (a.k.a. MPEG-TS) (standard container for digital broadcasting and for transportation over unreliable media; used also on Blu-ray Disc video)
  • MP4 (standard audio and video container for the MPEG-4 multimedia portfolio)
  • Ogg (standard container for Xiph.org audio format Vorbis and video format Theora)
  • RM (RealMedia; standard container for RealVideo and RealAudio)

其他:SWF、RMVB

音频格式 🎵

非压缩的音频格式:WAVE、AIFF、Raw PCM

无损压缩格式:FLAC、Monkey’s audio (APE extension), Shorten, WMA Lossless

有损压缩格式:MP3, AAC, WMA, AC3

image.png

图像格式 🖼

RAW、BMP、JPEG、JPEG2000、GIF、PNG

视频格式 🎞

MPEG-1、MPEG-2、MPEG-4 visual/AVC、H.261、H.263、H.264

  • Advanced Video Coding(ISO)=H.264(ITO)

tea:H 开头一般和电信相关

视频压缩标准的历史详看 视频编码 小节。

BMP、WAV、AVI 格式

Windows Bitmap🖼

文件结构

考点 4:Windows Bitmap 文件结构

image.png

bfOffBits:是从位图文件头到位图数据的偏移量。即位图信息头 (BITMAPINFOHEADER)+ 全部颜色对照表 (RGBQUAD) 的字节数。

数据由代表位图的连续行或扫描线的字节值数组组成。每条扫描线由连续的字节组成,这些字节按从左到右的顺序代表扫描线中的像素。

代表扫描线的字节数取决于位图的宽度。

扫描线以 32bit 为边界,必须用 0 填充至末尾。

  • 这意味着宽度为 8 位,20 位或 30 位的单色位图将具有相同的扫描线大小:32 位
  • 40 位宽的单色位图将具有 64 位的扫描线大小。

Bitmap 中的扫描线是自底向上存的

  • 数组中的第一个字节代表 bitmap 左下角
  • 数组中的最后一个字节代表 bitmap 右上角

位图种类

灰度位图

  • 每个像素使用 8 个比特(1 字节)。Info Header 中的 biBitCount 将为 8。
  • 每个字节代表 256 种灰度阴影。白色为 FF,黑色为 00
  • 实质上是 8-bit 彩色位图的特例。存在一个颜色表,其中条目 0 指向黑色,条目 255 指向白色,而介于两者之间的条目指向灰色阴影。对于一个给定大小的图像来说,8-bit 灰度位图和 8-bit 彩色位图是一样的

24-Bit 彩色位图

  • 每个像素使用 24 个比特(3 个字节)。Info Header 中的 biBitCount 将为 24。
  • 每个像素 3 个字节代表红绿蓝。白色 FFFFFF,黑色 000000,红色 FF0000,绿色 00FF00,蓝色 0000FF

8-Bit 彩色位图

  • 每个像素使用 8 个比特,只有 256 种颜色,通过调色板实现
  • 颜色表在 info header 和 Data 之间,每一对含有 4 个字节(R, G, B, 0x0)

颜色表:

image.png

WAV 格式 🎵

考点 5:WAVE 格式
考点 8:列出一个块的组件

WAV 是存储数字音频(waveform)的简单文件格式,使用了 RIFF 结构将文件内容分为不同的块(chunk)。

  • 每个块均由标头和数据字节组成。
  • Header 指定块数据字节的类型和大小。

它支持各种 bit 分辨率、采样率和音频通道

流行于 Windows 平台,广泛应用于处理数字音频波形程序中

image.png

image.png

所有使用 WAV 的应用必须能够读取两个必要块(fmt、data),并且可以有选择的忽略可选块。

程序复制一个 WAV,应该复制 WAV 中所有的块,即使有一些块最后不会被解释

次序要求:在 WAV 文件中,除了 Format 块必须在 Data 块前外,块的顺序没有限制

注意,format 块也许不是第一个块。一个 WAV 文件通常有三个 chunk 以及一个可选 chunk,其在文件中的排列方式依次是:

  1. RIFF chunk
  2. Format chunk
  3. Fact chunk(附加块,可选)
  4. Data chunk

所有的数据都以 8 位字节存储,以小端形式存于字节中

「块(的)数据」和「数据块」不是一个概念:数据块有「块大小」和一些「块数据」,其他所有块也是如此。

组成

WAV 组成:不同类型的 chunk 的集合。每个块包含头及数据,头指定了块数据的类型和大小,一些类型的块可能含有子块。RIFF 文件块必须以 2 个字节(1 word)对齐。

【必含】fmt 块

fmt 块,采样格式,包含描述波形的参数,比如采样率、位分辨率和通道数

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef struct {
ID chunkID; // 块的标识。总是「fmt 」注意末尾有空格。
long chunkSize; // 块的大小(除去chunkID、chunkSize)
short wFormatTag; // 存储数据时使用的压缩方法
unsigned short wChannels; // 音频的通道数。 1:单声道; 4:四通道
unsigned long dwSamplesPerSec; // 采样率。标准:44.1KHZ 48KHZ 32KHZ 22.05KHZ 96KHZ
unsigned long dwAvgBytesPerSec; // 每秒播放多少字节,用于估计RAM需要的大小。
// 其值应等于 dwSamplesPerSec * wBlockAlign的上取
unsigned short wBlockAlign; // 采样帧的大小(字节)
// 其值等于 wChannels * (wBitsPerSample / 8) 的上取
// 例如:
// 3个未压缩的通道组成一个块,每个通道2个字节,则Block align=6
unsigned short wBitsPerSample; // 采样点的位分辨率
unsigned short cbSize; // Size of the extension,扩展字段的长度
// 也许有额外的域, 取决于 wFormatTag
} FormatChunk;
🔺wFormatTag 值 含义
0x0001 WAVE_FORMAT_PCM 未压缩的数据
0x0002 WAVE_FORMAT_ADPCM
0x0006 WAVE_FORMAT_ALAW (电话格式)
0x0007 WAVE_FORMAT_MULAW (电话格式)
0x55=85 WAVE_FORMAT_MP3
WAVEFORMATEXTENSIBLE 扩展的 WAVE 格式块
1
2
3
4
5
6
7
8
9
10
11
typedef struct {
WAVEFORMATEX Format;
union {
WORD wValidBitsPerSample; // 信号精度的比特数
// 假设使用24bit,但只前20位有效,则wValidBitsPerSample=20
WORD wSamplesPerBlock; // 一个音频压缩块数据的样本数
WORD wReserved;
} Samples;
DWORD dwChannelMask; // 指定流中通道到扬声器位置的分配的位掩码
GUID SubFormat; // 对每一个波形数据类型定义的 ID。例如WMA中不同压缩方式。
} WAVEFORMATEXTENSIBLE

位掩码 dwChannelMask:

image.png

用于超过 2 通道或 16 分辨率的音频数据

  • wFormatTag = FFFE(-2)
  • cbSize = 24

以 6 通道 5.1 格式为例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WAVEFORMATPCMEX waveFormatPCMEx;
// FormatChunk
wFormatTag = WAVE_FORMAT_EXTENSIBLE; //FFFE
wChannels = 6;
dwSamplesPerSec = 48000L;
dwAvgBytesPerSec = 864000L; // nBlkAlign * nSamp/Sec = 18 * 48000
wBlockAlign = 18;
wBitsPerSample = 24; // Container has 3 bytes
cbSize = 22;
// 以下是拓展的域
wValidBitsPerSample = 20; // Top 20 bits have data
dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
// SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
// SPEAKER_FRONT_CENTER |SPEAKER_LOW_FREQUENCY |
// SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT
SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM

【必含】data 块

音频数据,包含实际波形数据,比如所有通道的数据波形

1
2
3
4
5
typedef struct {
ID chunkID;
long chunkSize;
unsigned char waveformData[];
} DataChunk;

交错立体声波样本:多通道采样存储于交错的波形数据中;8bit 样本采用无符号数据表示,其他样本使用有符号数据表示。

对于多声道声音,每个声道的单个采样点是交错的。一组交错的采样点称为一个采样帧。

image.png

假设存在两个通路,先存放 time1 的左通道和右通道数据,再存放 time2,以此类推。

其他

fact 块(详见 音频编码基础 小节 的 ADPCM 章节)、cue 块

AVI 格式 🎵🎞

考点 3:AVI 容器

AVI 是另一种 RIFF,由微软开发

音视频交织,即视频段数据紧接音频数据。这允许媒体播放器以块来读数据而不是文件整体

image.png

image.png

注意 AVI 是 Wave 格式,必须以两个字节(1 word)对齐,填充。解码时不需要考虑填充的数据。

索引目的:为了支持随机访问

考点 6:解释 FOURCC 中 “00dc”,“vids” 等标签的意思

🔺流列表中的四字节码:

  • vids:video stream
  • auds:audio stream
  • mp4v:MEPG4 visual

数据块可以直接驻留在 movi 列表中,或者被 res 列表包围。

🔺FOURCC,定义块中信息的类型:

  • db:未压缩的视频帧
  • dc:压缩的视频帧
  • wb:音频流

image.png

习题助记
  1. What does fourcc code “vids” stands for?
  2. What does fourcc code “auds” stands for?
  3. What does fourcc code “00db” stands for?
  4. What does fourcc code “01wb” stands for?
  5. ln which scemarops is wFormatTag equal to -2 in a WAVE file?
    音频通道大于 2,每一个抽样信号大于 16bit

音频编码基础

image.png

数字音频编码器:

  1. 输入:模拟音频信号
  2. 编码器:转换为方便地数字形式
  3. 存储、处理、传输
  4. 解码器:将数字数据转换为模拟信号

🔺音频编码目标:

  • 保真度:解码器尽量提高感知的音频质量,减少失真
  • 数据率:减少代表原始音频信号的数据量
  • 复杂性:减少计算复杂性
  • 延迟:减少编码延迟

PCM——最简单的编码器

image.png

量化是一种有损的过程。

在量化过程中使用的离散值数目越高,输出的信号越接近原始音频

CD:Compact Disc 激光唱片

考点 7:CD 的数据率

CD 的数据率:44.1k/s × 16 bit × 2 = 1.4112 Mb/s

  • 采样:时间间隔 0.023ms(1/0.000023≈43.5k)或采样频率 44.1k。
  • 每一个采样的比特数为 16bit,这种精度允许 65536 个离散电平来表示音频采样幅度。
  • 2 个通路

潜在的编码错误

考点 9:潜在的编码错误
  • 采样错误——混叠效应(抽样速率小于二倍带宽)
  • 🔺量化错误:过载错误、截断错误(round-off)
  • 比特错误:存储和传输错误

更复杂的编码器

心理声学表明,每个样本理想采样比特为 18-20bits 来描述中等频率(2~5kHz)的音频样本。

image.png

冗余:感知冗余、统计冗余

考点 10:有损压缩和无损压缩

有损压缩

image.png

有损压缩通过量化来实现。

量化

image.png

如果有 R 比特可以表示的最大数为 2R2^R,两种量化方法表示的不同样本/编码数为:

  • midtread 中平:2R12^R-1,一般来说效果较好,噪声抑制(小电频通常为噪声,Midtread 会过滤掉)
  • midrise 中升:2R2^R,噪声放大
考点 11:均匀量化和非均匀量化

均匀量化 Uniform Quantization

定义输入范围所需要的信息:

  • 量化器是 midtread 还是 midrise
  • 最大不过载的输入 xmaxx_{max}
  • 描述编码的比特数 R

R 比特允许我们设置的输入范围:

  • midrise:Δ=2xmax/2R\Delta=2*x_{max}/2^R
  • midtread:Δ=2xmax/(2R1)\Delta=2*x_{max}/(2^R-1)

非均匀量化 Nonuniform Quantization

均匀量化会存在截断误差(最大值为 Δ/2\Delta/2),但是,相对于非常低的幅度信号,此误差可能会很大。由于截取失真的感知与相对误差更相关,因此这意味着均匀量化器在低功率输入信号上的表现要比在高功率信号上的差得多。 要解决此问题,可以使用非均匀量化。

image.png

压缩方法:

  • 幂律压缩:cpower(x)=xp0<p<1c_{power}(|x|)=|x|^p,0<p<1, (ACC 或 MP3 中 p=0.75)
  • 对数压缩

量化错误 Quantization Errors:

  • 量化误差:q(t)=xout(t)xin(t)q(t)=x_{out}(t)-x_{in}(t)
  • 信噪比 SNR(Signal-to-noise ratio) SNR=10logxin2q2SNR=10 \log{\frac{x_{in}^2}{q^2}}
  • 低 量化误差 对应于 高 信噪比

截断错误 Round-off Error:产生于将一定范围的信号振幅输入对应到单一编码中

过载错误 Overload Error:

  • 出现原因:量化器接收的信号振幅(绝对值)过大
  • 导致爆鸣(突突突的声音),为了避免它,通常把 xmaxx_{max} 设置得足够大,但由于 R 比特数固定,这会导致截断错误。量化器设计要求在减少两种类型的误差之间取得平衡。

过载错误、截断错误属于量化错误。

无损压缩:熵编码

考点 12:熵和哈夫曼编码

翻译量化编码为一些代表符号,每个符号使用了一定数量的比特。

使一般的编码更短,从而降低平均的比特率。这需要估计每一个可能编码出现的概率。

比特率计算:R = i=1npiLiR = \sum_{i=1}^n{p_i \cdot L_i},其中 pip_i 表示编码出现的概率,LiL_i 表示编码后的长度。

熵代表了编码的极限:

image.png

当我们能确保下一个输出编码是什么时,熵会变低;反之变高。

例:在 2 编码符号系统中,有

image.png

数学图像 链接

  • 当 p=0 或 1 时,熵为 0。我们知道下一个编码是什么,所以我们不需要发送任何 Bits。
  • 当 p=0.5,熵为 1。当所有编码符号出现的概率相同时,达到最大熵。在这种情况下使用熵编码进行压缩没有效果。
  • 对于其他概率,存在一种编码方式使得平均符号编码使用小于 1 个比特

哈夫曼编码

被用于传真、ASCII 文本数据编码压缩。

是一种统计学编码,平均编码长度最小。

编码长度可变,且越经常使用的字符编码长度越短。

特点:

  1. 编码过程不唯一(取决于分支的标记或合并符号的选择),但 WPL 相同(在这里指的是比特率 R)且最优
  2. 在符号分布概率不均匀的情况下,哈夫曼编码的比特数比固定比特编码方法少
  3. 霍夫曼码中每个样本的平均位数在熵的一位以内,即平均采样比特数范围:$$Entropy\le _{Huffman} \le Entropy + 1$$

WAVE MS-ADPCM

考点 13:MS-ADPCM

DPCM 差分脉冲编码调制:

  • 以 PCM 为基线,增加了预测采样信号的功能。
  • 与 PCM 直接传输原始 PCM 采样不同的是,DPCM 传输的是原始采样信号与预测值(基于先前采样)之间的差异:diff=xn+1xpn+1diff=x_{n+1}-xp_{n+1}
  • 预测值计算举例:xpn+1=axn+bxn1xp_{n+1}=a*x_n+b*x_{n-1},a、b 为预测系数

diff 通常非常小,我们必须限制它的表示范围,如从 16bits 限制到 4bits。但我们也不能保证 diff 总是小的(如剧烈信号变化),为了解决这个问题,引入了 iDelta。如果 diff 非常大,则 iDelta 也会很大,反之亦然。

于是我们定义:iErrordata=diff/iDeltaiErrordata = diff / iDelta,这样新的差异值将会稳定。

iErrordata 以 4bit 保存,称为「nibble」,范围为 -8~7。每次新的 iErrordata 生成后,iDelta 相应做出改变。

1
2
3
4
iDelta = iDelta * AdaptableTable[(unsigned)nibble]/256;
const int AdaptationTable[ ] = {
230, 230, 230, 230, 307, 409, 512, 614, // 对应nibble:
768, 614, 512, 409, 307, 230, 230, 230 }; // 对应nibble:

WAVEFORMAT

image.png

MS-ADPCM 的 wave 文件中,存在与 fmt 块和 data 块的另一种块:fact 块

  • fact 块存储采样长度
  • data 块中,数据以块的方式存储,一个接着一个
  • 块有三个部分:头、数据和填充

编码过程

对于每个通道的每个块的编码过程:

  1. 决定块要使用的预测器
  2. 决定块的初始 idelta
  3. 输出块的头
  4. 编码并输出数据

块头写入:

  1. 对每一个通道,输出预测器的选择
  2. 对每一个通道,输出初始 idelta (量化比例)
  3. 对每一个通道,输出第一个采样的 16bit PCM 值
  4. 对每一个通道,输出第二个采样的 16bit PCM 值

然后剩下的块就可以进行编码。注意第一个编码的值是块的第三个采样,因为前两个已经包含在头中了。

当块中有许多采样需要进行编码,将采取下列步骤:

  1. 从前两个采样中预测下一个样本:
    image.png

用预测系数计算会导致运算量增长,而除以 256 只需要移位,无浮点数除法

  1. 产生 4bit 有符号 error delta 以及避免上/下溢:$$ierrordelta=\frac{sample(n)-Ipredsamp}{idelta}$$ 并将 ierrordelta 的范围修剪至[-8,7]
  2. 于是输出 nibble ierrordelta=putnibble(ierrordelta)
  3. 把「预测错误」加到预测的下一个样本,并避免上/下溢:$$Inewsamp=Ipredsample+(idelta*ierrordelta)$$ 将其缩紧至 16bit(short)
  4. 调整用于计算「预测错误」的量化步长:$$idelta=\frac{idelta*adaptiontable[ierrordelta]}{fixed_point_adaption_base}$$ 如果 idelta 过小,将其设为最小的合法值
  5. 更新先前样本的记录:$$isamp2 = isamp1; isamp1 = Inewsample$$
    image.png
    步骤 5 的目的是自适应量化步长。
    步骤 4.6 是为了保持和解码端一致,真正预测时是通过编码解码后的信号。此时和解码端保持一致,使误差不会太大。
习题助记

1.What is audio CD rate?
44.1KHZ × 2 × 16bit/s = 1.411 Mbit
2.What are audio coding goals?
delity,rate,complexity,delay
3.List the components of a chunk.
header,data
4.What kind of quantization errors are there in audio coding?
overlode,round-off
5.What is the average number of bits per sample in a Huffman code?

图片和视频编码基础

🔺人类视觉系统对低频图像更敏感。

图形学中的高低频:图像的低频代表着轮廓信息,高频代表着细节信息,相位代表位置信息。

特定自然视频片段中与视频处理和压缩相关的特征:

  • 空间特征:纹理变化、物体对象的数目和形状、颜色
  • 时间特征:物体运动、光线变化、摄像机/视角变化

image.png

帧率:

  • 每秒小于 10 帧:用于超低比特流视频通信
  • 10~20 帧:典型低比特率视频通信
  • 25~30 帧:电视图像标准
  • 50~60 帧:平滑(高数据率)
考点 23:色彩空间

色彩空间:

  • 单色图:仅需一个数字表示某一个空间采样的亮度
  • 彩色图:至少需要三个数字才能准确表示某一个像素的颜色

代表亮度和色彩的方法称为色彩空间:

  • RGB 色彩空间:捕获和显示图像的恰当方法。RGB 色彩空间中三种颜色同样重要,通常分辨率也相同。彩色阴极射线管(CRT)和液晶显示器(LCD)应用 RGB。
  • YCbCy 色彩空间(YUV 色彩模型)

图像的视觉质量受采样点数量的影响。

YCbCr

🔺人类视觉系统对亮度更敏感(和颜色相比)

人眼的视杆细胞(感知亮度)比视锥细胞(感知色彩)数量多。

色彩空间

在 RGB 颜色空间中,这三种颜色同等重要,因此通常都以相同的分辨率存储。

YCbCr 区分亮度和色度,亮度具有更高的分辨率。

image.png

Y:亮度(luma),RGB 的加权平均,Y=krR+kgG+kbB, kg = 1kbkrY=k_rR+k_gG+k_bB, k_g = 1-k_b-k_r

Cb:彩度蓝

Cr:彩度红

每一个色度是 R、G、B、Y 之间的差异

为了降低存储和传输需求,可以将 RGB 图像转换为 YCbCr 图像

image.png

ITU-R 建议的系数定义:kb=0.114,kr=0.299k_b=0.114, k_r=0.299

image.png

采样格式

为了利用人眼对亮度和色度的不同敏感性,将视频信号转换为亮度/色彩空间时,可以对色度进行空间上的次采样或低通滤波

4:4:4 采样

image.png

Y,Cb 和 Cr 有着相同的分辨率。因此每一个分量存在于任何位置的像素上

4:2:2 采样

image.png

色度组件的垂直分辨率与亮度相同,但水平分辨率只有亮度的一半。

用于高质量彩色录制。

4:2:0 采样

image.png

Cb 和 Cr 的水平和垂直分辨率都是 Y 的一半。

广泛用于消费类应用,如视频会议、DVD。

需要的采样数(比特)是 4:4:4 视频(或 RGB 视频)的一半

为什么不叫做 4:1:1 采样?
因为在历史上 4:1:1 采样已被用于指代这种采样:

image.png

例子:

image.png

视频帧格式

考点 24:视频帧格式

在进行压缩和传输之前,捕获的视频会被捕获或转换为一组“中间格式”之一。

常见的中间格式(CIF)是一组流行格式的基础。

image.png

质量评估

主观测量——ITU-R 500

image.png

通常采用的手段:双刺激连续质量量表(Double Stimulus Continuous Quality Scale)

花费昂贵,耗时长

客观质量测量

峰值信噪比 ( PSNR ) 用于表示信号的最大可能功率与影响其表示的保真度的破坏噪声的功率之间的比率。虽然较高的 PSNR 通常表明重建质量较高,但在某些情况下可能并非如此,必须非常小心该指标的有效性范围。只有当它用于比较来自相同编解码器和相同内容的结果时,它才是最终有效的。一般来说,在估计图像质量,尤其是人类感知的视频质量时,与其他质量指标相比,PSNR 表现不佳。

运用最广泛的是峰值信噪比(Peak Signal to Noise Ratio, PSNR)

PSNRdB=10log10(2n1)2MSESNR=10logxin2q2\begin{aligned} {PSNR}_{dB} =& 10 \log_{10}{\frac{(2^n-1)^2}{MSE}} \\ SNR=&10 \log{\frac{x_{in}^2}{q^2}} \end{aligned}

MSE:原始图像和受损图像或视频帧之间的均方误差

image.png

图像视频处理准则

考点 25:图像视频处理准则:四种类型冗余度

目标是减少信号中存在的冗余(🔺视频编码的四种冗余度):

  • 时间冗余度(Temporal redundancy):两帧相像
  • 空间冗余度(Spatial redundancy):两点相像
  • 统计冗余度(Perceptual redundancy)
  • 感知冗余度(Statistical redundancy)

JPEG 图像压缩

基本流程:

  • 在 JPEG 压缩中,图像被划分为 8×8 像素的块,然后对每个块进行 2-D 离散余弦转换(DCT)。
  • DCT 将像素块中的大多数信号压缩为小的 DCT 系数部分。
  • 量化这些 DCT 系数将使得它们大部分转化为 0。
  • 这些被量化的系数以之字形进行扫描,再进行游程编码和哈夫曼编码。

image.png

帧内帧间预测

每一帧可以都被编码为分开的图像,例如对每一帧独立应用类似 JPEG 的编码。

视频压缩通过利用时间冗余或帧间相似性达到比图片更好的压缩效果。

image.png

考点 26:视频编码中,编码帧的三种基本类型

🔺编码帧的三种基本类型:

  • 帧内编码帧(I - 帧):独立于于所有其他帧进行编码
  • 预测编码帧(P - 帧):基于先前编码的帧进行编码
  • 双向预测帧(B - 帧):基于先前帧和未来帧进行编码

image.png

运动估计与补偿

考点 27:运动估计和补偿

为了最大限度利用相邻帧的可预测性,在运动补偿过程中估算两帧之间的移动并形成正确预测是非常重要的。

估计帧与帧之间运动的过程称为运动估计;基于先前编码的参考帧预测给定帧,同时补偿两帧之间的相对运动的过程称为运动补偿预测 (MC-prediction)。

基于块的的运动估计补偿

对于当前帧 M×N 样本的每个块:

  1. 在参考帧中搜索一个区域,以找到一个“匹配”的 M×N 样本区域
  2. 被选中的候选区域称为当前块的预测块,并将其与当前块相减,得到残差
  3. 将残差块编译传输,当前块和候选位置区域之间的偏移(运动向量)也将被传输

image.png

运动补偿块的大小

image.png

子像素运动补偿

一个更好的运动补偿预测可以由参考帧中的差值样本位置构建。

分像素运动估计补偿引入查找分样本差值位置和整样本位置,选择最匹配的位置,并使用该位置的整数或子样本值进行运动补偿预测。

过程:

  1. 在整样本网格(圆圈标记)中找到最佳匹配
  2. 搜索紧挨着最佳匹配(方块标记)的半样本位置。
  3. 如果需要,则搜索最佳半样本位置(三角形标记)旁边的四分之一样本位置

image.png

预测越精确,残差越小,motion vector 数据量增加。

随着插补步骤的增加,性能增益趋于减小:

  • 与整样本运动补偿相比,半样本插值具有显著的增益。
  • 四分之一样本插值有一定适度改进。
  • 8 个样本插值改进更小,以此类推。

与更复杂的运动补偿方案相关的压缩效率权衡:更精确的运动补偿需要更多的比特来编码向量域,但编码残差比特数更少;反之亦然。

图像模型

  1. 转换:压缩数据并去相关
  2. 量化:降低传输数据的精确度
  3. 重新排序:组织数据以合并重要值
  4. 预测图像编码

预测图像编码

image.png

空间预测,以 DPCM 为例:

  1. 编码预测:prediction P(X) = (2A+B+C)/4
  2. 残差计算:R(X) = X-P(X) ,然后编码并传输 R(X)
  3. 解码器解码残差并形成预测:P(X) = (2A+B+C)/4
  4. 重建像素:X = R(X) + P(X)

转换编码

转换后的数据应当去相关且被压缩:在转换后的数据中,大多数的信息应当被集中于少量的值中。

转换应当可逆。

转换应当容易计算:低内存需求、可使用有限精度算法实现、算数操作数低

目前有许多转换:KLT,SVD,DCT

在 N×N 样本块中,DCT 始终受欢迎,且图像一直在块单元中被处理。

运动补偿残差往往会受到块边缘的伪影(blockiness)的影响。

对整个图像或帧做的基于图像的转换操作有:

  • 图像传输(离散小波变换 DWT)胜过静态图像压缩的块传输(JPEG2000)
  • DWT 需要更高的内存需求(尤其是大图像),因为是以整个图像作为一个单元处理图像的
  • DWT 并不“适合”基于块的运动补偿

2D-DCT

正向离散余弦转换:Y=AXATY=AXA^T

逆 DCT(IDCT):X=ATYAX=A^TYA

X 为 N×N 样本块,Y 为系数矩阵,A 为 N×N 传输矩阵

image.png

例子:N=4,有 A:

image.png

DCT 系数的特征

FDCT 输出是一组 N×N 的系数,表示 DCT 域中的图像块数据。

DCT 自身保存所有 N×N 图像块中的信息。

人眼对低频 DCT 参数更加敏感。

DCT 有助于将感知上重要的信息与感知上不重要的信息分离开来。

用更高的精度编码低频的 DCT 信息,但使用更少或不使用比特来编码高频系数,从而丢弃在感知上不太重要的信息。

image.png

在计算 IDCT 之前添加更多的系数,会逐渐提高原始区块的重建精度,到包含五个系数时,重建的区块与原始区块的匹配程度相当接近。

可以从 16 个 DCT 系数的子集中重建块的近似副本。

DCT 计算复杂性

在典型的 DSP 上,单个 8×8 DCT 或 IDCT 需要几百个指令周期。

以 CIF (352×288) 分辨率和 30 fps 帧率运行的解码器可能需要高达 71,280 IDCT /秒。

IDCT 计算可占用高达 30% 的视频解码器编译周期。

由于 DCT 和 IDCT 在小图像块上操作,因此内存需求相当小,与图像和视频压缩应用程序中的帧缓冲区和其他数据的大小相比,通常可以忽略不计。

DCT 和 IDCT 函数的高计算需求和小内存需求使它们成为使用专用硬件加速器实现的理想候选者。

量化

FQ=round(XQP)Y=FQQP\begin{aligned} FQ = &round\left( \frac{X}{QP} \right) \\ Y=&FQ\cdot QP \end{aligned}

QP 表示量化步长。

量化用于丢弃感知上不重要的信息

量化后,使用统计方法对剩余信息进行编码,从而使用尽可能少的比特。

量化和去量化对内存的要求通常可以忽略不计。

游程编码(RLC)

量化后,绝大多数高频 DCT 系数为零。

游程编码:

  • 将连续的 0 值系数成组(一个游程)
  • 编码 0 的个数(长度),不编码单独 0 系数

为了使连续零值系数的平均值尽可能高,我们以对角之字形的方式扫描 DCT 系数矩阵。

游程编码(RLC,Run-length coding)之后通常是可变长度编码(VLC)。

重新排序

image.png

重排序是将非零系数组合在一起,实现有效地表示零系数

可变长度编码(VLC)

一对(游程,量化 DCT 系数)的每个可能值称为一个符号。

常见的符号被分配较短的码字,而不常见的符号被分配较长的码字。

VLC 的一个缺点是编码图像中间的比特误差会阻止解码器正确重建剩余的比特流。

通过在整个编码比特流中散布“重新同步标记”,解码器能够在发生错误时搜索下一个重新同步标记以进行同步。

视频编码结构

image.png

通用视频编码模型

image.png

编码数据流

编码器的两个主要的数据流路径:从左到右(编码)、从右到左(重建)。

编码流:

  1. 输入视频帧 Fn 用于编码,并以宏块为单位进行处理
  2. Fn 和参考帧(如前编码帧 F’n-1)对比。运动估计函数在 F’n-1 中 16×16 的区域,查找出一个 Fn 中当前宏块的一个匹配。当前宏块位置和被选中的参考区域的偏移为一个移动向量(MV,motion vector)
  3. 基于被选中的 MV,生成运动补偿预测 P(被运动估计器选择的 16×16 区域)
  4. 当前宏块中减去 P 产生残差或 difference 宏块 D。

image.png

数据重建流:

image.png

解码数据流

解码数据流:

image.png

习题助记
  1. Write down the full name of ADPCM in English
    Adaptive Differential Pulse Code Modulation
  2. List the four types of redundancy used in video coding
    时间、空间、感知、统计
  3. What is the sample resolution of CIF
    352×288
  4. Write down the formula of PSNR
  5. ln video coding , there are three basic types of coded frames, what are they?
    I P B
  6. What is the purpose of DCT?
    去相关,使数据更紧凑
  7. What is the purpose of Zigzag Scan or reordering?
    是将非零系数组合在一起并有效地表示零系数
  8. What is the purpose of quantization?
    量化用于丢弃感知上无关紧要的信息
  9. In motion estimation and compensation, what kind of redundancy is used in video coding?
    temporal 时间冗余
  10. In 010 editor template, the following variable is defined at the beginning: char type[4];
    The variable type is mapped to 0 bytes 3 to in the file.

本小节参考链接

JPEG 图像编码

Baseline 方法是迄今为止实现最广泛的 JPEG 方法。

基于 DCT 的编码/解码过程

image.png

编码过程:

  1. 输入的组件样本为 8×8 块
  2. 每个块被前向 DCT(FDCT)转换为一组 64 个值,作为 DCT 系数。
    a. 第一个值称为 DC 系数
    b. 其他 63 个值为 AC 系数
  3. 然后使用量化表中 64 个对应值中的一个对 64 个系数中的每个系数进行量化
  4. 然后将量化系数传递给熵编码过程,以进一步压缩

解码过程:

  1. 熵解码器解码之字形的量化 DCT 系数
  2. 解量化后,通过反向 DCT(IDCT)将 DCT 系数转化为 8*8 样本块

前向 DCT(FDCT)

在编码器的输入中,原图像采样以 8×8 块成组,从无符号整数 [0,2P1][0,2^P-1] 的范围转换为有符号整数 [2P1,2P11][-2^{P-1},2^{P-1}-1],然后输入到 FDCT 中:

image.png

其中,

C(u),C(v)=1/2,when u,v=0C(u),C(v)=1,other conditions\begin{aligned} C(u),C(v)=&1/\sqrt{ 2 }, &when~u,v=0\\ C(u),C(v)=&1,&other~conditions \end{aligned}

反向 DCT(IDCT)

解码器的输出中,IDCT 输出 8×8 采样块以形成重构图片:

image.png

其中,

C(u),C(v)=1/2,when u,v=0C(u),C(v)=1,other conditions\begin{aligned} C(u),C(v)=&1/\sqrt{ 2 }, &when~ u,v=0\\ C(u),C(v)=&1,&other ~conditions \end{aligned}

块样本和 DCT 系数的关系

  • 对一个块进行前向 DCT 计算后,64 个 DCT 系数结果被均匀量化器量化
  • 每一个系数 SvuS_{vu} 的量化器步长为对应量化表中的元素 QvuQ_{vu}
    image.png

DC 编码

相邻的 8×8 块之间的 DC 系数通常有着强烈的关联性。量化的 DC 系数被编码为与前块的 DC 项的差值。这种特殊处理是值得的,因为 DC 系数包含了总图像能量的很大一部分。

image.png

之字形扫描

所有的量化系数将以之字形顺序进行组织,将低频系数(一般为非 0)放置在高频系数前,以便于进行熵编码。

image.png

压缩与图像质量

对于较复杂场景的彩色图像,所有基于 DCT 的操作模式通常会产生以下级别的图像质量:

  • 0.25-0.5 比特/像素:中等至良好质量
  • 0.5-0.75 比特/像素:良好至优秀质量
  • 0.75-1.5 比特/像素:杰出质量,满足大多数的应用
  • 1.5-2.0 比特/像素:和原图相差无几,满足有高质量需求的应用

根据源特性和场景内容的不同,质量和压缩会有很大的不同。

具有多个组件的源图像

源图像可能包含 1~255 个图像组件。每一个组件包含样本的矩形数组。

样本被定义为一个 [0,2P1][0, 2^{P-1}] 范围的无符号整数。

图像中的所有样本必须有着相同的精度 P,对于基于 DCT 的编解码器,P 可以是 8 或 12。

image.png

多组件交织

许多应用程序需要将显示/打印多组件图像的过程与解压过程并行。

这只有在组件在压缩数据流中交织在一起时才可行。

编码交错:如果编码器从 a 压缩一个数据单元,从 B 压缩一个数据单元,从 C 压缩一个数据单元,然后返回到 a…

image.png

不同维度的组件交织顺序

image.png

上例中,B、C 在水平方向上与 A 相比少了一半样本。在这个例子中,A 的两个数据单元和 B、C 的各一个单元进行交织。

考点 28:JPEG 编码与解码过程:最小编码单元、操作模式、DC 熵编码、AC 熵编码、游程、SIZE、EOB

最小编码单元 MCU

在基于 DCT 的编解码器中,数据单元是一个 8x8 的样本块。

最小编码单元 MCU:最小的交错数据单元组。对于非交错数据,MCU 是一个数据单元。对于交错数据,MCU 是由扫描中组件的采样因子定义的数据单元序列。交错数据是 MCU 的有序序列,MCU 中包含的数据单元数由交错的元件数及其相对采样因子决定。

image.png

当两个或更多的组件进行交织时,每一个组件 CiC_iViV_i 个数据单元划分为 HiH_i 的矩形区域。最大的组件交织数为 4,且每个 MCU 的数据单元最大值为 10:$$\sum_{\text{所有参与交织的}~i}{H_i\times V_i}\le 10$$(注:置于 10 这个数字是规定的,没有理由)

操作模式

🔺有四种不同的操作模式,在这些模式下定义了各种编码过程:

  • 基于 DCT 的顺序模式(从上到下,一块一块编码)
  • 基于 DCT 的渐进模式(从轮廓到细节)
  • 无损模式
  • 层次模式

image.png

顺序模式与渐进模式

在顺序模式中,每一个图片组件在单个扫描中编码。

在渐进模式中,每一个图片组件在多次扫描中编码。第一次扫描中编码粗糙,但可识别的图像版本可以快速传输,且通过后续的扫描进行改进,直到达到由量化表确定的图像质量水平。

有两种互补的方法可以对量化 DCT 系数块进行部分编码

  1. 在给定的扫描中,只有之字形序列特定的系数带需要进行编码
  2. 在给定的扫描中,无需将当前频带内的系数编码为完全(量化)精度。
    1. 最重要的 N 个比特可以在第一次扫描中编码
    2. 在随后的扫描中,次重要的比特再进行编码
    3. 这个过程叫做「连续逼近」

这两种程序可以单独使用,也可以灵活地混合使用。

量化 DCT 系数的传递:

image.png

光谱选择与逐次逼近:

image.png

层次模式

层次模式以多种分辨率的方式为图片提供金字塔型的编码。每一种的分辨率与其相邻的编码在水平或垂直维度或两者上相差两倍:

  1. 对原始图像在每个维度上按所需的 2 的倍数进行滤波和下采样。
  2. 使用顺序 DCT、渐进式 DCT 或无损编码器之一对这个减小尺寸的图像进行编码。
  3. 解码此缩小尺寸的图像,然后使用接收器必须使用的相同插值滤波器对它进行水平和/或垂直 2 插值和上采样。
  4. 使用此上采样图像作为该分辨率下的原始图像的预测,并使用前面介绍的顺序 DCT,逐行 DCT 或无损编码器之一对差异图像进行编码。
  5. 重复第 3 步和第 4 步,直到图像的全分辨率被编码

基线顺序熵编码

在基线顺序编码器中,FDCT、量化、DC 差分以及之字形排序步骤之后,是熵编码。

在熵编码之前,通常只有很少的非零系数和很多零值系数。熵编码的任务是更有效地编码这些系数。

基线顺序熵编码有两个步骤:

  1. 将量化 DCT 系数转换为中间符号序列(游程编码)
  2. 为符号分配可变长度代码(哈夫曼编码)

AC 系数

每一个非零的 AC 系数这样编码:

  • RUN-LENGTH:之字形扫描序列中,被表示的非零 AC 系数前,连续数字 0 的长度。
    • RUN-LENGTH 代表 0~15,Symbol-1 中 (15, 0) 代表 RUN-LENGTH=16。
    • (0,0) 代表 EOB(块结束),可以将其视为“转义”符号。
  • SIZE:编码 AMPLITUDE 所用的比特数

image.png

更多例子

0005 → (3,3)(5)
000003 → (5,2)(3)
00,-12 →  (2,4)(-12)
0…(16 个 0)…0 1 → (15,0)(0,1)(1)
0…(17 个 0)…0 1 → (15,0)(1,1)(1)
0…(18 个 0)…0 -3 → (15,0)(2,2)(-3)
00000 3 0…0 → (5,2)(3)(0,0)
0013 →  (2,1)(1) (0,2)(3)

AMPLITUDE 和 SIZE 的范围

量化 AC 系数的取值范围决定了 AMPLITUDE 和 SIZE 信息必须表示的值的范围。对 8×8 FDCT 方程的数值分析表明,如果 64 点 (8×8 块) 输入信号包含 N 位整数,则输出数字的非小数部分 (DCT 系数) 最多可以增长 3 位。这也是量化 DCT 系数的最大可能大小。

基线顺序在 [27,271][-2^7,2^7-1] 范围内有 8 位整数源样本,因此量化的 AC 系数幅度由 [210,2101][-2^{10},2^{10}-1] 范围内的整数覆盖。

带符号整数编码使用长度为 1 到 10 位的 symbol-2 AMPLITUDE 码,因此 SIZE 也代表 1 到 10 的值。RUNLENGTH 表示从 0 到 15 的值。

DC 系数

8×8 样本块的差分 DC 系数的中间表示结构类似:

  • Symbol-1 只表示 SIZE 信息
  • Symbol-2 表示振幅信息

image.png

因为 DC 系数是差分编码的,所以它覆盖的整数值 [211,2111][-2^{11},2^{11}-1] 是 AC 系数的两倍,因此必须为 DC 系数增加一个附加的电平。

因此,DC 系数大小的 symbol–1 表示从 0 到 11 的值。

差分编码(differential encoding)指的是对数字数据流,除第一个元素外,将其中各元素都表示为各该元素与其前一元素的差的编码。差分编码的简单例子是储存序列式资料之间的差异(而不是储存资料本身):不存“2, 4, 6, 9, 7”,而是存“2, 2, 2, 3, -2”。

可变长度熵编码

对于 DC 和 AC 系数,每个 symbol-1 均使用来自 Huffman 表集中的可变长度代码(VLC)进行编码。 每个 symbol-2 均使用“可变长度整数”(VLI)码进行编码。

VLCs 和 VLIs 是具有可变长度的代码,但 VLI 不是霍夫曼代码。一个重要的区别是,VLC( Huffman code)的长度直到解码才知道,而 VLI 的长度存储在其前一个 VLC 中。

Huffman 码必须在外部指定为 JPEG 编码器的输入。

请注意,Huffman 表在数据流中的表示形式是一种间接规范,解码器在解压缩之前必须以此间接规范来构造表(解码时需要重新构建 Huffman 树进行解码)。 JPEG 标准包括一组 Huffman 表的示例,但这不是强制性的。

基线编码例子

image.png

考点 29:JPEG 交换格式(JIF):图像、帧、扫描和标记

图像、帧和扫描的关系

  • 压缩的图像数据只包含一张图片。
  • 在渐进模式和顺序模式编码过程中,一张图片只包含一帧。
  • 在层次模式中,一张图片可以包含多帧。
  • 一帧可以包含一个或多个扫描。
  • 顺序模式下,一个扫描包含一个完整的、单个/多个图像组件的编码。
  • 在层次模式中:当一张图像的三个组件非交织时,一帧包含三个扫描;如果三个组件交织一起,那么一帧包含一趟扫描。
  • 一帧也可以包含两趟扫描:一趟是非交织的组件、另一趟为两组件交织。

标记

标记用于标识压缩数据格式的各种结构部分。

所有的标记赋予两个字节编码:0xFF+ 不等于 0 或 0xFF 的字节。

标记段包含一个标记以及相关参数的序列。标记段的第一个参数是两字节长的参数,它指定了标记段的字节数(除去两字节标记后的参数长度)

被 SOF 和 SOS 标记码标识出的标记段被视为头(headers):分别为帧报头和扫描报头。

SOI(0xFFD8):压缩图片开始标记

EOI(0xFFD9):压缩图片的结束标记

高级语法

基于顺序 DCT、渐进式 DCT 和无损操作模式的语法:

image.png

帧头语义

帧报头应该出现在帧的开始。该报头指定源图像特征、帧中的组件和每个组件的采样因子,并指定从中检索要与每个组件一起使用的量化表的目标。

image.png

标记结构 长度(字节) 解释
0xFFC0 2 SOF marker
Lf 2 Frame header length, not including the first two bytes 0xFF, 0xC0
P 1 Sampling precision, equals 0x08 in a baseline system
Y 2 Image height
X 2 Image width
Nf 1 Number of components in a frame. 1 (grey scale) or 3 (color)
C1 1 Component 1
(H1,V1) 1 Horizontal and vertical sampling factor
Tq1 1 Quantization table
C2 1 Component 2
(H2,V2) 1 Horizontal and vertical sampling factor
Tq2 1 Quantization table

扫描头语义

扫描头应在扫描开始时出现。这个报头指定扫描中包含哪些组件,指定从中检索要与每个组件一起使用的熵表的地址。

image.png

标记 长度(字节) 解释
0xFFDA 2 SOS marker
Ls 2 Scan header length, not including the first two bytes 0xFF, 0xDA
Ns 1 Number of components in a scan, in a baseline system, Ns=Nf (Number of components in a frame)
Cs1 1 Component number in a scan
(Td1,Ta1) 1 Tdn: the four most significant bits, used to select DC entropy coding table
Tan: the four least significant bits, used to select AC entropy coding table
Ss 1 Default values are [00] [3F] [00] in a baseline system
Se 1 Default values are [00] [3F] [00] in a baseline system
(Ah,Al) 1 Default values are [00] [3F] [00] in a baseline system

DQT 标记段语义

定义量化表 (DQT) 标记段,用于定义一个或多个量化表。

image.png

标记 长度(字节) 解释
0XFFDB 2 DQT marker
Lq 2 Quantization table length, not including 0XFF, 0XDB
(Pq,Tq) 1 Quantization table element precision
Pq=0, 8 bits for Q0~Qn, Pq=1, 16 bits for Qt;
Tq: Quantization table destination identifier
Q0 1 or 2 Quantization table element‐Specifies the kth element out of 64 elements
Q1 1 or 2 Quantization table element‐Specifies the kth element out of 64 elements
Qn 1 or 2 Quantization table element‐Specifies the kth element out of 64 elements

哈夫曼表规范语法

哈夫曼表标记 (DHT) 段定义了一个或多个霍夫曼表规范。

image.png

标记 长度(字节) 解释
0xFFC4 1 DHT marker
Ls 2 Huffman table definition length, not including 0xFF, 0xC4
(Tc,Th) 1 TC: Table class – 0 = DC table or lossless table, 1 = AC table.
Th:Huffman table destination identifier
Th Specifies one of four possible destinations at the decoder into which the Huffman table shall be installed.
L 1 1 Number of Huffman codes of length i
L 16 1
V 1 1 Value associated with each Huffman code, t=L1+L2+…L16
V t 1

JPEG 文件

考点 30:JPEG 文件交换格式(JFIF)

到目前为止,我们描述的文件格式被称为「JPEG 交换格式 (JIF)」。然而,这种“纯粹”的文件格式很少使用,主要是因为,这个标准的某些缺点:

  • 色彩空间定义
  • 组件子采样注册
  • 像素宽高比定义

JPEG 文件交换格式(JFIF)解决了 JIF 的局限性。JFIF 文件中的图像数据使用 JPEG 标准中的技术进行压缩,因此 JFIF 有时被称为“JPEG/JFIF”。

JPEG 文件交换格式是一种最小的文件格式,它使 JPEG 比特流能够在各种平台和应用程序之间进行交换。

此简化格式的唯一目的是允许交换 JPEG 压缩图像。

尽管 JPEG 文件交换格式 (JFIF) 的语法支持任何 JPEG 过程,但强烈建议将 JPEG 基线过程用于文件交换,这确保了与所有支持 JPEG 的应用程序的最大兼容性。

JPEG 文件交换格式与标准的 JPEG 交换格式完全兼容。唯一的额外要求是必须在 SOI 标记之后出现 APP0 标记。

JFIF 文件使用 APP0 标记段,并在帧头中限制某些参数,定义如下:

  • 长度、标识符、版本、单位、X 密度、Y 密度、X 缩略图、Y 缩略图、(RGB)n

image.png

image.png

image.png

编码过程

编码图像的流程

image.png

编码帧的流程

image.png

编码扫描的流程

image.png

编码重启间隔的流程

image.png

对最小编码单元进行编码的过程

image.png

使用哈夫曼编码 AC 系数的过程

image.png

非零 AC 系数的顺序编码过程

image.png

解码过程

解码压缩图像数据的过程

image.png

解码一帧的过程

image.png

解码扫描的过程:

image.png

解码重启间隙的过程:

image.png

解码 MCU 的过程:

image.png

习题助记
  1. What are markers used for in JIF?
    标识压缩数据格式中不同的结构部分
  2. Describe the full name of SOI,EOI,SOF,SOS
    Start of image marker,End of image marker,Start of Frame marker,Start of Scan marker
  3. What is JPEG file interchange format used for?
    定义分辨率颜色等相关参数,为了能在不同应用和平台转换
  4. An image contains ___ frame in the cases of sequential and progressive coding processes.
    one frame

视频编码

视频编码标准的制定

考点 2:视频压缩标准及应用

ITU-T 国际电信联盟 - 电信

H.261

  • 第一个视频压缩标准(1990 年)
  • 专为综合业务数字网络(ISDN)视频会议设计的。
  • 支持 352X288(CIF)和 176X144(QCIF)的分辨率色度分辨率子采样为 4:2:0
  • 由于视频电话需要,在仅需较低的复杂性同时进行实时编码和解码。
  • 由于它专注于对延迟敏感的双向视频,H.261 仅允许 I 和 P 帧,不允许 B 帧。(B 帧需要等待后帧解码,存在时延)
  • 基于整数像素精度进行运动估计运算和搜索范围为 +/- 15 像素。
  • 将基于 8x8 块的 DCT 应用于残差。然后在所有 AC 系数上进行固定的线性量化用固定的量化步长线性量化。
  • 首先对量化系数进行游程编码,然后可变长度(霍夫曼)编码。
  • 将简单的 2D FIR 滤波器应用于块边缘减少块效应。

H.263

  • 用于公共交换电话网络(PSTN)可视电话
  • H.263(1996)是在 H.261 之后开发的,专注于更好更低比特率的视频质量。
  • 通过普通电话调制解调器以 33.6 Kbps 的速度传输视频,是其重要的目标之一。
  • 目标分辨率为 SQCIF(128x96)至 CIF(352X288)
  • 与 H.261 类似,但运动矢量略有不同。其允许为½(“半像素”)的倍数。使用 16x16 宏块中的四个 8x8 像素块的四个运动矢量,而不是宏块的单个运动矢量。
  • PB 帧:P 帧和 B 帧(这是从当前编码的 P 帧和后一个先前编码的 P 帧预测而来的)编码为一个单元。
  • 使用基于内容的算术编码模式代替霍夫曼编码,对于相同的图像质量,比特率略有降低。
  • H.263 通常在相同的比特率下实现大约 3 dB 的改善,或者在相同的 SNR(质量)下将比特率减少 50%。

H.264:Advanced video coding

详看 🍂H.264-MPEG4-AVC(高级视频编码) 小节。

ISO 国际标准化组织

MPEG 成立于 1988 年,旨在开发在数字存储媒体上移动图片(视频)和关联的音频(光盘)的压缩标准。

MPEG-1

  • ISO 制定的第一个视频压缩算法 (1991)
  • 可在获得与 VHS 品质相似的视频和音频
  • 比特率 1.5Mb/s
  • 与典型的视频电话相比,支持电影内容中较重的运动(heavier motion)需要更多的计算资源
  • 允许更长的延迟,允许 B 帧
  • 使用自适应感知量化。单独的量化比例因子专门应用于每个频点以优化人类的视觉感知。

MPEG-2

  • 是 MPEG-1 的扩展,支持更高的比特率,更高分辨率和隔行扫描图片(用于电视)。(先打奇数行再偶数行)
  • 是为数字电视开发的比特率较高的应用:DTV,HDTV 和 DVD
  • 由许多部分组成,包括视频,音频,系统,兼容性测试。
  • 在 30:1 左右的压缩率下表现良好。 MPEG-2 以 4~8 Mbps 达到的质量对于消费者视频应用程序是可接受的。
MPEG-2 Profiles and Levels

这些标准旨在解决大量不同的应用程序需要许多不同的工具或功能的问题。典型的应用程序可能仅使用 MPEG 功能的一小部分。 为了实现更有效的实现,MPEG 将功能的子集适当的组合在一起,并定义了一组配置文件和级别。

  • 档次(profile)定义了视频语法和功能的子集。
  • 在档次(profile)中,级别定义了某些参数的最大范围,例如分辨率,帧速率,比特率和缓冲区大小(下限)。

两个广泛使用的配置文件/级别是:

  • Main Level at Main Profile (MP@ML):用于压缩 DVD 上使用的常规电视(例如 NTSC 或 PAL)和标清数字电视(SD DTV)
  • Main Profile at High Level (MP@HL):用于压缩高清电视(HDTV)(1080p)

image.png

MPEG-4

MPEG-4 与 MPEG-1 和 MPEG-2 完全不同,它的主要目标是提供新功能,而不仅仅是提供更好的压缩。将提供增强的功能:

  • 支持基于对象或基于内容的表示。这使得可以对视频场景中的不同视频对象进行单独编码,并且允许对视频中的不同对象进行单独访问和操作。请注意,MPEG-4 没有指定如何识别或分割视频中的对象。但是,如果单个对象已知,MPEG-4 提供了一种压缩这些对象的方法。
  • 支持对合成或计算机生成的视频对象进行压缩,以及在单个视频中集成自然对象和合成对象。此外,MPEG-4 支持通过差错恢复(例如 Internet 和 3G 无线系统)进行防错通信。因此,MPEG-4 同时支持基于对象和基于帧的视频编码。
  • 与场景的交互

image.png

Demuxer 用于解析和解码视频和音频对象。场景描述信息描述了解码对象如何组成和渲染以形成最终场景。

与 MPEG-2 和 MPEG-4 简单档次相比,H.264 / AVC 在压缩效率方面取得了重大突破,通常可实现约 2 倍的压缩。

为了满足从低质量,低分辨率监视摄像机到高清电视广播和 DVD 的各种应用,MPEG-4 第 2 部分定义了大约 21 个档次(profiles):Simple, Advanced Simple, Main, Core, Advanced Coding Efficiency, Advanced Real Time Simple 等。最常用的档次是 Advanced Simple 和 Simple(都是 Advanced Simple 的子集)。

当前视频压缩标准

年份 标准 发布机构 🔺常用于
1990 H.261 ITU-T ISDN 上的视频会议, 可视电话
1993 MPEG-1 part 2 ISO, IEC Video-CD 数字存储媒介(CD-ROM)上的视频
1995 H.262/MPEG-2 Part 2 ISO, IEC, ITU-T DVD Video, Blu-ray, Digital Video Broadcasting, 数字电视
1996 H.263 ITU-T 视频会议, PSTN 上的可视电话, Video on Mobile Phones (3GP)
1999 MPEG-4 Part 2 ISO, IEC Video on Internet (DivX, Xvid …), 基于对象的编码, 合成内容, 集成
2003 H.264/MPEG-4 AVC Sony, Panosonic, Samsung, ISO, IEC, ITU-T Blu-ray,HD DVD Digital Video Broadcasting, 无线, 因特网, 电影, 视频电话, 视频会议

标准化的范围

考点 31:视频编码和解码架构:normative, informative

视频压缩系统由一个编码器,压缩比特流和解码器组成。

标准限定的范围有限,是为了在确保互操作性同时尽可能实现差异化:

  • 标准指定比特流语法和解码过程
  • 标准不限定编码过程或具体解码器的实现。

image.png

考点 32:MPEG 编码结构、MPEG 语法

MPEG 编码结构

MPEG 以单元层次结构编码视频,这些单元称为序列、图像组 (GOPs)、图像、切片、宏块和 DCT 块

  • 对 16x16 像素的宏块执行 MC 预测(运动补偿预测)
  • 这些宏块组成一个切片
  • 一帧中的所有切片均包含一张图片,连续的图片形成一个 GOP。
  • 所有 GOP 形成一个序列。

image.png

GOP

视频帧被分组为编码单元,称为图像组 (GOPs)。

GOPs 具有重新初始化编码中使用的时间预测的属性。

GOP 的第一帧总是以帧内模式编码,称为 I 帧

image.png

用 I 帧通过正向预测或双向预测得到 P 帧或 B 帧。

GOP 长度通常在 9 到 15 帧之间。

每个 B 帧都取决于过去帧和一个将来帧,这意味着将来帧必须是在当前 B 帧可以被解/编码之前被解/编码。

编码后的视频数据以编码顺序放置在数据流中,而不是显示顺序

I P B 帧编码属性

I,P 和 B 帧的编码通常需要不同数据量。

  • I 帧需要大量数据,因为它们的编码与其他框架无关。
  • P 和 B 帧通常需要的数据少于 I 帧(时间预测)
  • B 帧的编码数据通常少于 P 帧,因为:
    • 同时使用前后参考帧,可以形成更好的预测。
    • 以较低的质量编码 B 帧通常不会带来负面影响,B 帧的编码质量较低不会影响序列中的其他帧。

宏块

MPEG 使用 16x16 像素 MC 预测来减少时间视频中固有的冗余。

在 I 帧中,必须以帧内模式对每个宏块进行编码。

在 P 帧中,每个宏块都可以使用前向编码预测或帧内模式。

在 B 帧中,每个宏块都可以前向编码,后向或双向预测或帧内模式。

为每个前向和后向预测指定一个 MV(motion vector)宏块,同时为每个双向指定两个 MV 预测宏块。

DCT 块

每个宏块(intra or inter)被划分为 8x8 像素块。

为每个块计算 2D-DCT。 DCT 系数被单独量化。

量化系数经过 zigzag 扫描,游程长度进行编码,结果对(游程长度,幅度组成的一对)经过霍夫曼编码并输出至比特流。

还有一些块间和宏块间处理。

Slices

MPEG 编码要求每个宏块都属于一个切片,所有切片都构成整个图片。

切片是一系列任意数量的连续宏块:

  • 每个切片至少应包含一个宏块。
  • 切片不得重叠。
  • 切片的位置可能因图片而异。

这提供了一种用于预测宏块中某些参数的结构,同时保持一定程度的错误弹性。

在 I 帧中,DCT 系数的 DC 值在一个片(Slice)内从块到块被差分编码。(JPEG 是整幅图做差分编码)

在 P 和 B 帧中,运动矢量在片内从宏块到宏块进行差分编码。

如果位流中发生错误,则切片中的剩余数据将丢失。 但是,解码器可以通过搜索下一个切片起始码,重新同步位流并继续解码过程来恢复。

MPEG Syntax

序列头指定图片的高度/宽度,以及样本宽高比,帧速率,比特率和缓冲区大小序列。 如果未使用默认的量化器,则还包括量化矩阵。

GOP 头指定时间代码并指示 GOP 是否打开或关闭。

图像头指定时间参考参数,图片类型(I,P 或 B)以及缓冲区充满度。 如果是使用时域预测,它还描述了运动矢量精度(完整或半像素)和运动矢量范围。

切片头指定了切片开始的宏块行,以及 DCT 系数的初始量化器比例因子。

宏块头包含一个标志,指示是内部还是帧间编码

对于帧间编码,它包含编码的运动矢量,这个运动矢量会基于相对于先前的运动矢量进行差分编码。

可以在宏块级别上调整量化器比例因子。1bit 用于指定是否调整因子。

序列、GOP、图片、切片的标头以这些代码开头:

  • 例如,通过简单地检查编码数据流而无需解析或解码数据,就能找到第二个 GOP 中第二张图片的第二切片编码的数据
  • 允许对压缩比特流的随机访问
  • 提高容错能力
习题助记

MPEG-1 is used in VCD ,MPEG-2 is used in DVD.
MP3 is a lossy compression method.
H.261、H.263 主要用于可视电话
The bit stream synatax is specified in MPEG video coding standard.
The encoding process is NOT specified in MPEG coding standard.
MPEG-1 allows B frames.
P frames require LESS data than I frames because of temporal prediction.
In video coding the position of slices may change from picture to picture.
In video coding the Picture header specifiles the temporal reference parameter

🍂H.264-MPEG4-AVC(高级视频编码)

考点 33:H.264 编码结构、基线档次、主档次、向量块大小、新特性、视频编码层级和网络抽象层

在过去十年中,视频编码领域最重要的发展之一是由 ITU 和 ISO/IEC 的联合视频团队(Joint Video Team,JVT)定义的 H.264/MPEG-4 AVC 标准。ITU 从 1997 年开始使用新的编码工具开展了 H.26L(for long term)的工作。结果令人印象深刻,因此 ISO/IEC 决定与 ITU 合作,采用一个共同的标准,成立了联合视频团队。ITU 于 2003 年 5 月批准了新的 H.264 标准。ISO 于 2003 年 10 月批准了该标准,命名为 MPEG-4 第 10 部分,即高级视频编码(AVC)。

块框图和特性:

image.png

H.264/AVC 在压缩效率方面取得了重大突破,通常相对于 MPEG-2 和 MPEG-4 简单档次实现了大约 2 倍的压缩比。

在 H.264 标准化时,它支持三种档次(profiles):基线档次、主要档次和扩展档次。

  • 后来,一项名为保真度范围扩展(FRExt)的修正引入了四个额外的配置,称为高级档次。
  • 最初,基本档次和主档次引起了最大的关注。

基本档次需要较少的计算和系统内存,并且针对低延迟进行了优化:

  • 基本档次不包括 B 帧(由于固有时延)CABAC(由于计算复杂性)。
  • 基本档次非常适合视频电话应用以及其他需要成本效益的实时编码应用。

主档次旨在为广播和内容存储应用提供尽可能高的视频质量和最低的比特率。

标准编解码器中的关键压缩特性:

image.png

image.png

应用趋势:

image.png

H.264/AVC 的目标和应用

视频编码专家组(VCEG),ITU-T SG16

  • H.26L 项目(1998 年初),最初的重点是视频会议和电话通信。
  • 目标是将编码效率提高一倍,超过任何其他现有的视频编码标准。
    应用领域:
  • 有线、卫星、地面数字视频广播
  • 媒体存储、DVD、蓝光 DVD 等
  • 互联网流媒体、视频电话在 3G/4G 网络上
  • 视频会议
  • 数字视频监控、数字电影等

与其他标准的关系

在 ITU-T 和 MPEG 中都将批准相同的设计。

在 ITU-T 中,这将是一个新的独立标准:

  • ITU-T 推荐标准 H.264。
  • ITU-T 系统(H.32x)将进行修改以支持它。
    在 MPEG 中,这将是 MPEG-4 套件中的一个新的“部分”:
  • 与之前的 MPEG-4 视觉编解码器设计分开。
  • 新的第 10 部分称为“高级视频编码”(类似于 MPEG-2 中的“AAC”位置,作为独立的编解码器)。
    与之前的标准不兼容(包括之前的 MPEG-4 视觉规范 - 核心技术不同)。
    MPEG-4 系统/文件格式正在进行修改以支持它。
    IETF 正在研究 RTP 有效载荷的封装。

新功能和共同元素

视频编码层基于混合视频编码(hybrid video coding),与其他标准在理念上类似,但存在重要的区别。

新的关键功能包括:

  • 增强的运动补偿
  • 用于变换编码的小块
  • 改进的去块滤波器
  • 增强的熵编码

与之前的标准相比,H.264/AVC 具有以下共同元素:

  • 16x16 宏块
  • 块运动位移
  • 块变换
  • 标量量化
  • I、P 和 B 帧类型
    相对于之前的标准,在相同感知质量下,H.264/AVC 可以实现约 50% 的比特率节省。

档次

受限基准档次(Constrained Baseline Profile,CBP):

  • 主要用于视频会议和移动应用等低成本应用,于 2009 年开发。
  • 对应于基准档次、主档次和高级档次之间共同支持的功能子集。

基准档次(Baseline Profile,BP):

  • 主要用于需要额外数据丢失鲁棒性的低成本应用,如视频会议和移动应用。
  • 包括所有受限基准档次支持的功能,以及用于提高鲁棒性的额外功能。
  • 所有受限基准档次的比特流也被视为基准档次的比特流,因为这两个档次共享相同的档次标识码值。

主档次(Main Profile,MP):

  • 用于使用 MPEG-4 格式的标准定义数字电视广播,符合 DVB 标准定义。

扩展档次(Extended Profile,XP):

  • 用于流媒体视频档次。
  • 具有相对较高的压缩能力和一些额外的技巧,以提高对数据丢失和服务器流切换的鲁棒性。

高级档次(High Profile,HiP):

  • 于 2004 年开发,用于广播和光盘存储应用,特别适用于高清电视应用(例如,已被蓝光光盘存储格式和 DVB 高清电视广播服务采用)。

高 10 档次(High 10 Profile,Hi10P):

  • 在高级档次的基础上增加了对每个样本解码图像精度高达 10 位的支持。

高 4:2:2 档次(High 4:2:2 Profile,Hi422P):

  • 针对使用隔行视频的专业应用。
  • 在高 10 档次的基础上增加了对 4:2:2 色度子采样格式的支持,同时使用高达 10 位的解码图像精度。

高 4:4:4 预测档次(High 4:4:4 Predictive Profile,Hi444PP):

  • 在高 4:2:2 档次的基础上增加了对 4:4:4 色度采样的支持,每个样本的解码图像精度高达 14 位。
  • 此外,还支持高效的无损区域编码和将每个图像编码为三个独立的色彩平面。

基准档次

特点包括:

  • I 和 P 帧类型(不包括 B 帧,因为时延较大)
  • 循环内去块滤波器
  • 1/4 像素级的运动补偿
  • 基于树状结构的运动分割,最小块大小为 4x4
  • 基于 VLC 的熵编码

一些增强的错误容忍特性包括:

  • 灵活的宏块排序/任意切片排序
  • 冗余切片
  • 主要用于视频会议和无线应用

主档次

主档次的特点包括:

  • 所有基准档次的特点,除了增强的错误容忍特性
  • B 帧类型
  • CABAC(上下文自适应二进制算术编码)
  • 宏块级别的帧/场切换
  • 对 B 帧和 P 帧预测进行自适应加权
  • 支持隔行图像扫描

主档次主要用于广播应用。

基本宏块编码结构

image.png

运动补偿

运动补偿的特点包括:

  • 不同的块大小和形状用于运动补偿
  • 1/4 像素精度
    • 6 点滤波器用于 1/2 像素精度
    • 简化滤波器用于 1/4 像素精度
  • 多个参考帧
  • 时间反转运动和广义 B 帧
  • B 帧预测加权

H.264/AVC 编码数据格式

H.264 区分视频编码层(VCL)和网络抽象层(NAL)。

编码过程的输出是 VCL 数据(表示编码视频数据的一系列比特),在传输或存储之前将其映射到 NAL 单元。

分别指定 VCL 和 NAL 的目的是区分编码特定的功能(在 VCL 中)和传输特定的功能。

每个 NAL 单元包含原始字节序列负载(RBSP),即对应于编码视频数据的一组数据和头部信息。

编码的视频序列由一系列 NAL 单元表示,可以通过基于数据包的网络、比特流传输链路或存储在文件中进行传输。

image.png

image.png

image.png

NAL 单元的第一个字节是一个头部,包含有关该包类型的信息。

1
2
3
ubyte forbidden_bit: 1; // set to 0
ubyte nal_ref_idc:2; // the level of priority
ubyte nal_unit_type:5; // NAL type
Type Defintion
0 Undefined
1 Slice layer without partitioning non IDR(instaneous decoding refresh 立即编码刷新)
2 Slice data partition A layer (Partition A:片头信息,片里面宏块头信息,最重要)
3 Slice data partition B layer (Partition B:帧内编码的数据)
4 Slice data partition C layer (Partition C:帧间编码的数据)
5 Slice layer without partitioning IDR
6 Additional information (SEI) 时间信息
7 Sequence parameter set 序列参数集(序列编号、帧数、参考帧数目、图像大小、场模式)
8 Picture parameter set 图像参数集(图像编号、熵编码方式、条带数目、初始量化步长)
9 Access unit delimiter
10 End of sequence
11 End of stream
12 Filler data
13…23 Reserved
24…31 Undefined

image.png

参考图片

H.264 编码器可以使用一到两个先前编码的图片作为参考,用于对每个帧间编码的宏块或宏块分区进行运动补偿预测。

这使得编码器可以从比先前编码的图片更广泛的图片集中搜索当前宏块分区的最佳匹配。

编码器和解码器各自维护一个或两个参考图片列表,其中包含先前已编码和解码的图片(出现在当前图片之前和/或之后的显示顺序中)。

  • P 帧中的帧间编码的宏块和宏块分区是从单个列表(列表 0)中的图片进行预测的。
  • B 帧中的帧间编码的宏块和宏块分区可以从两个列表(列表 0 和列表 1)中的图片进行预测。

Slices

一个视频图像被编码为一个或多个切片,每个切片包含从 1 个宏块到图像中的总宏块数的整数个宏块(每个图像一个切片)。

切片中的宏块数不需要在图像内是恒定的。编码切片之间的相互依赖性很小,这有助于限制错误的传播。

符合基准配置的比特流包含编码的 I 和/或 P 切片:

  • I 切片只包含帧内编码的宏块(从同一切片中先前编码的样本进行预测);
  • P 切片可以包含帧间编码的宏块(从先前编码的图片中的样本进行预测)、帧内编码的宏块或跳过的宏块。
    编码图像可以由不同类型的切片组成:
  • 基准档次的编码图像可以包含 I 和 P 切片的混合;
  • 主档次或扩展档次的图像可以包含 I、P 和 B 切片的混合。
    切片数据包括切片头、一系列编码的宏块和/或跳过的宏块的指示。
    切片头定义了切片类型和切片所属的编码图像,并可能包含与参考图片管理相关的指令。
考点 34:帧内预测、运动向量预测、帧间预测
考点 35:H.264 的 DCT 变换
考点 36:熵编码:指数格罗姆编码和 CAVLC

CAVLC

这是用于编码变换系数的残差和之字形有序块的方法。

image.png

CAVLC(Context-Adaptive Variable Length Coding)旨在利用量化的 4×4 块的几个特点:

  • 在预测、变换和量化之后,块通常是稀疏的(主要包含零)。
  • 在之字形扫描后,最高的非零系数通常是 +/-1 的序列。
  • 相邻块中的非零系数的数量是相关的。
  • 非零系数的级别(幅度)在之字形扫描开始时往往较高,并且随着频率增高而降低。

对一块变换系数进行 CAVLC 编码的过程如下:

  1. 编码系数的数量和尾部的 1。
  2. 编码每个尾部 1 的符号。
  3. 编码剩余非零系数的级别。
  4. 编码最后一个系数之前的零的总数。
  5. 编码每个零的连续出现次数。
  6. 编码系数的数量和尾部的 1
    第一步是编码非零系数的总数(NumCoef)和尾部的 1(T1s)。
    NumCoef 的取值范围可以是从 0(4x4 块中没有系数)到 16(16 个非零系数)。
    T1s 的取值范围可以是从 0 到 3。
    如果尾部的 +/- 1 的个数超过 3 个,只有最后 3 个被视为“特殊情况”,其他的被编码为普通系数。

例如:4x4 块

image.png

The Num-Coef = 7, and T1s = 3

用于编码 Num_Coeff 和 T1 的四个表格分别是 Num-VLC0、Num-VLC1、Num-VLC2 和 FLC。

Num-VLC0:

image.png

表格的选择取决于先前编码块中,上方和左方的非零系数的数量 NU 和 NL。

参数 N 的计算如下:

  • 如果块 U 和 L 都可用(即在同一个编码片中),N = (NU + NL) / 2。
  • 如果只有块 U 可用,N = NU。
  • 如果只有块 L 可用,N = NL。
  • 如果两者都不可用,N = 0。

表格的选择基于以下方式中的 N 值:

N Selected Table
0,1 Num-VLC0
2,3 Num-VLC1
4,5,6,7 Num-VLC2
8 or above FLC

FLC 的形式如下:xxxxyy(即 6 位)

其中 xxxx 和 yy 分别表示 Num_Coeff 和 T1。

  1. 对每个 T1 编码其尾随 1 的符号
    对于每个 T1,一个比特位编码其符号(0 表示正,1 表示负)。
    这些符号按照逆序编码,从最高频率的 T1 开始。

  2. 对剩余的非零系数编码其级别(符号和大小)
     块中每个剩余的非零系数的级别(符号和大小)按照逆序进行编码。
     选择用于编码每个级别的 VLC 表根据每个连续编码级别的大小进行自适应调整(上下文自适应)。
     有 7 个可供选择的 VLC 表,从 Level_VLC0 到 Level_VLC6。
     Level_VLC0 偏向较低的大小,Level_VLC1 偏向稍高的大小,依此类推。
     初始化表格为 Level_VLC0(除非非零系数超过 10 个且尾随 1 少于 3 个,在这种情况下从 Level_VLC1 开始)。
     编码最高频率的非零系数。
     如果该系数的大小大于预定义的阈值,则切换到下一个 VLC 表。

image.png

 级别的选择与最近编码的系数的大小相匹配。阈值列在表中;

 第一个阈值为零,这意味着在编码第一个系数级别之后,表总是递增。

  1. 编码最后一个系数之前的零的总数。

以下是用于编码最后一个系数之前的零的总数(TotZeros)的表格。

image.png

image.png

  1. 编码每个零的连续出现次数
    在每个非零系数之前的零的数量(run_before)按照逆序进行编码。对于每个非零系数,除了以下两种情况外,都会编码一个 run_before 参数:
    (a) 如果没有更多的零需要编码;
    (b) 对于最后(最低频率)的非零系数,不需要编码 run_before。

每个零的连续出现次数的 VLC 表的选择取决于:

(a) 尚未编码的零的数量(ZerosLeft);

(b) run_before。

image.png

例子:

image.png

考虑以下 4×4 帧间残差块

块的 Zigzag 重新排序如下所示:

0,3,0,1,-1,-1,0,1,0,0,0,0,0,0,0,0

因此,NumCoeff=5,TotZero=3,T1s=3

假设 N=1

编码:

image.png

解码:

image.png

心理声学模型

考点 19:心理声学模型:频域掩蔽、时域掩蔽、听觉阈值、SMR、关键带宽、巴克刻度、感知熵

声压等级 Sound Pressure Levels

声音以压力波的形式到达人耳。声压 pp[105,102][10^-5,10^2]Pa 范围之间变化。

声压等级 SPL,单位 dB:

SPL=10log10(pp0)2,p0=20μPaSPL= 10 \log_{10}{\left( \frac{p}{p_{0}} \right)^2}, p_{0}=20\mu Pa

p0 为音频在 2kHz 左右的听觉阈值处的声压。

声音也可以被声音强度 II 来描述,表示声波单位面积的功率,与 p 的平方成正比。

声压等级 SPL 也可以被定义为:

SPL=10log10(II0),I0=1012W/m2SPL= 10 \log_{10}{\left( \frac{I}{I_{0}} \right)}, I_{0}=10^{-12}W/m^2

I0I_0p0p_0 对应。

响度 Loudness

响度等级定义为,在正面入射平面场下,被感知到的与所检测的声音一样响亮的 1 kHz 声音的级别。

响度取决于强度、持续时间、时间和频谱结构。

单位为 phon,描述了自变量为频率的函数中一条等响曲线。下图每条曲线指的是同样的响度。

image.png

在高音量水平下,以 phon 为单位测量的响度与以 dB 为单位测量的声强之间的差异减小。

image.png

掩蔽现象

同时掩蔽(频域掩蔽)

image.png

频域掩蔽是指在掩蔽声与被掩蔽声同时存在时产生的掩蔽效应,又称为同时掩蔽。在这种情况下,掩蔽声在掩蔽效应发生期间持续影响着被掩蔽声,形成一种强烈的掩蔽效应。通常情况下,频域中的一个强音会掩盖附近较弱的声音,而距离强音较近的弱音往往更容易被掩蔽;相反地,距离较远的弱音不太容易受到掩蔽效应的影响。图 3 解释了频域掩蔽现象,可以看到一个强信号掩蔽了两个接近其频率的弱信号,低于掩蔽域值的弱信号将无法听见,这导致听觉的安静阈值在掩蔽作用下提高。一般来说,低频声音更容易掩蔽高频声音。

非同时掩蔽(时域掩蔽)

时域掩蔽效应是在时域中相邻的声音之间互相的掩蔽效应,或被称为非同时掩蔽。时域掩蔽又分为超前掩蔽(pre-masking 或 backward masking)和滞后掩蔽(post-masking 或 forward masking)

image.png

虚线之间是掩蔽声音实际的存在时间。

声音信号大多数时候是非稳态的瞬时信号,声压级随着时间变化很快,即强音后面跟着弱音,弱音后面又可能跟着强音。比较强的声音往往会掩蔽随后到来的较弱音。时域掩蔽又分为前掩蔽和后掩蔽。若掩蔽声音出现之前的一段时间内发生掩蔽效应,则称为前掩蔽;否则称为后掩蔽。前掩蔽效应要大于后掩蔽效应,前掩蔽发生作用的时间大于后掩蔽的时间。产生时域掩蔽的主要原因是人的大脑处理信息需要花费一定的时间,时域掩蔽也随着时间的推移很快衰减,是一种弱掩蔽效应。

窄带噪声掩蔽

image.png

信号掩蔽比(signal to mask ratio, SMR)。

注意:信噪比是 SNR(Signal-to-noise ratio)

窄带噪声通常是指带宽等于或者小于听觉临界频带的噪声。在图 1 中,以不同中心频率的窄带噪声作为掩蔽声时的听阈曲线,窄带噪声的中心频率分别为 0.25KHz,1KHz,4KHz,带宽分别为 0.1KHz、0.16KHz 和 0.7KHz,图上部水平虚线为掩蔽噪声声强级 60dB,中部实线表示刚好可听到的纯音声级,下部的虚线是听觉安静域值。从图中可以看出,被掩蔽纯音的频率偏离掩蔽噪声中心频率越大,掩蔽效应下降越快;因为是平滑以后的数据,故而不呈锯齿状。信号分量和掩蔽域值之间的声级差,称信号掩蔽比 (signal to mask ratio, SMR),SMR 越大,掩蔽效果越小。上图中,0.25KHz,1KHz,4KHz 的最小 SMR 分别为 2、3 和 5dB,最小 SMR 是设计音频编码器很重要的参数。

下图表示不同级别的掩蔽音调下,1kHz 窄带噪声掩蔽器的掩蔽阈值。

image.png

纯音掩蔽

image.png

从图中可以看出,当被掩蔽音声级较低时,掩蔽域值向低频扩展(斜率较小);而在声级较高时则相反。当掩蔽音声级为 90dB 时,掩蔽曲线峰值为 75dB,信号掩蔽比为 15dB。与噪声相比,纯音在掩蔽方面具有较大的信号掩蔽比(SMR),这意味着噪声比纯音具有更好的掩蔽效果。纯音的掩蔽效应基本符合以下几个规律:低频纯音容易掩蔽高频纯音,而高频纯音相对较难掩蔽低频纯音;频率相近的纯音容易互相掩蔽;当增加掩蔽声的声压级时,掩蔽阈值会提高,同时被掩蔽的频率范围也会扩展。

临界带宽

临界带宽指临界频带的带宽,即恰能产生变化的频率通带(频段)的宽度值。如响度测试中指恰能使声音响度产生变化的带宽值:当声音由一定频带组成时,它的响度变化呈现出下图所示的规律:带宽从很窄到越来越宽的过程中,声音整体响度开始时保持不变;当到达一个特定的带宽后,声音整体响度会随着带宽的变宽而变得更响。
image.png

image.png

Threshold of a narrow band noise centered between two sinusoidal maskers at a level of 50dB as a function of the frequency separation between the two sinusoidals.

掩蔽 Masking

掩蔽曲线的水平在接近遮蔽音调频率的地方最高

当测试信号频率超过临界带宽远离遮蔽音调频率时,掩蔽曲线迅速下降。

掩蔽频率曲线的形状取决于掩蔽音调的频率和水平

掩蔽曲线在很大程度上取决于掩蔽音调是音调还是噪声样式。

音频编码的心理声学模型

巴克刻度 Bark Scale

巴克刻度是一种心理声学的尺度。

临界频带指的是由于耳蜗构造产生的听觉滤波器的频率带宽。听觉系统中,耳蜗起着频谱分析的作用,基底膜上特定位置点是对某一特征频率(Characteristic Frequency, CF)的响应最大,当声波偏离 CF 时,该点的响应减少,因此基底膜上每一点可等效成具有特定中心频率(CF)的带通滤波器,整个听觉系统可等效成一系列具有连续 CF 的、相互交叠的带通滤波器,称为“听觉滤波器”。临界频带就是听觉系统带通滤波功能的反映,听觉滤波器的带宽即为临界带宽。

概括地说,临界频带是声音频率带,在临界频带中第一个单音感知度会被第二单音的听觉掩蔽所干扰。根据相关的心理声学的研究,由于人耳的特殊结构,在同一个临界频带内信号容易发生掩蔽效应,即:主要信号容易被能量大并且频率接近的掩蔽信号所掩蔽。因此我们可以认为 Bark 域越近的信号越容易产生掩蔽效应。

声学研究中,人们使用听觉滤波器来模拟不同的临界频带。后来研究者发现人耳结构大致会对 24 个频率点产生共振,根据这个结论 Eberhard Zwicker 在 1961 年针对人耳特殊结构提出:信号在频带上也呈现出 24 个临界频带,分别从 1 到 24。这就是 Bark 域。

通常将人耳可听范围内的 20Hz~16kHz 分成 24 个临界频带,用临界频带级来表示临界频带的宽度,单位为巴克(Bark):Bark=一个临界频带的宽度。当频率 f<500Hz 时,1 Bark=f/100,临界带宽几乎恒定为 100Hz;当频率 f>500Hz 时,1 Bark=4log(f/100), 临界带宽随中心频率的升高而增加,约为中心频率的 20%。
image.png

每个临界带宽(频率)对应于耳朵中基底膜上的固定距离。我们可以定义基底距离测量中的长度单位为一个临界带宽。

掩蔽传播模型

image.png

Excitation patterns for narrow-band noise signals centered at different frequencies and at a level of 60 dB.

image.png

Excitation patterns for narrow-band noise signals centered at 1kHz and at different levels.

image.png

The curve in the diagram be expressed as a function of the Bark scale difference between the maskee and masker frequency.

掩蔽曲线

image.png

MP3 的心理声学模型

image.png

感知熵

感知熵(Perceptual entropy)PE:在不引入任何感知差异的情况下,对信号进行编码所需的每个频率样本的平均比特数。

image.png

nbn_b 是分区带 b 中的频率线数量,energybenergy_b 是分区 b 中的信号能量,thresholdbthreshold_b 是掩蔽阈值。

PE 可以用于确定 MDCT 或 attack 的块类型(PE>1800 比特表示短窗口)

Block Switching State Diagram

image.png

本章参考的外部资源

🍂时频映射

音频编码框图:

image.png

T/F mapping: FFT, PQMF, MDCT

傅里叶变换

  • 1822 年,傅里叶指出实时信号可以表示为具有不同频率的信号的总和。

  • 傅里叶变换定义如下:
    image.png

  • 傅里叶逆变换等于:
    image.png

傅里叶级数

  • 对信号在有限时间间隔上的傅里叶变换可以用来在时域中重构原始信号。

  • 实际上,我们不需要完整的傅里叶变换数据来完全在时域中重构信号。

  • 我们只需要在离散频率点 f=k/T(其中 k 是整数)处的 X(f) 值。

  • 我们通过将窗口信号替换为在时间间隔从 -T/2 到 T/2 内相等的信号,但在该间隔之外周期性地重复,来进行数据压缩。
    对于生成的周期信号,我们可以定义傅里叶级数:
    image.png

  • X[k]X[k] 只是时间限定信号在离散频率集合 f=k/Tf=k/T 处的傅里叶变换。

  • 我们可以使用以下公式重构 x(t):image.png
    采样定理

  • 假设一个信号在频率范围从 -Fmax 到 Fmax 内具有频率内容。

  • 如果我们选择某个频率间隔 Fs≥2Fmax,并周期性地延续信号的频谱范围超出从 -Fs/2 到 Fs/2 的范围。

  • 从傅里叶级数的定义可以想象,这个频率周期函数只有离散时间分量 x[n]x[n](如果我们定义 T=1/FsT=1/F_s,则有 x[n]=x(nT)x[n]=x(nT))。

在时域中对信号进行窗函数处理

  • 假设我们开始处理一个带限信号,并以采样频率 Fs≥2Fmax 对信号进行采样。
  • 假设我们想要使用有限的样本块进行计算,以便在等待信号完成之前开始进行计算。
  • 实现这个目标的一种方法是将原始的非有限信号 x(t) 与矩形窗函数相乘。

矩形窗函数

  • 矩形窗函数 WR(t) 在 t=0 到 t=T 之间等于 1,在其他地方等于零。
  • 我们可能想知道这个时限信号是否仍然足够带限。
  • 时限信号的傅里叶变换等于原始信号的傅里叶变换与 WR(t) 的傅里叶变换 WR(f) 的卷积。
  • WR(f) 的傅里叶变换随着频率的增加下降得非常缓慢,这意味着时限信号的傅里叶变换很可能不再足够带限。
  • 如果我们使用这个窗函数,会发生混叠现象。

正弦窗函数

  • 矩形窗函数的问题在于窗口边缘处的截断非常尖锐。
  • 尖锐的变化会导致高频成分。
  • 在时域中,更好的窗函数选择是在边缘处缓慢衰减,以避免尖锐的不连续性。
  • 正弦窗函数为 ws(t) = sin(πt/T),0≤t≤T。当应用于离散时间信号的 N 个样本时,窗函数变为 ws[n] = sin(π(n+1/2)/N),其中 n=0,…,N-1。
  • 从频谱中可以看出,主瓣比矩形窗函数更宽,但频率幅度下降得更快。

汉宁窗函数

  • 汉宁窗函数在边缘处没有正弦窗函数那样的突变。
  • 汉宁窗函数为 wH(t) = 1/2(1-cos(2πt/T)),0≤t≤T。
  • 当应用于离散时间信号的 N 个样本时,窗函数变为 wH[n] = 1/2(1-cos[2π(n+1/2)/N]),其中 n=0,…,N-1。
  • 从频谱中可以看出,汉宁窗函数的衰减速度更快(有助于避免混叠),但其主瓣的宽度更大(对于准确的频率识别不利)。
  • 在窗函数设计中,我们面临权衡:低旁瓣能量(与杂散频率成分相关)和主瓣的宽度(窗函数的频率分辨率)。
考点 17:FFT 和复杂度

快速傅里叶变换(FFT)

  • 直接计算 DFT 需要 N2N^2 次复数乘法和加法运算。
  • 令人惊讶的是,FFT 允许我们在大约 N×log2NN×log_2N 次复数乘法/加法运算中完成完全相同的计算。
  • 以 N=1024 为例,FFT 只需要 DFT 所需计算时间的 1%。
  • 这个算法最早由高斯在 1880 年提出,后来由库利和图基在 1965 年重新发现。
考点 15:傅里叶变换、傅里叶级数、离散时间傅里叶变换、离散傅里叶变换
时域 频域
傅里叶变换 连续、无限 连续、无限
傅里叶级数 有限信号周期延拓,连续 离散
离散时间傅里叶变换 离散 有限频谱的周期延拓
离散傅里叶变换 离散,有限 离散,有限
考点 16:Windowing
去混叠 频率选择性
矩形窗 最差 最好
正弦窗 中等 中等
汉宁窗 最好 最差
考点 18:MDCT:重叠相加技术、长窗、短窗

MDCT

重叠相加技术

  • PQMF 通常被视为时频银行(Time Frequency banks)。相应的编码称为子带编码。
  • 如果在音频编码过程中,将时域的数据样本映射到频域的数据样本,例如使用 FFT,这种音频编码方法称为变换编码。
  • 我们已经知道,在进行 DFT 之前,音频信号会进行窗函数处理以避免混叠效应,在解码器中,我们需要知道如何恢复原始信号。
  • 除了应用逆离散傅里叶变换之外,我们还需要将窗函数的影响从数据中去除。
  • 第一种方法是将逆 DFT 的输出除以窗函数系数。
  • 问题在于量化/反量化会在信号中引入小的误差。
  • 这些误差可能是听不到的,但是将逆 DFT 的输出除以窗函数可能会放大数据块边缘附近的误差,因为窗函数在该区域被设计为平滑地趋近于零。

image.png

在编码器中,块输入信号是重叠的。在解码器中,我们重叠并相加输出信号。

窗函数的设计使得在没有量化的情况下可以恢复原始信号。

image.png

重叠量 NMN/2N-M ≤ N/2

在编码器中,每个连续的数据块从前一个数据块的起始位置后的 M 个样本开始,并包括 M 个新的数据样本。

在解码器中:

  • 我们将逆变换和窗函数处理后的数据的前 M 个样本传输到输出缓冲区。
  • 将剩余的 N-M 个样本存储到存储缓冲区中。
  • 我们将前一个数据块存储缓冲区中的 N-M 个样本与当前数据块输出缓冲区的前 N-M 个样本相加。
  • 然后,我们将输出缓冲区的 M 个样本发送到解码器的输出流中。

我们选择在解码器中进行窗函数处理的原因是:

  • 使逆变换块边缘附近的量化噪声较小;
  • 分析和合成阶段可以对称地进行。

对于分析和合成窗函数 wa[n]wa[n]ws[n]ws[n],有以下要求:

  • 在没有重叠的任何块区域中,image.png
  • 在重叠区域中,image.png
    该条件将一个块的窗函数的右侧与下一个块的窗函数的左侧相关联。i 是块的索引。

窗的选择:

如果分析和合成窗函数是相同的,我们有:

image.png

一个满足这个条件的简单窗函数是:

image.png

正弦窗口可能无法为特定应用提供频率分辨率与泄漏之间的权衡。实际上,我们可以通过一种归一化过程来修改任何窗口函数,以满足重叠相加条件。

image.png

如果 w’(p) 具有控制其形状的参数,我们可以调整这些参数以调节归一化窗口以适应特定应用。归一化过程可以使用 Kaiser-Bessel 窗口作为核窗口,并在相邻块之间具有 50% 的重叠来进行,从而创建所谓的“Kaiser-Bessel 衍生”窗口。

音频编码中的窗口考虑因素:

  • 在音频编码中,我们希望:
    • 最大化频率分离。
    • 最小化音频阻塞效应的影响。
  • 所选的窗口长度和形状与这两个属性有关。
  • 给定输入数据到滤波器组的块大小,窗口形状的选择决定了滤波器组的频谱分离程度:
    • 正弦窗口比α=4 的 KBD 窗口具有更好的近端选择性(主瓣更窄)。
    • 正弦窗口的侧瓣能量的抑制程度较差。
      根据输入音频信号的特性,正弦窗口或α=4 的 KBD 窗口可能为信号表示提供更好的频率分辨率:
  • 对于高度音调的信号,近端选择性比频率表示中的最终抑制更重要。
  • 如果信号的频率分量之间存在较大的分离,更高的最终抑制可以更好地利用信号分量的掩蔽效应。

改进离散余弦变换(MDCT):

  • 为了减少窗口化引起的阻塞效应,我们希望窗口边缘的过渡到零尽可能平缓。
  • 这意味着当我们设置大的重叠区域时,阻塞效应最小。
  • 然而,我们需要对每 M 个新的时间样本输入编码器的样本进行 N 个样本的变换数据的编码、传输/存储。
  • 在从冗余和无关信息去除中获得任何编码增益之前,我们将数据速率增加了 N/M 倍。
  • 为了解决这个问题,开发了 MDCT。
  • MDCT 是一种替代 DFT 的变换,允许块之间有 50% 的重叠,而不增加数据速率。
    image.png

MP3 的编码与解码

Normative:必须的,必要的

Informative:不必的

考点 22:MP3 的编解码器过程

编码器概览:

image.png

时频映射

PQMF:在一个帧中,对 1152 个 PCM 音频样本进行滤波,使得每个子带包含 36 个子带样本。

窗函数:在进行 MDCT 之前,对子带样本应用了四种不同的窗函数。

MDCT:使用两种不同的 MDCT 块长度,一种是长块,包含 36 个样本,另一种是短块,包含 12 个样本。短块适合变化较快的信号,长块适合平稳信号。

image.png

块模式

  • 注意,短块长度是长块长度的 1/3。在短块模式下,三个短块替代一个长块,这样无论块类型如何,音频样本帧的 MDCT 样本数量保持不变。
  • 对于给定的音频样本帧,MDCT 可以全部具有相同的块长度(长块或短块),或者采用混合块模式。
  • 在混合块模式下,MDCT 对于两个较低频率子带使用长窗口,对于 30 个较高频率子带使用短窗口。这种模式在不牺牲较高频率的时间分辨率的情况下,为较低频率提供更好的频率分辨率。

应用于 1152 个 PCM 样本的信号处理:

image.png

去混叠

image.png

在量化之前,应用了一种抗混叠处理来消除在分析 PQMF 中引入的混叠,以减少传输的信息量。

这种减少是通过一系列蝶形计算来实现的。

image.png

非均匀量化

image.png

image.png

global_gain:全局量化步长。控制比特率。

scale_factor:子带因子控制噪声。

在量化之前,将 MDCT 系数提升到 3/4 的幂,以在量化器值的范围内提供更一致的信噪比。

scale_factor 用于调整量化噪声,以适应掩蔽阈值的不同频率轮廓。

哈夫曼编码

有序的频率线被分为三个不同的区域,分别称为“rzero”、“count1”和“big_value”区域。

  • 连零区域:从较高的频率开始,编码器将连续的全零值识别为一个区域,即“rzero”区域。“rzero”区域必须包含偶数个零值。
  • 数 1 区域:4 个一起编码。由一系列仅包含 -1、0 或 1 的值组成。这个区域的两个霍夫曼表每次编码 4 个值,因此值的数量必须是 4 的倍数。
  • big_value 区:2 个一起编码。涵盖了所有剩余的值,称为“big_values”区域。这些值与 30 个霍夫曼表一起进行编码。这个区域进一步分为三个子区域,每个子区域都有自己特定的霍夫曼表。

比特分配(两层嵌套循环)

外层循环:

image.png

内层循环:

image.png

Quantizer_change is the change of global_gain.

考点 20:MP3:比特流格式、MP3 采样频率、stereo/joint channel/dual channel/single channel、哈夫曼编码域,比特池

比特流格式

为了生成符合 MP3 标准的比特流,霍夫曼编码的频率线、辅助信息和帧头被组合成比特流。

比特流被分割成帧,每帧表示 1152 个音频样本。

帧头描述了编码音频所使用的比特率和采样频率。

辅助信息告知使用的块类型、霍夫曼表、subband gain 和子带比例因子。

比特池

使用“比特储备池”方法来满足编码器对编码比特的时变需求。

编码器只能从过去的帧中借用比特,而不能从未来的帧中借用比特。

MPEG/Audio Layer 3 比特流使用一个 9 位指针,称为 main_data_begin,来表示当前处理帧的主数据的起始点。

image.png

Stereo Encoding

联合立体声

中侧立体声

强度立体声

MP3 解码器(Normative Elements)

MPEG 音频第三层解码概述:

image.png

解码器主要由三个部分组成:“比特流解码”,“逆量化”和“频率到时间映射”。

  • 输入的编码比特流通过第一部分进行同步,并提取每帧的量化频率线和其他信息。
  • 接下来,量化的频率线进行反量化。
  • 最后,应用逆 MDCT 和合成 PQMF 来获得以 PCM 格式输出的信号。

MP3 解码器的框图:

image.png

比特流解码框图:

image.png

辅助信息解码的过程

  • 帧中的辅助信息包含解码主数据所需的必要信息。
  • 它包含有关在 Huffman 解码过程中使用哪些霍夫曼表以及比例因子的信息。
  • 它还包含主数据开始的位置信息。

哈夫曼信息解码

  • Huffman 信息解码块的任务是设置 Huffman 解码块所需的所有参数。
  • 第一个任务是从辅助信息中收集有关 Huffman 编码比特的数据。这包括在比特流中找到 Huffman 编码的比特,并确定每个频谱区域分区所使用的 Huffman 表。
  • 此外,该块必须确保生成所有频率线,而不管 Huffman 编码比特中描述了多少频率线。当出现少于 576 个频率线时,Huffman 信息解码块必须执行零填充以填补数据的不足。

哈夫曼解码:

  • 由于 Huffman 编码是一种可变长度编码方法,没有尝试将 Huffman 编码比特中的各个码字分开,因此,如果不从已知为码字起始点的 Huffman 编码比特开始解码,无法识别 Huffman 编码比特中间的单个码字。
  • 如果在一串 Huffman 编码比特中发生错误,剩余的编码比特无法正确解码。我们可以直接找下一帧的同步字,那么这一帧就去掉。

子带因子解码:image.png

反量化(Dequantization)或去缩放(Descaling)

目的是重构编码器中由 MDCT 块生成的频率线的感知相同的数据。

长窗口的计算公式为:

image.png

短窗口的计算公式为:

image.png

反量化:

  • 全局步长(global_gain)定义了在一个 granule 内用于一个声道的量化步长
  • 编码器中的比例因子(scalefactors)使用步长为 2 或 sqrt(2) 进行量化,可以通过 scalefac_scale 标志的值来识别,如果 scalefac_scale=0,则 scalefac_multiplier=0.5,否则 scalefac_multiplier=1。
  • pretab 和 preflag 变量仅在长窗口的情况下使用。一个表格为 pretab 变量的每个比例因子带指定了一个单独的值。
  • 对于短窗口,通过 subblock_gain 指定了一个 gain factor。

重新排序(Reordering)

通过解量化生成的频率线并不总是以相同的方式排序。

在长窗口的 MDCT 块中,它会首先按子带,然后按频率生成排序的频率线。

为了增加频率线的 Huffman 编码效率,在短窗口中,频率线首先按子带排序,然后按频率排序,最后按窗口排序。

立体声处理

在解量化之后,重构的值在进入合成滤波器组之前进行中侧处理(MS)。

在中侧立体声(MS)模式下,传输的是归一化的中侧(middle/side)通道值 Mi/Si,而不是左右(left/right)通道值 Li/Ri。因此,可以使用这些 Mi/Si 值来重构 Li/Ri。

image.png

去混叠

image.png

反向 MDCT

从去混叠块中处理的频率线通过 IMDCT 块进行处理。IMDCT 的表达式如下所示:

image.png

Xk 表示频率线,对于短块 n=12,对于长块 n=36。

根据 block_type 值,xi 与之前定义的窗口之一相乘:

image.png

IMDCT 的重叠相加

image.png

合成多相滤波器组

image.png

编码语法(Normative Elements)

位流格式

一个 MP3 位流被组织成音频帧,其中包括五个部分:头部、CRC、辅助信息、主数据和附加数据。

单声道的辅助信息块长度为 136 位,双声道的辅助信息块长度为 256 位。

image.png

1
2
3
4
5
6
7
8
// 音频帧
frame()
{
header()
error_check()
audio_data() // 音频数据
ancillary_data()
}

一开始的 32 位(4 字节)是头部信息。

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
header()
{
syncword 12 bits bslbf // 12个1
ID 1 bit bslbf // 表明算法的ID。1表示MPEG音频,0做保留
layer 2 bits bslbf // 表明使用的层级。
// 11:Layer I; 10 Layer II
// 01:Layer III; 00 保留
protection_bit 1 bit bslbf // 指示是否在音频比特流中增加了冗余,以方便错误检测。
// 1:没有冗余,0:增加了冗余
bitrate_index 4 bits bslbf // 指示比特率。全0表示'free format',
// 可以使用不出现在列表中的固定比特率
sampling_frequency 2 bits bslbf // 抽样频率
padding_bit 1 bit bslbf // 1:帧包含额外的槽以调整平均比特率到采样频率,否则为0。
// padding只在44.1kHz采样频率下才有必要使用。
private_bit 1 bit bslbf // 私用比特。未来ISO将不再使用。
mode 2 bits bslbf
mode_extension 2 bits bslbf // 用于联合立体声模式中(mode='01')
// 指名应用哪种联合立体声编码方法类型。
//该算法中隐含了应用强度立体声模式和ms_stereo模式的频率范围
copyright 1 bit bslbf // 0:编码的比特流没有版权,1:存在版权保护
original/home 1 bit bslbf // 0:比特流为副本,1:比特流为原始版本
emphasis 2 bits bslbf // 加重的信息。表明解加重需要使用的类型。
}
bit_rate_index bit rate
‘0000’ free
‘0001’ 32 kbit/s
‘0010’ 40 kbit/s
‘0011’ 48 kbit/s
‘0100’ 56 kbit/s
‘0101’ 64 kbit/s
‘0110’ 80 kbit/s
‘0111’ 96 kbit/s
‘1000’ 112 kbit/s
‘1001’ 128 kbit/s
‘1010’ 160 kbit/s
‘1011’ 192 kbit/s
‘1100’ 224 kbit/s
‘1101’ 256 kbit/s
‘1110’ 320 kbit/s
‘1111’ forbidden

sampling_frequency 抽样频率:

MPEG-1 MPEG-2
‘00’ 44.1kHz 22.05kHz
‘01’ 48 kHz 24kHz
‘10’ 32 kHz 16kHz
‘11’ reserved reserved

mode:

‘00’ stereo 立体声
‘01’ joint_stereo 联合立体声 (intensity_stereo 增强立体声 and/or ms_stereo) ms->mid-size
‘10’ dual_channel
‘11’ single_channel 单通道

mode_extension:

intensity_stereo ms_stereo
‘00’ off off
‘01’ on off
‘10’ off on
‘11’ on on

emphasis:

‘00’ no emphasis
‘01’ 50/15 microsec. emphasis
‘10’ reserved
‘11’ CCITT J.17

ErrorCheck

1
2
3
4
5
error_check()
{
if (protection_bit==0) // 在Header中
crc_check 16 bits rpchof
}

Audio Data

每一个音频帧包含来自 1 到 2 个音频 granules 的压缩数据。

每一个 granule 由 18*32 子带样本组成

帧中的音频数据以下面的方式进行分配:

  • main_data_begin pointer
  • side info for both granules (scfsi)
  • side info granule 1
  • side info granule 2
  • scalefactors and Huffman code data granule 1
  • scalefactors and Huffman code data granule 2

边信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
audio_data(){
main_data_begin 9 bits uimsbf // main-data-begin 的值用于确定帧的主数据的第一个比特的位置。它将该位置指定为相对于音频同步字节的负偏移量(以字节为单位)
if (mode == single_channel) {
private_bits 5 bits bslbf // 用于私有用途的位。这些位在ISO的未来不会被使用。
// scfsi_band 控制着尺度因子组(scfsi_bands)的尺度因子选择信息的使用。
for (scfsi_band=0; scfsi_band<4; scfsi_band++)
scfsi[scfsi_band] 1 bits bslbf // 尺度因子选择信息。
// scfsi 控制着对于每个粒度是否传输尺度因子:
// '0' 对于每个粒度都传输尺度因子。
// '1' 对于粒度0传输的尺度因子也适用于粒度1。
for (gr=0; gr<2; gr++) {
part2_3_length[gr] 12 bits uimsbf
// 该值包含用于尺度因子和Huffman编码数据的主数据比特数。
// 由于边信息的长度始终相同,可以使用该值来计算每个粒度的主要信息的起始位置
// 以及辅助信息的位置(如果使用)。
// part2_length - 该值包含用于尺度因子的主数据比特数。
big_values[gr] 9 bits uimsbf // 每个粒度的频谱值使用不同的Huffman编码表进行编码。
// 完整的频率范围被分成几个区域,然后使用不同的Huffman表进行编码。
global_gain[gr] 8 bits uimsbf // 全局量化步长
scalefac_compress[gr] 4 bits bslbf // 选择用于比例因子传输的位数。
blocksplit_flag[gr] 1 bit bslbf // 表示该块使用非正常(类型0)的窗口。
}
}
if (blocksplit_flag[gr]){
block_type[gr] 2 bits bslbf // 指示实际粒度的窗口类型。
switch_point[gr] 1 bits uimsbf // 表示短/长变换的分割点。
for (region=0; region<2; region++)
table_select[region][gr] 5 bits bslbf // 指定用于压缩特定量化MDCT区域的Huffman编码表。
for (window=0; window<3; window++)
subblock_gain[window][gr] 3 bits uimsbf // 表示一个子块相对于全局增益的增益偏移量。仅在块类型2(短窗口)中使用。
}
else{
for (region=0; region<3; region++)
table_select[region][gr] 5 bits bslbf
// region_address1[gr],region_address2[gr]
// 对频谱进行进一步分区,以增强Huffman编码器的性能。
// 这是对big_values区域的细分。这个细分的目的是获得更好的错误鲁棒性(tea:这一点表示怀疑)和更好的编码效率。使用三个区域。
// 每个区域根据最大量化值和局部信号统计使用不同的Huffman编码表进行编码。
region_address1[gr] 4 bits bslbf
region_address2[gr] 3 bits bslbf
}
preflag[gr] 1 bit bslbf // 这是对量化值进行额外高频放大的快捷方式。
scalefac_scale[gr] 1 bit bslbf // 比例因子按对数方式进行量化,步长为2,取决于scalefac_scale的值。
// scalefac_scale = 0,步长为sqrt(2)
// scalefac_scale = 1,步长为2
count1table_select[gr] 1 bit bslbf // 此标志选择两个可能的Huffman编码表之一,用于幅度不超过1的量化值四元组的区域。
}
scfsi_band scalefactor bands
0 0,1,2,3,4,5,
1 6,7,8,9,10,
2 11 … 15
3 16 … 20

image.png

在长窗口的情况下,slen1 是用于比例因子带 0-10 的比例因子的长度。slen2 是用于比例因子带 11-21 的比例因子的长度。

scalefac_compress slen1 slen2
0 0 0
1 0 1
2 0 2
3 0 3
4 3 0
5 1 1
6 1 2
7 1 3
8 2 1
9 2 2
10 2 3
11 3 1
12 3 2
13 3 3
14 4 2
15 4 3

Main Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for (gr=0; gr<2; gr++)
if (blocksplit_flag[gr] == 1 && block_type[gr] == 2){
for (cb=0; cb<switch_point_l[gr]; cb++)
if (scfsi[cb]==0) || (gr==0)
scalefac[cb][gr] 0..4 bits uimsbf
for (cb=switch_point_s[gr]; cb<cblimit_short; cb++)
for (window=0; window<3; window++)
if (scfsi[cb]==0) || (gr==0)
scalefac[cb][window][gr] 0..4 bits uimsbf
}
else
for (cb=0; cb<cblimit; cb++)
if (scfsi[cb]==0) || (gr==0)
scalefac[cb][gr] 0..4 bits uimsbf
Huffmancodebits (part2_3_length-part2_length) bits bslbf
while (position != main_data_end){
ancillary_bit 1 bit bslbf
}
}

scalefac[cb][gr] - 比例因子用于给量化噪声上色。如果量化噪声被正确形状的颜色掩盖,它将完全被掩盖。

编码器和解码器使用比例因子来获取数值块的除法因子。这些块延伸到多个频率线上。这些块被称为比例因子带,被选择得尽可能接近临界带。

比例因子压缩表显示,比例因子 0…10 的范围为 0 到 15(最大长度为 4 位),比例因子 11…21 的范围为 0 到 7(最大长度为 3 位)。

将频谱细分为比例因子带对于每个块长度和采样频率是固定的,并存储在编码器和解码器的表中。

Huffman_code_bits - 伪函数

  • 所有绝对值小于等于 15 的量化值直接使用 Huffman 编码进行编码。总是对值 (x,y) 进行编码。
  • 如果发现幅度大于 15 的量化值,则使用 ESC 码来标记这些值。
  • 如果一对值中的一个或两个值不为零,则在 Huffman 编码字后附加一个或两个符号位。

hcod[|x|][|y|] 是值 x、y 的 Huffman 编码表条目。

hlen[|x|][|y|] 是值 x、y 的 Huffman 长度表条目。

max_table_entry 是最大的表条目索引。这是一个系统常量(15,单个表中的最大条目数为 256)。

signx 是第一个值的符号(如果为正,则为 0;如果为负,则为 1)。

signy 是第二个值的符号(如果为正,则为 0;如果为负,则为 1)。

考点 21:MP3 huffman code: linebits
1
2
3
4
5
6
7
struct coded_word {
codeword // hcod[|x|][|y|], length is hlen[|x|][|y|]
linbitsx // 如果(x=15),则构成一个ESC码。在这种情况下,该字段的长度为linbits,否则为零。该字段中包含的无符号整数加上15,以确定编码数据的绝对值。
signx // sign of x (transmitted only if x not equal 0)
linbitsy // See linbitsx.
signy // sign of y (transmitted only if y not equal 0)
}

只有在实际标记了大于或等于 15 的值时,才会使用 ESCaped 代码 linbitsx 或 linbitsy。

image.png

Huffman 编码

对于频谱的高端部分,使用两个特殊的 Huffman 表对值的四元组进行编码。

1
2
3
4
5
6
7
struct quad_word {
codeword // hcod[|v|][|w|][|x|][|y|],hlen[|v|][|w|][|x|][|y|]
signv //(仅当v不等于0时)
signw //(仅当w不等于0时)
signx //(仅当x不等于0时)
signy //(仅当y不等于0时)
}

在频谱的高端部分,只需计算零对的数量。由于当其他值已解码时,这个值是隐含已知的,因此不需要传输。

Huffman 编码数据的排序方式:

  • 如果 block_type 为 0、1 或 3,则根据频率递增的顺序对 Huffman 编码数据进行排序。
  • 如果 block_type 为 2(短块),则 Huffman 编码数据的排序如下:
    • 首先给出连续的比例因子带的 Huffman 编码数据,从比例因子带 0 开始,以比例因子带 11 结束。
    • 在每个比例因子带内,按照时间窗口的顺序给出数据,从窗口 0 开始,以窗口 2 结束。每个窗口内的数据值按照频率递增的顺序排列。

Characteristic of 32 Huffman tables:

image.png

image.png

TIP: 考试的时候以长块为准。

cb_limit - 长块(block_type != 2)的比例因子带数量。对于所有模式和所有采样频率的 Layer III,这是一个常数,为 21。

cb_limit_short - 短块(block_type=2)的比例因子带数量。对于所有模式和所有采样频率的 Layer III,这是一个常数,为 12。

window - 在 block_type=2 的情况下,实际时间槽的数量。window 的取值为 0、1、2。

88、010 编辑器之模板的使用

什么是 010 编辑器

010 编辑器是一个专业的文本/HEX 编辑器,它可以快速并易于编辑电脑上的任何文件内容。

  • 查看并编辑任何硬盘上的二进制文件,以及文本文件(Unicode 文件、C/C++ 源文件等)
  • 独家的二进制模板技术能让你理解任何二进制文件
  • 通过强大的工具(查找、替换等功能)分析并编辑文本以及二进制数据
  • 使用硬盘、软盘等查找并修复问题

二进制模板

010 编辑器可以将二进制文件已易于使用的方式将其结构呈现在你的面前。二进制模板可以将二进制文件解析为指定的结构。

模板有着和 C/C++ 相似的结构,但它们是以一个程序运行的。当模板中的变量声明后,变量将映射到当前文件的对应字节集合。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
struct FILE {
struct HEADER {
char type[4]; // 映射文件的0~3字节(注意,从0开始数)
int version; // 映射文件的4~7字节
int numRecords; // 映射文件的8~11字节
} header;
struct RECORD {
int employeeId;
char name[40];
float salary;
} record[header.numRecords];
} file;

当访问一个变量时,其值从文件中读出;当对一个变量进行赋值时,其值将写回文件。

这些模板的 structures 和常规的 C 不同,因为它包含了控制语句,如 if,for,while。

模板的执行顺序为从文件顶端到底部。

写一个二进制模板

模板基础

模板可以使二进制文件更容易理解和编辑。每一个模板是以 .bt 为后缀的文本文件,可以被 010 编辑器编辑。

数字

Decimal - 456

Hexadecimal - 0xff, 25h, 0EFh

Octal - 013 (任何数字前加 0)

Binary - 0b011

无符号值:数字后加 u,例如 12u

8 字节的 int64:数字后加 L,例如 1L

浮点数中对于一个指数会包含 e,例如 1e10

浮点数默认为 8 字节 double 型,除非数字后加了 f(4 字节 float,例子:2.0f)

数据类型

8-Bit Signed Integer - char, byte, CHAR, BYTE

8-Bit Unsigned Integer - uchar, ubyte, UCHAR, UBYTE

16-Bit Signed Integer - short, int16, SHORT, INT16

16-Bit Unsigned Integer - ushort, uint16, USHORT, UINT16, WORD

32-Bit Signed Integer - int, int32, long, INT, INT32, LONG

32-Bit Unsigned Integer - uint, uint32, ulong, UINT, UINT32, ULONG, DWORD

64-Bit Signed Integer - int64, quad, QUAD, INT64, __int64

64-Bit Unsigned Integer - uint64, uquad, UQUAD, UINT64, QWORD, __uint64

32-Bit Floating Point Number - float, FLOAT

64-Bit Floating Point Number - double, DOUBLE

模板中可以使用数字类型,但数字在被运算前,必须转换为 int 或 float

类型定义 typedef

其他类型可以通过 typedef 关键字创建。

1
2
3
4
5
6
7
8
9
10
11
// 创建类型语法:
typedef <data_type> <new_type_name>
// 例子:创建新类型myInt,表示无符号整数
typedef unsigned int myInt;

// 运用于数组:
typedef <data_type> <new_type_name> [ <array_size> ]
// array_size必须为常量,typedef不能用于创建多维数组,但可以在structs中使用。
// 例子:生成新的字符串类型数组
typedef char myString[15];
myString s = "Test";

声明模板变量

声明变量的方法类似于 C 语言但有一个重要的区别:模板中已声明的变量映射到文件中的一组字节。

可以通过定义 structs 或 unions 的方法将模板变量组织起来。

特殊属性

变量后后面可以使用 <> 将一个或多个的特殊属性括住。

支持以下属性:

1
2
3
4
5
6
7
8
9
<
format = hex|decimal|octal|binary,
fgcolor = <color>,
bgcolor = <color>,
comment = "<string>",
open = true|false|suppress,
hidden = true|false,
read = <function_name>
>

局部变量

在有些情况中,一些变量不需要映射到文件中的值或者显示在「模板结果」中(可以右击「模板结果」开启局部变量的查看)。我们可以使用关键字 local 声明变量。例子:

1
2
3
4
5
local int i, total = 0;
int recordCounts[5];
for( i = 0; i < 5; i++ )
total += recordCounts[i];
double records[ total ];

字符串

通常二进制文件中定义了 Null 结尾的字符串。010 编辑器可以通过特殊的语法进行阅读:

1
2
3
4
5
6
// 以下两种方法将读取字符串,直到遇到「0」字节
char str[];
string str;
// Unicode 字符串可以使用以下两种方法阅读:
wchar_t str[];
wstring str;

字符串中可以使用=、+、+=以及比较运算符,例子:

1
2
3
4
5
6
local char str[15] = "First";
local string s = "Second";
local string r1 = str + s;
local string r2 = str;
r2 += s;
return (r1 == r2);

颜色

解析文件时,使用模板可以将不同颜色应用到不同的变量上,有两种方式:

  • 方式一:对单个变量设置颜色
    1
    2
    3
    4
    5
    // 语法:在变量后添加以下标签
    <fgcolor=???> // 设置前景色
    <bgcolor=???> // 设置背景色
    // 例子:
    int id <fgcolor=cBlack, bgcolor=0x0000FF>;
  • 方式二:使用 SetForeColorSetBackColorSetColor 函数设置默认颜色。
    1
    2
    3
    4
    5
    6
    7
    8
    // 在这些函数后定义变量
    SetForeColor( cRed );
    int first; // will be colored red
    int second; // will be colored red

    // 关闭涂色的方法
    SetForeColor( cNone );
    int third; // will not be colored

顺序

当每一个模板变量都声明后,「当前文件的位置」将向前移动。可以通过使用函数 FTell 获取「当前文件位置」。

通过使用 FSeek 或 FSkip 函数,「当前位置」可以在整个文件中移动。这项技术允许我们不按顺序解析文件。

可以使用 ReadByte, ReadShort, ReadInt 等函数实现不定义变量而读取文件。

考点 14:010 编辑器:Array、Struct

结构 struct

关键字 struct 可以定义一个数据结构。可以使用 C/C++ 语法进行定义。例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 生成新类型myStruct,但不声明任何变量
struct myStruct {
int a;
int b;
int c;
};
// 声明一个结构
myStruct s;

// 定义结构并声明两个实例
// 其中,s1覆盖文件的前12个字节,s2覆盖接下来的12个字节
struct myStruct {
int a; // 4字节
int b;
int c;
} s1, s2;

使用控制语句(ifforwhile)的结构。例子:

1
2
3
4
5
6
7
8
// 实例s只生成两个变量:a、b或a、c
struct myIfStruct {
int a;
if( a > 5 )
int b;
else
int c;
} s;

结构可以嵌套,也可以声明数组。例子:

1
2
3
4
5
6
struct {
int width;
struct COLOR {
uchar r, g, b;
} colors[width];
} line1;

使用 typedef 定义 struct 的别名:

1
2
3
4
typedef struct {
ushort id;
int size;
} myData;

联合 union

union 中,所有变量从相同的位置开始。union 的大小为其中最大变量的大小。

可以使用和 struct 相同的语法进行声明。例子:

1
2
3
4
5
6
// 以下Union大小为8字节
union myUnion {
ushort s;
double d; // 8字节
int i;
} u;

带参数的 struct 和 union

struct 或 union 关键字后可以接参数列表。参数列表的定义和函数相似。例子:

1
2
3
4
5
6
7
8
9
10
11
12
struct VarSizeStruct (int arraySize)
{
int array[arraySize];
};
// 声明实例。传递参数到结构体中
VarSizeStruct s1(5);

// 可以使用typedef声明
typedef struct (int arraySize)
{
int array[arraySize];
} VarSizeStruct;

数组 Array

数组变量定义的语法:

1
<data type> <variable name> [ <expression> ] // 例子:int myArray[15];

一些例子:

1
2
3
4
5
// 与ANSI C不同的是,数组的大小可以为任意表达式(包括变量、函数或操作符)
int myArray[ FileSize() - myInt * 0x10 + (17 << 5) ];

// 使用中括号获取单个元素
myArray[i] = value;

当数组的大小定义为 0 时将有警告提示(不是异常)并且不声明任何变量。

010 编辑器允许数组以特殊的方式构建。当定义模板变量时,可以定义多个名称相同的变量。010 编辑器将这些相同变量看作数组,称之为 Duplicate Array。例子:

1
2
3
int x; int x; int x;
// 可以这样读取:
x[0]; // 读取第一个x的值

可以使用 for 或 while 定义 Duplicate arrays:

1
2
3
local int i;
for( i = 0; i < 5; i++ )
int x;

表达式

image.png

可以使用任何的赋值运算符:+=, -=, *=, /=, &=, ^=, %=, |=, <<=, >>=

可以使用小括号组合表达式。

布尔运算符

&&(AND)

||(OR)

!(NOT- 单操作符)

可以使用小括号指定操作顺序。

控制语句

可以使用 break、continue、return

if 语句

1
2
3
4
5
6
7
8
9
10
if( x < 5 )
x = 0;

if( y > x )
max = y;
else
{
max = x;
y = 0;
}

for 语句

1
2
3
4
for( i = 0, x = 0; i < 15; i++ )
{
x += i;
}

while 语句

1
2
3
4
5
6
7
8
9
10
11
while( myVar < 15 )
{
x *= myVar;
myVar += 2;
}

do
{
x *= myVar;
myVar += 2;
}while( myVar < 23 );

switch 语句

1
2
3
4
5
6
switch( <variable> )
{
case <expression>: <statement>; [break;]
...
default : <statement>;
}

比特域

比特域允许细分结构为多组比特。这一过程允许将多个变量打包成一个块的内存。

定义比特域的语法:

1
2
type_name <variable_name> : number_of_bits;
// type_name 可以是char, short, int, int64 (unsigned or signed) 或其他的等效类型

如果变量名省略,那么对应这个变量的比特数也将省略。例子:

1
2
3
4
// 打包alpha和beta为一个32比特的值中,但忽略中间的12bit
int alpha : 5;
int : 12;
int beta : 15;

比特域模式

010 编辑器有两个特殊的比特域模式,定义了比特如何打包到变量中:

  • padded bitfields(默认)。比特打包为变量的方式取决于当前的字节顺序(大小端)。默认为,小端文件从右到左打包,大端文件从左往右打包。
  • unpadded bitfields
Padded bitfields

例子:

1
2
3
4
5
ushort a : 4;
ushort b : 7;
ushort c : 5;
// 小端模式下,结构存储为:cccccbbb bbbbaaaa
// 大端模式下,结构存储为:aaaabbbb bbbccccc

当需要的时候,程序会增加填充。例如某些特定的比特域将跨越变量的边界,这将会添加填充使得比特域从下一个变量开始。例如:

1
2
3
4
5
6
7
8
9
// 第一个变量
int apple : 10;
int orange : 20;
// 第二个变量
int banana : 10;
int peach : 12;
// 此处填充10个比特
// 第三个变量
short grape : 4; // 字节类型改变为short
Unpadded Bitfields

将文件视为一个长长的比特流,不管是变量类型改变时还是比特不能被打包为单个变量时,都不存在任何的填充比特。

进入此模式的方法:调用 BitfieldDisablePadding 函数(调用 BitfieldEnablePadding 以返回 padding 模式)

在 unpadded Bitfield 模式中,每一个定义的变量从比特流中读取比特。例如:

1
2
3
4
5
6
BitfieldDisablePadding();
short a : 10; // 从文件中读取10个比特
int b : 20; // 读取接下来的20个比特
short c : 10;
// 如果比特域被定义为从右到左读取(小端数据的默认方式,或使用了BitfieldRightToLeft函数)
// 变量将以此方式存储比特:aaaaaaaa bbbbbbaa bbbbbbbb ccbbbbbb cccccccc

函数

010 编辑器中内置有大量的函数。支持许多标准 C 函数,并以首字母大写以区分它们。

调用

使用典型 C 语言语法进行函数调用:<function name> ( <argument_list> ),例子:Strlen(str);

定义

常规 C 语法:<return type> <function name> ( <argument_list> ) {<statements> }

return type 可以为 void 或其他支持的数据类型。

函数的参数

函数通常使用值传递,在变量名称前加上 & 可以使用引用传递。

在参数名称后加上 [] 表明其为数组类型,数组类型会尽量为引用传递,否则为值传递。

接口函数

int Printf(const char format[][,argument,...])

image.png

支持宽度、精度、对齐的调整。如 %5.2lf%-15s\n 表示换行。

void Warning(const char format[] [,argument,...])

Printf 函数相似,但结果字符串显示在状态栏中,并以橘色高亮显示。通常用于显示模板中的错误。

I/O 函数

void BigEndian()

表明所有从文件中读写的子序列使用大端顺序。用于指定变量的字节顺序。

void LittleEndian()

小端。

读取函数

char ReadByte( int64 pos )

double ReadDouble( int64 pos )

float ReadFloat( int64 pos )

int ReadInt( int64 pos )

int64 ReadInt64( int64 pos )

int64 ReadQuad( int64 pos )

short ReadShort( int64 pos )

uchar ReadUByte( int64 pos )

uint ReadUInt( int64 pos )

uint64 ReadUInt64( int64 pos )

uint64 ReadUQuad( int64 pos )

ushort ReadUShort( int64 pos )

返回从地址 pos 读取文件的内容。用于不声明任何变量从文件中读取数据。

int FEof()

如果当前读取位置为文件末尾,则返回 true。

int64 FileSize()

返回当前文件的比特数。

int FSeek(int64 pos)

设置当前读取位置为 pos 指向的地址。如果地址超出范围返回 -1,成功则返回 0。

int FSkip(int64 offset)

将当前读取位置向前移动 offset 字节。offset 可以为负,即将读取位置向后移动。如果地址超出范围返回 -1,成功则返回 0。

int64 FTell()

返回当前文件的读取位置。

数学函数

double Abs(double x)

double Ceil(double x)

double Cos(double a) double Sin(double a) double Tan(double a) The angle is given in degrees.

double Exp(double x)

double Floor(double x)

double Log(double x) 计算 x 的自然对数,ln(x)

double Max(double a, double b) double Min(double a, double b)

double Pow(double x, double y)

int Random(int maximum) 返回 0 到 maximum-1 的随机整数

double Sqrt(double x ) 计算数字 x 的正平方根

data_type SwapBytes(data_type x) 交换变量的比特并返回结果,可以指定任何的数据类型 (byte, short, int, int64, float, double)

模板限制

  • 不允许使用指针
  • 不支持 goto 语句
  • 不支持多维数组(包括字符串数组)的定义。写模板时,struct 和数组的合并可以模拟多维数组。例如:
    1
    2
    3
    4
    5
    typedef struct
    {
    float row[4];
    } MATRIX[4];
    MATRIX m;

名词解释

名词解释是考试内容之一。

JPEG:Joint Photographic Experts Group 联合图像专家组

MPEG:Moving picture Experts Group 运动图像专家组

TIFF:Tagged Image File Format 标记图像文件格式

AIFF:Audio Interchange File Format 音频交换文件格式

RIFF:Resource Interchange File Format 资源交换档案标准

ISO:International Organization for Standardization

ITU:International Telecommunication Union 国际电信联盟

ITU-T:International Telecommunications Union-Telecommunications

IEC:International Electrotechnical Commission 国际电工委员会

有另译:International Engineering committee

PCM:Pulse Code Modulation 脉冲编码调制

DPCM:Differential Pulse-code Modulation 差分脉冲编码调制

ADPCM:Adaptive Differential Pulse Code Modulation 自适应差分脉冲编码调制

AAC:Advanced Audio Coding

AVI:Audio Video Interleave

CODEC:enCOder / DECoder pair,解编码器

DCT:Discrete Cosine Transform

MDCT:modified discrete cosine transform

IDR:立即编码刷新

本课知识点

所有知识点如下:

  1. Audio, image and video format, container
  2. Video compression standards and applications
  3. AVI container
  4. Window Bitmap file structure
  5. WAVE format
  6. Explain the meaning of FOURCC tags “ 00db” , “ 01dc” , “01wb” ,“vids” , and “auds” in AVI container.
  7. What is CD data rate?
  8. List the components of a chunk.
  9. Potential coding errors
  10. Lossy compression and lossless compression
  11. Uniform and quantization and nonuniform quantization
  12. entropy and Huffman coding
  13. MS-ADPCM
  14. 010 editor: Array, struct
  15. Fourier transform, Fourier series, Discrete time Fourier transform, Discrete Fourier transform
  16. Windowing
  17. FFT and complexity
  18. MDCT: overlap and add technique, long window, short window
  19. Psychoacoustics: Frequency masking, temporal masking, threshold in quiet, signal to masker ratio, critical bandwidth, bark scale, perceptual entropy
  20. MP3: bitstream format, MP3 sampling frequency, stereo/joint channel/dual channel/single channel, Huffman coding region, bit reservoir
  21. MP3 huffman code: linebits
  22. MP3 encoder and decoder process
  23. Color space
  24. Video frame format
  25. Image and video coding principles: four types of redundancy
  26. Three basic types of code frame in video coding
  27. Motion estimation and compensation
  28. JPEG encoding and decoding process: Minimum code Unit, modes of operation, DC entropy coding, AC entropy coding, run-length, size, EOB
  29. JPEG interchange format: image, frame, scan, marker,
  30. JPEG file interchange format
  31. Video encoding and decoding architecture: normative, informative
  32. MPEG coding structure, MPEG syntax
  33. H.264 encoding structure, baseline profile, main profile, vector block size, new features, video coding layer and network abstraction layer
  34. Inter frame prediction, motion vector prediction, Intra-frame prediction
  35. DCT transform in H.264
  36. entropy coding: Exp-Golomb coding and CAVLC