audioflinger

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

Android 7.0 Audio: AudioFlinger介绍和初始

http://blog.csdn.net/xiashaohua/article/details/53818568

frameworks/av/services/audioflinger/Threads.cpp:3027:status_t AudioFlinger::PlaybackThread

frameworks/av/services/audioflinger/Tracks.cpp:879:void AudioFlinger::PlaybackThread::Track     AudioFlinger::ThreadBase::TrackBase

http://blog.csdn.net/droidphone/article/details/5951999

  • PlaybackTread::Track    // 用于普通播放,对应于应用层的AudioTrack
  • PlaybackThread::OutputTrack    // 用于多重设备输出,当蓝牙播放开启时使用
  • RecordThread::RecordTrack    // 用于录音,对应于应用层的AudioRecord

默认的播放线程是MixerThread,DuplicatingThread,它是MixerThread的子类。当系统中有两个设备要同时输出时,DuplicatingThread将被创建

Android Framework的音频子系统中,每一个音频流对应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到AudioFlinger中,由AudioFlinger把所有的AudioTrack进行混合(Mixer),然后输送到AudioHardware中进行播放,目前Android的Froyo版本设定了同时最多可以创建32个音频流,也就是说,Mixer最多会同时处理32个AudioTrack的数据流

  实际上,创建DuplicatingThread的工作是有AudioPolicyService中的AudioPolicyManager里发起的。主要是当蓝牙耳机和本机输出都开启时,AudioPolicyManager会做出以下动作:

  • 首先打开(或创建)蓝牙输出线程A2dpOutput
  • 以HardwareOutput和A2dpOutput作为参数,调用openDuplicateOutput,创建DuplicatingThread
  • 把属于STRATEGY_MEDIA类型的Track移到A2dpOutput中
  • 把属于STRATEGY_DTMF类型的Track移到A2dpOutput中
  • 把属于STRATEGY_SONIFICATION类型的Track移到DuplicateOutput中

结果是,音乐和DTMF只会在蓝牙耳机中输出,而按键音和铃声等提示音会同时在本机和蓝牙耳机中输出。

                                                                           图三  本机播放时的Thread和Track

                                                                        图四   蓝牙播放时的Thread和Track

建立联系的过程

下面的序列图展示了AudioTrack和AudioFlinger建立联系的过程:

                                                              图二 AudioTrack和AudioFlinger建立联系

解释一下过程:

  • Framework或者Java层通过JNI,new AudioTrack();
  • 根据StreamType等参数,通过一系列的调用getOutput();
  • 如有必要,AudioFlinger根据StreamType打开不同硬件设备;
  • AudioFlinger为该输出设备创建混音线程: MixerThread(),并把该线程的id作为getOutput()的返回值返回给AudioTrack;
  • AudioTrack通过binder机制调用AudioFlinger的createTrack();
  • AudioFlinger注册该AudioTrack到MixerThread中;
  • AudioFlinger创建一个用于控制的TrackHandle,并以IAudioTrack这一接口作为createTrack()的返回值;
  • AudioTrack通过IAudioTrack接口,得到在AudioFlinger中创建的FIFO(audio_track_cblk_t);
  • AudioTrack创建自己的监控线程:AudioTrackThread;

自此,AudioTrack建立了和AudioFlinger的全部联系工作,接下来,AudioTrack可以:

  • 通过IAudioTrack接口控制该音轨的状态,例如start,stop,pause等等;
  • 通过对FIFO的写入,实现连续的音频播放;
  • 监控线程监控事件的发生,并通过audioCallback回调函数与用户程序进行交互;

AudioFlinger.cpp

loadHwModule_l();//加载HAL模块{

 audio_hw_device_t *dev;
    int rc = load_audio_interface(name, &dev);

mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));//dev ==> AudioHwDevice->hwDevice();

}

load_audio_interface(){

hw_get_module_by_class

audio_hw_device_open;//初始化输出设备

}

openOutput_l();//打开输出设备{

AudioHwDevice->openOutputStream();

}

AudioStreamOut.cpp

open();{

hwDev()->open_output_stream();//hwDev()  <== AudioHwDevice->hwDevice();

}

HAL: hardware/libhardware/Hardware.c

hw_get_module_by_class

hardware/xxx/audio/hal/Android.mk:259:LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)

audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)

03-13 10:53:10.662   515   515 I AudioFlinger: loadHwModule() Loaded primary audio interface from xxx Audio HAL (audio) handle 10

03-13 10:53:10.800   515   515 I bt_a2dp_hw: adev_open:  adev_open in A2dp_hw module
03-13 10:53:10.800   515   515 I AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 18
03-13 10:53:10.805   515   515 I AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 26
03-13 10:53:10.808   515   515 I r_submix: adev_open(name=audio_hw_if)
03-13 10:53:10.809   515   515 I r_submix: adev_init_check()
03-13 10:53:10.809   515   515 I AudioFlinger: loadHwModule() Loaded r_submix audio interface from Wifi Display audio HAL (audio) handle 34

03-13 11:43:20.291   519   519 E AudioFlinger: int android::load_audio_interface(const char *, audio_hw_device_t **) couldn't load audio hw module audio.primary (Success)

03-13 11:43:20.903   519   519 E AudioFlinger: int android::load_audio_interface(const char *, audio_hw_device_t **) couldn't load audio hw module audio.a2dp (Success)
03-13 11:43:20.903   519   519 I bt_a2dp_hw: adev_open:  adev_open in A2dp_hw module
03-13 11:43:20.903   519   519 I AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 18
03-13 11:43:20.908   519   519 E AudioFlinger: int android::load_audio_interface(const char *, audio_hw_device_t **) couldn't load audio hw module audio.usb (Success)
03-13 11:43:20.908   519   519 I AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 26
03-13 11:43:20.923   519   519 E AudioFlinger: int android::load_audio_interface(const char *, audio_hw_device_t **) couldn't load audio hw module audio.r_submix (Success)

audio_hw_device_t **dev            struct audio_hw_device** device

hardware\libhardware\include\hardware\audio.h

/** convenience API for opening and closing a supported 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,
                                 (struct hw_device_t**)device);
}

 

hardware/xxx/audio/hal/audio_hw.c

static struct hw_module_methods_t hal_module_methods = {
    .open = adev_open,
};

struct audio_module HAL_MODULE_INFO_SYM = {
    .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 = "xxx Audio HAL",
        .author = "The Linux Foundation",
        .methods = &hal_module_methods,
    },
};

 

hardware/xxx/audio/hal/audio_extn/a2dp.c

hardware/libhardware/modules/usbaudio/audio_hal.c

static struct hw_module_methods_t hal_module_methods = {
    .open = adev_open,
};

struct audio_module HAL_MODULE_INFO_SYM = {
    .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 = "USB audio HW HAL",
        .author = "The Android Open Source Project",
        .methods = &hal_module_methods,
    },
};

hardware/libhardware/modules/audio_remote_submix/audio_hw.cpp

static struct hw_module_methods_t hal_module_methods = {
    /* open */ adev_open,
};

struct audio_module HAL_MODULE_INFO_SYM = {
    /* 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 */               "Wifi Display audio HAL",
        /* author */             "The Android Open Source Project",
        /* methods */            &hal_module_methods,
        /* dso */                NULL,
        /* reserved */           { 0 },
    },
};

猜你喜欢

转载自blog.csdn.net/lf12345678910/article/details/61414597
今日推荐