【问题标题】:Intermittent native crash in libstagefright_soft_aacdec.so when using MediaCodec (AAC decoding)使用 MediaCodec(AAC 解码)时 libstagefright_soft_aacdec.so 中的间歇性原生崩溃
【发布时间】:2016-02-21 22:09:07
【问题描述】:

在使用 Android 的 MediaCodec API 时,我遇到了间歇性的低级崩溃。我正在处理多个(最多 8 个)原始 AAC 音频流,因此我配置了 8 个 MediaCodec 实例,然后在它们到达时为它们提供样本缓冲区(来自单个线程,因此没有并行解码)。

这大部分工作正常,但我经常在会话开始时遇到低级崩溃。墓碑痕迹如下所示:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/hammerhead/hammerhead:6.0/MRA58K/2256973:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 32229, tid: 5451, name: gle.aac.decoder  >>> com.wizix.gridme <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4c
    r0 00007fff  r1 000002fc  r2 0000004c  r3 0000000d
    r4 00000010  r5 0000004c  r6 97adfc54  r7 0000000d
    r8 97ae0014  r9 00000001  sl 94a8c020  fp 97adf5b8
    ip 99c0ef08  sp 9422acd4  lr 000000f0  pc 99bf8cc0  cpsr 800f0030
    d0  0000000000000000  d1  0000000000000000
    d2  0000000000000000  d3  0000000000000000
    d4  fff9fff8fff70001  d5  fffdfffbfffafff7
    d6  fffdfffa00010003  d7  fff0fffb00040003
    d8  0000000000000000  d9  0000000000000000
    d10 0000000000000000  d11 0000000000000000
    d12 0000000000000000  d13 0000000000000000
    d14 0000000000000000  d15 0000000000000000
    d16 0000000000000000  d17 0000000000000000
    d18 0000000000000000  d19 0000000000000000
    d20 3f80000000000000  d21 0000000000000000
    d22 000000003f800000  d23 0000000000000000
    d24 bf56c16c16c15177  d25 3e21ee9ebdb4b1c4
    d26 392f1976b7ed8fc0  d27 b94377ce858a5d48
    d28 35e127004971adb1  d29 b94377ce858a5d48
    d30 3ff0000000000000  d31 3ba3198a2e000000
    scr 60000013

backtrace:
    #00 pc 00028cc0  /system/lib/libstagefright_soft_aacdec.so (maxSubbandSample(long**, long**, int, int, int, int)+85)
    #01 pc 0002a205  /system/lib/libstagefright_soft_aacdec.so (calculateSbrEnvelope(QMF_SCALE_FACTOR*, SBR_CALCULATE_ENVELOPE*, SBR_HEADER_DATA*, SBR_FRAME_DATA*, long**, long**, int, long*, unsigned int, int)+2644)
    #02 pc 000243a5  /system/lib/libstagefright_soft_aacdec.so (sbr_dec(SBR_DEC*, short*, short*, SBR_DEC*, short*, int, int, SBR_HEADER_DATA*, SBR_FRAME_DATA*, SBR_PREV_FRAME_DATA*, int, PS_DEC*, unsigned int)+632)
    #03 pc 00015a4d  /system/lib/libstagefright_soft_aacdec.so (sbrDecoder_Apply+740)
    #04 pc 0000ff8b  /system/lib/libstagefright_soft_aacdec.so (aacDecoder_DecodeFrame+610)
    #05 pc 0000ef15  /system/lib/libstagefright_soft_aacdec.so (android::SoftAAC2::onQueueFilled(unsigned int)+860)
    #06 pc 000224df  /system/lib/libstagefright_omx.so (android::SimpleSoftOMXComponent::onMessageReceived(android::sp<android::AMessage> const&)+242)
    #07 pc 000233d3  /system/lib/libstagefright_omx.so
    #08 pc 0000b2c9  /system/lib/libstagefright_foundation.so (android::AHandler::deliverMessage(android::sp<android::AMessage> const&)+16)
    #09 pc 0000d253  /system/lib/libstagefright_foundation.so (android::AMessage::deliver()+54)
    #10 pc 0000bcb7  /system/lib/libstagefright_foundation.so (android::ALooper::loop()+222)
    #11 pc 0001006d  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+112)
    #12 pc 0003f3e7  /system/lib/libc.so (__pthread_start(void*)+30)
    #13 pc 00019b43  /system/lib/libc.so (__start_thread+6)

在尝试诊断此问题时,我什至应该从哪里开始?

【问题讨论】:

  • 因为它在 libstagefright 内部崩溃了——可能是一个空指针取消引用——将你的崩溃发布到b.android.com 是合适的。
  • 该位置的崩溃可能也是 AAC 解码器错误的迹象,其中特定的比特流可能会使解码器崩溃。您是否可以记录/转储您输入单独解码器的数据包,并通过尝试使用一个实例化的单个解码器再次解码相同的数据包来重现崩溃,这些数据包被输入到崩溃的解码器实例中?

标签: android android-mediacodec stagefright


【解决方案1】:

最终找到了解决方案。我正在使用无效的 csd-0 流标头配置我的解码器。当它只需要 3 个字节时,它的长度是 7 个字节。前 3 个字节是正确的,因此解码器配置正常,但接下来的 4 个字节必须被解释为流数据本身的一部分,导致第一个音频数据包损坏。令人惊讶的是,它在大多数情况下仍然有效,但有时这种损坏显然足以使解码器崩溃。

无效的 CSD 标头是:0xF8, 0xF0, 0x21, 0x2E, 0x00, 0xBA, 0x00

正确的 CSD 标头是:0xF8, 0xF0, 0x20

我正在使用 16KHZ、单声道、AAC 低延迟,所以我的解码器配置如下所示:

byte[] asc = new byte[]{(byte) 0xF8, (byte) 0xF0, 0x20}; // here is the valid csd data
ByteBuffer ascBuf = ByteBuffer.wrap(asc);
mediaFormat.setByteBuffer("csd-0", ascBuf);             
m_decoder = MediaCodec.createByCodecName("OMX.google.aac.decoder");            
m_decoder.configure(mediaFormat, null, null, 0);

说明:

基于此供参考:http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio

CSD 由对象类型、频率索引、频道配置组成。

对我来说这是:

  • 对象类型 = 39:ER AAC ELD(增强型低延迟)

  • 频率指数 = 8 (16000Hz)

  • 频道配置 = 1(单声道)

如果对象类型大于 31,则前 5 位是对象类型或 31,然后使用接下来的 6 位代替 所以:11111

接下来的 6 位 = 39 所以:000111

接下来的4位是频率索引,8 = 16KHz 所以:1000

接下来的 4 位是通道配置 = 1 所以0001

这是 20 位,但我们只能使用字节,因此必须四舍五入到最接近的 8 并用零填充

所以最终的csd数据为:

1111 1000 1111 0000 0010 0000

十六进制的F8 F0 20

【讨论】:

  • 你能提供一个你提供的导致崩溃的 CSD 和数据包序列的样本吗?这将使人们更容易尝试在解码器库中修复此崩溃,以供后代使用。
  • 添加了我使用的无效 csd 标头。如果我有时间,我会在转储数据包内容的同时尝试重现错误并将其发布在这里。但基本上它在使用这个无效的标头时非常一致地发生(每 3 次或第 4 次会话),所以不应该太难重现。
猜你喜欢
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 2012-12-31
  • 2015-11-22
  • 1970-01-01
  • 2014-09-15
相关资源
最近更新 更多