【问题标题】:MediaCodec -- AMediaCodec_start() return -10000, why? how can I solve it?MediaCodec -- AMediaCodec_start() 返回 -10000,为什么?我该如何解决?
【发布时间】:2020-11-09 07:59:19
【问题描述】:
void_t destroyCodec(AMediaCodec* codec)
    {
        media_status_t status = AMediaCodec_releaseOutputBuffer(codec, mLastDecodedFrameIndex, true);
        if (status != AMEDIA_OK){
        OMAF_LOG_E("MediaCodec releaseOutputBuffer failed with status = %d", status);
                OMAF_ASSERT(false, "Release output buffer failed!");
            }

        status = AMediaCodec_stop(codec);

        if (status != AMEDIA_OK)
        {
            LOG_E("MediaCodec stop failed with status = %d", status);
            ASSERT(false, "Stop failed!");
        }
        else
        {
            if (codec)
            {
                delete codec;
                codec= nullptr;
            }
        }
        mLastDecodedFrameIndex = -1;
    }
void_t reCreateCodec(MimeType aType)
{
    if(mCodec){
      destroyCodec(mCodec);
    } 
    mType = aType;
    mCodec = AMediaCodec_createDecoderByType(mType.getData());
    Assert(mCodec!= NULL,"Failed to Create codec!");

    AMediaFormat* androidMediaFormat = AMediaFormat_new();

    AMediaFormat_setString(androidMediaFormat, AMEDIAFORMAT_KEY_MIME, mMimeType.getData());

    OMAF_ASSERT((mMimeType == VIDEO_H264_MIME_TYPE || mMimeType == VIDEO_HEVC_MIME_TYPE), "Unsupported mimetype");

    if (mMimeType == VIDEO_H264_MIME_TYPE){
        AMediaFormat_setBuffer(androidMediaFormat, "csd-0", mDecoderConfig.spsData, mDecoderConfig.spsSize);

        AMediaFormat_setBuffer(androidMediaFormat, "csd-1", mDecoderConfig.ppsData, mDecoderConfig.ppsSize);
    }
    else if (mMimeType == VIDEO_HEVC_MIME_TYPE){
        AMediaFormat_setBuffer(androidMediaFormat, "csd-0", mDecoderConfig.configInfoData,mDecoderConfig.configInfoSize);
    }

    AMediaFormat_setInt32(androidMediaFormat, AMEDIAFORMAT_KEY_WIDTH, mDecoderConfig.width);
    AMediaFormat_setInt32(androidMediaFormat, AMEDIAFORMAT_KEY_HEIGHT, mDecoderConfig.height);

    media_status_t status = AMediaCodec_configure(mCodec, androidMediaFormat, mOutputTexture.nativeWindow, NULL, 0);

    if (status != AMEDIA_OK){
        LOG_E("Could not configure video decoder, status = %d", status);
        AMediaFormat_delete(androidMediaFormat);
        mState = DecoderHWState::ERROR_STATE;
    }
    mState = DecoderHWState::CONFIGURED;
    AMediaFormat_delete(androidMediaFormat);
    media_status_t status = AMediaCodec_configure(mCodec, androidMediaFormat, mOutputTexture.nativeWindow, NULL, 0);
        
    if (status != AMEDIA_OK){
       LOG_E("Could not configure video decoder, status = %d", status);
       AMediaFormat_delete(androidMediaFormat);
    }
        
    status = AMediaCodec_start(mCodec);
    if (status != AMEDIA_OK){
       LOG_E("MediaCodec start failed, status = %d", status);
    }
}

日志只显示错误MediaCodec start failed, status = -10000

所以我们可以断言 AMediaCodec_configure() 运行良好,但 AMediaCodec_start() 失败。

而且这个错误只有在我们第 8 次重新创建新的 Codec 时才会出现。最近7次都没有发现问题。
're-Create' means : check if we have old ones. If so, destroy them and create new one

找了很多遍,MediaCodec中的Error-code -10000还是一无所知。

这里贴一些源代码在 NdkMediaCodec 中,我们可以知道错误码-10000是被响应的msg返回的:

int AMediaCodec_start(AMediaCodec *mData) {
    return translate_error(mData->mCodec->start());
}

status_t MediaCodec::start() {
    sp<AMessage> msg = new AMessage(kWhatStart, id());

    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

谁能给我一些提示?

【问题讨论】:

  • 猜测您没有正确销毁旧的并且操作系统限制了您可以拥有的开放编解码器的数量,请显示minimal reproducible example
  • @Alan Birtles 非常感谢!根据您的建议,我检查了我的“重新创建”,发现我只是使用 delete codec 而不是 AMediaCodec_delete(codec),这是 MediaCodec 中用于销毁编解码器的标准函数。
  • 如果您已经解决了自己的问题,请随时 edit 您的问题,以便它是 minimal reproducible example 然后添加一个答案,它可能会在未来帮助其他人

标签: c++ error-handling android-mediacodec


【解决方案1】:

感谢@Alan Birtles。

在他的建议下,我发现我滥用delete codec来破坏编解码器。实际上,NdkMediaCodec 有自己的 std::funtion AMediaCodec_delete() 来销毁编解码器。

所以destroyCodec(AMediaCodec* codec) 应该是:

   void_t destroyCodec(AMediaCodec* codec)
    {
        media_status_t status = AMediaCodec_releaseOutputBuffer(codec, mLastDecodedFrameIndex, true);
        if (status != AMEDIA_OK){
        OMAF_LOG_E("MediaCodec releaseOutputBuffer failed with status = %d", status);
                OMAF_ASSERT(false, "Release output buffer failed!");
            }

        status = AMediaCodec_stop(codec);

        if (status != AMEDIA_OK)
        {
            LOG_E("MediaCodec stop failed with status = %d", status);
            ASSERT(false, "Stop failed!");
        }
        else
        {
            if (codec)
            {
                status = AMediaCodec_delete(codec);
                if (status == AMEDIA_OK)
                   OMAF_LOG_I("[DECODER] Release codec Success!  %p", codec);
                codec = nullptr;
            }
        }
        mLastDecodedFrameIndex = -1;
    }

当操作系统的编解码器实例过多时,可能会出现错误代码-10000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2019-01-14
    相关资源
    最近更新 更多