2015-11-19 550 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個會話),因此不應該太難重現。 –