0

I'm getting an intermittent low level crash when using Android's MediaCodec API. I'm dealing with multiple (up to 8) raw AAC audio streams so I configure 8 MediaCodec instances and then feed them sample buffers as they arrive (from a single thread so no parallel decoding).

This mostly works fine but every so often I get a low level crash at the start of the session. The tombstone trace looks like this:

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

Where do I even start when trying to diagnose this issue?

Dean Wild
  • 5,886
  • 3
  • 38
  • 45
  • 1
    Since it's crashing deep inside libstagefright -- probably a null pointer dereference -- posting your crash to http://b.android.com/ would be appropriate. – fadden Nov 20 '15 at 16:58
  • 1
    A crash at that place _could_ also be a sign of a AAC decoder bug, where a specific bitstream can crash the decoder. Can you log/dump the packets you feed into the separate decoder, and reproduce the crash by trying to decode the same packets again with one single decoder instantiated, that were fed into the decoder instance that crashed? – mstorsjo Nov 20 '15 at 19:50

1 Answers1

0

Found the solution in the end. I was configuring my decoder with an invalid csd-0 stream header. It was 7 bytes in length when it only needed to be 3 bytes. The first 3 bytes were correct and thus the decoder was being configured OK but those next 4 bytes must have been interpreted as part of the stream data itself causing a corruption in the first audio packet. Amazingly it still works most of the time but sometimes that corruption was clearly enough to crash the decoder.

The invalid CSD header was: 0xF8, 0xF0, 0x21, 0x2E, 0x00, 0xBA, 0x00

The correct CSD header was: 0xF8, 0xF0, 0x20

I'm working with 16KHZ, mono, AAC Low Delay so my decoder config looks like this:

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

Explanation:

Based on this for reference : http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio

The CSD is made up of Object Type, Frquency Index, Channel config.

For me this is:

  • Object type = 39: ER AAC ELD (Enhanced Low Delay)

  • Frequency index = 8 (16000Hz)

  • Channel configuration = 1 (mono)

First 5 bits is the object type OR 31 if object type is greater than 31, which it is and then the next 6 bits are used instead So: 11111

Next 6 bits = 39 So: 000111

Next 4 bits is the frequency index, 8 = 16KHz So: 1000

Next 4 bits is channel config = 1 So 0001

That is 20 bits but we can only work with bytes so must round to nearest 8 and pad with zeros

So the final csd data is:

1111 1000 1111 0000 0010 0000

Which is F8 F0 20 in hex.

Dean Wild
  • 5,886
  • 3
  • 38
  • 45
  • 1
    Can you produce a sample of the sequence of CSD and packets you provided that made it crash? That would make it easier for someone to try to fix this crash in the decoder library, for future generations. – mstorsjo Nov 24 '15 at 11:36
  • Added the invalid csd header I was using. If I get time I will try to reproduce the error whilst dumping the packets contents and post it here. But basically it was happening pretty consistently (every 3rd or 4th session) when using this invalid header so shouldn't be too hard to reproduce. – Dean Wild Nov 24 '15 at 12:57