2015-11-19 127 views
0

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

这大部分工作正常,但每隔一段时间我会在会话开始时发生低级别的崩溃。墓碑跟踪如下所示:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
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) 

从哪里开始尝试诊断此问题?

+1

,因为它是深崩溃内libstagefright - 可能是一个空指针引用 - 发布您的崩盘http://b.android.com/将是适当的。 – fadden

+1

在那个地方崩溃也_could_是AAC解码错误,其中,一个特定的比特流可能会崩溃解码器的标志。您可以登录/甩了你送入独立解码器的数据包,并试图在同一数据包与实例化一个单独的解码器,即送入崩溃的解码器实例再次解码重现崩溃? – mstorsjo

回答

0

最终找到了解决方案。我用一个无效的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(16000,)

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

前5位是对象类型OR 31如果对象吨型大于31,它是和然后在接下来的6个比特被用来代替 所以:​​

接下来6位= 39 所以:000111

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

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

即20个比特,但也只能用字节工作,所以必须向最接近8和垫零

所以最终的CSD数据是:

1111 1000 1111 0000 0010 0000 

这是十六进制F8 F0 20

+1

你能出示您提供CSD和数据包的序列,使得它崩溃的样本?这将使人们更容易尝试在解码器库中解决这个崩溃问题,以便为后代服务。 – mstorsjo

+0

添加了我使用的无效csd标题。如果我得到时间,我会尝试重现错误,同时转储数据包内容并将其发布到此处。但基本上,使用这个无效标题时,会发生相当一致的情况(每第3或第4个会话),因此不应该太难重现。 –