330 lines · plain
1=========================2ALSA Compress-Offload API3=========================4 5Pierre-Louis.Bossart <pierre-louis.bossart@linux.intel.com>6 7Vinod Koul <vinod.koul@linux.intel.com>8 9 10Overview11========12Since its early days, the ALSA API was defined with PCM support or13constant bitrates payloads such as IEC61937 in mind. Arguments and14returned values in frames are the norm, making it a challenge to15extend the existing API to compressed data streams.16 17In recent years, audio digital signal processors (DSP) were integrated18in system-on-chip designs, and DSPs are also integrated in audio19codecs. Processing compressed data on such DSPs results in a dramatic20reduction of power consumption compared to host-based21processing. Support for such hardware has not been very good in Linux,22mostly because of a lack of a generic API available in the mainline23kernel.24 25Rather than requiring a compatibility break with an API change of the26ALSA PCM interface, a new 'Compressed Data' API is introduced to27provide a control and data-streaming interface for audio DSPs.28 29The design of this API was inspired by the 2-year experience with the30Intel Moorestown SOC, with many corrections required to upstream the31API in the mainline kernel instead of the staging tree and make it32usable by others.33 34 35Requirements36============37The main requirements are:38 39- separation between byte counts and time. Compressed formats may have40 a header per file, per frame, or no header at all. The payload size41 may vary from frame-to-frame. As a result, it is not possible to42 estimate reliably the duration of audio buffers when handling43 compressed data. Dedicated mechanisms are required to allow for44 reliable audio-video synchronization, which requires precise45 reporting of the number of samples rendered at any given time.46 47- Handling of multiple formats. PCM data only requires a specification48 of the sampling rate, number of channels and bits per sample. In49 contrast, compressed data comes in a variety of formats. Audio DSPs50 may also provide support for a limited number of audio encoders and51 decoders embedded in firmware, or may support more choices through52 dynamic download of libraries.53 54- Focus on main formats. This API provides support for the most55 popular formats used for audio and video capture and playback. It is56 likely that as audio compression technology advances, new formats57 will be added.58 59- Handling of multiple configurations. Even for a given format like60 AAC, some implementations may support AAC multichannel but HE-AAC61 stereo. Likewise WMA10 level M3 may require too much memory and cpu62 cycles. The new API needs to provide a generic way of listing these63 formats.64 65- Rendering/Grabbing only. This API does not provide any means of66 hardware acceleration, where PCM samples are provided back to67 user-space for additional processing. This API focuses instead on68 streaming compressed data to a DSP, with the assumption that the69 decoded samples are routed to a physical output or logical back-end.70 71- Complexity hiding. Existing user-space multimedia frameworks all72 have existing enums/structures for each compressed format. This new73 API assumes the existence of a platform-specific compatibility layer74 to expose, translate and make use of the capabilities of the audio75 DSP, eg. Android HAL or PulseAudio sinks. By construction, regular76 applications are not supposed to make use of this API.77 78 79Design80======81The new API shares a number of concepts with the PCM API for flow82control. Start, pause, resume, drain and stop commands have the same83semantics no matter what the content is.84 85The concept of memory ring buffer divided in a set of fragments is86borrowed from the ALSA PCM API. However, only sizes in bytes can be87specified.88 89Seeks/trick modes are assumed to be handled by the host.90 91The notion of rewinds/forwards is not supported. Data committed to the92ring buffer cannot be invalidated, except when dropping all buffers.93 94The Compressed Data API does not make any assumptions on how the data95is transmitted to the audio DSP. DMA transfers from main memory to an96embedded audio cluster or to a SPI interface for external DSPs are97possible. As in the ALSA PCM case, a core set of routines is exposed;98each driver implementer will have to write support for a set of99mandatory routines and possibly make use of optional ones.100 101The main additions are102 103get_caps104 This routine returns the list of audio formats supported. Querying the105 codecs on a capture stream will return encoders, decoders will be106 listed for playback streams.107 108get_codec_caps109 For each codec, this routine returns a list of110 capabilities. The intent is to make sure all the capabilities111 correspond to valid settings, and to minimize the risks of112 configuration failures. For example, for a complex codec such as AAC,113 the number of channels supported may depend on a specific profile. If114 the capabilities were exposed with a single descriptor, it may happen115 that a specific combination of profiles/channels/formats may not be116 supported. Likewise, embedded DSPs have limited memory and cpu cycles,117 it is likely that some implementations make the list of capabilities118 dynamic and dependent on existing workloads. In addition to codec119 settings, this routine returns the minimum buffer size handled by the120 implementation. This information can be a function of the DMA buffer121 sizes, the number of bytes required to synchronize, etc, and can be122 used by userspace to define how much needs to be written in the ring123 buffer before playback can start.124 125set_params126 This routine sets the configuration chosen for a specific codec. The127 most important field in the parameters is the codec type; in most128 cases decoders will ignore other fields, while encoders will strictly129 comply to the settings130 131get_params132 This routines returns the actual settings used by the DSP. Changes to133 the settings should remain the exception.134 135get_timestamp136 The timestamp becomes a multiple field structure. It lists the number137 of bytes transferred, the number of samples processed and the number138 of samples rendered/grabbed. All these values can be used to determine139 the average bitrate, figure out if the ring buffer needs to be140 refilled or the delay due to decoding/encoding/io on the DSP.141 142Note that the list of codecs/profiles/modes was derived from the143OpenMAX AL specification instead of reinventing the wheel.144Modifications include:145- Addition of FLAC and IEC formats146- Merge of encoder/decoder capabilities147- Profiles/modes listed as bitmasks to make descriptors more compact148- Addition of set_params for decoders (missing in OpenMAX AL)149- Addition of AMR/AMR-WB encoding modes (missing in OpenMAX AL)150- Addition of format information for WMA151- Addition of encoding options when required (derived from OpenMAX IL)152- Addition of rateControlSupported (missing in OpenMAX AL)153 154State Machine155=============156 157The compressed audio stream state machine is described below ::158 159 +----------+160 | |161 | OPEN |162 | |163 +----------+164 |165 |166 | compr_set_params()167 |168 v169 compr_free() +----------+170 +------------------------------------| |171 | | SETUP |172 | +-------------------------| |<-------------------------+173 | | compr_write() +----------+ |174 | | ^ |175 | | | compr_drain_notify() |176 | | | or |177 | | | compr_stop() |178 | | | |179 | | +----------+ |180 | | | | |181 | | | DRAIN | |182 | | | | |183 | | +----------+ |184 | | ^ |185 | | | |186 | | | compr_drain() |187 | | | |188 | v | |189 | +----------+ +----------+ |190 | | | compr_start() | | compr_stop() |191 | | PREPARE |------------------->| RUNNING |--------------------------+192 | | | | | |193 | +----------+ +----------+ |194 | | | ^ |195 | |compr_free() | | |196 | | compr_pause() | | compr_resume() |197 | | | | |198 | v v | |199 | +----------+ +----------+ |200 | | | | | compr_stop() |201 +--->| FREE | | PAUSE |---------------------------+202 | | | |203 +----------+ +----------+204 205 206Gapless Playback207================208When playing thru an album, the decoders have the ability to skip the encoder209delay and padding and directly move from one track content to another. The end210user can perceive this as gapless playback as we don't have silence while211switching from one track to another212 213Also, there might be low-intensity noises due to encoding. Perfect gapless is214difficult to reach with all types of compressed data, but works fine with most215music content. The decoder needs to know the encoder delay and encoder padding.216So we need to pass this to DSP. This metadata is extracted from ID3/MP4 headers217and are not present by default in the bitstream, hence the need for a new218interface to pass this information to the DSP. Also DSP and userspace needs to219switch from one track to another and start using data for second track.220 221The main additions are:222 223set_metadata224 This routine sets the encoder delay and encoder padding. This can be used by225 decoder to strip the silence. This needs to be set before the data in the track226 is written.227 228set_next_track229 This routine tells DSP that metadata and write operation sent after this would230 correspond to subsequent track231 232partial drain233 This is called when end of file is reached. The userspace can inform DSP that234 EOF is reached and now DSP can start skipping padding delay. Also next write235 data would belong to next track236 237Sequence flow for gapless would be:238- Open239- Get caps / codec caps240- Set params241- Set metadata of the first track242- Fill data of the first track243- Trigger start244- User-space finished sending all,245- Indicate next track data by sending set_next_track246- Set metadata of the next track247- then call partial_drain to flush most of buffer in DSP248- Fill data of the next track249- DSP switches to second track250 251(note: order for partial_drain and write for next track can be reversed as well)252 253Gapless Playback SM254===================255 256For Gapless, we move from running state to partial drain and back, along257with setting of meta_data and signalling for next track ::258 259 260 +----------+261 compr_drain_notify() | |262 +------------------------>| RUNNING |263 | | |264 | +----------+265 | |266 | |267 | | compr_next_track()268 | |269 | V270 | +----------+271 | compr_set_params() | |272 | +-----------|NEXT_TRACK|273 | | | |274 | | +--+-------+275 | | | |276 | +--------------+ |277 | |278 | | compr_partial_drain()279 | |280 | V281 | +----------+282 | | |283 +------------------------ | PARTIAL_ |284 | DRAIN |285 +----------+286 287Not supported288=============289- Support for VoIP/circuit-switched calls is not the target of this290 API. Support for dynamic bit-rate changes would require a tight291 coupling between the DSP and the host stack, limiting power savings.292 293- Packet-loss concealment is not supported. This would require an294 additional interface to let the decoder synthesize data when frames295 are lost during transmission. This may be added in the future.296 297- Volume control/routing is not handled by this API. Devices exposing a298 compressed data interface will be considered as regular ALSA devices;299 volume changes and routing information will be provided with regular300 ALSA kcontrols.301 302- Embedded audio effects. Such effects should be enabled in the same303 manner, no matter if the input was PCM or compressed.304 305- multichannel IEC encoding. Unclear if this is required.306 307- Encoding/decoding acceleration is not supported as mentioned308 above. It is possible to route the output of a decoder to a capture309 stream, or even implement transcoding capabilities. This routing310 would be enabled with ALSA kcontrols.311 312- Audio policy/resource management. This API does not provide any313 hooks to query the utilization of the audio DSP, nor any preemption314 mechanisms.315 316- No notion of underrun/overrun. Since the bytes written are compressed317 in nature and data written/read doesn't translate directly to318 rendered output in time, this does not deal with underrun/overrun and319 maybe dealt in user-library320 321 322Credits323=======324- Mark Brown and Liam Girdwood for discussions on the need for this API325- Harsha Priya for her work on intel_sst compressed API326- Rakesh Ughreja for valuable feedback327- Sing Nallasellan, Sikkandar Madar and Prasanna Samaga for328 demonstrating and quantifying the benefits of audio offload on a329 real platform.330