android - H264 RTP 视频流被 MediaCodec 损坏

标签 android video-streaming h.264 rtp android-mediacodec

我可以看到在我的 TextureView 中播放的视频,但它已经相当损坏了。我已确认我正在以正确的顺序收到完整的数据包。我已经能够正确解析 RTP header 。我相信我的问题与 SPS 和 PPS 以及 MediaCodec 有关。

我的理解是,您应该从消息中剥离 RTP header ,并将 0x00000001 的 RTP 起始代码插入到消息的开头,以便解码器的输入缓冲区的格式为 0x00000001[sps ] 0x00000001[pps] 0x00000001[视频数据]

我的困惑是 MediaCodec 似乎需要一个 MediaFormat,其中 SPS 和 PPS 是单独手动定义的。我找到了我目前正在使用的这个例子以及我在上面定义的消息格式:

MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height);

// from avconv, when streaming sample.h264.mp4 from disk
byte[] header_sps = {0, 0, 0, 1, 0x67, 0x64, (byte) 0x00, 0x1e, (byte) 0xac, (byte) 0xd9, 0x40, (byte) 0xa0, 0x3d,
            (byte) 0xa1, 0x00, 0x00, (byte) 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x3C, 0x0F, 0x16, 0x2D, (byte) 0x96}; // sps
byte[] header_pps = {0, 0, 0, 1, 0x68, (byte) 0xeb, (byte) 0xec, (byte) 0xb2, 0x2C}; // pps


format.setByteBuffer(CSD_0, ByteBuffer.wrap(header_sps));
format.setByteBuffer(CSD_1, ByteBuffer.wrap(header_pps));

如您所见,我没有为 MediaFormat 提供视频流中的 SPS 和 PPS,而是使用来自 Internet 示例的硬编码集。我试图找到解释如何从数据包中提取 SPS 和 PPS 的资源,但一直找不到任何东西。

问题:

如果 MediaFormat 已经提供了 SPS 和 PPS,我是否应该在将缓冲区传递给 MediaCodec 之前从缓冲区中剥离 SPS 和 PPS?

如何正确解析消息中的 SPS 和 PPS?

这是我的一个包含 header 的 RTP 数据包的前几个字节:

80 a1 4c c3 32 2c 24 7a f5 5c 9f bb 47 40 44 3a 40 0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0 0 1 c0 0 71 80 80 5 21 0 5d d6 d9 ff fb 12 c4 e7 0 5 5c 41 71 2c 30 c1 30 b1 88 6c f5 84 98 2c 82 f5 84 82 44 96 72 45 ca 96 30 35 91 83 86 42 e4 90 28 b1 81 1a 6 57 a8 37 b0 60 56 81 72 71 5c 58 a7 4e af 67 bd 10 13 1 af e9 71 15 13 da a0 15 d5 72 38 36 2e 35 11 31 10 a4 12 1e 26 28 40 b5 3b 65 8c 30 54 8a 96 1b c5 a7 b5 84 cb a9 aa 3d d4 53 47 0 45 34 55 0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff bf 9 95 2b 73 93 4e c3 f9 b1 d0 5f f5 de c9 9e f7 f8 23 ab a5 aa

最佳答案

是的,媒体编解码器需要先初始化 SPS 和 PPS,你是对的。您必须从 SDP 响应中提取 SPS/PPS,这是在 RTSP 握手期间发送到服务器(相机)的 DESCRIBE 命令的回复。在 SDP 响应中有一个包含 SPS/PPS 的 sprop 参数集。您可以在 WireShark 上看到它们:

Media format specific parameters: sprop-parameter-sets=Z2QAKKwbGoB4AiflwFuAgICgAAB9AAAOph0MAHz4AAjJdd5caGAD58AARkuu8uFAAA==,aO44MAA=

它们以逗号分隔,必须使用 Base64 解码。请参阅此以获取解释:How to decode sprop-parameter-sets in a H264 SDP?

关于android - H264 RTP 视频流被 MediaCodec 损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49697325/

相关文章:

android - okhttp 中的 java.net.SocketTimeoutException

Azure 媒体播放器无法在 MS Azure 媒体服务上播放上传的视频

html - 使用 HTML5 视频标签支持桌面和移动客户端

java - 如何在不改变android中的值的情况下按字母顺序对 HashMap 键进行排序?

Android - 如何确保我的服务重新启动?

python - 使用 websocket - Python 从 h.264 视频流中捕获第一张图像

windows - 使用 Media Foundation 进行硬件 H264 编码 ID3D11Texture2D

opencv - Windows 上的 FFMPEG(用于 H.264 RTSP 解码)

c# - 如果 Hub 在不同的项目 SignalR 中,如何连接 Hub?

c# - 从在线视频流捕获屏幕截图