2012-07-18 125 views
13

环境:H.264变换用的FFmpeg(从RTP流)

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

目标:

在我想有一个* .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字节是通过将NAL单元位从字节1和2放在一起创建的。

现在取决于碎片I型执行以下操作:

SPS/PPS:

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

带起始位的碎片

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

碎片无起始符

  1. 写原始数据

这意味着我的原始文件看起来像li柯本:

[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前缀(0×00 0×00 0×01),然后将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我可以发挥它。

有最初的原始文件之间以及在一个由FFmpeg的写入的以下差异(我已经写):

  1. 部首:FFmpeg的文件具有类似于大约的0x30部首
  2. 的字节
  3. 页脚: ffmpeg的文件也有一个页脚
  4. 更改前缀和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实际上做了什么?为什么它会改变视频数据中的一些字节?

+1

你能达到这个目标吗?如果是的话,你愿意分享解决方案吗?谢谢! – 2017-03-06 22:45:00

回答

0

看起来像流打包。许多容器格式将比特流分成数据包并添加一些信息,例如时间戳,数据包的长度等。这给钩子解码器跳过文件而不解码所有数据,当数据包丢失时重新同步,同步音频/视频,组合多个流等

看更多信息,MP4文件格式信息:
http://en.wikipedia.org/wiki/MPEG-4_Part_14

2

除了增加了MP4容器,ffmpeg的转换你的H.264附件B字节流(以NAL前缀)为长度前缀格式。

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

-1

您可以通过打开h264 specs了解有关更改的更多信息。章附录B.