音视频入门基础:H.264专题(3)——EBSP, RBSP和SODB

=================================================================

音视频入门基础:H.264专题系列文章:

音视频入门基础:H.264专题(1)------H.264官方文档下载

音视频入门基础:H.264专题(2)------使用FFmpeg命令生成H.264裸流文件

音视频入门基础:H.264专题(3)------EBSP, RBSP和SODB

音视频入门基础:H.264专题(4)------NALU Header:forbidden_zero_bit、nal_ref_idc、nal_unit_type简介

音视频入门基础:H.264专题(5)------FFmpeg源码中 解析NALU Header的函数分析

=================================================================

一、NALU

H.264码流中,所有的数据,都被封装成一个个NALU(又叫NAL Unit,全称为:Network Abstraction Layer Unit,中文被翻译为:网络抽象层单元)。而目前 H.264 流行的包装方式分别为AnnexB和avcC。对于AnnexB格式的H.264码流来讲,为了分割各个 NALU ,编码时在每个 NALU 前面加上0x000001或0x00000001作为startcode(起始码)。解码时,要将带有startcode的NALU 去掉 startcode,变为不带startcode的NALU:

二、EBSP

去掉startcode后,NALU 的第一个字节 为 占用 1 位的forbidden_zero_bit + 占用 2 位 的nal_ref_idc + 占用 5 位的nal_unit_type。它们加起来刚好8位,也就是1个字节,一般被我们称为NALU Header(NAL Unit Header)。解码时,去掉startcode然后去掉NALU Header后的NALU负载被我们称为EBSP(Encapsulate Byte Sequence Payload):

三、RBSP

由于去掉startcode然后去掉NALU Header后的NALU负载 中可能存在形式为0x00000X(其中X为0、1、2或3)的数据,为了防止它们跟startcode冲突,编码时会在0x0000之后添加一个emulation_preventon_three_byte (防竞争字节,值为0x03),使其变为0x0000030X,就像下面这样:

0x000000 => 0x00000300

0x000001 => 0x00000301

0x000002 => 0x00000302

0x000003 => 0x00000303

解码时,将EBSP中的防竞争字节去掉,就是RBSP(Raw Byte Sequence Payload)

四、SODB

SODB是真正的未加工过的H.264流。H.264 码流中的操作单位是位,而不是字节。因为视频的传输和存贮是十分在乎体积的,对于每一个比特(bit)要格外珍惜。所以H.264 中的操作单位是比特。比如H.264中的sps,它的constraint_set0_flag等属性就只占了1比特。

这就导致可能出现一种情况:H.264数据写完后,写入的数据量不满一个字节。所以编码时要在未加工过的H.264流之后,添加一个值等于1的尾部来表示H.264流的结束,该位称为停止位(rbsp_stop_one_bit)。然后为了字节对齐,在停止位(值为1)之后添加0位使得8位对齐(简单来讲,就是为了让H.264数据写完后,最后写入的数据满一个字节)。编码时通过补齐,让H.264流从位流(SODB)变为字节流(RBSP),以便每个语法的第一个位始终与字节的第一个位对齐。RBSP 去掉补齐的数据后,就是 SODB(String of Data Bits):

五、总结

六、参考文章

H.264 stream structure

H.264中NALU、RBSP、SODB的关系

Introduction to H.264: (1) NAL Unit

H264 - what, why and how

相关推荐
道剑剑非道4 小时前
QT开发技术【ffmpeg + QAudioOutput】音乐播放器 完善
开发语言·qt·ffmpeg
毒果4 小时前
FFmpeg 低延迟同屏方案
ffmpeg·同屏
aqi0011 小时前
FFmpeg开发笔记(六十三)FFmpeg使用vvenc把视频转为H.266编码
ffmpeg·音视频·直播·流媒体
梧桐樹下2 天前
FFmpeg avformat_open_input函数分析
ffmpeg
道剑剑非道2 天前
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
开发语言·qt·ffmpeg
IOsetting2 天前
Ubuntu24.04 交叉编译 aarch64 ffmpeg
ffmpeg
却道天凉_好个秋2 天前
ffmpeg(三):处理原始数据命令
ffmpeg
@残梦2 天前
129、QT搭建FFmpeg环境
开发语言·qt·ffmpeg
阿飞__3 天前
C++ 使用 ffmpeg 解码本地视频并获取每帧的YUV数据
c++·ffmpeg·音视频
好好学习O(∩_∩)O3 天前
QT6引入QMediaPlaylist类
前端·c++·ffmpeg·前端框架