Android-手动解码h264原始流

时间:2019-03-23 19:31:46

标签: android video h.264 decoder

因此,我正在尝试解码原始h264数据流并将其渲染到Android的表面上。步骤如下:

  1. 接收一个h264流数据包
  2. 对其进行累加并尝试提取NAL单元(字节序列以 00 00 00 01 (NAL标头)开始,直到下一个NAL标头。
  3. 对于每个提取的NAL单元,调用feedFrame(data),其中data是一个以NAL标头开头并包含提取的单元的byte []。
  4. 观看在我提供的表面上渲染的视频。

以下代码确实利用了AVC解码器:

public StreamReceiver(DashCamActivity activity, Surface surface, int width, int height, byte[] sps, byte[] pps) {
    this.activity = activity;
    decoder = MediaCodec.createDecoderByType("video/avc");

    format.setByteBuffer("csd-0", ByteBuffer.wrap(sps));
    format.setByteBuffer("csd-1", ByteBuffer.wrap(pps));
    decoder.configure(format, surface, null, 0);
    decoder.start();

}

public void shutdown() 
{
    decoder.stop();
    decoder.release();
}

public void feedFrame(byte[] data) 
{
    BufferInfo info = new BufferInfo();
    int inputIndex = decoder.dequeueInputBuffer(1000);
    if(inputIndex == -1)
        return;
    ByteBuffer inputBuffer = decoder.getInputBuffers()[inputIndex];
    if (inputIndex >= 0) {
        inputBuffer.clear();
        inputBuffer.put(data, 0, data.length);
        inputBuffer.clear();
        decoder.queueInputBuffer(inputIndex, 0, data.length, 0, 0);
    }

    int outIndex = decoder.dequeueOutputBuffer(info, 1000);

    switch (outIndex) {
    case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
        break;

    case MediaCodec.INFO_TRY_AGAIN_LATER:
        break;

    case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
        break;

    default:
        decoder.releaseOutputBuffer(outIndex, true);
        break;
    }
}

对于较小的分辨率(1024x768、1280x800),一切正常。但是,在较大的分辨率(1920x1080、1900x600)下,我提供的字节数组的长度大于65535(64k),视频开始出现断续和伪影,并且Logcat报告奇怪的解码器错误(例如IOCTL_MFC_DEC_EXE失败(ret:-2001)) Galaxy S3)。 这也发生在相对较新的设备上,该设备可以以我提供的两倍帧速播放4k。所以我肯定做错了什么,我不知道我的64k理论是否有任何真理,这仅仅是一个观察。

所以回顾一下:

    我从解码器开始向解码器提供单独的NAL单元 标头。
  • h264流具有基线配置文件(4.0级)。
  • 将NAL单元的内容按照到达的顺序写入文件,从而生成一个视频文件,该视频文件可以使用基本媒体播放器完全播放

如何使它以高分辨率播放?

0 个答案:

没有答案