繁体   English   中英

用MediaCodec解码h264

[英]Decode h264 with MediaCodec

我正在解码从android上的wifi摄像头收到的原始h264。

使用套接字获取原始数据包,并将接收到的数据解析为NAL单元。

我也有SPS和PPS单元(在MediaFormat设置为csd-0和csd-1)。

从网上阅读的所有帖子和信息,如果我向解码器提供正确的数据,我仍然无法获得。

这是解码时结果视频的示例 ,除了底部看起来还不错。

我还注意到了一些奇怪的事情,即当我移动摄像机时,Feed似乎运行得几乎完全顺畅(底部没有垃圾),一旦将其放下,垃圾视频就返回了(我以为是相反的方式) ...)

我正在将h264数据解析为以AUD开头的块,每个块均以AUD开头,并在另一个开始时结束。

例:

[0, 0, 0, 1, 9, 48, 0, 0, 0, 1, 6, 1, 9, 0, 12, 8, 36, 104, 0, 0, 3, 0, 1, -128, 0, 0, 0, 1, 33, -32, 96, 97, 92, -97, 71, 89, -31, 127, -120, 11, 23, ..., 0, 0, 1, -64, ... , -59, 2, -32, 62, -111, -64, 0, 0, 1, -32, 0, 0, -124, -128, 5, 33, 0, 1, -60, -31]

[0, 0, 0, 1, 9, 48, 0, 0, 0, 1, 6, 1, 9, 0, 14, 8, 36, 104, 0, 0, 3, 0, 1, -128, 0, 0, 0, 1, 33, -32, 112, 113, 92, -97, 72, 24, 96, 80, 2, 88, 70, ..., 98, -75, 27, 0, 0, 1, -64, 1, 82, ... , 119, 2, -32, 62, -111, -64, 0, 0, 1, -32, 0, 0, -124, -128, 5, 33, 0, 1, -31, 1]

而且每隔几帧,我就使用SPS和PPS获得一大块

0, 0, 0, 1, 9, 16, 0, 0, 0, 1, 39, SPS, 0, 0, 0, 1, 40, PPS, 0, 0, 0, 1, 6, 0, 13, -128, -89, 89, -128, 8, 117, 0, -89, 89, -128, 8, 117, 64, 1, 9, 0, 16, 8, 36, 104, 0, 0, 3, 0, 1, 6, 1, -60, -128, 0, 0, 0, 1, 37, -72, 1, 0, 1, -1, -16, 13, ... , 108, 60, -83, 101, 0, 0, 1, -32, 0, 0, -124, -128, 5, 33, 0, 3, 25, 65

据我了解,每个解析的“块”(以AUD开头)都是一个访问单元,这就是我放入缓冲区并馈送到解码器的内容。

我是否将正确的输入提供给解码器?

如何摆脱底部的垃圾视频?

什么会导致垃圾部分?

我还尝试过修剪每个块的部分,例如修剪开始- [0, 0, 0, 1, 9, 48, 0, 0, 0, 1, 6, 1, 9, 0, 12, 8, 36, 104, 0, 0, 3, 0, 1, -128]并且仅从[0, 0, 0, 1, 9, 48, 0, 0, 0, 1, 6, 1, 9, 0, 12, 8, 36, 104, 0, 0, 3, 0, 1, -128]传递0 ,0 ,0 ,1, 33但这并没有太大的区别。

“垃圾部分”看起来像编码器填充部分。 在内部,所有h264视频的编码尺寸均为16的倍数,但分别标记了应显示的确切尺寸。

如果使用的是SurfaceTexture作为输出,或者手动解释YUV缓冲区,则无需说明如何在屏幕上显示解码后的数据。

如果手动解释缓冲区,则需要应用裁剪字段,如下所述: https : //developer.android.com/reference/android/media/MediaCodec#data-types

基本部分是这样的:

视频帧的大小(旋转之前)可以这样计算:

 MediaFormat format = decoder.getOutputFormat(…); int width = format.getInteger(MediaFormat.KEY_WIDTH); if (format.containsKey("crop-left") && format.containsKey("crop-right")) { width = format.getInteger("crop-right") + 1 - format.getInteger("crop-left"); } int height = format.getInteger(MediaFormat.KEY_HEIGHT); if (format.containsKey("crop-top") && format.containsKey("crop-bottom")) { height = format.getInteger("crop-bottom") + 1 - format.getInteger("crop-top"); } 

如果您是通过RTP / UDP连接接收流的,则我的经验表明,某些数据包将通过Wifi丢失,并可能导致某些失真。 如果尝试在TCP(交织格式)上使用RTP,则应该具有非常可靠的流,并且不会丢失数据包。 这可以显示问题是否与您的解析有关或数据包丢失问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM