android - 如果 Android MediaCodec dequeueOutputBuffer() 返回 -3 是什么意思

标签 android h.264 android-mediacodec

我正在使用 MediaCodec API 来播放我通过以太网端口接收的视频流 (H.264)。

从官方文档和各种例子中了解到,我需要进行如下操作。

  1. 根据 mimetype(video/avc for H.264) 创建一个 MediaCodec 实例
  2. 为“csd-0”提供 SPS 帧数据。 SPS帧应该以0x00000001开始
  3. 向“csd-1”缓冲区提供 PPS 帧数据。 PPS 帧应以 0x00000001 开头
  4. 调用decoder.configure()decoder.start()。如果一切顺利,解码器配置正确,没有异常。
  5. 一旦配置了 MediaCodec,我们就可以向解码器提供所有剩余的帧(解包的 NAL 单元)。
  6. 成功出列操作后,解码缓冲区可以如下呈现在屏幕上。

outputBufferId = decoder.dequeueOutputBuffer(info, 1000); decoder.releaseOutputBuffer(outputBufferId, true);

问题

decoder.dequeueOutputBuffer() 在 android 6.0 上返回 -3。 官方文档说,如果在 dequeueOutputBuffer() 期间出现任何错误,只有 -1 (INFO_TRY_AGAIN_LATER) 和 -2 (INFO_OUTPUT_FORMAT_CHANGED) 被返回并且 -3 (INFO_OUTPUT_BUFFERS_CHANGED) 被弃用。那为什么我会收到 -3

我该如何纠正这个问题?

代码 fragment :

String mimeType = "video/avc";
decoder = MediaCodec.createDecoderByType(mimeType);
mformat = MediaFormat.createVideoFormat(mimeType, 1920, 1080);

while (!Thread.interrupted()) {
    byte[] data = new byte[size];
    bin.read(data, 0, size);
    if (data is SPS frame) {
        mformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);
        mformat.setByteBuffer("csd-0", ByteBuffer.wrap(data));
        continue;
    }

    if (data is PPS frame) {
        mformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);
        mformat.setByteBuffer("csd-1", ByteBuffer.wrap(data));
        decoder.configure(mformat. surface, null, 0);
        decoder.start();
        is_decoder_configured = true;
        continue;
    }

    if (!is_decoder_configured)
        continue;

    index = decoder.dequeueInputBuffer(1000);
    if (index < 0) {
        Log.e(TAG, "Dequeue in put buffer failed..\n");
        continue;
    }

    buf = decoder.getInputBuffer(index);
    if (buf == null)
        continue;
    buf.put(data);

    decoder.queueInputBuffer(index, 0, data.length, 0, 0);
    int outputBufferId = decoder.dequeueOutputBuffer(info, 1000);
    switch (outputBufferId) {
        case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
            Log.i("DecodeActivity", "New format " + decoder.getOutputFormat());
            break;
        case MediaCodec.INFO_TRY_AGAIN_LATER:
            Log.i("DecodeActivity", "dequeueOutputBuffer timed out!");
            break;
        default:
            Log.i(TAG, "Successfully decoded the output : " + outputBufferId);
            decoder.releaseOutputBuffer(outputBufferId, true);
            break;
    }
}

if (is_decoder_configured()) {
    decoder.stop();
    decoder.release();
}

如果您发现任何其他错误,请告诉我。将不胜感激!

最佳答案

我没看到任何说它永远不会被归还的东西。文档是这样说的:

This constant was deprecated in API level 21. This return value can be ignored as getOutputBuffers() has been deprecated. Client should request a current buffer using on of the get-buffer or get-image methods each time one has been dequeued.

也就是说,如果您正在使用 getOutputBuffers(),则需要监听此返回值并对其进行操作 - 但不推荐这样做。如果您不使用 getOutputBuffers(),只需忽略此返回值,即使用相同的参数再次调用 dequeueOutputBuffer(),然后查看它返回的内容。

关于android - 如果 Android MediaCodec dequeueOutputBuffer() 返回 -3 是什么意思,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39388975/

相关文章:

c++ - h.264文件读取和解析

image - AVFrame 到 RGB - 解码伪影

android - MediaCodec - 将图像编码为 mp4 视频

android - MediaMuxer 错误 "Failed to stop the muxer"

android - 使用 MediaCodec API 编辑 MP4 元数据

java - 代码中的 MultiSelectListPreference

android - Android 中的图像校正

iphone - 从 wifi h.264 摄像机直接直播到 iPhone

android - 从一项 Activity 切换到另一项 Activity 时 Intent 不起作用

android - 如何屏蔽 EditText 以接受特定格式的输入