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]。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小型语言模型与检索增强生成系统的融合:机遇与挑战

小型语言模型(SLMs)是大型语言模型(LLMs)的紧凑版本。其参数量通常比大型模型少得多:约30亿或更少。这使得它们具有相对轻量级的特点,推理速度更快。 当前研究的一个有趣方向是将SLMs整合到检索增强生成(RAG)系统中以提升性能。本文探讨这一最新趋势&…

使用 .NET 9 和 Azure 构建云原生应用程序:有什么新功能?

随着 .NET 9 推出一系列以云为中心的增强功能,开发人员拥有比以往更多的工具来在 Azure 上创建可扩展、高性能的云原生应用程序。让我们深入了解 .NET 9 中的一些出色功能,这些功能使构建、部署和优化云应用程序变得更加容易,并附有示例以帮助…

PostgreSQL:表分区与继承

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

Linux / Windows 下 Mamba / Vim / Vmamba 安装教程及安装包索引

目录 背景0. 前期环境查询/需求分析1. Linux 平台1.1 Mamba1.2 Vim1.3 Vmamba 2. Windows 平台2.1 Mamba2.1.1 Mamba 12.1.2 Mamba 2- 治标不治本- 终极版- 高算力版 2.2 Vim- 治标不治本- 终极版- 高算力版 2.3 Vmamba- 治标不治本- 终极版- 高算力版 3. Linux / Windows 双平…

开源项目更新到个人仓库二次开发并保持同步

当你克隆了一个开源项目并将其推送到自己的仓库后,定期更新该开源项目并与你的本地修改同步是一个常见的需求。为了高效地管理这一过程,你可以使用 Git 的 upstream 远程仓库和 rebase 技术来保持代码的整洁和线性历史。 1. 设置上游远程仓库 首先&…

多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测

多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测 目录 多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测&#…

MCP(模型上下文协议)入门指南:用Web开发的视角理解下一代AI引擎

引言:当Java Web遇到长期记忆 想象你正在开发一个在线法律咨询平台。用户上传一份300页的合同后,连续提出了10个问题: 第3页的违约条款具体内容是什么?请对比第15页和第120页的支付条件整份合同中最高的赔偿金额是多少&#xff…

简易Minecraft python

废话多说 以下是一个基于Python和ModernGL的简化版3D沙盒游戏框架。由于代码长度限制,这里提供一个核心实现(约500行),您可以通过添加更多功能和内容来扩展它: python import pygame import moderngl import numpy a…

element-ui自制树形穿梭框

1、需求 由于业务特殊需求,想要element穿梭框功能,数据是二级树形结构,选中左边数据穿梭到右边后,左边数据不变。多次选中左边相同数据进行穿梭操作,右边数据会多次增加相同的数据。右边数据穿梭回左边时,…

WPS宏开发手册——Excel实战

目录 系列文章5、Excel实战使用for循环给10*10的表格填充行列之和使用for循环将10*10表格中的偶数值提取到另一个sheet页使用for循环给写一个99乘法表按市场成员名称分类(即市场成员A、B、C...),统计月内不同时间段表1和表2的乘积之和&#x…

计算机网络-TCP的流量控制

内容来源:小林coding 本文是对小林coding的TPC流量控制的精简总结 什么是流量控制 发送方不能无脑的发数据给接收方,要考虑接收方处理能力 如果一直无脑的发数据给对方,但对方处理不过来,那么就会导致触发重发机制 从而导致网…

Spring Boot 七种事务传播行为只有 REQUIRES_NEW 和 NESTED 支持部分回滚的分析

Spring Boot 七种事务传播行为支持部分回滚的分析 支持部分回滚的传播行为 REQUIRES_NEW:始终开启新事务,独立于外部事务,失败时仅自身回滚。NESTED:在当前事务中创建保存点(Savepoint),可局部…

突破反爬困境:SDK开发,浏览器模块(七)

声明 本文所讨论的内容及技术均纯属学术交流与技术研究目的,旨在探讨和总结互联网数据流动、前后端技术架构及安全防御中的技术演进。文中提及的各类技术手段和策略均仅供技术人员在合法与合规的前提下进行研究、学习与防御测试之用。 作者不支持亦不鼓励任何未经授…

C++数据排序( 附源码 )

一.冒泡排序 原理:自左向右依次遍历,若相邻两数顺序错误,则交换两数. 这样,每一轮结束后,最大/最小的数就会到最后. Code: #include <iostream> #include <cstdio> using namespace std; const int N1e51; int n,a[N],in; void PrintArray(int a[],int n){for…

I2C 读写 AT24C02

根据AT24C02的 Datasheet 可知AT24C02有2K bit&#xff0c;即256B&#xff0c;分为32页,每页8个字节&#xff0c;结合数据手册和原理图可以得知&#xff0c;板载AT24C02的读地址为0xA2&#xff0c;写地址为0xA3&#xff1a; #define AT24C02_ADDR_WRITE 0xA2 #define AT24C02_…

K8S学习之基础七十四:部署在线书店bookinfo

部署在线书店bookinfo 在线书店-bookinfo 该应用由四个单独的微服务构成&#xff0c;这个应用模仿在线书店的一个分类&#xff0c;显示一本书的信息&#xff0c;页面上会显示一本书的描述&#xff0c;书籍的细节&#xff08;ISBN、页数等&#xff09;&#xff0c;以及关于这本…

Linux 查找文本中控制字符所在的行

参考资料 ASCIIコード表 目录 一. 业务背景二. 遇到的问题三. 分析3.1 url编码的前置知识3.2 出现控制字符的transactionid分析3.3 16进制分析 四. 从文本中查找控制字符所在的行五. 控制字符一览 一. 业务背景 ⏹在项目中&#xff0c;业务请求对应着下URL http://www.test.…

python将pdf文件转为图片,如果pdf文件包含多页,将转化的多个图片通过垂直或者水平合并成一张图片

要将PDF文件转换为图片&#xff0c;并将多页PDF垂直合并成一张图片&#xff0c;可以使用PyMuPDF&#xff08;也称为fitz&#xff09;库来读取PDF文件&#xff0c;并使用Pillow库来处理和合并图片。以下是一个示例代码&#xff0c;展示了如何实现这个功能&#xff1a; 首先&…

HarmonyOS 基础组件和基础布局的介绍

1. HarmonyOS 基础组件 1.1 Text 文本组件 Text(this.message)//文本内容.width(200).height(50).margin({ top: 20, left: 20 }).fontSize(30)//字体大小.maxLines(1)// 最大行数.textOverflow({ overflow: TextOverflow.Ellipsis })// 超出显示....fontColor(Color.Black).…

FrameWork基础案例解析(四)

文章目录 单独拉取framework开机与开机动画横屏Android.mk语法单独编译SDKmake 忽略warning单独修改和编译Camera2单独编译Launcher3Android Studio 导入、修改、编译Settings导入 Android Studio 导入、修改、编译Launcher3android 开机默认进入指定Launcher植入自己的apk到系…