안드로이드 아나토미 정리




 Android Audio System
(오디오 출력-트랙활성화)




                            박철희

                        1
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
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
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
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

Android audio system(오디오 출력-트랙활성화)

  • 1.
    안드로이드 아나토미 정리 Android Audio System (오디오 출력-트랙활성화) 박철희 1
  • 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