我正在尝试从来自轴摄像头的rtp流中解析不同的mpeg4帧,并使用avcodec_decode_video函数将数据包提供给ffmpeg库。这是我正在做的步骤 1. rtsp流已初始化 2. rtp流开始流入 3.我得到的第一个数据包以000001b0开始......配置数据跟随,然后该帧以000001b6开始。 第二个rtp有效载荷将不同,直到我得到一个rtp数据包,其中标记位被设置。之后我再次收到以000001b6开头的数据包并继续使用5-10 rtp数据包..此模式重复
我正在做的是 如果我检测到000001b0 / b6 - 在正确初始化解码器上下文之后,我将累积所有后来的数据包,并将更大的缓冲区提供给libavcodec的avcodec_decode_video函数。但是我在这里得到了一张糟糕的照片,其中最顶部的部分是水平条纹 - 水晶般清晰的照片,剩下的就是蹩脚的。我不确定为什么它会像这样。请帮帮我
我在rtp数据包中获得的数据是动态-96。
要注意的是:当我传递iframes和p帧时,它们全神贯注于其他制造商的propreitary协议,ffmpeg能够解析并提供非常好的pcitures。
感谢任何帮助
答案 0 :(得分:9)
尝试在AXIS IP摄像机上摆弄您的MPEG4流设置。注意Video&图像/高级部分,您应该设置它:
此外,尝试更改“优先级”或“优化视频流”设置(您应该具有帧速率,图像质量,带宽,无)。
如果这些都不起作用,请阅读更多内容......
我希望您了解MPEG4流是如何通过RTP传输的。简而言之(如果你不确定如何):
“配置框架”(Visual Object Sequence Start)以整数000001B0
(十六进制)开头。它包含要解码的视频所需的数据。只有在第一次尝试解码流时,才需要将其发送到解码器,并且它用于解码后面的所有VOP。请注意,AXIS在SDP中发送此数据包(对RTSP中的DESCRIBE的响应),例如:
a=fmtp:96 profile-level-id=245; config=000001B0F5000001B5891300000100000001200086C40FA28A021E0A21
。因此,如果流不会改变,并且你在SDP中得到这个,你就不需要将VOS传递给解码器......但如果你这样做,那就没有坏处。
视频对象平面(I-VOP,P-VOP,B-VOP)以整数000001B6
开头。如果将GOV长度设置为10,并将流的结构设置为“IP”,则将获得1个I帧(I-VOP)和9个P-VOP-s,但所有都将具有000001B6
个起始码。区分它们的技巧是检查第五个字节中的下两个BITS。检查表格以确定您获得的VOP类型:
VOP_CODING_TYPE (binary) Coding method
00 intra-coded (I)
01 predictive-coded (P)
10 bidirectionally-predictive-coded (B)
11 sprite (S)
现在,要解码视频,您必须将VOS发送到解码器,然后立即进行I-VOP。但是,你从RTP流中提取这些帧的方式很难......如果I-VOP的大小是10000B,而你的网络MTU是1400B,你就不能按原样发送它而没有网络拥塞。因此,AXIS摄像机将I-VOP和所有其他BIG帧分成FRAGMENTS,它通过RTP发送为RTP数据包,其大小不超过MTU。主要思想是这个(例子):
现在,当你收到这个时,你有点了解,但你需要恢复原来的10KB FRAME,以便解码器解码它。你正在做的方式是,只解码大得多的帧的第一个MTU字节,并且丢弃你发送给解码器的所有其他片段。这就是为什么你可以得到糟糕的图片......
要恢复原始帧:
000001B6
或000001B0
且RTP MARKER位设置为0的数据包。如果MARKER设置为1,那就是整个帧,您可以将其解码为是!如果是0,则更多部分跟随...... 在那里,希望我帮助......:)