mtk audio

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010481276/article/details/89225862

之前的版本,AF在Main_MediaServer.cpp里面启动,在android N,AF在main_audioserver.cpp里面启动,
在这里插入图片描述
AudioFlinger::instantiate()并不属于AudioFlinger的内部类,而是BinderService类的一个实现包括AudioFlinger,AudioPolicy等在内的几个服务都继承自这个统一的Binder的服务类,具体实现在BinderService.h中

// frameworks/native/include/binder/BinderService.h
static status_t publish(bool allowIsolated = false) {
sp sm(defaultServiceManager());
//SERVICE是文件中定义的一个模板,AudioFlinger调用了instantiate()函数,
//所以当前的SERVICE为AudioFlinger
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}

static void instantiate() { publish(); }

可以看出publish()函数所做的事获取到ServiceManager的代理,然后new一个调用instantiate的那个service的对象并把它添加到ServiceManager中。
所以下一步就是去分析AudioFlinger的构造函数了

AF是执行,APS是策略的规划者

audio的所有设备在AudioPolicyManager的构造函数里加载audio_policy.conf

void AudioPolicyService::onFirstRef()
{
    {
        Mutex::Autolock _l(mLock);

        // start tone playback thread
        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
        // start audio commands thread
        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
        // start output activity command thread
        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);

        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

从这可以看出AudioSystem是与其他接口的中间人如蓝牙或有线耳机能过 AudioSystem.setDeviceConnectionState接口来设置设备在audio系统的连接状态
过程中还创建了mtk自已的动作

extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    audiopolicymanagerMTK = (AudioPolicyManagerCustomInterface*) new AudioPolicyManagerCustomImpl();  // MTK_AUDIO
    return new AudioPolicyManager(clientInterface, audiopolicymanagerMTK);
}

在这里插入图片描述
mHwModules从配置文件中audio_policy.conf收集

    for (size_t i = 0; i < mHwModules.size(); i++) {
        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
        if (mHwModules[i]->mHandle == 0) {
            ALOGW("could not open HW module %s", mHwModules[i]->getName());
            continue;
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return AUDIO_MODULE_HANDLE_NONE;
    }

    return af->loadHwModule(name);
}

AudioPolicyManager的构造函数里用的是mpClientInterface的接口最终用的是AF的loadHwModule

// loadHwModule_l() must be called with AudioFlinger::mLock held
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
        if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
            ALOGW("loadHwModule() module %s already loaded", name);
            return mAudioHwDevs.keyAt(i);
        }
    }

    sp<DeviceHalInterface> dev;

    int rc = mDevicesFactoryHal->openDevice(name, &dev);

最终call到

status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    audio_hw_device_t *dev;
    status_t rc = load_audio_interface(name, &dev);
    if (rc == OK) {
        *device = new DeviceHalLocal(dev);
    }
    return rc;
}
static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
    const hw_module_t *mod;
    int rc;

    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
    if (rc) {
        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
        goto out;
    }
    rc = audio_hw_device_open(mod, dev);
    if (rc) {
        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
        goto out;
    }
    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
        rc = BAD_VALUE;
        audio_hw_device_close(*dev);
        goto out;
    }
    return OK;

out:
    *dev = NULL;
    return rc;
}

加载并打开audio_hw_device

static inline int audio_hw_device_open(const struct hw_module_t* module,
                                       struct audio_hw_device** device)
{
    return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,
                                 TO_HW_DEVICE_T_OPEN(device));
}

struct legacy_audio_module HAL_MODULE_INFO_SYM = {
    .module = {
        .common = {
            .tag = HARDWARE_MODULE_TAG,
            .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
            .hal_api_version = HARDWARE_HAL_API_VERSION,
            .id = AUDIO_HARDWARE_MODULE_ID,
            .name = "MTK Audio HW HAL",
            .author = "MTK",
            .methods = &legacy_audio_module_methods,
            .dso = NULL,
            .reserved = {0},
        },
    },
    static struct hw_module_methods_t legacy_audio_module_methods = {
        .open = legacy_adev_open
    };

最终执行legacy_adev_open,打开执行这个 "MTK Audio HW HAL"接口的open,这里作一些针对底层hal接口的赋值动作

结合AF中的
audio_interfaces加载三大接口与对应的so与节点下面的设备

#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary"
#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp"
#define AUDIO_HARDWARE_MODULE_ID_USB "usb"


static const char * const audio_interfaces[] = {
    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
    AUDIO_HARDWARE_MODULE_ID_A2DP,
    AUDIO_HARDWARE_MODULE_ID_USB,
};

与配置文件audio_policy.conf
遍历节点primary加载audio.primary.mt6580.so

 primary {
  global_configuration {
      attached_output_devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE
      default_output_device AUDIO_DEVICE_OUT_SPEAKER
      attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_FM_TUNER|AUDIO_DEVICE_IN_VOICE_CALL
      audio_hal_version 3.0 
    }   
  devices {
      headset {
        type AUDIO_DEVICE_OUT_WIRED_HEADSET
        gains {
          gain_1 {
            mode AUDIO_GAIN_MODE_JOINT
            channel_mask AUDIO_CHANNEL_OUT_

遍历节点a2dp加载audio.a2dp.default.so

  a2dp {
  global_configuration {
      audio_hal_version 2.0 
    }   
    outputs {
      a2dp {
        sampling_rates 44100
        channel_masks AUDIO_CHANNEL_OUT_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_OUT_ALL_A2DP
      }   
    }   
  inputs {

遍历节点usb加载audio.usb.mt6580.so

  usb {
  global_configuration {
      audio_hal_version 2.0 
    }   
    outputs {
      usb_accessory {
        sampling_rates 44100
        channel_masks AUDIO_CHANNEL_OUT_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_OUT_USB_ACCESSORY
      }   
      usb_device {
        sampling_rates dyna

在AF中加载三大接口

audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
    if (name == NULL) {
        return AUDIO_MODULE_HANDLE_NONE;
    }
    if (!settingsAllowed()) {
        return AUDIO_MODULE_HANDLE_NONE;
    }
    Mutex::Autolock _l(mLock);
    return loadHwModule_l(name);
}

从audio_policy.conf文件中可以发现,系统包含了primary、a2dp、usb等音频接口,对应着系统中的audio.<primary/a2dp/usb>..so。每个音频接口中又包含了若干个outputs & inputs,并且每个output or input又包含了若干个devices,且还有采样频率,声道数等信息。这些devices信息、采样频率信息 & 声道信息等都会保存在各自module的IOProfile中。按上文中audio_policy.conf配置文件所描述,系统最后会生成6个modules(eg.primary,a2dp,hdmi,r_submix,hs_usb & usb)以及7个outputs。以AUDIO_DEVICE_OUT_SPEAKER为例,该device会定义在primary模块中outputs所属的IOProfile1中,其它设备依次类推

audiomanager.setParameters会call到AudioFlinger::setParameters

status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d",
            ioHandle, keyValuePairs.string(), IPCThreadState::self()->getCallingPid());

    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
    if (ioHandle == AUDIO_IO_HANDLE_NONE) {
        Mutex::Autolock _l(mLock);
        // result will remain NO_INIT if no audio device is present
        status_t final_result = NO_INIT;
        {
            AutoMutex lock(mHardwareLock);
            mHardwareStatus = AUDIO_HW_SET_PARAMETER;
            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
                sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
                status_t result = dev->setParameters(keyValuePairs);
                // return success if at least one audio device accepts the parameters as not all
                // HALs are requested to support all parameters. If no audio device supports the
                // requested parameters, the last error is reported.
            status_t result = **dev->setParameters**(keyValuePairs);

对于HAL以上的逻辑,只需找到ID和相应的名字即可找到需要使用的模块,即使你有100个厂商,100个厂商又有100个模块,还是依照明确的标准去走,这个就是面向对象编程中的一个核心理念,面向接口编程,不管你逻辑如何变,接口一定不能变!这样就能确保软件的低耦合,可移植

.id = AUDIO_HARDWARE_MODULE_ID,

.name = “MTK Audio HW HAL”,

vendor/mediatek/proprietary/hardware/audio/common/aud_drv/audio_hw_hal.cpp

ladev->device.set_parameters = adev_set_parameters; 
    
  static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) {
#ifdef AUDIO_HAL_PROFILE_ENTRY_FUNCTION
        AudioAutoTimeProfile _p(__func__);
#endif
        struct legacy_audio_device *ladev = to_ladev(dev);
        return ladev->hwif->setParameters(String8(kvpairs));
    }

其中
ladev->hwif->setParameters(String8(kvpairs));
ladev->hwif = createMTKAudioHardware();

AudioMTKHardwareInterface *AudioMTKHardwareInterface::create() {
    /*
     * FIXME: This code needs to instantiate the correct audio device
     * interface. For now - we use compile-time switches.
     */
    AudioMTKHardwareInterface *hw = 0;
    char value[PROPERTY_VALUE_MAX];

    ALOGV("Creating MTK AudioHardware");
    //hw = new android::AudioALSAHardware();
    hw = android::AudioALSAHardware::GetInstance();

    return hw;

}

extern "C" AudioMTKHardwareInterface *createMTKAudioHardware() {
    /*
     * FIXME: This code needs to instantiate the correct audio device
     * interface. For now - we use compile-time switches.
     */
    return AudioMTKHardwareInterface::create();

}

即ladev->hwif是AudioALSAHardware中的实例,所调用的为它的方法
即最终所调用的是

status_t AudioALSAHardware::setParameters(const String8 &keyValuePairs) {

AudioALSAHardware::setParameters()是Audio setParameters()的最终执行函数

如下数据结构中 struct audio_stream_out stream;为AF/APS需要用的,属于平台无关数据

struct legacy_stream_out {
        struct audio_stream_out stream;

    AudioMTKStreamOutInterface *legacy_out;
};

在这里插入图片描述
vendor/mediatek/proprietary/hardware/audio/common/aud_drv/audio_hw_hal.cpp

out->legacy_out = ladev->hwif->openOutputStreamWithFlags(devices, flags,
                                                                 (int *) &config->format,
                                                                 &config->channel_mask,
                                                                 &config->sample_rate, &status);

AudioALSAHardware.cpp

AudioMTKStreamOutInterface *AudioALSAHardware::openOutputStreamWithFlags(uint32_t devices,
                                                                         audio_output_flags_t flags,
                                                                         int *format,
                                                                         uint32_t *channels,
                                                                         uint32_t *sampleRate,
                                                                         status_t *status) {
    return mStreamManager->openOutputStream(devices, format, channels, sampleRate, status, flags);
    //AudioMTKStreamOutInterface *AudioALSAStreamManager::openOutputStream(

}

之后
AudioALSAStreamManager.cpp中如下返回的是AudioALSAStreamOut

AudioMTKStreamOutInterface *AudioALSAStreamManager::openOutputStream(

则out_write对应的out->legacy_out为AudioALSAStreamOut则struct audio_stream_out *stream的out_write就变为AudioALSAStreamOut::write()

    static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
                             size_t bytes) {
#ifdef AUDIO_HAL_PROFILE_ENTRY_FUNCTION
        AudioAutoTimeProfile _p(__func__, AUDIO_HAL_FUNCTION_WRITE_NS);
#endif
        struct legacy_stream_out *out =
                reinterpret_cast<struct legacy_stream_out *>(stream);
        return out->legacy_out->write(buffer, bytes);
    }

在写的函数AudioALSAStreamOut::write()中发现为standby模式会重新打开open会调用如下开启线程
AudioALSAStreamOut->open

./vendor/mediatek/proprietary/hardware/audio/common/V3/aud_drv/AudioALSAStreamManager.cpp

createPlaybackHandler

AudioALSAPlaybackHandlerBTCVSD

createCaptureHandler
AudioALSACaptureHandlerBT

使用栈跟踪代码cpp

在你的模块的Android.mk添加libutils动态库:
LOCAL_SHARED_LIBRARIES :=

libutils
(2). 在你需要获取native调用栈的位置定义android::CallStack对象,即可将调用栈输出到main log里:
#include <utils/CallStack.h> /* add this line /
android::CallStack stack(“xxxx”); /
add this code at necessary place /
注意带
android namespace要在前面加#include <utils/CallStack.h> /
add this line */,否则不生效
如:

#define calc_time_diff(x,y) ((x.tv_sec - y.tv_sec )+ (double)( x.tv_nsec - y.tv_nsec ) / (double)1000000000)
#include <utils/CallStack.h> /* add this line */

namespace android {

猜你喜欢

转载自blog.csdn.net/u010481276/article/details/89225862
MTK