WebRTC源码之音频设备播放流程源码分析

WebRTC源码之音频设备播放流程源码分析

WebRTC源码之音频设备播放流程源码分析

  • WebRTC源码之音频设备播放流程源码分析
  • 前言
  • ADM
    • 一、 ADM的作用即创建
      • 1、Audio Device Module 类关系图
      • 2、创建ADM的时机
      • 3、创建ADM的过程
    • 二、 WIndows Audio Core 基本概念
      • 1、从Window Vista开始提供了 Core Audio API
      • 2、 其运行在用户空间的
      • 3、Core Audio 是DirectSound和WaveXxx的基础
      • 4、Win7 对Core Audio API做了增强的
      • 5、Core Audio 的特性
      • 6、Core Audio关系图
      • 7、音频设备种类
      • 8、音频终端设备
      • 9、音频适配设备
    • 三、 Audio Core API
      • 1、MMDevice API,最常用到的接口
        • ①、MMDevice API 的作用
        • ②、MMDevice API的组成
        • ③、IMMDeviceEnumerator接口
        • ④、创建IMMDeviceEnumerator接口
        • ⑤、COM组件
        • ⑥、IMMDeviceEnumerator支持的方法
      • 2、Windows Audio Session API (WASAPI)
      • 3、Device Topology API(更高级的API)
      • 4、EndpointVolume API( 修改主声音或独享方式使用)
    • 四、ADM的初始化与设备管理
    • 五、AudioState 的作用
    • 六、音频播放设备的初始化
    • 七、音频播放设备任何工作
    • 八、音频采集设备的初始化
    • 九、音频采集设备任何工作
    • 十、采集后的数据交给谁?
    • 十一、播放设置从哪儿获取数据?
  • InitPlay基础知识
    • 一、几个主要的状态值
    • 二、音频的数据结构
    • 三、 音频接口 IAudioClient 接口
      • 1、IAuidoClient的几个重要方法
        • ①、初始化音频流
        • ②、GetService方法
  • 总结:


WebRTC专题开嗨鸭 !!!

一、 WebRTC 线程模型

1、WebRTC中线程模型和常见线程模型介绍

2、WebRTC网络PhysicalSocketServer之WSAEventselect模型使用

二、 WebRTC媒体协商

三、 WebRTC 音频数据采集

1、WebRTC源码之音频设备播放流程源码分析

2、WebRTC源码之音频设备的录制流程源码分析

四、 WebRTC 音频引擎(编解码和3A算法)

五、 WebRTC 视频数据采集

六、 WebRTC 视频引擎( 编解码)

七、 WebRTC 网络传输

1、WebRTC的ICE之STUN协议

2、WebRTC的ICE之Dtls/SSL/TLSv1.x协议详解

八、 WebRTC服务质量(Qos)

1、WebRTC中RTCP协议详解

2、WebRTC中RTP协议详解

3、WebRTC之NACK、RTX 在什么时机判断丢包发送NACK请求和RTX丢包重传

4、WebRTC源码之视频质量统计数据的数据结构分析

九、 NetEQ

十、 Simulcast与SVC

前言

WebRTC音频引擎启动基本流程图
WebRTC源码之音频设备播放流程源码分析_第1张图片

ADM

一、 ADM的作用即创建

1、Audio Device Module 类关系图

WebRTC源码之音频设备播放流程源码分析_第2张图片

2、创建ADM的时机

WebRTC源码之音频设备播放流程源码分析_第3张图片

3、创建ADM的过程

WebRTC源码之音频设备播放流程源码分析_第4张图片

二、 WIndows Audio Core 基本概念

1、从Window Vista开始提供了 Core Audio API

2、 其运行在用户空间的

3、Core Audio 是DirectSound和WaveXxx的基础

4、Win7 对Core Audio API做了增强的

5、Core Audio 的特性

①、低延迟

②、提高了可靠性,API从内核层移到了用户层

③、安全性更高

等等…

6、Core Audio关系图

WebRTC源码之音频设备播放流程源码分析_第5张图片

MMDevice API

WAS API

DeviceTopology API

EndpointVolume API

Core Audio 有两种模式: 同享模式和独享模式

7、音频设备种类

  1. 音频终端设备,指外设
  2. 音频适配器设备,一般集成在主板上,接供PCI/PNP插口

8、音频终端设备

  1. 扬声器
  2. 麦克风
  3. 辅助输入设备(耳机)

9、音频适配设备

  1. 不行输出设备(数模转换器)
  2. 输出控制设备(音量和静音控件)
  3. 波输入设备(模数转换器)
  4. 输入控制设备(输入音量控制器,多数复用器)

WebRTC源码之音频设备播放流程源码分析_第6张图片

三、 Audio Core API

分下面四种API

1、MMDevice API,最常用到的接口

①、MMDevice API 的作用

  1. 获得音频终端设备得Client
  2. 决定音频终端设备的能力
  3. 能为音频终端设备创建驱动实例

②、MMDevice API的组成

  1. IMMDevice,代表一个音频设备
  2. IMMDeviceCollection,音频设备集
  3. IMMDeviceEnumerator,用于枚举音频设备
  4. IMMEndpoint,代表一个音频终端设备

③、IMMDeviceEnumerator接口

  1. 它是IMMDevice API种最关键的接口
  2. 通过它可以获得IMMDevice接口
  3. 通过它可以获取IMMDeviceCollection接口

④、创建IMMDeviceEnumerator接口

⑤、COM组件

  1. 它是一个小的,可单独运行的程序;使用时类似一个API
  2. 应用程序可以通过多个COM组件的构成
  3. COM组件有可复用、动态更新、灵活等优点
要记住
  1. 两个COM对象能实现相同的接口

    通过CLSID找到组件

    通过IID找到COM组件种的接口

  2. 每个COM组件对象可以实现多个接口

⑥、IMMDeviceEnumerator支持的方法

  1. GateDefaultAudioEndpoint获取默认设备
  2. EnumAudioEndpoint枚举音频设备

等等

WebRTC源码之音频设备播放流程源码分析_第7张图片
WebRTC源码之音频设备播放流程源码分析_第8张图片

2、Windows Audio Session API (WASAPI)

3、Device Topology API(更高级的API)

4、EndpointVolume API( 修改主声音或独享方式使用)

四、ADM的初始化与设备管理

五、AudioState 的作用

六、音频播放设备的初始化

七、音频播放设备任何工作

八、音频采集设备的初始化

九、音频采集设备任何工作

十、采集后的数据交给谁?

十一、播放设置从哪儿获取数据?

InitPlay基础知识

一、几个主要的状态值

状态 默认值 作用
_playing false 是否处于播放状态
_playIsinitialized false 是否对播放参数进行了设置
_buildInAecEnabled false 是否启用了硬件AEC功能
_recIsInitiaized false 是否对录录制参数进行了设备
_recording false 是否处理录制状态
_speakerIsInitialized false 是否对扬声器进行了初始化
_microphoneIsIntialized false 是否对microphone进行了初始化

二、音频的数据结构

/* general extended waveform format structure
   Use this for all NON PCM formats
   (information common to all formats)
*/
#ifndef _WAVEFORMATEX_
#define _WAVEFORMATEX_

typedef struct tWAVEFORMATEX
{
    WORD    wFormatTag;        /* 设置声音格式类型 PCM  format type  */
    WORD    nChannels;         /* 设置通道数 number of channels (i.e. mono, stereo...)   */
    DWORD   nSamplesPerSec;    /* 设置采样率  sample rate */
    DWORD   nAvgBytesPerSec;   /* 设置每秒平均字节数 for buffer estimation */
    WORD    nBlockAlign;       /* 设置对齐字节数 block size of data */
    WORD    wBitsPerSample;    /*设置每个采样的大小(位深) Number of bits per sample of mono data */
    WORD    cbSize;            /* 额外消息大小 The count in bytes of the size of
                                    extra information (after cbSize) */

} WAVEFORMATEX;
typedef WAVEFORMATEX       *PWAVEFORMATEX;
typedef WAVEFORMATEX NEAR *NPWAVEFORMATEX;
typedef WAVEFORMATEX FAR  *LPWAVEFORMATEX;
#endif /* _WAVEFORMATEX_ */

#ifdef GUID_DEFINED

三、 音频接口 IAudioClient 接口

  1. 该接口属于WASAPI
  2. 该接口能够再音频应用程序和音频引擎之间采集音频流
  3. 也能再应用程序和设备的硬件缓冲区之间创建音频流
音频设备客户端分为两种分别:
  1. 采集客户端
  2. 扬声器客户端

 MIDL_INTERFACE("1CB9AD4C-DBFA-4c32-B178-C2F568A703B2")
    IAudioClient : public IUnknown
    {
    public:
         
          //        TODO@chensong 2022-07-24 初始化音频流
          ///
          /**
          * @param AUDCLNT_SHAREMODE : 共享模式/独占模式
          * @param DWORD             : 控制流创建的flag
          * @param REFERENCE_TIME    : 请求缓冲区的大小
          * @param REFERENCE_TIME    : 周期时间
          * @param WAVEFORMATEX      : 数据格式
          * @param LPCGUID           : Audio Session 的 GUID       
          * @return
          */
          
          /
          // StreamFlags 参数类型解释:
          // AUDCLNT_STREAMFLAGS_LOOPBACK		: 
          // AUDCLNT_STREAMFLAGS_EVENTCALLBACK	:
          // ...
        virtual HRESULT STDMETHODCALLTYPE Initialize( 
            /* [annotation][in] */ 
            _In_  AUDCLNT_SHAREMODE ShareMode,
            /* [annotation][in] */ 
            _In_  DWORD StreamFlags,
            /* [annotation][in] */ 
            _In_  REFERENCE_TIME hnsBufferDuration,
            /* [annotation][in] */ 
            _In_  REFERENCE_TIME hnsPeriodicity,
            /* [annotation][in] */ 
            _In_  const WAVEFORMATEX *pFormat,
            /* [annotation][in] */ 
            _In_opt_  LPCGUID AudioSessionGuid) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetBufferSize( 
            /* [annotation][out] */ 
            _Out_  UINT32 *pNumBufferFrames) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetStreamLatency( 
            /* [annotation][out] */ 
            _Out_  REFERENCE_TIME *phnsLatency) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetCurrentPadding( 
            /* [annotation][out] */ 
            _Out_  UINT32 *pNumPaddingFrames) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE IsFormatSupported( 
            /* [annotation][in] */ 
            _In_  AUDCLNT_SHAREMODE ShareMode,
            /* [annotation][in] */ 
            _In_  const WAVEFORMATEX *pFormat,
            /* [unique][annotation][out] */ 
            _Out_opt_  WAVEFORMATEX **ppClosestMatch) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetMixFormat( 
            /* [annotation][out] */ 
            _Out_  WAVEFORMATEX **ppDeviceFormat) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetDevicePeriod( 
            /* [annotation][out] */ 
            _Out_opt_  REFERENCE_TIME *phnsDefaultDevicePeriod,
            /* [annotation][out] */ 
            _Out_opt_  REFERENCE_TIME *phnsMinimumDevicePeriod) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE Start( void) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE Stop( void) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE SetEventHandle( 
            /* [in] */ HANDLE eventHandle) = 0;
        
        /
          //   TODO@chensong 2022-07-24 GetService 方法解释
          
          /** 
          * 
          *   @param rrid    : 接口ID
          *   @param ppv     : 输出的接口对象
          *   return STDMETHODCALLTYPE 
          */
        virtual HRESULT STDMETHODCALLTYPE GetService( 
            /* [annotation][in] */ 
            _In_  REFIID riid,
            /* [annotation][iid_is][out] */ 
            _Out_  void **ppv) = 0;
        
    };
    

音频流的访问方式

WebRTC源码之音频设备播放流程源码分析_第9张图片

1、IAuidoClient的几个重要方法

  1. Initialize (模式[共享,独享] …)
  2. GetBufferSize
  3. SetEventHandle
  4. GetService

①、初始化音频流

WebRTC源码中音频流初始化在 modules/audio_device/win/audio_device_core_win.cc文件中InitPlayout方法中调用的音频流初始化方法Initialize

...


  //        TODO@chensong 2022-07-24 初始化音频流
  ///
  /**
  * @param AUDCLNT_SHAREMODE : 共享模式/独占模式
  * @param DWORD             : 控制流创建的flag
  * @param REFERENCE_TIME    : 请求缓冲区的大小 [是与时间有关系的哈]
  * @param REFERENCE_TIME    : 周期时间 [10ms采集一次、 20ms采集一次]
  * @param WAVEFORMATEX      : 数据格式
  * @param LPCGUID           : Audio Session 的 GUID       
  * @return
  */

 /
  // StreamFlags 参数类型解释:
  // AUDCLNT_STREAMFLAGS_LOOPBACK		: 
  // AUDCLNT_STREAMFLAGS_EVENTCALLBACK	:
  // ...
  hr = _ptrClientOut->Initialize(
      AUDCLNT_SHAREMODE_SHARED,  // share Audio Engine with other applications
      AUDCLNT_STREAMFLAGS_EVENTCALLBACK,  // processing of the audio buffer by
                                          // the client will be event driven
      hnsBufferDuration,  // requested buffer capacity as a time value (in
                          // 100-nanosecond units)
      0,                  // periodicity
      &Wfx,               // selected wave format
      NULL);              // session GUID

  if (FAILED(hr)) {
    RTC_LOG(LS_ERROR) << "IAudioClient::Initialize() failed:";
  }
...

②、GetService方法

  1. 它是IAudioClient中的方法
  2. 用于获取IAudioRenderClient接口
  3. 用于下写数据到渲染终端的buffer

WebRTC源码中音频流初始化在 modules/audio_device/win/audio_device_core_win.cc文件中InitPlayout方法中调用的音频流初始化方法GetService


...
    
/
  //   TODO@chensong 2022-07-24 GetService 方法解释
  
  /** 
  * 
  *   @param rrid    : 接口ID
  *   @param ppv     : 输出的接口对象
  *   return STDMETHODCALLTYPE 
  */
  // Get an IAudioRenderClient interface.
  SAFE_RELEASE(_ptrRenderClient);
  hr = _ptrClientOut->GetService(__uuidof(IAudioRenderClient),
                                 (void**)&_ptrRenderClient);
  EXIT_ON_ERROR(hr);

...

总结:

WebRTC源码分析地址:https://github.com/chensongpoixs/cwebrtc

你可能感兴趣的:(WebRTC源码探秘,webrtc,网络)