Android FFmpeg输出损坏的NAL单元

Android FFmpeg输出损坏的NAL单元,android,ffmpeg,h.264,Android,Ffmpeg,H.264,我需要将我的Windows PC的屏幕传输到Android。我打算使用FFmpeg捕获屏幕并使用H.264编解码器进行编码,通过RTP发送流,最后用于解码视频并将其显示在SurfaceView上 我尝试了以下FFmpeg命令: ffmpeg -f gdigrab -i desktop -an -video_size 1920x1080 -f rtp rtp://192.168.0.12:23000 但是,所有产生的NAL单元似乎都已损坏,因为: NAL单元头的禁止零位(最高有效位)为1。例如,

我需要将我的Windows PC的屏幕传输到Android。我打算使用FFmpeg捕获屏幕并使用H.264编解码器进行编码,通过RTP发送流,最后用于解码视频并将其显示在SurfaceView上

我尝试了以下FFmpeg命令:

ffmpeg -f gdigrab -i desktop -an -video_size 1920x1080 -f rtp rtp://192.168.0.12:23000
但是,所有产生的NAL单元似乎都已损坏,因为:

  • NAL单元头的禁止零位(最高有效位)为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
    ...
    ...
    ...
    

    我还尝试在FFmpeg中明确指定视频编解码器,如下所示:

    ffmpeg -f gdigrab -i desktop -an -vcodec libx264 -f rtp rtp://192.168.0.12:23000
    
    在本例中,我没有得到附录B样式的NAL单位,而是AVCC样式的单位(没有0x00 0x00 0x01分隔符,但前面有它们的长度,如上所述)

    对于AVCC NAL单元,我真的不知道一个从哪里结束,另一个从哪里开始,以及上面链接的问题中提到的“外部数据”在哪里

    总之,我想知道的是:

  • 为什么第一个命令输出的NAL单元已损坏

  • 据我所知(),您必须将单独的NAL单元提供给以进行解码。那么,如何将AVCC格式的NAL单元彼此分离呢

  • 在将视频编解码器指定为libx264时,我是否可以强制FFmpeg输出附件B样式的NAL单元而不是AVCC单元

  • 有没有更直接的方法在Windows上捕获屏幕、编码、将流发送到Android设备并在我的应用程序中显示视频?(可能是我没有注意到的库或API)

  • 1) 为什么第一个命令输出的NAL单元已损坏

    那里没有腐败。RTP数据包中存在原始h264数据以外的信息。该信息可能包含字节序列
    00 01
    ,并且不表示后面有NALU

    2) 据我所知(从这里),你必须单独喂养孩子 单元到MediaCodec进行解码。那么,我如何将NAL单元划分为 AVCC格式从另一个

    解析流,包括协议开销

    3) 我是否可以强制FFmpeg输出附录B样式的NAL单元 在将视频编解码器指定为libx264时,是否使用AVCC编码

    这不符合RTP规范。如果使用RTP,将获得AVCC start lengthsize值

    4) 有没有一种更直接的方式在屏幕上捕捉屏幕 Windows、编码、将流发送到Android设备和 在我的应用程序中显示视频?(可能是一个库或一个API 逃避我的注意)

    这是一个相当固执己见的问题。RTP非常直截了当。但可能还有其他选择,每种选择都有利弊

    1) 为什么第一个命令输出的NAL单元已损坏

    那里没有腐败。RTP数据包中存在原始h264数据以外的信息。该信息可能包含字节序列
    00 01
    ,并且不表示后面有NALU

    2) 据我所知(从这里),你必须单独喂养孩子 单元到MediaCodec进行解码。那么,我如何将NAL单元划分为 AVCC格式从另一个

    解析流,包括协议开销

    3) 我是否可以强制FFmpeg输出附录B样式的NAL单元 在将视频编解码器指定为libx264时,是否使用AVCC编码

    这不符合RTP规范。如果使用RTP,将获得AVCC start lengthsize值

    4) 有没有一种更直接的方式在屏幕上捕捉屏幕 Windows、编码、将流发送到Android设备和 在我的应用程序中显示视频?(可能是一个库或一个API 逃避我的注意)


    这是一个相当固执己见的问题。RTP非常直截了当。但可能还有其他选择,各有利弊。

    你成功了吗?我现在也在打同样的战斗。当我输入完整的帧数据时,我确实得到了一个输出,但是MediaCodec在输出到表面之前缓冲了大约15帧,这意味着我得到了巨大的延迟。在我剪切帧数据并在0x00 0x00 0x01序列之间馈送数据之后馈送NAL单元时,我得到了损坏的输出。@Hey'Youssef还没有。我明天再谈。您是否也在使用ffmpeg捕获Windows计算机的屏幕?如果是的话,你能分享一下你使用的确切命令吗?你成功了吗?我现在也在打同样的战斗。当我输入完整的帧数据时,我确实得到了一个输出,但是MediaCodec在输出到表面之前缓冲了大约15帧,这意味着我得到了巨大的延迟。在我剪切帧数据并在0x00 0x00 0x01序列之间馈送数据之后馈送NAL单元时,我得到了损坏的输出。@Hey'Youssef还没有。我明天再谈。您是否也在使用ffmpeg捕获Windows计算机的屏幕?如果是这样,您能分享您使用的确切命令吗?实际上,仿真预防字节用于确保
    00 00 01
    只能在NAL单元之前找到(在附录B样式单元中)。它们肯定会被破坏,因为,正如我在问题中解释的,如果禁止的0位等于1,这意味着NAL单元已经引入了错误。这里可以找到一个很好的解释:
    您解析流,包括协议开销
    您的意思是我应该直接将RTP数据包(包括它们的头)传递给MediaCodec吗?实际上,仿真预防字节用于确保
    00 00 01
    只能在prec中找到