当前位置: 首页 > news >正文

H.264添加 SEI 信息技术文档

  1. 概述
    本文档描述如何在 H.264 视频流中动态插入自定义 SEI信息。SEI 是 H.264/AVC 标准中定义的一种元数据格式,可用于携带时间戳、版权信息、场景标记等附加数据。本方案基于 FFmpeg 的 AVPacket 结构和标准 H.264 NAL 单元格式实现,支持与视频帧的精确同步。
  2. SEI 核心概念
  3. SEI 的作用
    1. 元数据承载:传递与视频帧相关的非压缩数据(如 GPS 信息、时间戳)。
    2. 解码辅助:提供解码器增强信息(如颜色空间描述)。
    3. 流分析:用于视频流完整性校验或内容标记。
  4. SEI 结构
    字段 长度 描述
    NAL Header 1 byte NAL 单元类型(0x06 表示 SEI)
    Payload Type 可变长度 SEI 数据类型(如用户自定义=5)
    Payload Size 可变长度 负载数据的字节长度
    Payload Data N bytes 实际负载内容
  5. 实现原理
  6. 整体流程
    A[输入H.264数据包] --> B[生成SEI NAL单元]
    B --> C[合并到原始数据前]
    C --> D[更新AVPacket]
    D --> E[写入封装层]
  7. 关键技术点
    1. NAL 单元封装:遵循 H.264 Annex B 格式,添加 0x00000001 起始码。
    2. 可变长度编码:对 payload_type 和 payload_size 进行多字节编码。
    3. 内存管理:使用 FFmpeg 的 AVBufferRef 安全管理数据内存。
  8. 代码实现详解
  9. 代码实现
    // 将字符串转换为二进制表示
    std::vector<uint8_t> string_to_binary(const std::string& str) {
    return std::vector<uint8_t>(str.begin(), str.end());
    }

// 编码payloadType和payloadSize
void encode_sei_header(std::vector<uint8_t>& nal_unit, uint32_t payload_type, size_t payload_size) {
while (payload_type > 0x7F) {
nal_unit.push_back((payload_type & 0x7F) | 0x80);
payload_type >>= 7;
}
nal_unit.push_back(payload_type);

    while (payload_size > 0x7F) {nal_unit.push_back((payload_size & 0x7F) | 0x80);payload_size >>= 7;}nal_unit.push_back(payload_size);

}

// H.264起始码
const uint8_t H264_START_CODE[] = {0x00, 0x00, 0x00, 0x01};

void append_custom_sei_to_packet(AVPacket *pkt, const std::string &sei_message)
{
// 创建SEI负载
std::vector<uint8_t> sei_payload = string_to_binary(sei_message);

// 构建SEI NAL单元
std::vector<uint8_t> sei_nal;
sei_nal.insert(sei_nal.end(), H264_START_CODE, H264_START_CODE + 4);  // 添加起始码
sei_nal.push_back(0x06);                                              // SEI NAL单元头// 编码SEI消息头
encode_sei_header(sei_nal, 5, sei_payload.size());  // payloadType=5 表示用户数据未注册// 合并NAL头和负载
sei_nal.insert(sei_nal.end(), sei_payload.begin(), sei_payload.end());// 分配新内存并复制数据
size_t   new_size = pkt->size + sei_nal.size();
uint8_t *new_data = (uint8_t *)av_malloc(new_size);
if (!new_data)
{fprintf(stderr, "Memory allocation failed\n");return;
}
memcpy(new_data, sei_nal.data(), sei_nal.size());
memcpy(new_data + sei_nal.size(), pkt->data, pkt->size);// 更新pkt的数据和大小
av_packet_unref(pkt);
pkt->data = new_data;
pkt->size = new_size;// 创建AVBufferRef
AVBufferRef *buffer_ref = av_buffer_create(new_data, new_size, av_buffer_default_free, NULL, 0);
if (!buffer_ref)
{fprintf(stderr, "Failed to create AVBufferRef\n");av_free(new_data);return;
}
pkt->buf = buffer_ref;

}

void MP4Recorder::receiveH264Stream(const uint8_t *data, size_t size, const std::string &sei)
{
if (!m_bIsRecording || !ofmt_ctx) return;

    AVPacket pkt;init_packet(&pkt);pkt.data = const_cast<uint8_t*>(data);pkt.size = size;// 动态生成并附加SEI到当前帧append_custom_sei_to_packet(&pkt, sei);write_video_packet(pkt);av_packet_unref(&pkt);

}
2. 函数说明
1. string_to_binary:将字符串转换为二进制数据
2. encode_sei_header:编码 SEI 头部(Payload Type + Size),nal_unit: 输出的 NAL 单元容器,payload_type: SEI 类型(如 5=用户未注册数据),payload_size: 负载数据长度,每个字节最高位为延续标志(1 表示后续还有字节),其余7 位存储数据,按小端序排列
3. append_custom_sei_to_packet:将 SEI 添加到 AVPacket 开头,构建 SEI NAL 单元(起始码 + NAL头 + 负载),合并原始视频数据,更新 AVPacket 内存引用

http://www.xdnf.cn/news/225469.html

相关文章:

  • MySQL bin目录下的可执行文件
  • 零基础学Java——第八章:Java网络编程(下)
  • 数据资产管理与AI融合:物联网时代的新征程
  • 【KWDB 创作者计划】_存储引擎深度解析
  • 核心技能:ArcGIS洪水灾害普查、风险评估及淹没制图
  • MT6765 android上层获取VCM lens位置
  • macOS 安装了Docker Desktop版终端docker 命令没办法使用
  • ‌阿里云dns服务器不可用怎么办?dns可以随便改吗?
  • Dockerfile最佳实践:构建高效、安全的容器镜像
  • AI生成Flutter UI代码实践(一)
  • 学习记录:DAY21
  • EasyRTC嵌入式音视频实时通话SDK技术,打造低延迟、高安全的远程技术支持
  • 【JavaEE】网络原理之初识(1.0)
  • M1 Mac pip3 install错误记录
  • 算法基础学习|03整数二分
  • 【工具变量】地级市李白消费指数及预期指数数据集(2012-2022年)
  • Java学习手册:Spring 中常用的注解
  • day11 python超参数调整
  • 在若依前后端分离项目中集成 ONLYOFFICE 以实现在线预览、编辑和协作功能
  • 网页出现502的报错是什么意思?
  • 泰迪杯特等奖案例学习资料:基于多模态数据融合与边缘计算的工业设备健康监测与预测性维护系统
  • GPU集群中的超节点
  • 基于Q学习的2048游戏智能体:制作一个自己会玩游戏的智能体
  • CSS实现DIV水平与垂直居中方法总结
  • tailwindcss如何改变antd子组件的样式
  • CSS:选择器-复合选择器
  • RHCSA Linux 系统 文件系统权限
  • Linux——HTTP协议理解
  • 7.计算机网络相关术语
  • Axure疑难杂症:中继器制作下拉菜单(多级中继器高级交互)