如何将rtp数据包有效载荷字节H264 / 90000转换为任何视频数据?

问题描述

Studying the sip protocol,我谈到了H264编解码器的主题。我开始以rtp数据包的形式接收数据。我设法从包中成功获取了以下数据:有效负载类型(在我的情况下为97),时间戳,序列号和有效负载数据(字节数组)。接下来,我要绘制在此数据中编码的图像。在android平台上,我使用android.media.MediaCodec类。我遵循MediaCodec failing on S7之类的示例。

我创建MediaCodec的实例。使用MediaFormat进行配置。然后,我将接收到的字节传输到inputBuffer,并等待通过dequeueOutputBuffer进行更新。就我而言,dequeueOutputBuffer方法始终返回MediaCodec.INFO_TRY_AGAIN_LATER

我试图在传递给MediaCodec之前处理字节。已定义nal_unit_type。我得到7、8和28。我还在包中定义了startBitendBit。我尝试将所有以startBit开始并以endBit结尾的包粘合在一起,然后以粘合形式将它们传输到MediaCodec。结果是相同的-dequeueOutputBuffer方法始终返回MediaCodec.INFO_TRY_AGAIN_LATER

告诉我我错过了什么。

服务器将有关视频的以下信息发送到SDP:

m=video 23542 RTP/AVP 97
b=TIAS:4096000
a=content:main
a=rtpmap:97 H264/90000
a=fmtp:97 profile-level-id=428028; max-fs=8192; packetization-mode=0; max-br=4096; max-fps=3000
a=sendrecv

编辑#1

例如,第一个接收到的数据包有效负载(无符号字节数组):

27 42 00 28 95 a0 1e 00 89 f9 70 11 00 00 03 00
42 00 28 95 a0 1e 00 89 f9 70 11 00 00 03 00 01
00 28 95 a0 1e 00 89 f9 70 11 00 00 03 00 01 00

我敢建议这是一个Single NAL Unit Packet。该数据包没有填充。 通过rfc3984/1.3,我进入第一个字节:

//                                           0 1 2 3 4 5 6 7
//                                          +-----+---------+
//                                                |   type  |
//                                          +-----+---------+
val nal_unit_type = payload[0].toInt() and 0b0_0_0_1_1_1_1_1

nal_unit_type == 7我决定此数据包包含Sequence Parameter Set数据。接下来,我想获取解密的SPS并从中获取有用的信息(宽度和高度,帧速率...)

我进入第二个字节:

//                                       0 1 2 3 4 5 6 7
//                                      +-+-+-----------+
//                                      |s|e|
//                                      +-+-+-----------+
val start_bit = payload[1].toInt() and 0b1_0_0_0_0_0_0_0 != 0
//                                      +-+-+-----------+
val end_bit = payload[1].toInt() and   0b0_1_0_0_0_0_0_0 != 0

start_bit == falseend_bit == true

从第三个字节(payload[2])开始,我解析SPS。

编辑#2

当我确定nal_unit_type 7或8的第二个字节是FU头(带有startend位)时,我错了。有效负载的第二个字节已经是SPS的第一个字节。因此,我设法成功地解密了SPS,例如,发现图像大小1920/1080在那里被加密了(与预期的一样)。但这还没有以任何方式帮助我将生成的视频流绘制到android表面视图。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)