Android Audio Playback Mode

常见Playback Mode

1 Deep buffer Playback:音频文件是在AP侧解码成PCM文件,然后再送到ADSP中处理,音效处理在AP侧或者ADSP中进行。
Playback mode in which PCM data is sent to the aDSP, postprocessed, and rendered to output sound device; audio effects can also be applied in the ARM or aDSP.
FLAG: AUDIO_OUTPUT_FLAG_DEEP_BUFFER

2 Low Latency Playback : 和Deep buffer Playback方式类似,但是它所分配的buffer更小些,并且在ADSP侧只做很少或者基本不做处理, 主要是播放一些对延迟要求较高的音频,
Playback mode similar to deep buffer that uses a smaller buffer size and minimal or no
postprocessing in the aDSP so that the PCM stream is rendered to the output sound
device
Use cases – Touchtone, gaming audio
FLAG:AUDIO_OUTPUT_FLAG_FAST

3 Offload Playback: 音频解码部分的工作是在ADSP中完成,AP侧只负责把音频数据送到ADSP中,送出去后,AP侧会进行休眠,ADSP中会分配一块较大的buffer去处理此数据,在ADSP中进行解码,音效的处理工作,在ADSP解码器处理完数据之前,它会唤醒AP侧去送下一包数据。
Playback mode in which a large-sized buffer is sent to the aDSP and the APSS goes to sleep; the aDSP decodes, applies postprocessing effects, and outputs the PCM data to the physical sound device. Before the aDSP decoder input runs out of data, it interrupts the APSS to wake up and send the next set of buffers.
Examples – MP3, AAC, FLAC 24 bit, 24 bit wav playback
FLAG:AUDIO_OUTPUT_FLAG_DIRECT,AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,AUDIO_OUTPUT_FLAG_NON_BLOCKING

每个平台支持哪几种播放模式,以及个播放模式的标志,支持的格式,声道数,输出设备等信息,是在
audio_policy.conf文件里配置的。

常见 FLAG

typedef enum {  
  AUDIO_OUTPUT_FLAG_NONE = 0x0,  
  AUDIO_OUTPUT_FLAG_DIRECT = 0x1,  
  AUDIO_OUTPUT_FLAG_PRIMARY = 0x2,  
  AUDIO_OUTPUT_FLAG_FAST = 0x4,  
  AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8,  
  AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 0x10,  
  AUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20  
} audio_output_flags_t;  

AUDIO_OUTPUT_FLAG_DIRECT:不进行软件混音直接交HAL进行处理; Indicates cases that need to bypass AudioFlinger
AUDIO_OUTPUT_FLAG_PRIMARY:软件解码、软件混音、采样率转换(SRC)基本都不能少;
AUDIO_OUTPUT_FLAG_FAST:不进行采样率转换(SRC);
AUDIO_OUTPUT_FLAG_DEEP_BUFFER:经处理后(混音加音效等)交HAL进行处理;
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD:编码数据直接交HAL进行处理(往往需要有DSP进行硬解码); Indicates the stream should be offloaded
AUDIO_OUTPUT_FLAG_NON_BLOCKING – Indicates the writes for this stream are nonblocking

常见的播放录音线程

android/frameworks/av/services/audioflinger/AudioFlinger.cpp


1929  sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
1930                                                              audio_io_handle_t *output,
1931                                                              audio_config_t *config,
1932                                                              audio_devices_t devices,
1933                                                              const String8& address,
1934                                                              audio_output_flags_t flags)
1935  {
      ..........
             sp<PlaybackThread> thread;
1995              if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
1996                  thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady);
1997                  ALOGV("openOutput_l() created offload output: ID %d thread %p",
1998                        *output, thread.get());
1999              } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
2000                      || !isValidPcmSinkFormat(config->format)
2001                      || !isValidPcmSinkChannelMask(config->channel_mask)) {
2002                  thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
2003                  ALOGV("openOutput_l() created direct output: ID %d thread %p",
2004                        *output, thread.get());
2005              } else {
2006                  thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
2007                  ALOGV("openOutput_l() created mixer output: ID %d thread %p",
2008                        *output, thread.get());
2009              }
2010              mPlaybackThreads.add(*output, thread);
2011              return thread;

这里写图片描述

RecordThread
RecordThread : public ThreadBase, public AudioBufferProvider
用于录音的线程。

PlaybackThread:
class PlaybackThread : public ThreadBase
用于播放的线程

MixerThread
MixerThread : public PlaybackThread
用于混音的线程,注意是从PlaybackThread派生下来的。负责处理标识为 AUDIO_OUTPUT_FLAG_PRIMARY、AUDIO_OUTPUT_FLAG_FAST、AUDIO_OUTPUT_FLAG_DEEP_BUFFER 的音频流,MixerThread 可以把多个音轨的数据混音后再输出

DirectoutputThread
DirectOutputThread : public PlaybackThread
直接输出线程,DIRECT_OUTPUT最终和这个线程有关。负责处理标识为 AUDIO_OUTPUT_FLAG_DIRECT 的音频流,这种音频流数据不需要软件混音,直接输出到音频设备

OffloadThread
classOffloadThread : publicDirectOutputThread {

DuplicatingThread
DuplicatingThread : public MixerThread
复制线程,而且从混音线程中派生

Audio HAL 输出流设备

Audio HAL 中,我们通常看到如下 4 种输出流设备,分别对应着不同的播放场景:

primary_out:主输出流设备,用于铃声类声音输出,对应着标识为 AUDIO_OUTPUT_FLAG_PRIMARY 的音频流和一个 MixerThread 回放线程实例

low_latency:低延迟输出流设备,用于按键音、游戏背景音等对时延要求高的声音输出,对应着标识为 AUDIO_OUTPUT_FLAG_FAST 的音频流和一个 MixerThread 回放线程实例

deep_buffer:音乐音轨输出流设备,用于音乐等对时延要求不高的声音输出,对应着标识为 AUDIO_OUTPUT_FLAG_DEEP_BUFFER 的音频流和一个 MixerThread 回放线程实例

compress_offload:硬解输出流设备,用于需要硬件解码的数据输出,对应着标识为 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD

PlaybackThread 与输出流设备的关系:PlaybackThread 实例与输出流设备是一一对应的,比方说 OffloadThread 只会将音频数据输出到 compress_offload 设备中,MixerThread(with FastMixer) 只会将音频数据输出到 low_latency 设备中。
下图简单描述 AudioTrack、PlaybackThread、输出流设备三者的对应关系:

这里写图片描述

系统启动时,就已经打开 primary_out、low_latency、deep_buffer 这三种输出流设备,并创建对应的 MixerThread 了;而此时 DirectOutputThread 与 OffloadThread 不会被创建,直到标识为 AUDIO_OUTPUT_FLAG_DIRECT/AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD 的音频流需要输出时,才开始创建 DirectOutputThread/OffloadThread 和打开 direct_out/compress_offload 设备。

猜你喜欢

转载自blog.csdn.net/ch853199769/article/details/79916166