【Audio Framework】AudioFlingerの起動と作成

1 AudioFlingerクラスを作成する

AudioFlinger は、audioserver プロセスの開始時に次のように構築および初期化されます。

int main(int argc __unused, char **argv)
{
    ...
    AudioFlinger::instantiate();
    ...
}

1.1 AudioFlingerはBinderServiceを継承した派生クラスであり、BinderServiceのデータメンバとメンバ関数を継承しています。AudioFlinger::instantiate() は、実際には BinderService::instantiate() 関数を呼び出し、最後にpublish() 関数を呼び出します。

template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    }
...
    static void instantiate() { publish(); }
..
};

1.2 sp<IServiceManager> sm(defaultServiceManager()) を通じて IServiceManager オブジェクトを取得します。これは、ServiceManager と通信し、AudioFlinger サービスを登録するためです。デザインはシングルトンパターンを採用。

1.3 addService 関数は、Binder サービスを登録するために使用されます。

virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                bool allowIsolated = false,
                                int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;

sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags)

1.4 バインダーサービス名:SERVICE::getServiceName(),AudioFlinger::getServiceName()

 static const char* getServiceName() ANDROID_API { return "media.audio_flinger"; }

1.5 new SERVICE()、テンプレート クラス、new AudioFlinger() と同等。クラスが作成されると、そのコンストラクターが呼び出されます。

1.6 AudioFlinger を addService 関数の const sp<IBinder>& サービス パラメータとして渡し、それを強参照ポインタとして定義します。最初に参照されると、その onFirstRef 関数が呼び出されます。

2 AudioFlinger::AudioFlinger() コンストラクター

    AudioFlinger::AudioFlinger()
        : BnAudioFlinger(),  //
          mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
          mPrimaryHardwareDev(NULL),
          mAudioHwDevs(NULL),
    ...
    {
      ..
    	//2.2 
        mDevicesFactoryHal = DevicesFactoryHalInterface::create(); 
    	//2.3
        mEffectsFactoryHal = EffectsFactoryHalInterface::create();

    	...
    }

2.1 メンバーの初期化

BnAudioFlinger基本クラスのデフォルトのコンストラクターを呼び出します。mMediaLogNotifier、mPrimaryHardwareDev、mAudioHwDevs などのメンバー変数の初期化。

2.2 オーディオ HAL との接続を確立してデバイスを開く機能を取得する

mDevicesFactoryHal = DevicesFactoryHalInterface::create() 、名前から大まかに 2 つの情報がわかります。関数は HAL デバイスを開くことに関連している必要があり、DevicesFactoryHalInterface は、mDevicesFactoryHal を作成するために create メソッドを呼び出す Factory ファクトリ クラスです。コード呼び出しプロセスは次のとおりです。


// frameworks/av/media/libaudiohal/DevicesFactoryHalInterface.cpp
//根据IDevicesFactory的版本(HAL provider进程 android.hardware.audio)调用createDevicesFactoryHal,其实最终是同一个函数。
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
    if (hardware::audio::V5_0::IDevicesFactory::getService() != nullptr) {
        return V5_0::createDevicesFactoryHal();
    }
    if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
        return V4_0::createDevicesFactoryHal();
    }
    if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
        return V2_0::createDevicesFactoryHal();
    }
    return nullptr;
}
//DevicesFactoryHalHybrid.h	frameworks\av\media\libaudiohal\impl
sp<DevicesFactoryHalInterface> createDevicesFactoryHal() {
    return new DevicesFactoryHalHybrid();
}

上記のコードから、 mDevicesFactoryHalHybrid クラスが実際に作成されていることがわかります: mDevicesFactoryHal = new DevicesFactoryHalHybrid()。これまでのところ、Audio HAL との関連付けを確認して、DevicesFactoryHalHybrid クラスのコンストラクターを分析することはできません。

DevicesFactoryHalHybrid.cpp	frameworks\av\media\libaudiohal\impl
DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
        : mLocalFactory(new DevicesFactoryHalLocal()),
          mHidlFactory(new DevicesFactoryHalHidl()) {
}

DevicesFactoryHalHybrid.cpp	frameworks\av\media\libaudiohal\impl
status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0 &&
        strcmp(AUDIO_HARDWARE_MODULE_ID_HEARING_AID, name) != 0) {
        return mHidlFactory->openDevice(name, device);
    }
    return mLocalFactory->openDevice(name, device);
}

2.2.1 新しい DevicesFactoryHalLocal() と新しい DevicesFactoryHalHidl() は、mLocalFactory と mHidlFactory という 2 つのクラスを作成します。
2.2.2 mLocalFactory、DevicesFactoryHalLocal::openDevice は、load_audio_interface を呼び出してオーディオ HAL ライブラリ ファイルをローカル (現在のプロセス) で開き、オーディオ HAL の audio_hw_device_t 構造体を取得して、それを DeviceHalLocal クラスにカプセル化します。これにより、AudioFlinger は、オーディオ装置。
2.2.3 mHidlFactory は、HAL ライブラリをローカルに直接ロードしませんが、HIDL を介してクロスプロセス呼び出しを行います。DevicesFactoryHalHidl コンストラクターは次のとおりです。

DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
    //1 defaultFactory函数定义,获得IDevicesFactory对象
    sp<IDevicesFactory> defaultFactory{IDevicesFactory::getService()};
    if (!defaultFactory) {
        ALOGE("Failed to obtain IDevicesFactory/default service, terminating process.");
        exit(1);
    }
    //2 获得IDevicesFactory对象,并保存在mDeviceFactories,使当前类具备与DevicesFactory通信的能力
    mDeviceFactories.push_back(defaultFactory);
    if (MAJOR_VERSION >= 4) {
        // The MSD factory is optional and only available starting at HAL 4.0
        sp<IDevicesFactory> msdFactory{IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD)};
        if (msdFactory) {
            mDeviceFactories.push_back(msdFactory);
        }
    }
    for (const auto& factory : mDeviceFactories) {
        // It is assumed that the DevicesFactoryHalInterface instance is owned
        // by AudioFlinger and thus have the same lifespan.
        factory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
    }
}

DevicesFactoryHalHidl::openDevice は、HIDL を通じて IDevice を取得し、それを DeviceHalHidl クラスにカプセル化します。これにより、AudioFlinger がオーディオ デバイスを制御できるようになります。関係の概略図は次のとおりです。

    
     audioserver                                     [email protected]
	 _____________________________                   _______________________
    |                             |                 |                       |
    |  +----------------------+   |                 |  +------------------+ |
    |  |DevicesFactoryHalHIDL +------IDevicesFactory-->| DevicesFactory   | |
    |  +----------------------+   |  openDevice     |  +---+--------------+ |  
    |                             |                 |      |                |
    |  +----------------------+   |                 |______|________________| 
    |  |DevicesFactoryHalLocal|   |                        |
    |  +---------------------++   |                        |
    |________________________|____|                        | openDevice
    DevicesFactoryHalHybrid  |                             |
    mDevicesFactoryHal       | openDevice                  |
    AudioFlinger             |                             |
                          +--+------+                 +----+----+
                          |Auido HAL|                 |Auido HAL|
                          +---------+                 +---------+
————————————————————————————————————————————————————————————————————————————————————
	______________________________________________________________________ 
    | 					HW Binder(Linux Kernel)                           | 
    |_____________________________________________________________________| 

2.2.4 a2dp およびHearing_Aid Audio HAL を開く場合は DevicesFactoryHalLocal を使用し、それ以外の場合は DevicesFactoryHalHidl を使用します。

概要: mDevicesFactoryHal = DevicesFactoryHalInterface::create() 呼び出しは、AudioFlinger と Audio HAL の間の接続を確立します。AudioFlinger は、mDevicesFactoryHal メンバーを通じて Audio HAL を開いて、オーディオ デバイスを制御する機能を取得できます。この時点では、AudioFlinger はまだ Audio を開いていないことに注意してください。ステージ、HAL。

2.3 AudioEffect サウンド制御チャネルの確立

Android は、一連のオーディオ処理フレームワーク Android Audio Effect を提供します。これにより、開発者はイコライザー、ステレオ エンハンサー、リバーブなどのさまざまなオーディオ エフェクトをアプリケーションに簡単に追加できます。Audio HAL と同様に、オーディオ エフェクト アルゴリズムもライブラリの形式でロードされます。
mEffectsFactoryHal = EffectsFactoryHalInterface::create()呼び出しプロセスは DevicesFactoryHalInterface とほぼ同様です。

EffectsFactoryHalInterface.cpp	frameworks\av\media\libaudiohal	
sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
    if (hardware::audio::effect::V5_0::IEffectsFactory::getService() != nullptr) {
        return effect::V5_0::createEffectsFactoryHal();
    }
    if (hardware::audio::effect::V4_0::IEffectsFactory::getService() != nullptr) {
        return effect::V4_0::createEffectsFactoryHal();
    }
    if (hardware::audio::effect::V2_0::IEffectsFactory::getService() != nullptr) {
        return effect::V2_0::createEffectsFactoryHal();
    }
    return nullptr;
}

EffectsFactoryHalHidl.h	frameworks\av\media\libaudiohal\impl
sp<EffectsFactoryHalInterface> createEffectsFactoryHal() {
    return new EffectsFactoryHalHidl();
}

mEffectsFactoryHal = new EffectsFactoryHalHidl();と同等です。

2.3.1 EffectsFactoryHalHidl コンストラクター

EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
    //获得IEffectsFactory对象,建立与EffectsFactory通信的通道
    mEffectsFactory = IEffectsFactory::getService();
    if (mEffectsFactory == 0) {
        ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
        exit(1);
    }
}

2.3.2 EffectsFactory Binder サービスも [email protected] プロセス空間にあり、関係図は次のとおりです。

	audioserver                                     [email protected]
	 _____________________________                   _______________________
    |                             |                 |                      |
    |  +----------------------+   |                 |  +------------------+|
    |  |EffectsFactoryHalHidl +------IEffectsFactory-->| EffectsFactory   || 
    |  +----------------------+   |                 |  +-----------+------+|  
    |                             |                 |              |       |
	|_____________________________|                 |______________|_______|
    mEffectsFactoryHal       createEffect/queryAllDescriptors/..   |  		
    AudioFlinger                      							   |	
															+------+---+
															|libeffects|
															+----------+
—————————————————————————————————————————————————————————————————————————————
	+----------------------------------------------------------------------+ 
    | 					HW Binder(Linux Kernel)                            |
 	+----------------------------------------------------------------------+  

3 AudioFlinger::onFirstRef() 関数

static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);

void AudioFlinger::onFirstRef()
{
...
    char val_str[PROPERTY_VALUE_MAX] = { 0 };
    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
        uint32_t int_val;
        if (1 == sscanf(val_str, "%u", &int_val)) {
            mStandbyTimeInNsecs = milliseconds(int_val);
            ALOGI("Using %u mSec as standby time.", int_val);
        } else {
            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
            ALOGI("Using default %u mSec as standby time.",
                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
        }
    }
...

}

mStandbyTimeInNsecs が初期化され、property_get() 関数を呼び出してシステム プロパティから「ro.audio.flinger_standbytime_ms」プロパティの値が取得されます。値を取得できる場合は、それを mStandbyTimeInNsecs に割り当てます。それ以外の場合は、デフォルト値の mStandbyTimeInNsecs (3 秒) を使用します。

再生スレッドが mStandbyTimeInNsecs の期間内にクライアント (オーディオトラック) からデータを受信しない場合にのみ、スタンバイ コマンドをオーディオ HAL に送信し、オーディオ ループ全体の終了を制御します。

おすすめ

転載: blog.csdn.net/Q_Lee/article/details/131498066