I use the MediaExtractor / MediaCodec
combo on Android (target API level >= 16) to decode audio streams. Now I have a subtle problem when playing back mp4/m4a containers that contain MPEG-4 HE-AAC audio data.
When querying track's MediaFormat
for the MediaFormat.KEY_SAMPLE_RATE
I actually get only half of the expected size, e.g for a track that needs a playback sample rate of 44100 the MediaFormat
returns 22050. After reading some documentation on HE-AAC I understand that this is "correct" in terms of how that codec works.
Still, to play back the audio track on an AudioTrack
instance I have to configure it with the correct (playback) samplerate which is 44100 and not 22050.
Therefore, I am looking for a way to know for sure when the audio is HE-AAC encoded with API target level >= 16 so I can set the sample rate of the AudioTrack
to two times the reported sample rate.
Edit: I do check the MediaFormat
when MediaCodec
return with MediaCodec.INFO_OUTPUT_FORMAT_CHANGED
. The format will look like this:
max-input-size=946,
aac-profile=2,
mime=audio/mp4a-latm,
durationUs=158499410,
csd-0=java.nio.ByteArrayBuffer[position=0,limit=5,capacity=5],
channel-count=2,
sample-rate=22050
To get a proper playback on the AudioTrack
I need to set the sample rate to 2 * sample-rate = 44100.
I wonder if the csd-0
contains more information to deduce the profile/format/etc. For the above example the 5 bytes from the csd-0
buffer looks like this:
0x13 0xffffff90 0x56 0xffffffe5 0xffffffa0
Now I'm wondering about the concrete structure of this "codec specific data"
You should only treat the MediaFormat
returned by MediaExtractor
as a hint; you need to look at what MediaCodec
returns with INFO_OUTPUT_FORMAT_CHANGED
, this should return the real samplerate. This means that you can only configure AudioTrack
once decoding of the content has started.