Skip to content

Commit 21f3098

Browse files
committed
update post
1 parent 12ad4a8 commit 21f3098

3 files changed

Lines changed: 70 additions & 30 deletions

File tree

_posts/2022-06-08-av_into.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,53 @@ tags:
5959

6060
上图是 H.264 编码的示意图,每幅图像被分割成 8*8 像素尺寸来编码。
6161

62+
#### 色彩空间
63+
色彩空间(Color space)是对色彩的组织方式。色彩模型(Color model)是一种抽象数学模型,通过一组数字来描述颜色(例如RGB使用三元组、CMYK使用四元组)。由于“色彩空间”有着固定的色彩模型和映射函数组合,非正式场合下,这一词汇也被用来指代色彩模型。常见的色彩模型包括 `RGB``YUV(YCbCr)``HSV``HSL``CMYK` 等。下面我们重点介绍 `YUV` 色彩模型。
64+
65+
`YUV` 是一种表示颜色的模型。但是我们常说的 `YUV` ,其实指的是 `YCbCr`,其中`Y`是指亮度分量,`Cb`指蓝色色度分量,而`Cr`指红色色度分量,是标准 `YUV` 的一个翻版,此文中,我们就用 `YUV` 指代 `YCbCr` 了。
66+
67+
`YUV` 格式按照数据大小分为三个格式,`YUV 420``YUV 422``YUV 444`。由于人眼对 `Y` 的敏感度远超于对 `U``V` 的敏感,所以有时候可以多个 `Y` 分量共用一组 UV,这样既可以极大得节省空间,又可以不太损失质量。
68+
69+
- `YUV 420`,由 4 个 `Y` 分量共用一套 `UV` 分量
70+
- `YUV 422`,由 2 个 `Y` 分量共用一套 `UV` 分量
71+
- `YUV 444`,不共用,一个 `Y` 分量使用一套 `UV` 分量
72+
73+
在这三种类型之下,我们又可以按照 `YUV` 的排列储存顺序,将其细分为好多种格式。按照 `YUV` 的排列方式,再次将 `YUV` 分成三个大类,`Planar``Semi-Planar``Packed`
74+
75+
- Planar YUV 三个分量分开存放
76+
- Semi-Planar Y 分量单独存放,UV 分量交错存放
77+
- Packed YUV 三个分量全部交错存放
78+
79+
#### 封装格式(Byte Stream Format)
80+
`H.264` 编码有两种 `Byte Stream Format`,分别是 `AnnexB``AVCC`
81+
82+
```
83+
AnnexB format:
84+
([start code] NALU) | ( [start code] NALU) |
85+
AVCC format:
86+
([extradata]) | ([length] NALU) | ([length] NALU) |
87+
```
88+
89+
In annexb, [start code] may be 0x000001 or 0x00000001.
90+
In avcc, the bytes of [length] depends on NALULengthSizeMinusOne in avcc extradata, the value of [length] depends on the size of following NALU and in both annexb and avcc format, the NALUs are no different.
91+
92+
> `Annex B` 多用于网络流媒体中:rtmp、rtp 格式,`AVCC` 多用于文件存储中mp4的格式
93+
{: .prompt-info }
94+
95+
`H.265` 编码和 `H.264` 不同,其 `Byte Stream Format` 包含 `H.265 Annex B``H.265 Parameter Sets`
96+
6297
### 使用 FFmpeg 查看视频文件信息
6398
我们可以使用 ffmpeg 提供的 ffprobe 工具来查看视频文件信息。
6499

65100
从下图中高亮部分可以看到,该视频文件为 mp4 文件,时长 7.62 秒,码率为 13805 kb/s,包含了 2 条 `Stream`
66101

67-
其中, Video 使用 `H.264` 编码,色彩空间为 `yuv420`,分辨率为 `1920*1080`,帧率为 `29.97`
102+
其中, Video 使用 `H.264` 编码,色彩空间为 `yuv420`,分辨率为 `1080P(1920*1080)`,帧率为 `29.97`
68103

69104
Audio 使用 `aac` 编码,采样率为 `44.1kHz`,立体声
70105

106+
> 1080p是一种视频分辨率标准,指的是视频的垂直分辨率为1080像素。具体来说,1080p视频的分辨率为1920x1080,其中1920是水平像素数,1080是垂直像素数。字母“p”代表“逐行扫描”(progressive scan)的意思。这意味着视频的每一帧都是通过扫描整个图像的每一行像素来创建的,而不是通过交替扫描奇数和偶数行像素来创建的。与交替扫描的“隔行扫描”(interlaced scan)相比,逐行扫描可以提供更清晰的图像,因为它可以更好地保留运动图像中的细节和清晰度。
107+
{: .prompt-info }
108+
71109
![ffprobe_video_info](/assets/img/post/post-2022-06-08/ffprobe_video_info.png){: width="972" height="589" .w-100 .normal}
72110

73111
问题思考:
@@ -80,4 +118,6 @@ Audio 使用 `aac` 编码,采样率为 `44.1kHz`,立体声
80118

81119
参考资料
82120
- https://www.volcengine.com/docs/6489/72015
121+
- https://zh.wikipedia.org/zh-cn/%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%96%93
122+
- https://zhuanlan.zhihu.com/p/384455058
83123
- ChatGPT

_posts/2023-06-01-app_mach_o.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ tags:
1111

1212
## 进程
1313

14-
App 的本质是一个可执行程序,是一段计算机代码和数据的集合。从操作系统的角度来看,App 的本质是一个进程。进程是计算机中正在运行的程序的实例。在操作系统中,进程是操作系统分配资源和调度执行的基本单位。每个进程都有自己的内存空间、寄存器集合、文件句柄、网络连接等资源,它们可以独立地运行和被管理。
14+
App 的本质是一个可执行程序,是一段计算机代码和数据的集合。从操作系统的角度来看,App 的本质是一个**进程**。进程是计算机中正在运行的程序的实例。在操作系统中,进程是操作系统分配资源和调度执行的基本单位。每个进程都有自己的内存空间、寄存器集合、文件句柄、网络连接等资源,它们可以独立地运行和被管理。
1515

16-
进程是操作系统中最基本的资源分配和调度单位。操作系统通过进程控制块Process Control Block,PCB)来管理进程,PCB 包含了进程的状态、进程 ID、进程优先级、内存使用情况、文件句柄等信息。当操作系统需要切换到另一个进程时,它会保存当前进程的上下文,然后加载另一个进程的上下文,从而实现进程之间的切换。
16+
进程是操作系统中最基本的资源分配和调度单位。操作系统通过进程控制块 `PCB(Process Control Block)` 来管理进程,`PCB` 包含了进程的状态、进程 ID、进程优先级、内存使用情况、文件句柄等信息。当操作系统需要切换到另一个进程时,它会保存当前进程的上下文,然后加载另一个进程的上下文,从而实现进程之间的切换。
1717

18-
在 macOS 中,PCB 被称为 proc。[proc 结构体](https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/proc_internal.h.auto.html)是 macOS 内核中非常重要的数据结构,用于描述进程在内核中的状态和信息。
18+
`macOS` 中,`PCB` 被称为 `proc`[proc 结构体](https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/proc_internal.h.auto.html)`macOS` 内核中非常重要的数据结构,用于描述进程在内核中的状态和信息。
1919
``` c
2020
struct proc {
2121
LIST_ENTRY(proc) p_list; /* List of all processes. */
@@ -43,25 +43,25 @@ struct proc {
4343
/* 以下其他字段已省略 */
4444
};
4545
```
46-
proc 包含了大量的字段和指针,用于描述进程的各种属性和资源使用情况,例如进程状态(p_stat)、进程 ID(p_pid)、进程名称(p_comm)、进程优先级(p_priority)、进程内存使用情况(p_vmspace)、文件描述符表(p_fd)、线程列表(p_threadlist)等。
46+
`proc` 包含了大量的字段和指针,用于描述进程的各种属性和资源使用情况,例如进程状态(`p_stat`)、进程 ID(`p_pid`)、进程名称(`p_comm`)、进程优先级(`p_priority`)、进程内存使用情况(`p_vmspace`)、文件描述符表(`p_fd`)、线程列表(`p_threadlist`)等。
4747

4848
## Mach-O 文件
4949

50-
在 App 加载到内存成为进程之前,macOS 上的可执行文件是 Mach-O 文件。Mach-O 文件包含了可执行代码、数据、符号表、动态链接信息等多个部分,是 macOS 中应用程序和库文件的基本格式。
50+
在 App 加载到内存成为进程之前,macOS 上的可执行文件是 `Mach-O` 文件。`Mach-O` 文件包含了可执行代码、数据、符号表、动态链接信息等多个部分,是 `macOS` 中应用程序和库文件的基本格式。
5151

52-
Mach-O 文件的格式可以分为文件头(Header)、加载命令(Load commands)和数据区(Raw segment data)三个部分。
52+
`Mach-O` 文件的格式可以分为文件头(`Header`)、加载命令(`Load commands`)和数据区(`Raw segment data`)三个部分。
5353

5454
![Mach-O](/assets/img/post/post-2023-06-01/mach_o.png){: width="972" height="589" .w-50 .normal}
5555
_Mach-O file_
5656

57-
包含多个 CPU 架构的 Mach-O 文件被称为 Fat Binary。可以通过 file 命令查看 Mach-O 文件的 CPU 架构。
57+
包含多个 CPU 架构的 `Mach-O` 文件被称为 `Fat Binary`。可以通过 `file` 命令查看 `Mach-O `文件的 CPU 架构。
5858
``` bash
5959
$ file /System/Applications/Calculator.app/Contents/MacOS/Calculator
6060
/System/Applications/Calculator.app/Contents/MacOS/Calculator: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
6161
/System/Applications/Calculator.app/Contents/MacOS/Calculator (for architecture x86_64): Mach-O 64-bit executable x86_64
6262
/System/Applications/Calculator.app/Contents/MacOS/Calculator (for architecture arm64e): Mach-O 64-bit executable arm64e
6363
```
64-
Fat Binary 对应的 fat_header 在操作系统中的数据结构定义是 [fat_header](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/fat.h.auto.html)
64+
`Fat Binary` 对应的 `fat_header` 在操作系统中的数据结构定义是 [**fat_header**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/fat.h.auto.html)
6565

6666
```c
6767
struct fat_header {
@@ -78,15 +78,15 @@ struct fat_arch {
7878
};
7979
```
8080

81-
可以看到,macOS 系统的计算器程序 Mach-O 文件,是包含了 x86_64 和 arm64e 两种 CPU 架构的 Fat Binary。
82-
> iOS 系统自 iOS 11.0 版本以后,不再支持 armv7armv7s 等架构,只支持 arm64 架构。所以仅支持 iOS 11.0 以后版本的项目,打包产物的 Fat Binary 只有 arm64 架构的 Mach-O 文件。这也是 Xcode 14.0 取消了 bitcode 的原因,因为不再需要编译成 bitcode 中间产物,且 bitcode 转译会消耗 AppStore 的服务器资源
81+
可以看到,macOS 系统的计算器程序 `Mach-O` 文件,是包含了 `x86_64``arm64e` 两种 CPU 架构的 `Fat Binary`
82+
> iOS 系统自 iOS 11.0 版本以后,不再支持 `armv7``armv7s` 等架构,只支持 `arm64` 架构。所以仅支持 `iOS 11.0` 以后版本的项目,打包产物的 `Fat Binary` 只有 `arm64` 架构的 `Mach-O` 文件。这也是 `Xcode 14.0` 取消了 `bitcode` 的原因,因为不再需要编译成 `bitcode` 中间产物,且 `bitcode` 转译会消耗 AppStore 的服务器资源
8383
{: .prompt-tip }
8484

8585
### 文件头(haeder)
8686

87-
Mach-O 文件头包含了文件类型、CPU 类型、加载命令数量等信息。Mach-O 文件支持多种文件类型,包括可执行文件、动态链接库、框架等。CPU 类型指定了可执行文件适用的 CPU 架构,例如 x86x86_64armv7arm64 等。加载命令数量指定了文件中包含的加载命令数量。
87+
`Mach-O` 文件头包含了文件类型、CPU 类型、加载命令数量等信息。`Mach-O` 文件支持多种文件类型,包括可执行文件、动态链接库、框架等。CPU 类型指定了可执行文件适用的 CPU 架构,例如 `x86``x86_64``armv7``arm64` 等。加载命令数量指定了文件中包含的加载命令数量。
8888

89-
`otool` 命令是 macOS 和 iOS 等操作系统上的一个工具,用于查看可执行文件、动态库和框架等二进制文件的信息。它可以用来查看二进制文件的头部信息、节表、符号表、动态链接信息等。
89+
`otool` 命令是 `macOS``iOS` 等操作系统上的一个工具,用于查看可执行文件、动态库和框架等二进制文件的信息。它可以用来查看二进制文件的头部信息、节表、符号表、动态链接信息等。
9090

9191
```bash
9292
$ otool -h /System/Applications/Calculator.app/Contents/MacOS/Calculator
@@ -96,15 +96,15 @@ Mach header
9696
0xfeedfacf 16777228 2 0x80 2 29 4208 0x00200085
9797
```
9898

99-
除了 `otools` 命令,还可以使用 MachOView 工具通过图形化页面来查看 Mach-O 文件
99+
除了 `otools` 命令,还可以使用 `MachOView` 工具通过图形化页面来查看 `Mach-O` 文件
100100
```bash
101101
brew install machoview
102102
```
103103
![MachOView](/assets/img/post/post-2023-06-01/machoview.png){: width="972" height="589" .w-100 .normal}
104104
_MachOView_
105105

106106

107-
Fat Binary 中,每个架构都有一个 header 文件头,被称为 [mach_header](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html)。64 位架构的 mach_header 会多一个保留字段。
107+
`Fat Binary` 中,每个架构都有一个 `header` 文件头,被称为 [**mach_header**](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html)。64 位架构的 `mach_header` 会多一个保留字段。
108108
```c
109109
/*
110110
* The 32-bit mach header appears at the very beginning of the object file for
@@ -142,11 +142,11 @@ struct mach_header_64 {
142142
```
143143
## 加载命令(Load commands)
144144
145-
Mach-O 文件中的加载命令(Load Command)用于描述可执行文件的各个段的属性和位置等信息,操作系统会根据这些信息将可执行文件加载到内存中。每个 Load Command 描述了一个特定的段或区域。常见的 Load Command 包括:
146-
- LC_SEGMENT 和 LC_SEGMENT_64:描述可执行代码和数据的段信息;
147-
- LC_SYMTAB 和 LC_DYSYMTAB:描述符号表和动态符号表信息;
148-
- LC_LOAD_DYLIB 和 LC_LOAD_WEAK_DYLIB:描述动态链接库的信息;
149-
- LC_MAIN:描述程序入口点的信息。
145+
`Mach-O` 文件中的加载命令(`Load Command`)用于描述可执行文件的各个段的属性和位置等信息,操作系统会根据这些信息将可执行文件加载到内存中。每个 `Load Command` 描述了一个特定的段或区域。常见的 `Load Command` 包括:
146+
- `LC_SEGMENT``LC_SEGMENT_64`:描述可执行代码和数据的段信息;
147+
- `LC_SYMTAB``LC_DYSYMTAB`:描述符号表和动态符号表信息;
148+
- `LC_LOAD_DYLIB``LC_LOAD_WEAK_DYLIB`:描述动态链接库的信息;
149+
- `LC_MAIN`:描述程序入口点的信息。
150150
151151
[load_command](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html)
152152
@@ -159,7 +159,7 @@ struct load_command {
159159

160160
## 数据区(Raw segment data)
161161

162-
Mach-O 文件的数据区包含了多个段(Segment),每个段包含了不同类型的数据。常见的段包括 __TEXT__DATA__LINKEDIT 等。其中,__TEXT 段包含了代码和只读数据,__DATA 段包含了全局变量和静态变量等数据,__LINKEDIT 段包含了符号表和重定位信息等。
162+
`Mach-O` 文件的数据区包含了多个段(`Segment`),每个段包含了不同类型的数据。常见的段包括 `__TEXT`、`__DATA`、`__LINKEDIT` 等。其中,`__TEXT` 段包含了代码和只读数据,`__DATA` 段包含了全局变量和静态变量等数据,`__LINKEDIT` 段包含了符号表和重定位信息等。
163163

164164
[segment](https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html)
165165
```c
@@ -178,9 +178,9 @@ struct segment_command_64 { /* for 64-bit architectures */
178178
};
179179
```
180180

181-
在 Mach-O 文件中,每个 Segment 包含一个或多个 section,每个 section 包含了一组相关的数据或代码。例如,在一个可执行文件中,常见的 Segment 包括 __TEXT、__DATA__LINKEDIT 等,每个 Segment 包含了多个 section,例如 __TEXT 包含了 __text__cstring__stub 等多个 section。
181+
`Mach-O` 文件中,每个 `Segment` 包含一个或多个 `section`,每个 `section` 包含了一组相关的数据或代码。例如,在一个可执行文件中,常见的 `Segment` 包括 __TEXT、`__DATA``__LINKEDIT` 等,每个 `Segment` 包含了多个 `section`,例如 `__TEXT` 包含了 `__text``__cstring``__stub` 等多个 `section`
182182

183-
Section 是 Mach-O 文件中的一个子单元,它是 Segment 中的一个子段,包含了一组相关的数据或代码。每个 Section 都有一个名称和一个类型,例如 __text__data__cstring 等。在 Mach-O 文件中,Section 的名称和类型通常与编译器和链接器相关,不同的编译器和链接器可能会使用不同的名称和类型。
183+
`Section``Mach-O` 文件中的一个子单元,它是 `Segment` 中的一个子段,包含了一组相关的数据或代码。每个 `Section` 都有一个名称和一个类型,例如 `__text``__data``__cstring` 等。在 `Mach-O` 文件中,`Section` 的名称和类型通常与编译器和链接器相关,不同的编译器和链接器可能会使用不同的名称和类型。
184184

185185
```c
186186
struct section_64 { /* for 64-bit architectures */

0 commit comments

Comments
 (0)