深入浅出H.264码流分析

深入浅出H.264码流分析

一、H.264是啥?

H.264就像视频的快递打包术

  • 作用:把原始视频压缩成小包裹(节省空间/带宽)
  • 地位:最常用的视频编码标准(监控/直播/视频网站都在用)
  • 压缩原理:只存储画面变化的部分(关键帧+差异帧)

二、H.264码流结构

1. 三层结构

graph TD A[H.264码流] --> B[NALU单元] B --> C[Slice切片] C --> D[宏块MB]

2. 关键概念

术语 作用 类比
NALU 数据基本单元 快递包裹
SPS/PPS 解码参数说明书 快递面单
I帧 完整画面 完整商品
P帧 与前一帧的差异 商品补发件
B帧 前后帧的差异 需要前后包裹才能组装

三、NALU单元解析

1. NALU头部格式

diff 复制代码
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|F|NRI| Type   |
  • F(1bit):错误标志(0=正常)
  • NRI(2bit):重要性(11=最重要)
  • Type(5bit):类型代码

2. 常见NALU类型

类型值 名称 作用
1 非IDR Slice 普通帧数据
5 IDR Slice 关键帧(I帧)
6 SEI 补充信息(如时间戳)
7 SPS 解码参数集
8 PPS 图像参数集

四、手工分析H.264文件

1. 用xxd查看二进制

bash 复制代码
xxd -g 1 test.h264 | less

输出示例

makefile 复制代码
00000000: 00 00 00 01 67 64 00 1e ac d9 40 50 05 bb 01 10  ....gd....@P....
00000010: 00 00 00 01 68 eb e3 cb 22 c0 00 00 00 01 65 b8  ....h...".....e.
  • 00 00 00 01:NALU起始码
  • 67:SPS(type=7)
  • 68:PPS(type=8)
  • 65:IDR帧(type=5)

2. 使用工具分析

bash 复制代码
# 使用ffprobe查看
ffprobe -v error -show_frames test.h264

# 输出示例:
[FRAME]
media_type=video
key_frame=1  # 关键帧
pkt_pts=0
pkt_size=28543
[/FRAME]

五、安卓代码解析H.264

1. 提取SPS/PPS

java 复制代码
// 从MediaCodec获取参数
ByteBuffer sps = format.getByteBuffer("csd-0"); // SPS
ByteBuffer pps = format.getByteBuffer("csd-1"); // PPS

// 转16进制打印
Log.d("H264", "SPS: " + bytesToHex(sps));
Log.d("H264", "PPS: " + bytesToHex(pps));

2. 实时解析帧类型

java 复制代码
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
int outputIndex = decoder.dequeueOutputBuffer(info, timeout);
if (outputIndex >= 0) {
    ByteBuffer buffer = outputBuffers[outputIndex];
    byte[] data = new byte[info.size];
    buffer.get(data);
    
    // 检查NALU类型
    int nalType = data[4] & 0x1F; // 取第5字节的低5位
    String frameType;
    switch (nalType) {
        case 5: frameType = "I帧"; break;
        case 1: frameType = "P帧"; break;
        default: frameType = "其他帧";
    }
    Log.d("H264", "帧类型: " + frameType);
}

六、H.264关键帧结构

1. I帧(关键帧)

  • 特点:完整图像,解码不依赖其他帧

  • 结构

    css 复制代码
    SPS + PPS + SEI + I Slice

2. GOP(图像组)

graph LR I --> P --> B --> B --> P --> B --> I
  • GOP长度:两个I帧之间的间隔(直播通常2秒)

七、码流分析工具推荐

工具 用途 平台
Elecard StreamEye 可视化分析 Windows
H264Visa 逐帧查看 Windows
FFmpeg/FFprobe 命令行分析 全平台
CodecVisa 安卓端分析 Android

八、避坑指南

1. 常见问题

  • 花屏:丢失I帧或SPS/PPS
  • 无法解码 :NALU缺少起始码00 00 00 01
  • 同步问题:时间戳(PTS/DTS)错乱

2. 优化建议

  • 关键帧间隔:直播设2秒(GOP=帧率×2)
  • SPS/PPS:每个I帧前重复发送
  • 码率控制:根据分辨率调整

九、终极分析口诀

"H.264码流分三层,NALU里藏乾坤

SPS/PPS是配置,I帧完整P帧差

起始码头要认准,0x000001是标准

分析工具辅助看,编解码问题无处藏"

掌握H.264码流分析,你就能像"视频医生"一样精准诊断问题! 🩺📹

相关推荐
慢热型网友.2 小时前
从PDF中提取表格:以GB/T2260—2007为例
android·pdf
安小牛2 小时前
Kotlin 学习-方法和参数类型
android·学习·kotlin·android studio
_一条咸鱼_6 小时前
大厂Android面试秘籍:Activity 结果回调处理(八)
android·面试·android jetpack
_一条咸鱼_6 小时前
大厂Android面试秘籍:Activity 与 Fragment 交互(九)
android·面试·android jetpack
青山渺渺8 小时前
简单记录一下Android四大组件
android
每次的天空9 小时前
Android学习总结之OKHttp拦截器和缓存
android·学习·okhttp
aaajj10 小时前
【Android】ContentResolver的使用
android
时光少年10 小时前
Android ExoPlayer版本升级遇上系统的”瓜“
android·前端
你说你说你来说12 小时前
安卓布局详解
android·笔记
奔跑吧 android12 小时前
【android bluetooth 框架分析 02】【Module详解 3】【HciHal 模块介绍】
android·bluetooth·bt·gd·aosp13·hcihal