app
java
streamTrack.play()
base/media/java/android/media/AudioTrack.java play
java
public void play()
startImpl();
}
private void startImpl() {
baseStart(new int[0]); // unknown device at this point
native_start();
}
base/core/jni/android_media_AudioTrack.cpp native_start
cpp
static void
android_media_AudioTrack_start(JNIEnv *env, jobject thiz)
{
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
lpTrack->start();
}
libaudioclient
av/media/libaudioclient/AudioTrack.cpp lpTrack->start
cpp
status_t AudioTrack::start()
{
status_t status = NO_ERROR; // logged: make sure to set this before returning.
mAudioTrack->start(&status);
return status;
}
audioflinger
av/services/audioflinger/Tracks.cpp TrackHandle::start
因为之前分析创建流程时知道,libaudioclient 的 mAudioTrack 就是 TrackHandle ,所以这里调用的是 TrackHandle::start
cpp
Status TrackHandle::start(int32_t* _aidl_return) {
*_aidl_return = mTrack->start();
return Status::ok();
}
status_t Track::start(AudioSystem::sync_event_t event __unused,
audio_session_t triggerSession __unused)
{
status_t status = NO_ERROR;
const sp<IAfThreadBase> thread = mThread.promote();
auto* const playbackThread = thread->asIAfPlaybackThread().get();
status = playbackThread->addTrack_l(this);
return status;
}
av/services/audioflinger/Threads.cpp
将 track 加入到 mActiveTracks
cpp
status_t PlaybackThread::addTrack_l(const sp<IAfTrack>& track)
{
status_t status = ALREADY_EXISTS;
// 不在mActiveTracks 中再加入
if (mActiveTracks.indexOf(track) < 0) {
mActiveTracks.add(track);
}
onAddNewTrack_l();
return status;
}
void PlaybackThread::onAddNewTrack_l()
{
ALOGV("signal playback thread");
broadcast_l();
}
void ThreadBase::broadcast_l()
{
mSignalPending = true;
mWaitWorkCV.notify_all();
}
threadLoop
av/services/audioflinger/Threads.cpp
processConfigEvents_l处理一些事件
prepareTracks_l
threadLoop_mix
threadLoop_write
cpp
bool PlaybackThread::threadLoop()
{
Vector<sp<IAfTrack>> tracksToRemove;
for (int64_t loopCount = 0; !exitPending(); ++loopCount)
{
processConfigEvents_l();
// 休眠逻辑
if ((mActiveTracks.isEmpty() && systemTime() > mStandbyTimeNs) ||
isSuspended()) {
// 进休眠
threadLoop_standby();
if (mActiveTracks.isEmpty() && mConfigEvents.isEmpty()) {
// wait ...
mWaitWorkCV.wait(_l);
continue;
}
}
// 返回一个状态 MIXER_TRACKS_READY
mMixerStatus = prepareTracks_l(&tracksToRemove);
// 满足播放要求 mix
if (mMixerStatus == MIXER_TRACKS_READY) {
threadLoop_mix();
}
if (!waitingAsyncCallback()) {
// mSleepTimeUs == 0 means we must write to audio hardware
if (mSleepTimeUs == 0) {
if (mBytesRemaining) {
ret = threadLoop_write();
}
}
}
}
return false;
}
prepareTracks_l
av/services/audioflinger/Threads.cpp prepareTracks_l
将 track 构造并添加到 mAudioMixer
mAudioMixer->create构造
track->framesReady
cpp
PlaybackThread::mixer_state MixerThread::prepareTracks_l(
Vector<sp<IAfTrack>>* tracksToRemove)
{
mixer_state mixerStatus = MIXER_IDLE;
size_t count = mActiveTracks.size();
for (size_t i=0 ; i<count ; i++) {
const sp<IAfTrack> t = mActiveTracks[i];
IAfTrack* const track = t.get();
// 获取 控制头
audio_track_cblk_t* cblk = track->cblk();
// 获取唯一id
const int trackId = track->id();
// 如果混音器中没有这个 id
if (!mAudioMixer->exists(trackId)) {
status_t status = mAudioMixer->create(
trackId,
track->channelMask(),
track->format(),
track->sessionId());
size_t framesReady = track->framesReady();
// 静音
if (track->getInternalMute()) {
vrf = 0.f;
vlf = 0.f;
}
// 处理音量 设置音量
track->setFinalVolume(vlf, vrf);
// 设置参数
mAudioMixer->enable(trackId);
mAudioMixer->setParameter(trackId, param, AudioMixer::VOLUME0, &vlf);
mAudioMixer->setParameter(trackId, param, AudioMixer::VOLUME1, &vrf);
}
}
return mixerStatus;
}
// mixerStatus 参考 av/services/audioflinger/IAfThread.h
enum mixer_state {
MIXER_IDLE, // no active tracks
MIXER_TRACKS_ENABLED, // at least one active track, but no track has any data ready
MIXER_TRACKS_READY, // at least one active track, and at least one track has data
MIXER_DRAIN_TRACK, // drain currently playing track
MIXER_DRAIN_ALL, // fully drain the hardware
};
av/media/libaudioprocessing/AudioMixerBase.cpp create
根据 cblk 的信息创建一个 AudioMixerBase
cpp
status_t AudioMixerBase::create(
int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
{
auto t = preCreateTrack();
mTracks[name] = t;
return OK;
}
}
std::shared_ptr<AudioMixerBase::TrackBase> AudioMixerBase::preCreateTrack()
{
return std::make_shared<TrackBase>();
}
av/services/audioflinger/Tracks.cpp framesReady
cpp
size_t Track::framesReady() const {
return mAudioTrackServerProxy->framesReady();
}
av/media/libaudioclient/AudioTrackShared.cpp framesReady
rear - mFront返回填满的未读取的数据帧数
cpp
__attribute__((no_sanitize("integer")))
size_t AudioTrackServerProxy::framesReady()
{
audio_track_cblk_t* cblk = mCblk;
const int32_t rear = getRear();
ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
return filled;
}
threadLoop_mix
av/services/audioflinger/Threads.cpp threadLoop_mix
主要干的事就是混音重采样 最后将数据送到hal中
cpp
void MixerThread::threadLoop_mix()
{
// mix buffers...
mAudioMixer->process();
mSleepTimeUs = 0;
}
// 主要干的事就是混音重采样 最后将数据送到hal中
// av/media/libaudioprocessing/include/media/AudioMixerBase.h process
void process() {
preProcess();
(this->*mHook)();
postProcess();
}
threadLoop_write
av/services/audioflinger/Threads.cpp
cpp
ssize_t MixerThread::threadLoop_write()
{
return PlaybackThread::threadLoop_write();
}
av/services/audioflinger/Threads.cpp threadLoop_write
AudioMixerBase 将mSinkBuffer 填充,将数据写入到 hal 中
cpp
ssize_t PlaybackThread::threadLoop_write()
{
ssize_t bytesWritten;
const size_t offset = mCurrentWriteLength - mBytesRemaining;
if (mNormalSink != 0) {
const size_t count = mBytesRemaining / mFrameSize;
ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
}
return bytesWritten;
}

dumpsys media.audio_flinger
bash
Notification Clients:
pid uid name
1448 1013 media
1709 1000 android.uid.system
2485 10157 android.uid.systemui
2651 1001 android.uid.phone
3976 1041 audioserver
4385 10133 org.lineageos.glimpse
10242 10187 com.example.myapplication
Global session refs:
session cnt pid uid name
641 1 1709 1000 android.uid.system
857 1 2485 10157 android.uid.systemui
1009 1 10242 10187 com.example.myapplication
Supported latency modes: { }
Stream volumes in dB: 0:-inf, 1:-11, 2:-inf, 3:-inf, 4:-inf, 5:-8.7, 6:-inf, 7:-inf, 8:-inf, 9:0, 10:-inf, 11:-inf, 12:0, 13:0, 14:0
Normal mixer raw underrun counters: partial=0 empty=0
2 Tracks of which 0 are active
Type Id Active Client(pid/uid) Session Port Id S Flags Format Chn mask SRate ST Usg CT G db L dB R dB VS dB PortVol dB PortMuted Server FrmCnt FrmRdy F Underruns Flushed BitPerfect InternalMute Latency
S 56 no 1709/ 1000 641 24 S 0x600 00000001 00000003 44100 1 d 4 -17 -6 -6 0 -11 false 0000612C 4146 0 f 0 0 false false 61.79 k
S 74 no 2485/ 10157 857 42 S 0x600 00000001 00000003 44100 1 d 4 -17 -6 -6 0 -11 false 0000A2AD 8329 0 f 0 0 false false 61.78 k