type
status
date
slug
summary
tags
category
icon
password
Property
Mar 20, 2023 02:19 AM
基础知识
流媒体编解码流程
- ⾳视频编码在流媒体和⽹络领域占有重要地位;流媒体编解码流程⼤致如下图所示:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F1aadba6d-8afe-4ae7-82aa-7ac51bd0bcd1%2FUntitled.png?table=block&id=b8f201e6-c0af-41ff-b6cb-9cb56a63d281)
H.264
H.264 简介
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F3c3bc124-b5e8-446c-a354-597b104771a1%2FUntitled.png?table=block&id=fcaa0cad-6f2f-4b0e-ac89-12f5a025c8fc)
H.264 编码原理
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8ebc4169-c0f8-4ee7-84e6-86c9f25bb268%2FUntitled.png?table=block&id=c60d10b6-0dff-43e0-9ac7-8d1f852c4107)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fcd631a86-119a-4256-89b8-9ca076ea3ed2%2FUntitled.png?table=block&id=bad4201d-e491-481f-b2a5-eda2cb6f7cdd)
H.264 编码结构解析
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8ce41d54-cb6a-4303-8a43-949b540fbb5d%2FUntitled.png?table=block&id=f5f0c764-02d5-42de-a98a-70c8c3015cb6)
GOP
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F655d922f-1dea-48c0-b753-0489ebf730b1%2FUntitled.png?table=block&id=9a95e018-98d0-47bd-9dc1-1721c43b5d80)
I、P、B帧
- 压缩方式:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F1146f3eb-61b3-4e75-9d1a-7cfe4c83aa54%2FUntitled.png?table=block&id=5ceb01d2-70fa-41dd-821e-06568fba41e4)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fa95c443f-6d19-426f-852c-37f143c43e9e%2FUntitled.png?table=block&id=da318843-ea04-4c9a-8a09-49605242054a)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ff78be196-0a08-4d39-bb07-1b0e476f66ca%2FUntitled.png?table=block&id=d0654244-1f6c-48f5-ae9c-9df76722dc3d)
- I 帧:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ffe958aea-e762-4796-8672-05fb53971ab6%2FUntitled.png?table=block&id=55a818e6-827a-4d2a-8ecb-08dad1c15f1f)
- P 帧:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F34372ee6-b0ec-44ef-9664-75700ec51538%2FUntitled.png?table=block&id=609110ca-7dd4-498c-a838-cf32a47489ff)
- B 帧:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F394b83ae-1520-4814-b831-12afc734b3eb%2FUntitled.png?table=block&id=15f9a993-8b18-4ad0-bf8d-4a2432e7bf1a)
IDR 帧
- IDR(Instantaneous Decoding Refresh,即时解码刷新):
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F70e77d0b-7799-4e58-809f-68f03dbdd3c7%2FUntitled.png?table=block&id=e487d2d8-76fe-4717-aa74-b58f704e41c7)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8e2fe4ca-6d12-4f92-95c9-e7b6cc8428a8%2FUntitled.png?table=block&id=a999b9cc-5291-40cf-9f7e-1f9de4cbffa3)
- 直播一般不插入B帧(以1秒25帧为例),下图情况B帧将产生160ms的延迟:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F43580370-7a70-4325-822e-2da2d2e7a3d6%2FUntitled.png?table=block&id=719976c9-467a-4033-bad9-930a9aef9764)
NALU
NALU 简介
NALU(Network Abstract Layer Unit) 是用于视频编码的一种数据格式,主要用于 H.264(也称为 AVC)和 H.265(也称为 HEVC)编码标准中。它是视频编码器输出的基本单位,也是视频解码器输入的基本单位。
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe6358214-c62d-4048-98e0-d5e7d5d32813%2FUntitled.png?table=block&id=629d3caa-0330-4ad6-8056-eb489e094aad)
- 若码流中间有改变(如分辨率发生变化):需要重新发送 SPS 和 PPS,否则码流会解析不出来
NALU 结构
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F2428453f-573e-4c6c-9691-b3dbdad9a119%2FUntitled.png?table=block&id=6f411419-c2f5-431c-85e9-c7de4c7b76df)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fbb254e4c-8bbb-410d-8b41-2cc527885ef6%2FUntitled.png?table=block&id=05b3e376-c7d3-40a1-ab27-8687b2810899)
- FFmpeg 中:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F08d24ba2-73a0-4699-9b29-c3536179a8a9%2FUntitled.png?table=block&id=4f2551ce-9b8f-4698-8ad7-b44c75d6c622)
解析 NALU
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F341076eb-7245-4ea8-89d6-8b5111dfe062%2FUntitled.png?table=block&id=ede3625e-9e67-45b3-9743-32a33a097f4e)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F94e76b3c-7329-464a-8d29-405c184181b7%2FUntitled.png?table=block&id=4e67d29d-7589-42a4-a816-82dc8569f64d)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F5ddd6368-743c-4195-a64d-1c3564b4ab77%2FUntitled.png?table=block&id=c230a000-3e18-4a5d-b0a1-70b80747a36c)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F01d058c1-0fcb-4f85-a37d-6ff459987edf%2FUntitled.png?table=block&id=c671a1cb-374a-41e2-8b5a-2d786d4ab660)
- 对于NALU分析主要关注5/6/7/8 四种类型。
H.264 两种封装模式
- annexb 模式和 mp4 模式:
- ES是Elementary Stream的缩写,即基本流或基本码流。在音视频领域中,通常将音频或视频的数据流称为Elementary Stream。 ES 是指不带有容器(如MP4、FLV等)或不包含其他流(如字幕、元数据等)的音视频数据流,是音视频数据的最基本形式。一个ES中只包含一种媒体(音频或视频)的数据,而且不包含容器格式和文件头等信息,只包含编码后的压缩数据。 ES 通常会进行编码和解码,然后通过其他方法将其打包到容器中(如MP4、FLV等),以实现文件的存储和传输。
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F852d8179-5c46-4f0e-9562-c509380b3937%2FUntitled.png?table=block&id=97856a4c-7e02-4caf-94a7-ed3e95d75c36)
- FFmpeg 实现 mp4 格式转换为 annexb 格式:
提取 H.264 代码
FFmpeg 实现从 MP4 上提取 H.264 的 NALU
过滤器相关 API 解析
av_bsf_get_by_name
:是用于获取指定名称的 AVBitStreamFilter 过滤器的函数。该函数的作用是在 FFmpeg 中注册的过滤器列表中查找指定名称的过滤器,并返回一个指向 AVBitStreamFilter 结构体的指针。如果找到了指定名称的过滤器,则返回该指针;否则,返回 NULL。- 函数原型如下:
函数参数 name 是一个字符串,表示要查找的过滤器的名称。在 FFmpeg 中,已经注册的过滤器名称都是唯一的,因此可以根据名称来精确查找指定的过滤器。
av_bsf_alloc
:是用于创建 AVBSFContext 上下文结构体的函数,用于进行音视频码流的转换和处理。该函数会根据指定的过滤器创建一个 AVBSFContext 结构体,并对其进行初始化和配置,以便后续进行音视频码流的转换处理操作。- 函数原型如下:
函数参数 filter 是一个指向 AVBitStreamFilter 结构体的指针,表示要使用的过滤器。参数 ctx 是一个指向 AVBSFContext 结构体指针的指针,表示创建的 AVBSFContext 上下文结构体的地址。函数返回值为整数类型,表示函数的执行状态,如果执行成功,则返回 0;否则,返回负数表示执行出错。
avcodec_parameters_copy
:用于将一个 AVCodecParameters 结构体的值复制到另一个 AVCodecParameters 结构体中。AVCodecParameters 结构体用于描述编解码器的参数,包括编码格式、视频宽高、帧率、音频采样率、声道数等信息。在进行音视频编解码时,需要根据输入或输出媒体文件的编码格式和参数,对编解码器进行初始化,因此需要用到 AVCodecParameters 结构体。- 函数原型如下:
该函数接收两个参数:dst 和 src,分别表示目标和源 AVCodecParameters 结构体。函数的作用是将源 AVCodecParameters 结构体中的值复制到目标 AVCodecParameters 结构体中。如果复制成功,则返回 0,否则返回一个负数错误代码表示执行出错。
av_bsf_init
:用于初始化一个比特流过滤器(Bitstream Filter)上下文。比特流过滤器是用于对编码数据进行处理的组件,可以用于压缩格式转换、增加或删除视频/音频流等。在进行音视频编解码时,经常需要对输入或输出数据进行比特流过滤,因此需要用到比特流过滤器。- 函数原型如下:
该函数接收一个 AVBSFContext 结构体指针作为参数,表示需要初始化的比特流过滤器上下文。如果初始化成功,则返回 0,否则返回一个负数错误代码表示执行出错。
av_bsf_send_packet
:用于向比特流过滤器发送待处理的音视频数据。它用于将需要进行处理的音视频帧数据送入过滤器链中,让过滤器对数据进行处理。- 函数原型如下:
该函数接收两个参数,第一个参数 ctx 是一个指向 AVBSFContext 结构体的指针,表示需要处理的比特流过滤器上下文。第二个参数 pkt 是一个指向 AVPacket 结构体的指针,表示待处理的音视频帧数据。如果发送成功,则返回 0,否则返回一个负数错误代码表示执行错。
av_bsf_receive_packet
:用于从比特流过滤器接收处理后的音视频帧数据。它用于从过滤器链中读取经过处理的音视频帧数据。- 函数原型如下:
- 为什么需要多次调用
av_bsf_receive_packet
? - AVBSFContext结构体中可能会包含多个AVPacket数据包,因此av_bsf_receive_packet函数可以被调用多次,以从AVBSFContext中接收所有数据包。每次调用该函数时,它将尝试接收并返回一个AVPacket数据包。如果该数据包包含完整的数据,则函数将返回1。如果数据包只包含部分数据,则函数将返回0。如果在数据包的结尾处没有更多数据,则函数将返回AVERROR_EOF。
- 在你的代码中,可能存在一些情况导致一次调用av_bsf_receive_packet函数无法接收到所有数据。例如,如果输入文件的大小不是数据包大小的整数倍,则最后一个数据包可能不完整,并且需要在下一次读取时才能完成。此外,如果输出文件的写入速度低于输入文件的读取速度,则会导致AVBSFContext中的缓冲区被填满,从而需要多次调用av_bsf_receive_packet函数才能接收所有数据包。因此,为了正确地处理所有数据,你需要在循环中多次调用av_bsf_receive_packet函数,直到它返回AVERROR_EOF。
该函数接收两个参数,第一个参数 ctx 是一个指向 AVBSFContext 结构体的指针,表示需要处理的比特流过滤器上下文。第二个参数 pkt 是一个指向 AVPacket 结构体的指针,表示接收到的经过处理后的音视频帧数据。如果成功读取到了数据,则返回 0,否则返回一个负数错误代码表示执行出错。
- 作者:OctalZero
- 链接:https://octalzero.com/article/64397a60-3980-448b-99e8-f6734ee3f95f
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章