h264分析一(基本码流分析)

为什么要进行视频编码?

如果不进行编码的话,视频文件非常大,不利于传输和存储。如果一个YUV420格式的视频,分辨率1080P,帧率25fps,时常2小时,不压缩的情况下大小为1920 x 1080 x 1.5 x 25 x 2 x 3600 = 521.4G

为什么使用YUV而不是RGB存储?

RGB有颜色相关性,不容易压缩。???

从那些方面来压缩视频?

  • 空间冗余(帧内压缩):将一帧图像划分16 x 16的块后,相邻的块很多时候都有明显的相似性,这种就叫空间冗余
  • 时间冗余(帧间压缩):帧率25的视频前后两帧相差只有40ms,两张图像变化比较小,相似度很高,这种叫时间冗余
  • 视觉冗余(变换、量化):人眼对高频信息的敏感度小于低频信息。去除部分高频信息,人眼看起来差别不大,这种就视觉冗余。
  • 信息熵冗余(熵编码):例如tar压缩文件,去压缩数据,这种叫信息熵冗余。

YUV宏块的大小分别是多少?

  • Y:16 x 16
  • U:8 x 8
  • V:8 x 8

h.264与h.265与av1

编码差别

相同码率质量与速度差别

帧有几种类型?

帧类型主要分为三类

知道什么是IDR帧吗?为什么要有IDR帧?

IDR帧也叫立即刷新帧。如果一个参考帧出现问题,后面所有的P帧和B帧都会出现问题,错误会不断累积,为了解决这个问题,H264规定IDR帧之后的帧不能参考IDR帧之前的帧。

什么是Slice?Slice有什么作用?

Slice是帧内部的概念,是为了并行编码设计的。可以将一帧图片划分为几个Slice,并且Slice之间相互独立、互不依赖、独立编码,这样就可以多线程并行对多个Slice进行编码,从而提升速度。但是也因为一帧内的几个Slice是相互独立的,帧内预测不能跨Slice进行,所以帧内编码会降低性能。

为什么帧内编码Slice会降低性能?

  • 预测范围受限:在帧内预测中,一个像素块可以参考其相邻的已编码块进行预测。但当帧被划分成多个 Slice 时,每个 Slice 内的块只能参考同一个 Slice 内的块,而不能参考其他 Slice 内的块。这种限制减少了可用于预测的像素块数量,降低了预测的准确性。
  • 减少了预测模式选择:帧内预测有多种模式,选择最佳模式是基于周围块的像素值。当 Slice 限制了块的参考范围,某些模式可能无法使用或其效果显著降低,从而影响编码效率。
  • 增加了编码冗余:由于 Slice 间不能相互预测,必须为每个 Slice 内的块单独进行预测和编码。这可能导致某些模式和参数在不同 Slice 中重复出现,增加了编码冗余。
  • 码率和压缩效率:由于 Slice 的独立性,编码器需要为每个 Slice 单独管理压缩参数,这会增加编码复杂度和码率开销,从而降低整体压缩效率。

帧的在码流中到底是怎么存储的?

一帧图像可以划分为一个或者多个Slice,一个Slice中包含多个宏块(宏块头和宏块data),一个宏块又可以划分为多个不同尺寸的子块

码流结构具体是怎么样的?

首先是起始码

h264的码流结构有两种

  • Annexb格式:使用4字节的00 00 00 01或者3字节的00 00 01来作为起始码。图像编码数据中也可能出现00 00 00 01或者00 00 01,会将图像编码数据中的几种字节做特殊处理
    • 00 00 00改为00 00 03 00
    • 00 00 01改为00 00 03 01
    • 00 00 02改为00 00 03 02
    • 00 00 03改为00 00 03 03
  • MP4格式:在图像编码数据的开始使用4个字节作为长度标识

然后是NALU

除了图像数据,还有一些编码数据需要存储,将一些通用的编码数据提取,不在图像编码中重复,H264设计了2个数据集SPS(序列参数集)、PPS(图像参数集)。由于帧是被划分为一个或多个Slice,所以帧在码流中是以Slice单元存储的。为了区分这几种数据,H264设计了NALU(网络抽象层)来区分这些数据。SPS是一个NALU、PPS是一个NALU、每一个Slice是一个NALU。

  • SPS的NALU:1字节的NALU Header + n字节的NALU Data
  • PPS的NALU:1字节的NALU Header + n字节的NALU Data
  • Slice的NALU:1字节的NALU Header + n字节的NALU Data(Slice Header + Slice Data(MB Data))

NALU是怎么区分上述类型的?

使用NALU头进行区分上述类型。NALU头共占用1字节,第一位在h264必须是0,后续2位代表该NALU的重要性,参考帧、SPS、PPS该值必须大于0,后续5位代表NALU的类型。

NALU类型

怎么区分非IDR帧中的I、P、B帧?

由于NALU头只区分了IDR帧和非IDR帧,具体的帧判断要解析Slice头中的slice_type字段来判断。

总结H264编码:

H.264 原始码流(裸流)是由⼀个接⼀个 NALU 组成,它的功能分为两层:VCL(视频编码层)和 NAL(⽹络抽象层)。

  • 视频编码层 VCL(Video Coding Layer):是对视频编码核心算法过程、片、宏块、子宏块等概念的定义。可通过空间冗余、时间冗余、视觉冗余、信息熵冗余四个方向来进行视频压缩,分别对应帧内编码、帧间编码、dst变换和量化、熵编码来进行视频压缩。为了提高编解码速度,会将帧划分为Slice,进行并行编码。为了解决帧内编码的块效应问题,使用去块滤波。

  • 网路抽象层 NAL(Network Abstract Layer):负责将 VCL 产生的比特字符串适配到各种各样的网络和多元环境中,主要结构:

    • 起始码->NALU(header data(SPS/PPS/SEI/Slice...)

    • Slice(header data)->MB(header data)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值