h264 extradata解析,提取参数集SPS/PPS
1 背景在音视频处理中AVCC 格式转换为 Annex-B 格式的典型场景包括以下六种情况一、Android/Harmony等平台硬件解码场景Android/Harmony 系统硬解码器通常仅支持 Annex-B 格式的码流输入。当从 MP4/MKV/MOV等容器默认使用 AVCC 格式中提取 H.264码流进行解码时需通过 SPS/PPS 提取、起始码替换等操作完成格式转换。例如 MP4 文件头部的 AVCDecoderConfigurationRecord 数据结构需被解析后重组为 Annex-B 的头部结构。二、实时流传输协议封装在 RTP/RTSP 协议传输或 TS 流封装场景中Annex-B 格式作为标准要求存在。由于 Annex-B 使用 0x000001 或 0x00000001 起始码标识 NALU 边界便于流媒体服务端进行码流分割和实时传输。三、容器格式转换场景将 MP4 文件重新封装为 FLV、TS 等格式时需遵循目标容器的编码规范。例如 FLV 容器要求视频编码信息通过 AVCDecoderConfigurationRecord 传递而 TS 流通常直接使用 Annex-B 格式的起始码分割 NALU。四、硬件解码兼容性修复某些硬件解码器如部分 GPU 加速方案对 Annex-B 格式有强依赖性。若使用 FFmpeg 的 h264_mp4toannexb 等 Bitstream Filter 处理码流时未正确处理 SPS/PPS 插入逻辑可能引发硬解异常此时需规范转换流程。五、防竞争字节处理需求AVCC 格式使用长度前缀标识 NALU 大小而 Annex-B 需在码流中插入防竞争字节Emulation Prevention Bytes避免起始码冲突。当需要兼容老式解码设备或特定流媒体服务器时必须进行格式转换以实现防竞争处理。六、低延迟直播场景优化Annex-B 格式允许在关键帧前周期性插入 SPS/PPS使解码器可从视频流任意位置开始解码。这种特性使其更适合低延迟直播场景而 AVCC 格式因依赖容器头部的集中式参数存储难以满足实时流随机接入需求。AVCC转 Annex-B 场景中当视频帧是IDR帧时需要将参数集SPS/PPS在IDR前拷贝到解码器输入缓存中才能正常解码。本文讲解H.264 extradata语法以及如何从mp4/mkv/mov等容器中提取参数集SPS/PPS。2 AVCC和Annex-B的定义和区别AVCCAVCC是一种用于封装H.264码流的格式它将SPSSequence Parameter Set和PPSPicture Parameter Set封装为ExtraData通常用于MP4/MKV/MOV等封装格式的文件头中播放器通过这些信息初始化解码器‌。Annex-B‌这是一种对NALU层进行包装的格式每个NALU前面加上起始码如0x000001或0x00000001用于分隔不同的NALU。为了防止原始码流中出现相同的起始码Annex-B引入了防竞争字节Emulation Prevention Bytes的概念即在出现0x0001之前插入一个字节内容为0x3‌。 AVCC以长度信息替代起始码其NALU内部的原始数据无需额外处理即可避免数据与起始码冲突的问题因此没有防竞争码。AVCC 结构AVCC封装的H.264码流中最前面的是AVCDecoderConfigurationRecord或称为extradata。AVCDecoderConfigurationRecord语法如下所示(H.264-AVC-ISO_IEC_14496-15)字段解释 configurationVersion 占1字节版本号固定为1。 AVCProfileIndication 占1字节SPS的profile_idc即(H.264标准规定的)SPS的第一个字节。 profile_compatibility占1字节即(H.264标准规定的)SPS的第二个字节。 AVCLevelIndication 占1字节SPS的level_idc即(H.264标准规定的)SPS的第三个字节。 lengthSizeMinusOne取该字节低2位lengthSizeMinusOne为存贮NALUnitLength所需的空间减1 单位为字节。比如当lengthSizeMinusOne为2那么存贮该路H.264码流的每个NALUnitLength所需 的空间为(21)个字节。我们在读取每个NALU之前先读(21)个字节把读取到的数据转成整数 这就是该NALU的总长度了。 numOfSequenceParameterSets取该字节低5位该extradata中SPS个数。 sequenceParameterSetLength占2字节SPS长度以字节为单位。 sequenceParameterSetNALUnitSPS二进制数据长度为sequenceParameterSetLength字节。 numOfPictureParameterSets占1字节该extradata中PPS个数。 pictureParameterSetLength占2字节PPS长度以字节为单位。 pictureParameterSetNALUnitPPS二进制数据长度为pictureParameterSetLength字节。 chroma_format取低2位包含由chroma_format_idc参数定义的chroma_format指示符。 bit_depth_luma_minus8取低3位表示Luma数组中样本的位深度。例如位深度为8用0 表示 位深度8bit_depth_luma_minus8。此字段的值应在0到4的范围内包括0和4。 bit_depth_chroma_minus8取低3位表示Chroma阵列中样本的位深度。例如位深度为8用0 表示 位深度8bit_depth_luma_minus8。此字段的值应在0到4的范围内包括0和4。 numOfSequenceParameterSetExt占1字节表示用于解码AVC基本流的序列参数集扩展的数量。 sequenceParameterSetExtLength占2字节表示SPS 扩展的长度。 sequenceParameterSetExtNALUnit表示SPS 扩展二进制数据长度为sequenceParameterSetExtLength字节。AVCProfileIndicationprofile_compatibilityAVCLevelIndication三个字段对应H.264标准(44 Rec. ITU-T H.264 (08/2021))定义的前三个字节如下图所示。Annex-B‌ 结构(Recommendation ITU-T H.264 08/2021)3 实例分析01 :configurationVersion固定为164:AVCProfileIndication 1字节00:profile_compatibility1字节28:AVCLevelIndication1字节ff:低2位是 “11”,即3 说明存储 “NALUnitLength”所需空间是31 即4.e1:numOfSequenceParameterSets取低5位“00001” ,即100 1e:这两个字节是 numOfSequenceParameterSets的长度二进制“11110”, 十进制30SPS nal 长30个字节跳过sps nal 30个字节。01pps个数 100 06:pps二进制数据长度6个字节跳过6个字节fd:chroma_format,取低2位为0f8:bit_depth_luma_minus8取低三位0f8:bit_depth_chroma_minus8取低三位04 获取avc extradatah264, extra data存在于trak-mdia-minf-stbl-stsd-avc1-avcc 通常使用ffmpeg解封装后得到。// 解析文件intretavformat_open_input(fmtCtx_,filepath_.toStdString().c_str(),nullptr,nullptr);if(ret0){qDebug()avformat_open_input failed;return;}retavformat_find_stream_info(fmtCtx_,nullptr);if(ret0){qDebug()avformat_find_stream_info failed;return;}for(inti0;ifmtCtx_-nb_streams;i){AVStream*streamfmtCtx_-streams[i];if(stream-codecpar-codec_id!AV_CODEC_ID_H264){qDebug()please input h264 file;return;}constAVCodec*decavcodec_find_decoder(stream-codecpar-codec_id);AVCodecContext*codec_ctx;if(!dec){qDebug()Failed to find decoder for stream:i;return;}codec_ctxavcodec_alloc_context3(dec);if(!codec_ctx){qDebug()Failed to allocate the decoder context for stream:i;return;}retavcodec_parameters_to_context(codec_ctx,stream-codecpar);if(ret0){qDebug()Failed to copy decoder parameters to input decoder context for stream:i;return;}if(codec_ctx-codec_typeAVMEDIA_TYPE_VIDEO||codec_ctx-codec_typeAVMEDIA_TYPE_AUDIO){if(codec_ctx-codec_typeAVMEDIA_TYPE_VIDEO){codec_ctx-framerateav_guess_frame_rate(fmtCtx_,stream,NULL);videoCodecCtx_codec_ctx;videoDec_(AVCodec*)dec;videoStreamIndex_i;if(videoCodecCtx_-extradata_size0){QString exepathQCoreApplication::applicationDirPath()/extradata.bin;FILE*fpfopen(exepath.toStdString().c_str(),w);if(fp){fwrite(videoCodecCtx_-extradata,videoCodecCtx_-extradata_size,1,fp);fclose(fp);}}}elseif(codec_ctx-codec_typeAVMEDIA_TYPE_AUDIO){audioCodecCtx_codec_ctx;audioDec_(AVCodec*)dec;audioStreamIndex_i;}retavcodec_open2(codec_ctx,dec,NULL);if(ret0){qDebug()Failed to open decoder for stream:i;return;}}}5 解析avc extradatavoidMainWindow::parseAvcExtradata(constuint8_t*extra_data){intpos1;// AVCProfileIndication1字节intavcprofileidcextra_data[pos];// profile_compatibility1字节intavcprofilecompatextra_data[pos];// AVCLevelIndication1字节intavclevelidcextra_data[pos];// lengthSizeMinusOne低2位intlensizeextra_data[pos]0x03;// numOfSequenceParameterSets低5位intnumSPSextra_data[pos]0x1F;// aways 1std::vectoruint8_tsps;for(inti0;inumSPS;i){// sequenceParameterSetLength2字节intspsLen(extra_data[pos]8)|extra_data[pos1];pos2;sps.assign(extra_datapos,extra_dataposspsLen);posspsLen;}std::vectoruint8_tpps;// numOfPictureParameterSets低5位intnumPPSextra_data[pos];for(inti0;inumPPS;i){// pictureParameterSetLength2字节intppsLen(extra_data[pos]8)|extra_data[pos1];pos2;pps.assign(extra_datapos,extra_dataposppsLen);posppsLen;}// chroma_format, 取低2位intchroma_formatextra_data[pos]0x03;// bit_depth_luma_minus8, 取低3位intbit_depth_luma_minus8(extra_data[pos]0x07);// bit_depth_chroma_minus8, 取低3位intbit_depth_chroma_minus8(extra_data[pos]0x07);// numOfSequenceParameterSetExt,占1字节intspsextnumextra_data[pos];std::vectoruint8_tspsext;for(inti0;ispsextnum;i){// sequenceParameterSetExtLength,2字节intspsextLen(extra_data[pos]8)|extra_data[pos1];pos2;spsext.assign(extra_datapos,extra_dataposspsextLen);posspsextLen;}}6 代码连接avc extradata提取和解析代码运行界面如下C 音视频开发问题音视频同步花屏卡顿crashCPU占用过高延时问题解决代码跨平台移植/国产平台适配 / 资源优化等一系列音视频痛点问题

相关新闻

React Native笔记

React Native笔记

React Native(RN)采用JavaScript编写应用逻辑,利用React框架构建UI。在运行时,RN通过桥接机制将JavaScript代码与原生平台代码进行通信。对于iOS和Android,RN分别有对应的原生渲染引擎。在iOS上,它利用iOS的…

2026/9/28 7:26:18 阅读更多 →
AI字体匹配失效真相(2024字体神经网络训练数据泄露报告)

AI字体匹配失效真相(2024字体神经网络训练数据泄露报告)

更多请点击: https://intelliparadigm.com 第一章:AI字体匹配失效真相(2024字体神经网络训练数据泄露报告) 2024年3月,安全研究团队在审计某主流设计平台的字体推荐API时发现:其底层AI模型在跨字体语义匹配…

2026/9/21 9:26:48 阅读更多 →
2026亚马逊多店铺运营的环境隔离架构与合规实践

2026亚马逊多店铺运营的环境隔离架构与合规实践

做亚马逊多店铺的朋友,先别急着问"用哪款工具更稳"。我在这个行业里做指纹浏览器底层研发,也带团队把产品卖到海外几十个国家,见过太多卖家拿着一套"通用方案"冲进来,以为配个工具就能高枕无忧,结…

2026/10/3 1:11:51 阅读更多 →

最新新闻

数据跑完只会复制P值?云智变AI数据分析功能:把“统计输出”翻译成“论文证据”

数据跑完只会复制P值?云智变AI数据分析功能:把“统计输出”翻译成“论文证据”

云智变AI官网www.yunzhibian.cn 微信公众号搜一搜 云智变ai学术 一个比“不会跑数据”更致命的问题 很多研究生以为数据分析的难点在于“不会用SPSS”“不会写R代码”“Python报错看不懂”。 但真正让论文卡住的,往往不是跑不出结果,而是结果跑出来之…

2026/10/4 7:53:13 阅读更多 →
GPT Image 2.5 中文渲染实战:从海报到电商主图的工程化指南

GPT Image 2.5 中文渲染实战:从海报到电商主图的工程化指南

1. 中文渲染这道坎,GPT Image 2.5 到底跨过去没有先说结论:跨过去了,但没完全跨过去。我拿它跑了差不多两百张图,从最简单的四字标语到整段竖排文案,中文的笔画粘连、缺笔、错字、乱码这四类老毛病,出现频率…

2026/10/4 7:53:13 阅读更多 →
volatile到底在拦什么:SysTick->VAL读的哪格

volatile到底在拦什么:SysTick->VAL读的哪格

那个空循环&#xff0c;怎么在别人机器上就废了我在自己板子上写了个空循环延时&#xff0c;跑了半个月啥事没有。代码就长这样&#xff1a;uint32_t i; for (i 0; i < 72000U; i) { }结果代码丢给同事&#xff0c;他编译完一烧&#xff0c;延时直接没了&#xff0c;电机启…

2026/10/4 7:53:13 阅读更多 →
为什么Go开发者都在用Monibuca?纯Go流媒体服务器框架完整解析

为什么Go开发者都在用Monibuca?纯Go流媒体服务器框架完整解析

为什么Go开发者都在用Monibuca&#xff1f;纯Go流媒体服务器框架完整解析 【免费下载链接】monibuca Monibuca&#xff08;简称 m7s&#xff09;是一款纯 Go 开发的开源流媒体服务器开发框架。 项目地址: https://gitcode.com/langhuihui/monibuca Monibuca&#xff08;…

2026/10/4 7:53:13 阅读更多 →
MRAM+STM32 SPI驱动实战:工业存储掉电保存无需等待

MRAM+STM32 SPI驱动实战:工业存储掉电保存无需等待

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 7:53:13 阅读更多 →
Node.js事件驱动与非阻塞I/O:高并发下的性能基石与实战解析

Node.js事件驱动与非阻塞I/O:高并发下的性能基石与实战解析

1. 为什么Node.js能扛住高并发&#xff1a;从一次面试追问说起Node.js 事件驱动模型和非阻塞I/O这两个词&#xff0c;相信每个写过JavaScript的人都见过。但真正理解它们价值的人&#xff0c;可能比想象中少。几年前我去面试一家做实时通信的中厂&#xff0c;面试官问了一个很实…

2026/10/4 7:52:12 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →