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,
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
}
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