我有一个项目,我被要求在android中显示视频流,流是原始H.264,我连接到服务器,将从服务器接收字节流。
基本上我想知道有没有办法将原始字节发送到android中的解码器并将其显示在表面上?
我使用android 4.1中的新MediaCodec和MediaExtractor API成功解码了包含在mp4容器中的H264,遗憾的是我还没有找到使用这些API解码原始H264文件或流的方法。
我知道一种方法是编译和使用FFmpeg,但我宁愿使用可以使用硬件加速的内置方法。我也理解Android中支持RTSP流,但这不是一个选项。 Android版本不是问题。
不幸的是,我不能为此提供任何代码,但我会尽力根据我如何使用它来解释它。
所以这里是我对如何使用MediaCodec类获得原始H.264编码视频的概述。
使用上面的链接有一个获取解码器设置以及如何使用它的示例,您需要将其设置为解码H264 AVC。
H.264的格式是它由NAL单元组成,每个NAL单元的起始前缀为三个字节,值为0x00,0x00,0x01,每个单元的类型不同,具体取决于这些后面的第4个字节的值。 3个起始字节。一个NAL单元不是视频中的一个帧,每个帧由许多NAL单元组成。
基本上我写了一个方法,找到每个单独的单元并将其传递给解码器(一个NAL单元是起始前缀,其后是任何字节,直到下一个起始前缀)。
现在,如果你有解码器设置解码H.264 AVC并从解码器有一个InputBuffer,那么你就准备好了。您需要使用NAL单元填充此InputBuffer并将其传递回解码器并继续对流的长度执行此操作。但是,为了完成这项工作,我必须先将解码器传递给SPS(序列参数集)NAL单元。在启动前缀(第4个字节)之后,该单元的字节值为0x67,在某些设备上解码器会崩溃,除非它首先接收到该单元。基本上直到找到这个单元,忽略所有其他NAL单元并继续解析流直到你得到这个单元,然后你可以将所有其他单元传递给解码器。
有些设备首先不需要SPS,有些设备确实需要SPS,但最好先将它传递给它。
现在,如果你有一个表面,你在配置它时传递给解码器,那么一旦它获得足够的NAL单位的帧,它应该在表面上显示它。
以下是我在类似项目中发现有用的资源:
您可以从服务器下载原始H.264,然后通过手机上运行的本地HTTP服务器提供它,然后让VLC for Android从该HTTP服务器进行播放。您应该使用VLC的http / h264://方案强制解复用器使用原始H.264(如果您不强制解复用器VLC可能无法识别流,即使HTTP服务器返回的MIME类型是设置正确)。看到
有关如何创建将启动VLC的Intent的示例。
注意:原始H.264显然没有时序信息,因此VLC将尽可能快地播放。首先将其嵌入MPEGTS会更好。还没有找到能够做到这一点的Android库。