ffmpeg.exe (encode PCM to AAC-LC and pack the data to adts format)
- exec ffmpeg.exe from my program
ffmpeg.exe -f f32le -ar 48000 -ac 2 -i - -f u16le -ar 24000 -ac 1 -map 0 -codec:a aac -profile aac_low -ab 8k -f adts -
- my program passes captured PC internal sound data through stdin of ffmpeg.exe process
- IMPORTANT: passing samples is needed 1024 samples at the same time (= pass 1024 samples with one write call and then call flush)
- stdout of ffmpeg.exe is read by my program and send it to Android app.
- IMPORTANT: you should read ffmpeg write data with one read call (it should be a adts frame)
Decoder with MediaCodec class
decode.cs
HandlerThread callbackThread = new HandlerThread("AACDecodingHandler");
callbackThread.Start();
Handler handler = new Handler(callbackThread.Looper);
decoder = MediaCodec.CreateDecoderByType("audio/mp4a-latm");
// samplingRate and ch is your required value
var format = MediaFormat.CreateAudioFormat("audio/mp4a-latm", samplingRate, ch);
// IMPORTANT: csd_data is byte array (7 elements). this data is exist head of stream (= stdout of ffmpeg.exe)
// this 7 bytes is adts fixed header of first frame but you should not removed it from frame.
// you should pass first adts frame to InputBuffer with header (first 7 bytes).
int profile = (csd_data[2] & 0xC0) >> 6;
int srate = (csd_data[2] & 0x3C) >> 2;
int channel = ((csd_data[2] & 0x01) << 2) | ((csd_data[3] & 0xC0) >> 6);
byte csd0_0 = (byte)(((profile + 1) << 3) | srate >> 1);
byte csd0_1 = (byte)(((srate << 7) & 0x80) | channel << 3 );
byte[] bytes = new byte[] { csd0_0, csd0_1 };
ByteBuffer csd = ByteBuffer.Wrap(bytes);
format.SetInteger(MediaFormat.KeyIsAdts, 1);
format.SetByteBuffer("csd-0", csd);
// cbk is your callback class
decoder.SetCallback(cbk, handler);
decoder.Configure(format, null, null, 0);
decoder.Start();
Useful tool for validating your AAC adts data
Whole code
- https://github.com/ryogrid/RemoteDesktopOneWindowForNovelGrame/tree/4112bfac2b23de7b551e86c46c69241ce81f1faf/RemoteDesktop.Server.XamaOk
- https://github.com/ryogrid/RemoteDesktopOneWindowForNovelGrame/tree/4112bfac2b23de7b551e86c46c69241ce81f1faf/RemoteDesktop.Client.Android