【发布时间】:2020-08-25 09:25:10
【问题描述】:
我需要将 Windows PC 的屏幕流式传输到 Android。我打算使用 FFmpeg 捕获屏幕并使用 H.264 编解码器进行编码,通过 RTP 发送流,最后使用MediaCodec 解码视频并将其显示在 SurfaceView 上。
我尝试了以下 FFmpeg 命令:
ffmpeg -f gdigrab -i desktop -an -video_size 1920x1080 -f rtp rtp://192.168.0.12:23000
但是,生成的所有 NAL 单元似乎都已损坏,因为:
NAL单元头的forbidden_zero_bit(最高有效位)为1。例如下图所示的NAL单元头(0x00 0x00 0x01之后的字节)为0xB6,那么显然最高有效位是等于 1。
NAL 单元中的很多字节等于 0xFF。我真的不知道他们是否应该是这样的,他们对我来说似乎很奇怪。
这是 FFmpeg 输出的 NAL 单元之一的开头,使用 Wireshark 捕获:
0000 00 00 01 b6 56 5a bc 7c fd de ea e7 72 ff ff ff
0010 ff ff ff ef 7d d7 ff bd 6f 5f ff ee d7 ba bf ff
0020 fd df bd 7b a5 ff ff ff ff ff fd d7 78 bf fd e2
0030 ff ff ff ff ff ff 7b fe eb ff ff ff ff ff ff ff
0040 fe f5 ff ff ff ff fd b4 c6 17 45 ba 7e f4 e9 fb
0050 d7 ef 7f de ff ff ff ff fd d7 ff 79 ff bc ff ff
0060 ff ff ff ff ff ba ff ff ff ff ff ff ff 7b ff f7
0070 27 ff ff ff de ff ff ff ff ff ff ff fe ef fd c7
0080 de ef 6f 7b db dd db 74 de dd 37 bd ef ff ff ff
0090 ff ff ff ff 77 bb ff 75 ee ee bf ff ff fb dd df
00a0 ee d7 79 5e 5f ff ff ff fb 9b ff fb d7 ff ff ff
00b0 de bf ff ff ff ff ff ff ff ff fb 9d ef bd df 00
00c0 00 8f 03 ef ff ff ff ff ff ff ff 7b f7 03 1f fd
00d0 ed e5 ba ef 5d d5 cc 5f ff ff ff ff ff ff ff ff
00e0 ff ff ff ee 06 37 be f4 f6 eb ff ff ff ff ff ff
00f0 ff ff ff ff ff ff ff ba 5f f7 af ff ff ff ff ff
0100 ff ff ff ff ff ff ff ff fd d3 fb c2 ef 1b dd ed
...
...
...
Screenshot from Wireshark (same NAL unit)
我还尝试在 FFmpeg 中明确指定视频编解码器,如下所示:
ffmpeg -f gdigrab -i desktop -an -vcodec libx264 -f rtp rtp://192.168.0.12:23000
在这种情况下,我没有得到附件 B 样式的 NAL 单元,而是 AVCC 样式的单元(没有 0x00 0x00 0x01 分隔符,但前面有它们的长度,如 here 所述)。
对于 AVCC NAL 单元,我真的不明白一个结束和另一个开始的地方,以及上面链接的问题中提到的“额外数据”在哪里。
综上,我想知道的如下:
为什么第一个命令输出的 NAL 单元损坏了?
据我了解 (from here),您必须将单独的 NAL 单元提供给 MediaCodec 以进行解码。那么,如何将 AVCC 格式的 NAL 单元彼此分开?
在将视频编解码器指定为 libx264 时,我能否以某种方式强制 FFmpeg 输出附件 B 样式的 NAL 单元而不是 AVCC 单元?
是否有更直接的方法在 Windows 上捕获屏幕、编码、将流发送到 Android 设备并在我的应用程序中显示视频? (可能是我没有注意到的库或 API)
【问题讨论】:
-
你成功了吗?我目前正在打完全相同的战斗。当我输入全帧数据时,我确实得到了输出,但 MediaCodec 在输出到表面之前缓冲了大约 15 帧,这意味着我得到了巨大的延迟。在我剪切帧数据并在 0x00 0x00 0x01 序列之间输入数据后输入 NAL 单元时,输出损坏。
-
@Hey'Youssef 还没有。明天我会回来的。您是否也在使用 ffmpeg 来捕获 Windows 机器的屏幕?如果是这样,您能否分享您使用的确切命令?