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

一台设备上的MediaCodec解码h264错误

徐洛华
2023-03-14

我正在尝试使用Android的MediaCodec接口解码H.264流。在我的测试设备上,一切都运行得很好,但在一个我无法访问的客户设备(三星Tab S)上,却出现了奇怪的问题。

当我解码流时,我不发送任何SPS/PPS、NALs或初始帧。我只是开始从现场流中推送数据,将其分割成以0x09 NAL结尾的块,解码器就会很好地同步自己,没有问题,非常快。

至少这一个设备的问题是,当我从解码器获得一个BufferInfo时,它会声称它解码了1413120字节的数据,但缓冲区大小只有1382400!当然,如果我试图从缓冲区中获取那么多数据,它就会崩溃。

视频为1280x720,解码为NV12,所以缓冲区大小刚刚好。报告的解码输出大小不是。如果我强制大小为1382400并将NV12转换为RGB,我得到几乎正确的图片。前32行绿色浓重,蓝色通道偏移相当大。这意味着UV块在此设备上解码部分错误。

以前有人遇到过这种问题吗?我已经记录了原始的h264流从特定的设备,它发挥只是很好,没有绿色块或色移。

在开始流媒体之前,我真的应该设置SPS/PPS和初始帧吗?该流似乎包含了所需的一切,因为解码器实现了正确的分辨率,设置了缓冲区,并在我测试过的每一个设备上进行解码,除了这一个。所以我想知道三星是不是有什么特别的事情发生了。

这里有一个结果的例子。不要只有流的图像,要注意帧是旋转的。在绿色区域中的Y组件还不错,在右边的白色块上,你可以清楚地看到蓝移。

编辑:即使我用csd-0中的SPS/PPS块启动解码器,颜色问题仍然存在。所以不是因为那个。

还设法用另一个设备测试了准确的流。没有绿色条,没有颜色偏移。所以这是特定器件/型号的编解码器的问题。

共有1个答案

孙恩
2023-03-14

我在过去也遇到过类似的问题(特别是在三星设备上),如果我没记错的话,那是由于缺少SPS/PPS数据造成的。如果要获得一致的结果,必须输入SPS/PPS数据。

不是一个直接解决您的问题,但一个可能的解决办法是使用替代解码器(如果存在)时,运行在特定设备。

我不确定您是如何实例化解码器的,但人们经常使用mime类型,如下所示:

decoder = MediaCodec.createDecoderByType("video/avc");

然后设备将选择首选的解码器(可能是硬件)。

您也可以实例化一个特定的解码器,如下所示:

decoder = MediaCodec.createByCodecName("OMX.google.h264.decoder");

// OR

decoder = MediaCodec.createByCodecName("OMX.qcom.video.decoder.avc");

根据我的经验,大多数设备至少有2个不同的H264解码器可用,您可能会发现该设备上的另一个解码器可以正常工作。

static MediaCodecInfo[] getCodecs() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
        return mediaCodecList.getCodecInfos();
    } else {
        int numCodecs = MediaCodecList.getCodecCount();
        MediaCodecInfo[] mediaCodecInfo = new MediaCodecInfo[numCodecs];

        for (int i = 0; i < numCodecs; i++) {
            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
            mediaCodecInfo[i] = codecInfo;
        }

        return mediaCodecInfo;
    }       
}
 类似资料:
  • 我正在解码从Android上的wifi摄像头接收到的原始h264。 这是解码时产生的视频的一个例子,除了底部部分看起来很好。 我还注意到一些奇怪的事情,当我移动摄像机时,饲料似乎运行几乎完全流畅(底部没有垃圾),一旦我把它放下,垃圾视频返回(我会以为它是相反的方式...) 我正在将h264数据解析成以澳元开头的块,每个块以澳元开头,当另一个开始时结束。 我的理解是,每个解析的“块”(以AUD开头)

  • 问题内容: 我已经使用Android的MediaCodec API编写了H264流编码器。我在大约十种使用不同处理器的不同设备上对其进行了测试,并且可以在所有这些设备上正常工作,除了在使用Snapdragon 800的设备(Google Nexus 5和Sony Xperia Z1)上。在这些设备上,我得到了SPS和PPS以及第一个关键帧,但是在那之后,mEncoder.dequeueOutput

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

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

  • 我从服务器接收到h264数据,我想在Android上使用mediacodec和texture view对该流进行解码。我从服务器获取数据,解析它得到SPS、PPS和视频帧数据,然后我将该数据传递给mediacodec,但函数dequeueOutputBuffer(info,100000)总是返回-1,并且我得到dequeueOutputBuffer超时。 请帮忙,我三周来一直在忙这个问题。 这是用