当前位置: 首页 > 知识库问答 >
问题:

用MediaCodec解码h264

华温书
2023-03-14

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

这是解码时产生的视频的一个例子,除了底部部分看起来很好。

我还注意到一些奇怪的事情,当我移动摄像机时,饲料似乎运行几乎完全流畅(底部没有垃圾),一旦我把它放下,垃圾视频返回(我会以为它是相反的方式...)

我正在将h264数据解析成以澳元开头的块,每个块以澳元开头,当另一个开始时结束。

[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]
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开头)是一个访问单元,这是我放入缓冲区并馈送到解码器的内容。

我把正确的输入输入到解码器了吗?

我怎么才能摆脱底部的垃圾视频?

共有1个答案

华旭
2023-03-14

“垃圾部分”看起来像编码器填充部分。在内部,所有的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");
}
 类似资料:
  • 我从服务器接收到h264数据,我想在Android上使用mediacodec和texture view对该流进行解码。我从服务器获取数据,解析它得到SPS、PPS和视频帧数据,然后我将该数据传递给mediacodec,但函数dequeueOutputBuffer(info,100000)总是返回-1,并且我得到dequeueOutputBuffer超时。 请帮忙,我三周来一直在忙这个问题。 这是用

  • 我正在使用对三星S6上的h264流进行解码,发现mediacodec的输入缓冲区必须以“0001”开头(并且不需要设置pps、sps),否则ACodec将报告错误。 我也尝试使用mediaextractor播放一个mp4文件,它工作良好,但缓冲区到mediacodec不是以“0001”开始。 我不知道为什么decodec一个h264流有这样的限制,目前我需要从socket分析流,并将数据切割成小包

  • 我正在尝试用android低级媒体API实时解码h264 nals。 每个nal都包含一个完整的帧,所以我希望在用我的nal提供输入并调用之后,它会“立即”(当然有一个litle延迟)显示我的帧,但它没有显示。我看到了第一个帧,出列器返回第一个缓冲区,只有在将第二个缓冲区馈送给解码器之后才返回第一个缓冲区,此时该缓冲区应该呈现第二个帧。帧编码时预置为x264,因此没有B帧等。 我想可能有一种方法可

  • 这是本问题的后续问题。 这是我的代码: 我的问题-我的实现对于呈现由解码的H264流是否可以?或者我需要做EGL设置或其他什么? 提前道谢!

  • 我正在尝试使用Android上的MediaCodec API来解码AAC流。(它是原始AAC。)我尝试使用MediaFormat.createAudioFormat()来创建要传递给MediaCodec.configure()的格式对象,但我在使用AAC(音频/mp4a-latm)时一直出错。(不过它适用于MP3(音频/mpeg)...) 最后,我为一个AAC文件创建了一个MediaExtract

  • 我正在开发一个使用MediaCodec API的H.264解码器。我试图在JNI层中调用MediaCodec java API,该函数如下所示: 稍后,我将把发送到我现有的视频呈现管道,并在上呈现。 我希望我能够编写一个Java函数来解码输入流,但这些将是一个挑战- 此资源声明- …你不能对解码的视频帧做任何事情,只能将它们呈现在表面 这里,一个已被传递在表面上呈现输出并且声明。 那么,我是否能够