如何处理原始UDP数据包,以便它们可以由directshow源过滤器中的解码器过滤器解码

很长的故事:

>有一个H264 / MPEG-4源
>我可以连接这个源与RTSP协议。
>我能够获得原始UDP包与RTP协议
>然后将这些原始UDP分组发送到解码器[h264 / mpeg-4] [DS源过滤器]
>但是那些“原始”UDP分组不能由解码器[h264 / mpeg-4]过滤器解码

不久:

我如何处理这些原始udp数据为了可解码的H264 / MPEG-4解码器滤波器…任何人清楚地识别步骤我有关H264 / MPEG流?

额外信息:

我可以用FFmpeg这个…我不能真正搞清楚FFmpeg如何处理原始数据,以便它可以解码由解码器。

蛋糕和平!

1.获取数据

我可以看到,你已经知道如何做(启动RTSP会话,设置RTP / AVP / UDP;单播;传输,并获得用户数据报)…但如果你有疑问,问。

无论是传输(UDP还是TCP),数据格式都是相同的:

> RTP数据:[RTP头部 – 12字节] [视频数据]
> UDP:[RTP数据]
> TCP:[$ – 1byte] [传输信道 – 1字节] [RTP数据长度 – 2字节] [RTP
数据]

所以要从UDP获取数据,你只需要去掉表示RTP头的前12个字节。但要注意,你需要它来获取视频定时信息,而对于MPEG4来说,封装化信息!

对于TCP,你需要读取第一个字节,直到你得到byte $。然后读下一个字节,这将是以下数据所属的传输信道(当服务器响应SETUP请求时,它表示:传输:RTP / AVP / TCP; unicast; interleaved = 0-1这意味着VIDEO DATA将具有TRANSPORT_CHANNEL = 0并且VIDEO RTCP DATA将具有TRANSPORT_CHANNEL = 1)。你想获得VIDEO DATA,所以我们期望0 …然后读取一个短(2字节),表示后面的RTP数据的长度,所以读取这么多字节,现​​在做与UDP相同。

拆分数据

H264和MPEG4数据通常被打包(在SDP中有packetization-mode参数,它们的值分别为0,1和2,如何解包,你可以看到HERE),因为有一定的网络限制一个端点可以通过称为MTU的TCP或UDP发送。通常为1500字节或更少。因此,如果视频帧大于(并且通常是),则其需要被分段(分组化)成MTU大小的分段。这可以通过编码器/流传输在TCP和UDP传输,或者你可以中继IP到片段和重新组装在另一侧的视频帧…第一个是更好,如果你想有一个平滑的错误倾向的视频在UDP和TCP。

H264:要检查RTP数据(通过UDP到达或通过TCP交织)是否保存一个较大的H264视频帧的片段,您必须知道片段在分组时如何看起来:

H264 Fragment

First byte:  [ 3 NAL UNIT BITS | 5 FRAGMENT TYPE BITS] 
Second byte: [ START BIT | END BIT | RESERVED BIT | 5 NAL UNIT BITS] 
Other bytes: [... VIDEO FRAGMENT DATA...]

现在,获取称为Data的字节数组中的第一个VIDEO DATA,并获取以下信息:

int fragment_type = Data[0] & 0x1F;
int nal_type = Data[1] & 0x1F;
int start_bit = Data[1] & 0x80;
int end_bit = Data[1] & 0x40;

如果fragment_type == 28,则其后面的视频数据表示视频帧片段。下一个检查是start_bit设置,如果是,那么该片段是序列中的第一个。您使用它通过从第一个有效负载字节(3 NAL单元位)的前3位重组IDR的NAL字节,并将它们与从第二个有效负载字节(5 NAL单元位)的最后5位组合,所以你会得到一个这样的字节[ 3 NAL单元| 5 NAL单元位]。然后将该NAL字节首先写入具有来自该片段的VIDEO FRAGMENT DATA的清除缓冲区。

如果start_bit和end_bit为0,则只需将VIDEO FRAGMENT DATA(跳过前两个识别片段的有效载荷字节)写入缓冲区。

如果start_bit是0,end_bit是1,那意味着它是最后一个片段,你只需将其VIDEO FRAGMENT DATA(跳过识别片段的前两个字节)写入缓冲区,现在你已经重构了视频帧!

记住,RTP数据在前12个字节中保存RTP报头,并且如果帧被分段,您不必在碎片整理缓冲区中写入前两个字节,并且您需要重构NAL字节并首先写入它。如果你在这里乱七八糟的东西,图片将是部分的(一半将是灰色或黑色或你会看到文物)。

MPEG4:
这是一个容易的。您需要检查RTP头中的MARKER_BIT。如果视频数据表示整个视频帧,则该字节被设置(1),并且视频数据的0是一个视频帧片段。所以要解包,你需要看看MARKER_BIT是什么。如果它是1,它只是读取视频数据字节。

全框:

   [MARKER = 1]

包装框架:

   [MARKER = 0], [MARKER = 0], [MARKER = 0], [MARKER = 1]

具有MARKER_BIT = 0的第一分组是第一视频帧片段,包括具有MARKER_BIT = 1的第一分组的所有其它分组是相同视频帧的片段。所以你需要做的是:

>直到MARKER_BIT = 0,将VIDEO DATA放在解包缓冲区中
>将下一个VIDEO DATA(其中MARKER_BIT = 1)放入同一个缓冲区
>拆分缓冲器现在保存一个完整的MPEG4帧

解码器的处理数据(NAL字节流)

当您已经拆分视频帧时,您需要使NAL字节流。它具有以下格式:

> H264:0x000001 [SPS],0x000001 [PPS],0x000001 [VIDEO FRAME],0x000001 …
> MPEG4:0x000001 [Visual Object Sequence Start],0x000001 [VIDEO FRAME]

规则:

>每个帧必须附加0x000001 3字节代码,无论编解码器
>每个流必须以配置信息(CONFIGURATION INFO)开始,对于H264,按顺序是SPS和PPS帧(SDP中的sprop参数集),对于MPEG4,VOS帧(SDP中的配置参数)

所以你需要为H264和MPEG4建立一个配置缓冲区,前面加上3个字节0x000001,首先发送它,然后用相同的3个字节预处理每个拆包的视频帧,并将它发送到解码器。

如果你需要任何澄清只是评论… 🙂

http://stackoverflow.com/questions/7665217/how-to-process-raw-udp-packets-so-that-they-can-be-decoded-by-a-decoder-filter-i

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:如何处理原始UDP数据包,以便它们可以由directshow源过滤器中的解码器过滤器解码