H264/H265 NALU的nalu_unit_type解析
一、概述
在 H.264/H.265 编码中,视频数据被封装为一系列 NALU(Network Abstraction Layer Unit),每个 NALU 包含不同类型的数据(如 SPS/PPS 参数集、I 帧 / P 帧 / B 帧等)。
二、解析nal_unit_type
#include <cstdint> #include <vector> class NaluTypeParser { public: // 初始化码流数据(data: 码流指针,size: 数据大小,is_h265: 是否为H.265) NaluTypeParser(const uint8_t* data, size_t size, bool is_h265) : data_(data), size_(size), is_h265_(is_h265), pos_(0) {} // 解析下一个NALU的类型(返回类型值,-1表示无更多NALU) int parse_next_type() { // 查找NALU起始码 size_t start_code_len = find_start_code(); if (start_code_len == 0) return -1; // 跳过起始码,定位到NAL头部 pos_ += start_code_len; if (pos_ >= size_) return -1; // 提取NALU类型值 return is_h265_ ? parse_h265_type() : parse_h264_type(); } private: const uint8_t* data_; // 码流数据指针 size_t size_; // 数据总大小 bool is_h265_; // 是否为H.265码流 size_t pos_; // 当前解析位置 // 查找起始码(返回起始码长度:3或4字节,0表示未找到) size_t find_start_code() { while (pos_ + 4 <= size_) { // 检查4字节起始码 0x00000001 if (data_[pos_] == 0 && data_[pos_+1] == 0 && data_[pos_+2] == 0 && data_[pos_+3] == 1) { return 4; } // 检查3字节起始码 0x000001 if (pos_ + 3 <= size_ && data_[pos_] == 0 && data_[pos_+1] == 0 && data_[pos_+2] == 1) { return 3; } pos_++; } return 0; } // 解析H.264的NALU类型(低5位) int parse_h264_type() { if (pos_ >= size_) return -1; return data_[pos_] & 0x1F; // 低5位为类型 } // 解析H.265的NALU类型(6位) int parse_h265_type() { if (pos_ + 1 >= size_) return -1; uint8_t byte1 = data_[pos_]; uint8_t byte2 = data_[pos_ + 1]; return ((byte1 & 0x3F) << 2) | ((byte2 & 0xC0) >> 6); // 6位类型 } };