gpt4 book ai didi

video - 使用 FFmpeg 进行 H.264 转换(来自 RTP 流)

转载 作者:行者123 更新时间:2023-11-28 21:38:51 27 4
gpt4 key购买 nike

环境:

我有一个 IP 摄像机,它能够以 H.264 编码格式通过 RTP 传输数据。这个原始流是从以太网记录的。有了这些数据,我必须工作。

目标:

最后我想要一个 *.mp4 文件,我可以用普通的媒体播放器(如 VLC 或 Windows MP)播放它。

到目前为止我做了什么:

我获取并解析我拥有的原始流数据。由于数据已通过 RTP 传输,我需要处理 NAL 字节、SPS 和 PPS。

1.写一个原始文件

首先,我确定通过以太网接收的每个帧的类型。为此,我解析了每个 RTP 有效负载的前两个字节,因此我可以获得 8 NAL 单元位、片段类型位以及起始位、保留位和结束位。在有效负载中,它们是这样排列的:

Byte 1: [          3 NAL Unit Bits          | 5 Fragment Type Bits]
Byte 2: [Start Bit | Reserved Bit | End Bit | 5 NAL Unit Bits]

由此我可以确定:

  • 开始和结束一个视频帧 -> 开始位和结束位
  • 有效载荷类型 -> 5 个片段类型位
  • NAL 单元字节

在我的案例中需要的片段类型是:

Fragment Type  7 = SPS
Fragment Type 8 = PPS
Fragment Type 28 = Video Fragment

NAL 字节是通过将字节 1 和字节 2 的 NAL 单元位放在一起创建的。

现在根据碎片类型,我执行以下操作:

SPS/PPS:

  1. 写入 NAL 前缀 (0x00 0x00 0x01),然后写入 SPS 或 PPS 数据

带起始位的碎片

  1. 写NAL前缀
  2. 写入NAL单元字节
  3. 写入剩余的原始数据

没有起始位的碎片

  1. 写入原始数据

这意味着我的原始文件看起来像这样:

[NAL Prefix][SPS][NAL Prefix][PPS][NAL Prefix][NAL Unit Byte][Raw Video Data][Raw Video Data]....[NAL Prefix][NAL Unit Byte][Raw Video Data]...

对于我在流数据中找到的每个 PPS 和 SPS,我只写一个 NAL 前缀 ( 0x00 0x00 0x01 ),然后是 SPS/PPS 本身。

现在我无法使用某些媒体播放器播放此数据,这导致我:

2.转换文件

因为我想避免过多地使用编解码器,所以我只是去使用现有的应用程序 -> FFmpeg。这是我用这些参数调用的:

ffmpeg.exe -f h264 -i <RawInputFile> -vcodec copy -r 25 <OutPutFilename>.mp4

-f h264 : 这应该告诉 ffmpeg 我有一个 h264 编码流

-vcodec copy :从联机帮助页引用:

Force video codec to codec. Use the "copy" special value to tell that the raw codec data must be copied as is.

-r 25 : 将帧速率设置为 25 FPS。

当我使用这些参数调用 ffmpeg 时,我得到一个 .mp4 文件,我可以用 VLC 和 Windows MP 播放它,所以它确实有效。但是文件现在看起来与我的原始文件有点不同。

这引出了我的问题:

我实际上做了什么?

我的问题不是它不起作用。我只是想/需要知道调用 ffmpeg 时我实际做了什么。我有一个我无法播放的原始 H264 文件。使用 FFmpeg 后,我可以播放它。

原始raw文件(我写的)和FFmpeg写的有以下区别:

  1. header :FFmpeg 文件有大约 0x30 字节的 header
  2. 页脚:FFmpeg 文件也有页脚
  3. 更改前缀和 2 个新字节:

虽然原始文件中的新视频帧开始像 [NAL Prefix][NAL Unit Byte][Raw Video Data]在新文件中它看起来像这样:

[0x00 0x00][2 "Random" Bytes][NAL Unit Byte][Raw Video Data].....[0x00 0x00[2 other "Random" Bytes][NAL Unit Byte][Raw Video Data]...

我知道视频流需要一种容器格式(如果我错了请纠正我,但我认为新的页眉和页脚对此负责)。但是为什么它实际上改变了原始数据中的一些字节呢?它不可能是某种解码,因为流本身应该由播放器而不是 ffmpeg 解码。

如您所见,我不需要针对我的问题的新解决方案,而更需要一个解释(这样我就可以自己解释了)。 ffmpeg 实际上做了什么?为什么它会改变视频数据中的一些字节?

最佳答案

除了添加 MP4 容器外,ffmpeg 还将您的 H.264 Annex B 字节流(带有 NAL 前缀)转换为长度前缀格式。

您的 [0x00 0x00][2 "Random"Bytes] 是一个 32 位整数,以字节为单位给出以下 NAL 单元的长度。

关于video - 使用 FFmpeg 进行 H.264 转换(来自 RTP 流),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11543839/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com