2. 1.트랙 활성화 요청 안드로이드 아나토미 정리
Mediaplayerservice.cpp
void MediaPlayerService::AudioOutput::start()
{
if (mTrack) {
mTrack->start();
}
}
AudioTrack,cpp
void AudioTrack::start()
{
t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);audiotrack 실행
status = mAudioTrack->start();
}
status_t AudioFlinger::TrackHandle::start() {
return mTrack->start();
}
status_t AudioFlinger::PlaybackThread::Track::start(){
playbackThread->addTrack_l(this);
}
status_t AudioFlinger::PlaybackThread::addTrack_l{
track->mRetryCount = kMaxTrackStartupRetries;pcm data 버퍼에 채워질때 까지 시도하는 retry count(50)
mActiveTracks.add(track); ---(1)
mWaitWorkCV.broadcast(); ----(2)
mixerthread의 mWaitWorkCV.wait(mLock); 에서 기다리는 thread의 lock을 풀어준다.
}
2
3. 1.트랙 활성화 요청 안드로이드 아나토미 정리
(1)mActiveTracks.add(track);
트랙활성화 vector에 등록한다. ActiveTracks는 SortedVector 형이다.
mActiveTracks
track
PCM
…. Audio mixer 데이터
track add
PCM
데이터
PCM
데이터
(2)mWaitWorkCV.broadcast();
mixerthread의 mWaitWorkCV.wait(mLock); 에서 기다리는 thread의 lock을 풀어준다.
1)활성화 트랙 벡터 획득
2)컨디션 대기 prepareTrack_l()
Y
3)PCM 오디오 출력
데이터유무
N
4)재시도횟수 Y 트랙
> 50 제거
Mixerthread threadloop()
N 동작과정
5)일시대기
3
4. 2.Mixerthread thread loop 동작 과정 안드로이드 아나토미 정리
bool AudioFlinger::MixerThread::threadLoop()
{
while (!exitPending())
{
1)활성화 트랙 벡터 획득
const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
//activetrack이 없을 경우(보통 믹스쓰레드가 처음 만들어 지면, active track 이 없기 때문에 이쪽으로 들어온다.)
if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) || mSuspended) {
2)컨디션 대기
mWaitWorkCV.wait(mLock);
여기서 기디리다가, PlaybackThread::addTrack_l 의 mWaitWorkCV.broadcast();
이 불리면 대기상태에서 깨어난다.
continue; while문의 처음으로 이동
}
3)PCM 데이터 유무 확인, 4)재시도 횟수 확인
mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
3,4 과정은 prepareTracks_l에서 수행된다.
//오디오 출력
if (sleepTime == 0) { Sleeptime 0은 buffer에 data가 있다는 의미이다.
//오디오 출력
}
else{ 5)일시 대기
usleep(sleepTime);
sleeptime동안 sleep후에 다시 loop의 처음으로 돌아가서 prepareTracks_l 안에서 pcm data 유무 및
재시도 횟수를 확인한후 재시도 횟수가 50을 넘었어면 활성화 트랙 벡터에서 제거된다.
}
4
5. 2.Mixerthread thread loop-prepareTracks_l 안드로이드 아나토미 정리
uint32_t AudioFlinger::MixerThread::prepareTracks_l
{
size_t count = activeTracks.size();
for (size_t i=0 ; i<count ; i++) activetrack 만큼 for 문을 돌면서
{
if (cblk->framesReady() && track->isReady() && !track->isPaused() && !track->isTerminated())
{
//pcm data가 있으면 mixing을 위해서 AudioMixer의 setParameter 를 불러서
paratmeter등을 설정한다.(volume,format, mainbuffer 등)
}
else
{
retrycount가 0보다 같거나 작으면 즉, 50번을 기다렸는데 pcm data가 없으면
if (--(track->mRetryCount) <= 0) {
tracksToRemove->add(track);
tracksToRemove 에 추가.
}
else if (mixerStatus != MIXER_TRACKS_READY)
{
mixerStatus = MIXER_TRACKS_ENABLED;
status를 MIXER_TRACKS_ENABLED 로 유지 하면서 pcm data가 들어올때까지 기다린다.
}
mAudioMixer->disable(AudioMixer::MIXING);
트랙의 pcm 데이터를 오디오 믹서가 믹싱하지 않도록 설정한다.
}
}
count = tracksToRemove->size();
for (size_t i=0 ; i<count ; i++){
mActiveTracks.remove(track);
}
tracksToRemove size만큼 for문을 돌면서 해당 track을 활성화 트랙 벡터에서 제거한다.
5