【问题标题】:OMXCodec::onEvent -- OMX Bad ParameterOMXCodec::onEvent -- OMX 错误参数
【发布时间】:2013-03-07 16:35:18
【问题描述】:

我一直在尝试使用OMXCodec 到Stagefright。我已经实现了ICS 版本的Android 的代码。我有两个类CustomDataSource 派生MediaSource,另一个是CustomOmxCodec,它调用OMXCodec::Create 方法并执行读取操作以解码h264 帧。我已经在带有omx.google.video.avc 软件解码器的设备上测试了这个实现,它工作正常。现在,当我尝试在具有硬件 h264 解码的 android 手机上运行相同的实现时,它在读取调用时返回错误。错误如下:

[OMX.MTK.VIDEO.DECODER.AVC] ERROR (0x80001005, 0)

0x80001005 用于OMX_ErrorBadParameter。 我在读取操作时收到错误代码-1103。 我尝试了各种参数,但没有成功。

完整的日志如下:

[OMX.MTK.VIDEO.DECODER.AVC] mVideoInputErrorRate (0.000000)

!@@!>>create tid (21087) O<XCodec mOMXLivesLocally=0, mIsVideoDecoder (1), mIsVideoEncoder (0), mime(video/avc)

[OMX.MTK.VIDEO.DECODER.AVC] video dimensions are 640X480

mSupportesPartialFrames 1 err 0

[OMX.MTK.VIDEO.DECODER.AVC] allocating 10 buffers of size 65536 on input port.

[OMX.MTK.VIDEO.DECODER.AVC] mMemHeapBase = 0x00E8C288,  mOutputBufferPoolMemBase=0x51F8E000, size  = 9578848

[OMX.MTK.VIDEO.DECODER.AVC] ERROR (0x80001005, 0)

OMXCodec::onEvent--OMX Bad Parameter!!

Read Error : -1103

我会很感激这方面的任何指导。

【问题讨论】:

    标签: android-ndk android-hardware stagefright openmax


    【解决方案1】:

    根据问题,硬件编解码器(即OMX.MTK.VIDEO.DECODER.AVC)不支持作为配置步骤的一部分传递的参数之一。

    从OMXCodec::create,configureCodec 将被调用,内部调用许多其他函数。由于错误是 OMXCodec::onEvent 的一部分,因此可能的情况之一是组件在解码第一帧的前几个字节时遇到错误。

    具体来说,当组件遇到SPS 和PPS(编解码器特定数据的一部分)时,组件通常会触发portSettingsChanged。根据您的回复,我感觉在这个过程中,出现了一些错误,因此触发了onEvent。

    请分享更多日志以进一步分析。

    【讨论】:

    • 感谢您的回复。我还没有设置 kKeyAVCC 参数。是否有必要或推荐定义 kKeyAVCC?我正在整合stagefright来逐帧解码。我正在从我的帧集合中解析编码帧,而不是来自 mp4 或任何其他媒体容器。那么在这种情况下,是否可以将sps和pps设置为kKeyAVCC呢?以后会分享更多日志。
    • @sam18 模拟器和硬件的 android 代码应该相同。因此,我认为 kKeyAVCC 已经作为第一个缓冲区传递给解码器。这个问题似乎源于别的东西。从您的日志中,该错误似乎是在创建输出缓冲区期间发生的。你能分享完整的日志吗?
    【解决方案2】:

    从日志和映射到实现的代码中,我感觉发生了以下情况

    [OMX.MTK.VIDEO.DECODER.AVC] allocating 10 buffers of size 65536 on input port.
    

    这一步在解码器的输入端口分配缓冲区

    从代码流程来看,分配输入端口缓冲区后,输出端口上的缓冲区从nativeWindow到allocateOutputBuffersFromNativeWindow分配。

    作为此方法实现一部分的步骤之一是将输出端口上的缓冲区数量增加 2 并将其设置为 OMX 组件,如 here 所示。

    我觉得您的错误可能源于这一特定点,因为nBufferSize 是OMX_IndexParamPortDefinition 索引的只读 参数。请参阅OMX Standard,第 3.1.3.12.1 节,第 83 页,其中清楚地表明nBufferSize 是一个只读 参数。

    看来您的OMX 组件可能是严格符合OMX 的组件,而在Android 中从ICS 开始,会出现某些偏差。这可能是您的错误的潜在原因之一。

    P.S:如果您能分享更多信息,我们可以提供更多帮助。

    【讨论】:

    • 非常感谢您提供深入的信息。我可以使用您的信息进行更深入的挖掘。我已经粘贴了我在 logcat 中找到的所有日志。还有其他方法可以生成特定于 omx 的日志吗?
    • @sam18 您可以在OMXCodec 中添加更多日志,也可以在OMXNodeInstance 中启用日志。请使用OMXCodec 中的Codec_LOGV 构造来区分不同的编解码器打印。如果可以联系OMX组件开发者,请检查OMX组件是否支持我帖子中提到的偏差。
    • 您说问题出在第一次读取操作时的输出缓冲区创建过程中。这让我猜测问题的原因。在使用 OMXCodec::Create 方法创建视频源时,我没有将 sp 的指针作为最后一个参数传递,而是传递了 null。因为我想在我的控制下渲染表面。这可能是我的问题的原因吗?由于没有硬件解码器可以为其分配输出缓冲区的表面,因此它失败并显示错误代码 -1103 并为 ERR Bad Parameter 抛出 (0x80001005, 0)。
    • @sam18 如果您不提供nativeWindow 并传递NULL,如果为您的组件设置了kRequiresAllocateBufferOnOutputPorts,组件将通过OMX_AllocateBuffer 自行分配缓冲区或OMXCodec 将自己创建缓冲区并调用OMX_UseBuffer。您的读取将调用OMXCodec::start,它将为输入和输出端口提供缓冲区并开始处理。您将需要更多日志来缩小问题范围。否则,我们只是在猜测潜在的障碍。
    • @sam18 你能进一步定位这个问题吗?运气好吗?
    【解决方案3】:

    MTK H264解码器需要参数csd-0和csd-1来初始化解码器(您可以在http://developer.android.com/reference/android/media/MediaCodec.html获得一些信息)。 csd-0和csd-1分别代表H264的SPS和PPS。我问了一位MTK工程师,他说我们可以使用下面的代码来设置这两个参数。

    byte[] sps = {0,0,0,1,103,100,0,40,-84,52,-59,1,-32,17,31,120,11,80,16,16,31
                  ,0,0,3,3,-23,0,0,-22,96,-108};
    byte[] pps = {0,0,0,1,104,-18,60,-128};
    MediaFormat mFormat = MediaFormat.createVideoFormat("video/avc", width, height);
    mFormat.setByteBuffer("csd-0", ByteBuffer.wrap(sps));
    mFormat.setByteBuffer("csd-1", ByteBuffer.wrap(pps));
    

    也许这就是我们收到 OMX Bad Parameter 错误消息的原因。

    【讨论】:

    • 但我得到了错误:E/MtkOmxVenc( 6724): Error: BufferType is not Gralloc Source !!!! 作为您的建议。
    猜你喜欢
    • 1970-01-01
    • 2016-06-08
    • 2020-07-29
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多