使用FFmpeg进行H.264转换(来自RTP流) [英] H.264 conversion with FFmpeg (from a RTP stream)

查看:348
本文介绍了使用FFmpeg进行H.264转换(来自RTP流)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境:



我有一个IP摄像头,能够以H.264编码格式通过RTP流式传输数据。该原始流从以太网记录。



目标:



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





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



1。编写原始文件



首先,我确定通过以太网接收的每个帧的类型。为了做到这一点,我解析了每个RTP有效负载的前两个字节,所以我可以得到8 NAL单位,片段类型位和起始,保留和结束位。在有效载荷中,它们的排列如下:

 字节1:[3 NAL单位位| 5片段类型位] 
字节2:[起始位|保留位|结束位| 5 NAL单位]

从这里我可以确定:





  • a的开始和结束视频帧 - >起始位和结束位

  • 有效载荷 - > 5个片段类型位的类型

  • NAL单位字节



我的情况下需要的片段类型是: p>

 片段类型7 = SPS 
片段类型8 = PPS
片段类型28 =视频片段

NAL字节是通过将Byte 1和2的NAL单位位置在一起来创建的。



现在根据碎片类型我做以下操作:



SPS / PPS:


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

使用起始位分段


  1. 写NAL前缀

  2. 写NAL单元字节

  3. 写入剩余的原始数据

没有开始位的分片




  1. 编写原始数据

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

   

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



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

2。转换文件



由于我想避免使用编解码器,我只是去使用现有的应用程序 - > FFmpeg。这是我调用这些参数:



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



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



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

强制视频编解码器到编解码器。使用复制特殊值来说明原始编解码器数据必须按原样复制。



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



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



这让我看到我的问题:



我实际做了什么?



我的问题不在于它不工作。我只是想/需要知道我实际上通过调用ffmpeg做了什么。我有一个原始的H264文件,我不能播放。使用FFmpeg之后,我可以播放它。



原始文件(我写的)和写入的原始文件之间有以下区别通过FFmpeg:


  1. 标题:FFmpeg文件像0x30字节的标题

  2. 页脚: FFmpeg文件还有一个页脚

  3. 更改前缀和2个新字节:

虽然原始文件中的新视频帧起始像新文件中的
[NAL前缀] [NAL单位字节] [原始视频数据] ,如下所示: / p>

  [0x00 0x00] [2随机字节] [NAL单位字节] [原始视频数据] ..... [ 0x00 0x00 [2其他随机字节] [NAL单位字节] [原始视频数据] ... 

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



正如你所看到的,我不需要一个新的解决方案问题更多的解释(所以我可以自己解释)。 ffmpeg究竟做了什么?为什么会在视频数据中更改一些字节?

解决方案

除了添加MP4容器,ffmpeg将您的H.264附件B字节流(使用NAL前缀)转换为长度前缀格式。



您的[0x00 0x00] [2随机字节是一个32位整数,给出以下NAL单位的长度(以字节为单位)。


Environment:

I have an IP Camera, which is capable of streaming it's data over RTP in a H.264 encoded format. This raw stream is recorded from the ethernet. With that data I have to work.

Goal:

In the end I want to have a *.mp4 file, which I can play with common Media Players (like VLC or Windows MP).

What have I done so far:

I take that raw stream data I have and parse it. Since the data has been transmitted via RTP I need to take care of the NAL Bytes, SPS and PPS.

1. Write a raw file

First I determine the type of each frame received over Ethernet. To do so, I parse the first two bytes of every RTP Payload, so I can get the 8 NAL Unit Bit, the Fragment Type Bits and the Start, Reserved and End Bit. In the payload, they're arranged like this:

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

From this I can determine:

  • Start and End of a Video Frame -> Start Bit and End Bit
  • Type of the Payload -> 5 Fragment Type Bits
  • NAL Unit Byte

The Fragment types which are necessary in my case are:

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

The NAL Byte is created by putting the NAL Unit Bits from Byte 1 and 2 together.

Now depending on the fragmentation type I do the following:

SPS/PPS:

  1. Write the NAL Prefix (0x00 0x00 0x01) and then the SPS or PPS data

Fragmentation with Start Bit

  1. Write NAL Prefix
  2. Write NAL Unit Byte
  3. Write remaining raw data

Fragmentation without Start Bit

  1. Write raw data

This means my raw file looks something like this:

[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]...

For every PPS and SPS I find in my stream data, I just write a NAL Prefix ( 0x00 0x00 0x01 ) and then the SPS/PPS itself.

Now I can't play this data with some media player, which leads me to :

2. Convert the file

Since I wanted to avoid working much with codecs I just went to use an existing application -> FFmpeg. This I am calling with those parameters:

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

-f h264: This should tell ffmpeg I have a h264 coded stream

-vcodec copy: Quote from the manpage:

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

-r 25: Sets the framerate to 25 FPS.

When I call ffmpeg with those parameters I get an .mp4 File, which I can play with VLC and Windows MP, so it actually works. But the file now looks a bit different from my raw file.

This leads me to my question:

What did I actually do?

My problem is not that it is not working. I just want/need to know what I have actually done with calling ffmpeg. I had a raw H264 file which I could not play. After using FFmpeg I can play it.

There are the following differences between the original raw file (which I have written) and the one written by FFmpeg:

  1. Header: The FFmpeg File has like about 0x30 Bytes of Header
  2. Footer: The FFmpeg File also has a footer
  3. Changed Prefix and 2 new Bytes:

While a new Video Frame from the Raw File started like [NAL Prefix][NAL Unit Byte][Raw Video Data] in the new file it looks like this:

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

I understand that the Video Stream needs a container format (correct me if I am wrong but I assume that the new header and footer are responsible for that). But why does it change actually some Bytes in the raw data? It can't be some decoding since the stream itself should get decoded by the player and not ffmpeg.

As you can see I don't need a new solution for my problem as far more an explanation (so I can explain it by myself). What does ffmpeg actually do? And why does it change some bytes within the video data?

解决方案

Besides adding the MP4 container, ffmpeg converted your H.264 Annex B byte stream (with NAL prefixes) to a length prefixed format.

Your [0x00 0x00][2 "Random" Bytes] is a 32 bit integer, giving the length of the following NAL unit in bytes.

这篇关于使用FFmpeg进行H.264转换(来自RTP流)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆