memdiacodec解码器在Android 5.0上工作但在android 4.4上没有

时间:2016-08-16 04:19:48

标签: android h.264 mediacodec

我正在尝试解码h264流在Android上使用MediaCodec。

我使用csd-0csd-1来设置spspps

MediaFormat format = MediaFormat.createVideoFormat(MIME, WIDTH, HEIGHT);
format.setByteBuffer("csd-0", sps);
format.setByteBuffer("csd-1", pps);

我使用输出表面配置解码器以渲染输出数据。

decoder.configure(format, surface, null, 0);

然后,我只是启动一个线程来解码我使用这个循环从网络收到的数据。

while (running) {
    if (!isEOS) {
        int inIndex = decoder.dequeueInputBuffer(10000);
        if (inIndex >= 0) {
            ByteBuffer buffer = inputBuffers[inIndex];
            byte[] data = getVideoPacket(); // native method that get data from network
            buffer.put(data);

            decoder.queueInputBuffer(inIndex, 0, data.length, 0L, 0);
        }
    }

    int outIndex = decoder.dequeueOutputBuffer(info, 10000);
    switch (outIndex) {
        case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
            Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
            outputBuffers = decoder.getOutputBuffers();
            break;
        case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
            Log.d("DecodeActivity", "New format " + decoder.getOutputFormat());
            MediaFormat format = decoder.getOutputFormat();
            break;
        case MediaCodec.INFO_TRY_AGAIN_LATER:
            Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
            break;
        default:
            ByteBuffer buffer = outputBuffers[outIndex];
            Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);

            decoder.releaseOutputBuffer(outIndex, true); // render
            break;
    }

    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
        Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
        break;
    }
}

请注意,我使用0作为queueInputBuffer的presentationTimestamp,因为我获得的数据来自网络套接字,而且我不知道如何计算适当的时间戳。

我得到了我想要的Android 5.0(及以上),但是当我在android 4.4上运行这些代码时,表面上没有任何东西出现(实际上我偶尔可以看到相同的图片片段,但大部分时间,表面是只是黑色)。

我试图用从文件中获取的数据填充输入缓冲区(使用MediaExtractor),它在android 5.0和4.4上运行良好。

任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

似乎问题是获取数据的方式。我习惯于来自原生层的get数据:

public static native byte[] getVideoPacket();

现在i push数据从本机层到java层:

env->CallVoidMethod(..., data);

现在一切正常。我不知道为什么,但这种方式适合我。