1. 程式人生 > >錄音相關的處理流程

錄音相關的處理流程

一.AudioRecord錄音的初始化設定
AudioRecord::set
 ->
AudioSystem::getInput
 ->
呼叫IAudioPolicyService.cpp檔案中的
BpAudioPolicyService的getInput函式
    remote()->transact(GET_INPUT, data, &reply);
BnAudioPolicyService::onTransact(
case GET_INPUT:
    audio_io_handle_t input = getInput(inputSource,
                                   samplingRate,
                                   format,
                                   channels,
                                   acoustics); // 呼叫的是AudioPolicyService::getInput函式
 ->
AudioPolicyService::getInput
 ->
AudioPolicyManagerBase::getInput
    mpClientInterface->openInput
 ->
AudioPolicyService::openInput
 ->
BpAudioFlinger的openInput函式
 ->
AudioFlinger::openInput
    mAudioHardware->openInputStream
 ->
AudioHardwareALSA::openInputStream
    err = mALSADevice->open(&(*it), devices, mode(), 0);

    in = new AudioStreamInALSA(this, &(*it), acoustics);
    err = in->set(format, channels, sampleRate);
 ->
alsa_default.cpp
呼叫s_open函式
ALSAStreamOps::set
    if (rate && *rate > 0) {
        if (mHandle->sampleRate != *rate) {
            LOGE("%s L%d  mHandle->sampleRate = %d, return BAD_VALUE %d ", __FUNCTION__, __LINE__,   mHandle->sampleRate, BAD_VALUE);
            return BAD_VALUE;
        }
    }
E/AudioHardwareALSA( 1181): set L123  mHandle->sampleRate = 8000, return BAD_VALUE -22 // 如果取樣率不是8000,則返回BAD_VALUE
E/AudioHardwareALSA( 1181): openInputStream L314 in->set err = -22
// BAD_VALUE的定義是
BAD_VALUE           = -EINVAL,
#define EINVAL        3
按照以上定義,BAD_VALUE的值應該是-3,但log輸出的值是-22,很奇怪。

----------------------------------------------------------------------------------
二.錄音start函式的處理流程
1.如果是錄影,則錄影中的音訊錄製的呼叫順序是:
MPEG4Writer::start
->
MPEG4Writer::startWriterThread()
->
MPEG4Writer::startTracks
->
MPEG4Writer::Track::start
->
錄影時,video track是CameraSource,即呼叫CameraSource::start函式
audio track是AMRNBEncoder,即呼叫AMRNBEncoder::start函式
->
2.如果是單純的錄音操作,則直接走下面的路程:
AudioSource::start
->
AudioRecord::start()
->
IAudioRecord::start()
如果返回值為DEAD_OBJECT,則呼叫
->
AudioRecord::openRecord
  ->
  AudioFlinger::openRecord
  ->
  返回RecordHandle物件
  ->
  AudioFlinger::RecordHandle::start()
  ->
  AudioFlinger::RecordThread::start
  ->
  AudioSystem::startInput(mId);
  ->
  AudioPolicyService::startInput
  ->
  AudioPolicyManagerBase::startInput

如果AudioRecord::openRecord返回NO_ERROR,則繼續呼叫IAudioRecord::start()
如果IAudioRecord::start()返回NO_ERROR,則啟動ClientRecordThread執行緒。

----------------------------------------------------------------------------------
三.AudioRecord開始錄音的處理流程
1.frameworks\base\media\java\android\media\AudioRecord.java檔案中的
startRecording()函式
    // start recording
    synchronized(mRecordingStateLock) { // 一直處於同步狀態,同一時間只能有一個錄音
        if (native_start() == SUCCESS) { // 呼叫native方法
            mRecordingState = RECORDSTATE_RECORDING;
        }
    }
->
2.native_start對應frameworks\base\core\jni\android_media_AudioRecord.cpp檔案中的
android_media_AudioRecord_start 函式
取得AudioRecord物件lpRecorder,然後呼叫lpRecorder->start()的函式,開始錄音
->
3.frameworks\base\media\libmedia\AudioRecord.cpp檔案的
AudioRecord::start()函式
3.1 取得ClientRecordThread物件t
3.2 呼叫IAudioRecord物件mAudioRecord->start()
(1)如果返回DEAD_OBJECT,則執行AudioRecord::openRecord函式,呼叫IAudioFlinger的openRecord函式開啟錄音裝置,然後再執行mAudioRecord->start()開始錄音