问题描述
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。我还在包中定义了startBit
和endBit
。我尝试将所有以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 == false
和end_bit == true
从第三个字节(payload[2]
)开始,我解析SPS。
编辑#2
当我确定nal_unit_type
7或8的第二个字节是FU头(带有start
和end
位)时,我错了。有效负载的第二个字节已经是SPS的第一个字节。因此,我设法成功地解密了SPS,例如,发现图像大小1920/1080在那里被加密了(与预期的一样)。但这还没有以任何方式帮助我将生成的视频流绘制到android表面视图。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)