📄 本群聊天记录200608.htm
字号:
</table>firstime <br>
(500144) 20:56:03 <br>
我们看一下 JM 解码器是如何按顺序处理这些语法元素的 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>Pertinax <br>
(54411308) 20:56:07 <br>
建议安排专门的时间提问. <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:56:16 <br>
请打开 JM86 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:56:22 <br>
找到 main 函数 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:57:24 <br>
main 函数中 decode_one_frame 以前的部分不做分析,因为这些部分都是一些初始化工作,以及读文件操作,并没有解码 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:57:34 <br>
我们进入 decode_one_frame 函数 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:57:55 <br>
再进入 read_new_slice 函数 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:58:17 <br>
read_new_slice 函数的主要作用是读取 NALU 单元数据 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:58:29 <br>
附带做一些解码的准备工作 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:59:10 <br>
在 read_new_slice 函数中<br>
我们最先遇到的两个函数是 GetAnnexbNALU 和 GetRTPNALU <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 20:59:35 <br>
这两个函数由一个 if 语句控制,选择调用 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:00:24 <br>
这就涉及到 H.264 的两种码流格式<br>
GetAnnexbNALU 处理字节流格式的码流<br>
GetRTPNALU 处理 RTP 格式码流 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:01:20 <br>
字节流格式的码流主要用于存储,例如制作 DVD(当然现在的 DVD 还不是用 H.264)<table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>
firstime <br>
(500144) 21:01:41 <br>
RTP 格式码流主要用于网络传送,例如在线看电影 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:01:56 <br>
现在我们进入 GetAnnexbNALU 函数 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:02:48 <br>
在 GetAnnexbNALU 函数 中,我们可以看见一下三行语句:<br>
nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;<br>
nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;<br>
nalu->nal_unit_type = (nalu->buf[0]) & 0x1f; <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:03:12 <br>
第一行就是解码器在处理 7.3.1 小节中的第一个语法元素 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:03:29 <br>
第二行就是解码器在处理 7.3.1 小节中的第二个被加粗的语法元素 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:05:09 <br>
我们知道 H.264 码流的第一个 NALU 是 SPS <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:05:32 <br>
所以 7.3 部分接下来就描述了 SPS 的语法结构 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:06:01 <br>
那么解码器下一步工作当然是要解码 SPS <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:06:20 <br>
我们先看一下标准中 SPS 的结构,请看 7.3.2.1 小节 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:06:50 <br>
加粗的字体就是被编码的语法元素,也就是解码器必须解码的语法元素 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:07:19 <br>
而且解码器必须按照 7.3 部分中加粗字体的顺序来解码 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:07:58 <br>
对于 SPS,按照 7.3.2.1 的规定,解码器必须首先解码 profile_idc <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:08:44 <br>
profile_idc 后面的 u(8) 我就不说什么意思了<br>
刚才已经解释过了,profile_idc 的含义我也不说了,在 7.4.2.1 小节中有解释 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:09:07 <br>
那么我们看看解码器到底是不是按照 7.3.2.1 规定来做的呢 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:10:05 <br>
请看 read_new_slice 函数的 case 语句 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:10:18 <br>
也就是第 576 行 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:10:59 <br>
根据 NALU 的头解析出来的 nal_unit_type <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
</table>firstime <br>
(500144) 21:11:21 <br>
解码器会进行不同 NALU 单元的处理<br>
大家可以浏览一下 <table border="0" width="1080" id="table1" cellspacing="0" cellpadding="0">
<tr><br>
<td><font color="#B3C9E8" size="2">
----------------------------------------------------------------------------------------------------------------------------------------------------------</font></td>
</tr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -