【问题标题】:What does it mean if Android MediaCodec dequeueOutputBuffer() returns -3如果Android MediaCodec dequeueOutputBuffer() 返回-3是什么意思
【发布时间】:2016-09-08 10:48:58
【问题描述】:

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

从官方文档和各种示例中了解到,我需要执行以下操作。

  1. 根据mimetype创建MediaCodec实例(video/avc for H.264
  2. 使用 SPS 帧数据馈送“csd-0”。 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

我应该如何纠正这个问题?

代码片段:

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();
}

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

【问题讨论】:

    标签: android h.264 android-mediacodec


    【解决方案1】:

    我没有看到任何说它永远不会被退回的说法。文档是这样说的:

    此常量在 API 级别 21 中已弃用。 由于不推荐使用 getOutputBuffers(),因此可以忽略此返回值。每次出列时,客户端应使用 get-buffer 或 get-image 方法中的一种请求当前缓冲区。

    也就是说,如果您使用 getOutputBuffers(),您需要监听此返回值并对其采取行动——但不建议这样做。如果你没有使用 getOutputBuffers(),则忽略这个返回值,即使用相同的参数再次调用 dequeueOutputBuffer(),然后查看它返回的内容。

    【讨论】:

    • OP 询问的是dequeueOutputBuffer(),而不是getOutputBuffers()
    • 是的,并且答案解释了在哪些情况下应该忽略 dequeueOutputBuffer() 的返回码 -3(解释为什么它在 API 中被弃用)。有两种 API 使用模式;您可以在每次 dequeueOutputBuffer() 返回 -3 (INFO_OUTPUT_BUFFERS_CHANGED) 时使用单个 getOutputBuffers() 调用,或者在从 dequeueOutputBuffer() 返回的每个非负值之后使用 getOutputBuffer(int index)。如果您使用前一种模式,您仍然需要使用此代码并对此做出反应(即使已弃用)。如果您使用后一种模式,请忽略该值。
    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2015-02-24
    • 2023-03-11
    • 2013-04-25
    • 2012-09-06
    • 2014-05-16
    • 1970-01-01
    相关资源
    最近更新 更多