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

ffmpeg中格式转换需要注意点总结

某些封装格式(例如MP4/FLV/MKV等)的H.264码流的SPS和PPS信息存储在AVCodeccontext结构体的extradata中。分离某些封装格式(例如MP4/FLV/MKV等)中的H.264的时候,需要首先写入SPS和PPS,否则会导致分离出来的数据没有SPS、PPS而无法播。需要使用ffmpeg中名称为“h264 mp4toannexb”的bitstream filter处理

关键概念解析与操作指南


一、SPS/PPS 的作用与存储位置
  1. SPS (Sequence Parameter Set)
    定义视频序列的全局参数,包括分辨率、帧率、编码级别等。
  2. PPS (Picture Parameter Set)
    定义图像解码参数,如熵编码模式、分片参数等。
  3. 存储位置
    • 在 MP4/FLV/MKV 等封装格式中,SPS/PPS 通常存储在 ‌AVCodecContext->extradata‌ 中,而非嵌入到每个关键帧。
    • 裸 H.264 流(如 Annex B 格式)要求在每个关键帧(IDR帧)前携带 SPS/PPS。

二、问题根源分析

当直接从封装格式(如 MP4)中提取 H.264 裸流时:

  • 直接提取的缺陷‌:
    输出的 H.264 数据缺少 SPS/PPS 头部信息,导致播放器无法初始化解码器。
  • 典型报错‌:

    [h264 @ 0x7f8a5c006800] no frame! Invalid NAL unit size


三、解决方案:使用 Bitstream Filter

通过 FFmpeg 的 ‌h264_mp4toannexb‌ 比特流过滤器,实现以下功能:

  1. 从 extradata 提取 SPS/PPS‌:
    自动读取 AVCodecContext->extradata 中的参数集。
  2. 转换为 Annex B 格式‌:
    • 在码流起始位置插入 SPS/PPS。
    • 在每个关键帧前插入起始码 0x00000001 或 0x000001

四、操作命令示例

提取 MP4 中的 H.264 裸流并修复 SPS/PPS:

ffmpeg -i input.mp4 -c:v copy -bsf:v h264_mp4toannexb output.h264

  • 参数说明‌:
    • -c:v copy:直接复制视频流,不重新编码。
    • -bsf:v h264_mp4toannexb:对视频流应用比特流过滤器。

五、不同封装格式的适配
封装格式比特流过滤器作用
MP4h264_mp4toannexb插入 SPS/PPS,添加起始码
FLVh264_mp4toannexb同上(FLV 的 H.264 存储方式类似 MP4)
MKVh264_mp4toannexb同上
TS无需过滤器TS 流已符合 Annex B 格式

六、验证输出文件
  1. 使用 ffprobe 检查‌:

    ffprobe -v error -show_streams output.h264

    确认输出中包含 codec_tag_string=avc1 和 extradata
  2. 播放测试‌:

    ffplay output.h264


七、底层原理详解
  1. extradata 结构
    • MP4 中 extradata 的格式为 ‌AVCDecoderConfigurationRecord‌,包含 SPS/PPS 的二进制数据。
    • h264_mp4toannexb 过滤器解析此结构,将其转换为 Annex B 的头部。
  2. Annex B 格式要求
    • 每个 NAL 单元以起始码 0x00000001 或 0x000001 开头。
    • SPS/PPS 必须出现在码流开头或关键帧前。

八、扩展场景:处理多路流

若需合并多个 MP4 文件的 H.264 流,需对每个输入单独应用过滤器:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \ "[0:v]bsf=h264_mp4toannexb[0v];[1:v]bsf=h264_mp4toannexb[1v]; \ [0v][1v]concat=n=2:v=1" -c:v libx264 output_combined.mp4


通过上述方法,可确保提取的 H.264 裸流符合播放器要求,避免因缺失 SPS/PPS 导致的解码失败问题。

ffmpeg -i 1.mp4 -c:v copy output_without_sps_pps.h264转换完成后通过ffplay播放的h264为什么播放速度很快

问题原因解析

使用 ffmpeg -i 1.mp4 -c:v copy output.h264 转换的 H.264 裸流播放速度异常加快,主要与 ‌时间戳信息丢失‌ 和 ‌封装格式差异‌ 相关,具体原因如下:


1. ‌时间基(Timebase)未正确传递
  • MP4 容器特性‌:MP4 文件的时间戳基值(time_base)通常为 1/1000 或 1/90000,而 H.264 裸流无容器层,默认时间基可能被错误解析为 1/25 或 1/30[‌2][‌7]。
  • 播放器误判‌:ffplay 根据 H.264 裸流的 NAL 单元间隔推算帧率,若时间戳缺失或错误,会强制按默认高帧率(如 25fps)播放[‌1][‌7]。
2. ‌关键帧间隔(GOP)与 B/P 帧依赖断裂
  • -c:v copy 的局限性‌:直接复制流时,B/P 帧的解码依赖关系可能因裸流缺少容器层的元数据而断裂,导致解码器跳过参考帧计算,加速播放[‌2][‌7]。
3. ‌SPS/PPS 信息未嵌入
  • 缺失参数集‌:MP4 中的 SPS/PPS 存储在 extradata 中,直接复制时未通过 h264_mp4toannexb 过滤器插入码流,播放器可能无法正确初始化解码器时间轴[‌1][‌2]。

解决方案

1. ‌强制指定输出帧率

通过 -r 参数显式定义输出帧率,覆盖默认值:

 

bashCopy Code

ffmpeg -i 1.mp4 -c:v copy -r 30 output.h264

  • 作用‌:强制 H.264 裸流按 30fps 播放,避免时间基误判[‌2][‌7]。
2. ‌添加比特流过滤器处理时间戳

使用 setpts 滤镜修正时间戳:

 

bashCopy Code

ffmpeg -i 1.mp4 -c:v copy -bsf:v h264_mp4toannexb -vf "setpts=PTS-STARTPTS" output.h264

  • 关键参数‌:
    • -bsf:v h264_mp4toannexb:插入 SPS/PPS 并修正 NAL 单元格式[‌1][‌2]。
    • setpts=PTS-STARTPTS:重置时间戳为从零开始,消除容器时间基差异[‌7]。
3. ‌验证与调试
  • 检查时间戳信息‌:
     

    bashCopy Code

    ffprobe -show_frames output.h264 | grep "pkt_pts_time"

    确认输出帧的 pkt_pts_time 均匀递增(如 0.033s 间隔对应 30fps)[‌7]。
  • 对比播放效果‌:
     

    bashCopy Code

    ffplay -vf "setpts=PTS-STARTPTS" output.h264 # 强制按原始速度播放


扩展场景:直播推流中的类似问题

若需将 USB 相机的 RGBA 数据编码为 H.264 并推流至 RTMP,需在编码器初始化时手动插入 SPS/PPS,并通过 avcodec_parameters_from_context 传递至输出流上下文,否则 RTMP 播放会出现加速或花屏[‌1][‌2]。


总结

H.264 裸流播放速度异常的本质是 ‌时间戳与帧率元数据丢失‌,需通过过滤器修正时间基或显式指定帧率参数[‌1][‌2][‌7]。

相关文章:

  • 设计模式基础入门
  • Android 使用CameraX实现预览、拍照、录制视频(Java版)
  • AI产品的基础设施:算法、数据与大语言模型
  • 解决安卓手机WebView无法直接预览PDF的问题(使用PDF.js方案)
  • 基于SpringBoot的仓库管理系统-023
  • 递归详解:从原理到实战
  • 9.常用模板引擎
  • Elasticsearch索引的字段映射
  • 串口中断接收与环形缓冲实例(apollo3 blue plus)
  • Perl 哈希
  • Springboot实战:如何用Docker和Kubernetes部署微服务
  • Unity中MonoBehaviour组件禁用时协程的行为
  • Qt基本框架(1)
  • 正则表达式和通配符
  • Python 中的 `partial`:函数参数预设的艺术
  • unity UI管理器
  • 笔记:代码随想录算法训练营day64:拓扑排序精讲、dijkstra(朴素版)精讲
  • 算法设计学习3
  • HTTP,请求响应报头,以及抓包工具的讨论
  • go 使用os复制文件
  • 医学统计专家童新元逝世,终年61岁
  • 游客曝九寨沟打网约车被出租车围堵,官方:前者违规,后者做法不对
  • 长三角铁路“五一”假期运输今启动:预计发送旅客量增6%,5月1日当天有望创新高
  • 我国成功发射卫星互联网低轨卫星
  • ​关键词看中国经济“一季报”:韧,长期向好看底气
  • 外交部:欢迎外国朋友“五一”来中国