• 【多媒体信号处理课程】Course Introduction-1 AVI Walk Through-2 Audio coding basics-3 AI翻译


    Course Introduction-1 多媒体信号处理课程介绍

    1
    多媒体信号处理
    Multimedia Signal Processing

    3
    课程内容

    • M. Bosi,《数字音频编码技术与标准导论》
    • I. G. Richardson,《H.264和MPEG-4视频压缩》
    • 其他讲义

    4

    什么是多媒体?

    • 多媒体是指使用多种媒体形态的组合内容。
    • 多媒体包括文字、音频、静态图像、动画、视频或交互式内容的组合。
    • 应用:广告、艺术、教育、娱乐、工程、医学、数学、商业等。

    什么是信号处理?

    • 信号处理是系统工程、电子工程和应用数学的一个领域,处理或分析模拟和数字化信号,表示时间变化或空间变化的物理量。
    • 典型操作和应用:
      • 信号获取和重建
      • 信号压缩(源编码)
      • 特征提取,如图像理解
      • 品质改进,如降噪、图像增强等

    7
    本课程的内容

    • 多媒体信号处理和压缩导论
      • 音频处理和压缩
      • 图像处理和压缩
      • 视频处理和压缩
    • 音视频容器格式
    • 010编辑器

    8
    数据压缩

    • 数据压缩,也称源编码或比特率减少,是使用比原始表示更少的比特来对信息进行编码的过程。
    • 无损压缩通过识别和消除统计冗余来减少位。无损压缩不会丢失任何信息。
      • LZW、霍夫曼编码、算术编码
    • 有损压缩通过识别和消除不必要的信息来减少位数。
      • 量化、JPEG

    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
    音频格式

    • 无压缩音频格式
      • WAVE、AIFF、PCM
    • 无损压缩格式
      • FLAC、Monkey’s Audio(APE扩展名)、Shorten、WMA无损
    • 有损压缩格式
      • MP3、AAC、WMA、AC3

    18
    音频格式(续)

    • MP3编码器
    • 演示

    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演练

    AVI Walk Through-2 AVI文件演练

    Windows位图数据

    • 数据由表示位图的连续行或扫描线的字节数组组成。
    • 每个扫描线由表示扫描线中的像素的连续字节组成,从左到右的顺序。
    • 表示一个扫描线的字节数取决于位图的宽度。

    Windows位图数据

    • 如果需要,扫描线必须用0填充以在32比特边界结束。
      • 这意味着宽度为8比特、20比特或30比特的单色位图将具有相同的扫描线大小:32比特。
      • 宽度为40比特的单色位图的扫描线大小为64比特。
    • 位图中的扫描线从下到上存储。
      • 这意味着数组中的第一个字节表示位图左下角的像素,最后一个字节表示右上角的像素。

    灰度位图

    • 每像素使用8比特(即1字节)
      • 回想一下,信息头的biBitCount字段将为8
    • 每个字节表示256阶灰度。
      • 白色是“ff”
      • 黑色是“00”
      • 中间的数字代表从白色到黑色的几个灰度阶。

    24位彩色位图

    • 每像素使用24比特(即3字节)
      • 回想一下,信息头的biBitCount字段将为24。
    • 每个像素有3字节分别表示红色、绿色和蓝色。
      • 白色是“ffffff”
      • 黑色是“000000”
      • 红色是“ff0000”
      • 绿色是“00ff00”
      • 蓝色是“0000ff”

    8位色位图

    • 每像素使用8比特。只能有256种颜色
      • 使用哪些颜色?
    • 使用调色板,称为调色板,来选择要使用的颜色
      • 在一个位图中,颜色0可以是“浅橙色”,颜色1可以是“深棕色”
      • 在另一个位图中,颜色0可以是“浅黄色”,颜色1可以是“深红色”。
    • 颜色表位于信息头和数据之间
      • 每个条目有4字节(R、G、B、0x0)

    颜色表

    重新看灰度位图

    • 这实际上是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. 霍夫曼编码过程不是唯一的。标记分支的不同方法和合并符号的不同选择会产生不同的前缀码。
    2. 如果符号分布不均匀,霍夫曼编码可以减少固定位数编码的位数。
    3. 霍夫曼码中每个样本的平均位数在熵的一个比特之内:
      熵 ≤ 霍夫曼 ≤ 熵 + 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
    编码过程
    编码块中剩余样本时,使用以下步骤:

    1. 从前两个样本预测下一个样本。
      lpredsamp = ((isamp1 * icoef1) + (isamp2 * icoef2)) / 固定点系数基
    2. 生成并防止溢出/下溢的4比特有符号误差delta。
      ierrordelta = (sample(n) - lpredsamp) / idelta
      将ierrordelta削减至[-8, 7]的范围内。
    3. 然后写出半字节ierrordelta: putnibble(ierrordelta)。

    57
    编码过程
    4) 将“预测误差”加到预测的下一个样本上,并防止溢出/下溢错误。
    lnewsamp = lpredsample + (idelta * ierrordelta);
    将数据钳制为short类型(16位)
    5) 调整用于计算“预测误差”的量化步长。
    idelta = idelta * 自适应表[ierrordelta] / 固定点自适应基
    如果idelta太小,使其为最小允许值。
    6) 更新前一个样本的记录。
    isamp2 = isamp1;
    isamp1 = lnewsample.

  • 相关阅读:
    如何在Vue中实现拖拽上传文件
    软件开发原则
    Docker的网络模式
    PHP对接企业微信创建审批应用和对接提交审批
    LINUX定时解压缩方案
    这三个方法轻松实现Excel表格名翻译不求人
    穿越数据的迷宫-数据管理知识介绍
    javaer你还在手写分表分库?来看看这个框架怎么做的 干货满满
    关于#c语言#的问题:力扣求长度最小的数组
    第4章丨IRIS Global —— 对象使用多维存储
  • 原文地址:https://blog.csdn.net/haostart_/article/details/133297565