在Android中解码Raw H264流?

wil*_*ill 34 android ffmpeg decoding rtsp h.264

我有一个项目,我被要求在android中显示视频流,流是原始H.264,我连接到服务器,将从服务器接收字节流.

基本上我想知道有没有办法将原始字节发送到android中的解码器并将其显示在表面上?

我使用android 4.1中的新MediaCodec和MediaExtractor API成功解码了包含在mp4容器中的H264,遗憾的是我还没有找到使用这些API解码原始H264文件或流的方法.

我知道一种方法是编译和使用FFmpeg,但我宁愿使用可以使用硬件加速的内置方法.我也理解Android中支持RTSP流,但这不是一个选项.Android版本不是问题.

wil*_*ill 30

不幸的是,我不能为此提供任何代码,但我将尽力根据我如何使用它来解释它.

所以这里是我如何使用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单位的帧,它应该在表面上显示它.


小智 0

您可以从服务器下载原始 H.264,然后通过手机上运行的本地 HTTP 服务器提供它,然后让 Android 版 VLC 从该 HTTP 服务器进行播放。您应该使用 VLC 的 http/h264:// 方案强制解复用器为原始 H.264(如果不强制解复用器 VLC 可能无法识别流,即使 HTTP 服务器返回的 MIME 类型是设置正确)。看

https://github.com/rauljim/tgs-android/blob/integrate_record/src/com/tudelft/triblerdroid/first/VideoPlayerActivity.java#L211

有关如何创建将启动 VLC 的 Intent 的示例。

注意:原始 H.264 显然没有计时信息,因此 VLC 将尽可能快地播放。首先将其嵌入 MPEGTS 中会更好。还没有找到可以做到这一点的 Android 库。

  • 我对你的解决方案非常感兴趣。因此,如果您能概述一下您是如何做到的,那就太好了,我会非常高兴 (4认同)