android 4.4 本地播放 一首mp3的流程
以一首mp3的播放流程来理解audio 架构与代码流程。
播放命令
通过网络adb连接板子 cmd中输入:
am start -a "android.intent.action.VIEW" -t "audio/mp3" -d "file:///data/mytest/zl_cd.mp3"
1.
创建播放器
AmSuperPlayer
AwesomePlayer
new AudioPlayer
2.
音频文件探测
MP3Extractor
3.
OMXCodec
MP3采用软件的方式进行解码
//SoftMP3::onQueueFilled
//notifyEmptyBufferDone(inHeader);
//notifyFillBufferDone(outHeader);
4.
AudioTrack 播放线程
AudioTrack 获取到软件解码后的数据,并写入audioflinger的buff中
//AudioTrack->binder->audioflinger
AudioTrack::set
AudioTrack::createTrack_l
AudioFlinger::createTrack
AudioFlinger::PlaybackThread::threadLoop()
AudioFlinger::PlaybackThread::threadLoop_write() audioflinger Threads.cpp
ssize_t framesWritten = mNormalSink->write(mMixBuffer + offset, count);
libnbaio.so (android::AudioStreamOutSink::write(void const*, unsigned int)+15) libnbaio AudioStreamOutSink.cpp
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) audio_hw.c
5.
音频渲染层 把解码后的pcm音频数据写入驱动层,使得喇叭发声
audioflinger
从AudioTrack 写入的buff中取出 解码后的pcm数据
//mNormalSink->write
//mOutput->write
//audioflinger->pcm out->kernel hdmi
#if 0
D/audio_hw_primary( 3857): #00 pc 000012c6 /system/lib/hw/audio.primary.amlogic.so (dumping_callstack+21)
D/audio_hw_primary( 3857): #01 pc 00002020 /system/lib/hw/audio.primary.amlogic.so
D/audio_hw_primary( 3857): #02 pc 00002bea /system/lib/hw/audio.primary.amlogic.so
D/audio_hw_primary( 3857): #03 pc 00003a58 /system/lib/libnbaio.so (android::AudioStreamOutSink::write(void const*, unsigned int)+15)
D/audio_hw_primary( 3857): #04 pc 0001b3b0 /system/lib/libaudioflinger.so
D/audio_hw_primary( 3857): #05 pc 0001c312 /system/lib/libaudioflinger.so
D/audio_hw_primary( 3857): #06 pc 0000ea5a /system/lib/libutils.so (android::Thread::_threadLoop(void*)+213)
D/audio_hw_primary( 3857): #07 pc 0000e58c /system/lib/libutils.so
D/audio_hw_primary( 3857): #08 pc 0000d1a0 /system/lib/libc.so (__thread_entry+72)
D/audio_hw_primary( 3857): #09 pc 0000d338 /system/lib/libc.so (pthread_create+240)
#endif
//debug_stamp
3.3 数据传递总结
@1 对于不同的MODE, 这些Proxy指向不同的对象:
AudioTrack中含有mProxy, 它被用来管理共享内存, 里面含有obtainBuffer, releaseBuffer函数。
Track中含有mServerProxy, 它被用来管理共享内存, 里面含有obtainBuffer, releaseBuffer函数
@2 AudioTrack和AudioFlinger通过mCblkMemory这块内存来实现“生产者-消费者”数据交互,下面我们来分析一下ServerProxy和ClientProxy通过共享内存进行数据交互的原理:
创建 track 时 AudioFlinger 会给每个 track 分配 audio 共享内存,AudioTrack、AudioFlinger 以该buffer 为参数通过
AudioTrackClientProxy、AudioTrackServerProxy 创建 mClientProxy、mServerProxy。
AudioTrack( APP应用端)通过 mClientProxy 向共享 buffer 写入数据,
AudioFlinger(server 端)通过 mServerProxy 从共享内存中 读出数据。
这样 client、server 通过 proxy 对共享内存 形成了生产者、消费者模型。
@3 AudioTrackClientProxy、AudioTrackServerProxy( 这两个类都位于 AudioTrackShared.cpp )
分别封装了 client 端、server 端共享 buffer 的使用方法 obtainBuffer 和 releaseBuffer,这些接口的功能如下:
@@3.1 Client 端:
AudioTrackClientProxy:: obtainBuffer()从 audio buffer 获取连续的空buffer;
AudioTrackClientProxy:: releaseBuffer ()将填充了数据的 buffer 放回 audio buffer。
@@3.2 Server 端:
AudioTrackServerProxy:: obtainBuffer()从 audio buffer 获取连续的填充了数据的 buffer; PCM
AudioTrackServerProxy:: releaseBuffer ()将使用完的空buffer 放回 audio buffer。
原文链接:https://blog.csdn.net/vviccc/article/details/105312220