Saturday, May 25, 2013

Encode AAC ADTS using android Media codec API

I faced this problem recently while recording AAC Audio with Mediacodec APIs.

Configure Android 4.1+ MediaCodec APIs to record AAC Audio as shown in below figure.


 Where P1, P2, P3...Pn are individual AAC audio frames coming out of Medicacodec AAC encoder's outputbuffer queue.

For similar source code you can refer here.

Problem is after you store each packets to a file or send RTP packetised P1, P2, P3 ...Pn  packets over network, most of the decoders cannot decode these AAC frames as packets don't have ADTS config header data along with them.

I refer to ADTS packets details here

Solution is to "Prepend" 7 or 9 bytes of ADTS headers to each AAC encoded frame coming out. 

When you are configuring mediacodec api for encoding AAC, you will mention,
mime type = "audio/mp4a-latm",
bitrate,
samplerate,
channel count etc
 
Once encoder is created, we can assume that encoder is honoring our configurations.
 

So using these info, create ADTS headers ( I use 7 bytes) and prepend them to each encoded buffer of mediacodec output. 

something similar to below info:

private void fillInADTSHeader(byte[] ENCodedByteArray, int encoded_length) {
         int finallength = 
encoded_length + 7;//7 bytes of adts headers
       
        int length3bits    = ((finallength & 0xFFFF) & 0x07) << 5;
        int length8bits    = (finallength & 0xFFFF) >> 3;
        int lengthMax2bits = (((finallength & 0xFFFF) & 0x1800) >> 11);
       
        ENCByteArray[0] = (byte)0xFF;
        ENCByteArray[1] = (byte)0xF1;//layer = 0; Mpeg-4 version, Protection absent
        ENCByteArray[2] = (byte)0x6C;//1 channel, AAC LC, private stream 0, sampling freq 8000
        ENCByteArray[3] = (byte)(0x40 | ((lengthMax2bits & 0xFF) << 6));//last 2 bits msb
        ENCByteArray[4] = (byte)length8bits;// 8 bits
        ENCByteArray[5] = (byte)length3bits;//3 bits lsb
        ENCByteArray[6] = (byte)0x00;//number of frames = 1
}

Catch with android phones are, Generated AAC profiles are not always same configured aac profiles (depends on phone :( 

No comments:

Post a Comment