Loading hal/audio_hw.c +27 −29 Original line number Diff line number Diff line Loading @@ -53,14 +53,14 @@ #include "voice_extn.h" #include "sound/compress_params.h" #define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024) #define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (8 * 1024) #define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024) #include "sound/asound.h" #define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4 /* ToDo: Check and update a proper value in msec */ #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96 #define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000 #define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER struct pcm_config pcm_config_deep_buffer = { Loading Loading @@ -153,28 +153,6 @@ static unsigned int audio_device_ref_count; static int set_voice_volume_l(struct audio_device *adev, float volume); /* Read offload buffer size from a property. * If value is not power of 2 round it to * power of 2. */ static uint32_t get_offload_buffer_size() { char value[PROPERTY_VALUE_MAX] = {0}; uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE; if((property_get("audio.offload.buffer.size.kb", value, "")) && atoi(value)) { fragment_size = atoi(value) * 1024; //ring buffer size needs to be 4k aligned. CHECK(!(fragment_size * COMPRESS_OFFLOAD_NUM_FRAGMENTS % 4096)); } if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE; else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE; ALOGVV("%s: fragment_size %d", __func__, fragment_size); return fragment_size; } static int check_and_set_gapless_mode(struct audio_device *adev) { Loading Loading @@ -205,7 +183,9 @@ static int check_and_set_gapless_mode(struct audio_device *adev) { static bool is_supported_format(audio_format_t format) { if (format == AUDIO_FORMAT_MP3 || format == AUDIO_FORMAT_AAC) format == AUDIO_FORMAT_AAC || format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD || format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) return true; return false; Loading @@ -222,6 +202,10 @@ static int get_snd_codec_id(audio_format_t format) case AUDIO_FORMAT_AAC: id = SND_AUDIOCODEC_AAC; break; case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD: case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD: id = SND_AUDIOCODEC_PCM; break; default: ALOGE("%s: Unsupported audio format :%x", __func__, format); } Loading Loading @@ -2147,8 +2131,10 @@ static int adev_open_output_stream(struct audio_hw_device *dev, out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD; if (config->offload_info.channel_mask) out->channel_mask = config->offload_info.channel_mask; else if (config->channel_mask) else if (config->channel_mask) { out->channel_mask = config->channel_mask; config->offload_info.channel_mask = config->channel_mask; } out->format = config->offload_info.format; out->sample_rate = config->offload_info.sample_rate; Loading @@ -2165,7 +2151,14 @@ static int adev_open_output_stream(struct audio_hw_device *dev, else out->compr_config.codec->id = get_snd_codec_id(config->offload_info.format); out->compr_config.fragment_size = get_offload_buffer_size(); if (audio_is_offload_pcm(config->offload_info.format)) { out->compr_config.fragment_size = platform_get_pcm_offload_buffer_size(&config->offload_info); } else { out->compr_config.fragment_size = platform_get_compress_offload_buffer_size(&config->offload_info); } out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS; out->compr_config.codec->sample_rate = compress_get_alsa_rate(config->offload_info.sample_rate); Loading @@ -2175,6 +2168,11 @@ static int adev_open_output_stream(struct audio_hw_device *dev, popcount(config->channel_mask); out->compr_config.codec->ch_out = out->compr_config.codec->ch_in; if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD) out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE; else if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE; if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) out->non_blocking = 1; Loading hal/msm8974/platform.c +84 −0 Original line number Diff line number Diff line Loading @@ -31,12 +31,30 @@ #include "platform.h" #include "audio_extn.h" #include "voice_extn.h" #include "sound/compress_params.h" #define MIXER_XML_PATH "/system/etc/mixer_paths.xml" #define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml" #define LIB_ACDB_LOADER "libacdbloader.so" #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID" #define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024) #define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024) #define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024) #define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024) /* Used in calculating fragment size for pcm offload */ #define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 2000 /* 2 secs */ #define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 100 /* 100 millisecs */ /* MAX PCM fragment size cannot be increased further due * to flinger's cblk size of 1mb,and it has to be a multiple of * 24 - lcm of channels supported by DSP */ #define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024) #define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024) #define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1))) /* * This file will have a maximum of 38 bytes: * Loading Loading @@ -1579,3 +1597,69 @@ bool platform_listen_update_status(snd_device_t snd_device) else return false; } /* Read offload buffer size from a property. * If value is not power of 2 round it to * power of 2. */ uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info) { char value[PROPERTY_VALUE_MAX] = {0}; uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE; if((property_get("audio.offload.buffer.size.kb", value, "")) && atoi(value)) { fragment_size = atoi(value) * 1024; } if (info != NULL && info->has_video && info->is_streaming) { fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING; ALOGV("%s: offload fragment size reduced for AV streaming to %d", __func__, out->compr_config.fragment_size); } fragment_size = ALIGN( fragment_size, 1024); if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE; else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE; ALOGV("%s: fragment_size %d", __func__, fragment_size); return fragment_size; } uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info) { uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE; uint32_t bits_per_sample = 16; if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) { bits_per_sample = 32; } if (!info->has_video) { fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE; } else if (info->has_video && info->is_streaming) { fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING * info->sample_rate * bits_per_sample * popcount(info->channel_mask))/1000; } else if (info->has_video) { fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV * info->sample_rate * bits_per_sample * popcount(info->channel_mask))/1000; } fragment_size = ALIGN( fragment_size, 1024); if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE) fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE; else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE) fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE; ALOGV("%s: fragment_size %d", __func__, fragment_size); return fragment_size; } hal/platform_api.h +5 −1 Original line number Diff line number Diff line Loading @@ -57,4 +57,8 @@ int platform_update_usecase_from_source(int source, audio_usecase_t usecase); bool platform_listen_update_status(snd_device_t snd_device); #endif // QCOM_AUDIO_PLATFORM_API_H struct audio_offload_info_t; uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info); uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info); #endif // AUDIO_PLATFORM_API_H policy_hal/AudioPolicyManager.cpp +123 −0 Original line number Diff line number Diff line Loading @@ -881,6 +881,129 @@ float AudioPolicyManager::computeVolume(int stream, #endif return AudioPolicyManagerBase::computeVolume(stream, index, output, device); } // This function checks for the parameters which can be offloaded. // This can be enhanced depending on the capability of the DSP and policy // of the system. bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) { ALOGV(" isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," " BitRate=%u, duration=%lld us, has_video=%d", offloadInfo.sample_rate, offloadInfo.channel_mask, offloadInfo.format, offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, offloadInfo.has_video); #ifdef VOICE_CONCURRENCY if(isInCall()) { ALOGD("\n blocking compress offload on call mode\n"); return false; } #endif // Check if stream type is music, then only allow offload as of now. if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) { ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); return false; } char propValue[PROPERTY_VALUE_MAX]; bool pcmOffload = false; if (audio_is_offload_pcm(offloadInfo.format)) { if(property_get("audio.offload.pcm.enable", propValue, NULL)) { bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); if (prop_enabled) { ALOGW("PCM offload property is enabled"); pcmOffload = true; } } if (!pcmOffload) { ALOGV("PCM offload disabled by property audio.offload.pcm.enable"); return false; } } if (!pcmOffload) { // Check if offload has been disabled if (property_get("audio.offload.disable", propValue, "0")) { if (atoi(propValue) != 0) { ALOGV("offload disabled by audio.offload.disable=%s", propValue ); return false; } } //check if it's multi-channel AAC format if (AudioSystem::popCount(offloadInfo.channel_mask) > 2 && offloadInfo.format == AUDIO_FORMAT_AAC) { ALOGV("offload disabled for multi-channel AAC format"); return false; } if (offloadInfo.has_video) { if(property_get("av.offload.enable", propValue, NULL)) { bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); if (!prop_enabled) { ALOGW("offload disabled by av.offload.enable = %s ", propValue ); return false; } } else { return false; } if(offloadInfo.is_streaming) { if (property_get("av.streaming.offload.enable", propValue, NULL)) { bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); if (!prop_enabled) { ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue ); return false; } } else { //Do not offload AV streamnig if the property is not defined return false; } } ALOGV("isOffloadSupported: has_video == true, property\ set to enable offload"); } } //If duration is less than minimum value defined in property, return false if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); return false; } } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); //duration checks only valid for MP3/AAC formats, //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats if (offloadInfo.format == AUDIO_FORMAT_MP3 || offloadInfo.format == AUDIO_FORMAT_AAC || pcmOffload) return false; } // Do not allow offloading if one non offloadable effect is enabled. This prevents from // creating an offloaded track and tearing it down immediately after start when audioflinger // detects there is an active non offloadable effect. // FIXME: We should check the audio session here but we do not have it in this context. // This may prevent offloading in rare situations where effects are left active by apps // in the background. if (isNonOffloadableEffectEnabled()) { return false; } // See if there is a profile to support this. // AUDIO_DEVICE_NONE IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, offloadInfo.sample_rate, offloadInfo.format, offloadInfo.channel_mask, AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); ALOGV("isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT "); return (profile != NULL); } extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface) { return new AudioPolicyManager(clientInterface); Loading policy_hal/AudioPolicyManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ public: uint32_t format, uint32_t channels, AudioSystem::audio_in_acoustics acoustics); virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo); protected: // return the strategy corresponding to a given stream type static routing_strategy getStrategy(AudioSystem::stream_type stream); Loading Loading
hal/audio_hw.c +27 −29 Original line number Diff line number Diff line Loading @@ -53,14 +53,14 @@ #include "voice_extn.h" #include "sound/compress_params.h" #define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024) #define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (8 * 1024) #define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024) #include "sound/asound.h" #define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4 /* ToDo: Check and update a proper value in msec */ #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96 #define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000 #define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER struct pcm_config pcm_config_deep_buffer = { Loading Loading @@ -153,28 +153,6 @@ static unsigned int audio_device_ref_count; static int set_voice_volume_l(struct audio_device *adev, float volume); /* Read offload buffer size from a property. * If value is not power of 2 round it to * power of 2. */ static uint32_t get_offload_buffer_size() { char value[PROPERTY_VALUE_MAX] = {0}; uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE; if((property_get("audio.offload.buffer.size.kb", value, "")) && atoi(value)) { fragment_size = atoi(value) * 1024; //ring buffer size needs to be 4k aligned. CHECK(!(fragment_size * COMPRESS_OFFLOAD_NUM_FRAGMENTS % 4096)); } if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE; else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE; ALOGVV("%s: fragment_size %d", __func__, fragment_size); return fragment_size; } static int check_and_set_gapless_mode(struct audio_device *adev) { Loading Loading @@ -205,7 +183,9 @@ static int check_and_set_gapless_mode(struct audio_device *adev) { static bool is_supported_format(audio_format_t format) { if (format == AUDIO_FORMAT_MP3 || format == AUDIO_FORMAT_AAC) format == AUDIO_FORMAT_AAC || format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD || format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) return true; return false; Loading @@ -222,6 +202,10 @@ static int get_snd_codec_id(audio_format_t format) case AUDIO_FORMAT_AAC: id = SND_AUDIOCODEC_AAC; break; case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD: case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD: id = SND_AUDIOCODEC_PCM; break; default: ALOGE("%s: Unsupported audio format :%x", __func__, format); } Loading Loading @@ -2147,8 +2131,10 @@ static int adev_open_output_stream(struct audio_hw_device *dev, out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD; if (config->offload_info.channel_mask) out->channel_mask = config->offload_info.channel_mask; else if (config->channel_mask) else if (config->channel_mask) { out->channel_mask = config->channel_mask; config->offload_info.channel_mask = config->channel_mask; } out->format = config->offload_info.format; out->sample_rate = config->offload_info.sample_rate; Loading @@ -2165,7 +2151,14 @@ static int adev_open_output_stream(struct audio_hw_device *dev, else out->compr_config.codec->id = get_snd_codec_id(config->offload_info.format); out->compr_config.fragment_size = get_offload_buffer_size(); if (audio_is_offload_pcm(config->offload_info.format)) { out->compr_config.fragment_size = platform_get_pcm_offload_buffer_size(&config->offload_info); } else { out->compr_config.fragment_size = platform_get_compress_offload_buffer_size(&config->offload_info); } out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS; out->compr_config.codec->sample_rate = compress_get_alsa_rate(config->offload_info.sample_rate); Loading @@ -2175,6 +2168,11 @@ static int adev_open_output_stream(struct audio_hw_device *dev, popcount(config->channel_mask); out->compr_config.codec->ch_out = out->compr_config.codec->ch_in; if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD) out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE; else if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE; if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) out->non_blocking = 1; Loading
hal/msm8974/platform.c +84 −0 Original line number Diff line number Diff line Loading @@ -31,12 +31,30 @@ #include "platform.h" #include "audio_extn.h" #include "voice_extn.h" #include "sound/compress_params.h" #define MIXER_XML_PATH "/system/etc/mixer_paths.xml" #define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml" #define LIB_ACDB_LOADER "libacdbloader.so" #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID" #define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024) #define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024) #define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024) #define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024) /* Used in calculating fragment size for pcm offload */ #define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 2000 /* 2 secs */ #define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 100 /* 100 millisecs */ /* MAX PCM fragment size cannot be increased further due * to flinger's cblk size of 1mb,and it has to be a multiple of * 24 - lcm of channels supported by DSP */ #define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024) #define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024) #define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1))) /* * This file will have a maximum of 38 bytes: * Loading Loading @@ -1579,3 +1597,69 @@ bool platform_listen_update_status(snd_device_t snd_device) else return false; } /* Read offload buffer size from a property. * If value is not power of 2 round it to * power of 2. */ uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info) { char value[PROPERTY_VALUE_MAX] = {0}; uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE; if((property_get("audio.offload.buffer.size.kb", value, "")) && atoi(value)) { fragment_size = atoi(value) * 1024; } if (info != NULL && info->has_video && info->is_streaming) { fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING; ALOGV("%s: offload fragment size reduced for AV streaming to %d", __func__, out->compr_config.fragment_size); } fragment_size = ALIGN( fragment_size, 1024); if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE; else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE) fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE; ALOGV("%s: fragment_size %d", __func__, fragment_size); return fragment_size; } uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info) { uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE; uint32_t bits_per_sample = 16; if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) { bits_per_sample = 32; } if (!info->has_video) { fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE; } else if (info->has_video && info->is_streaming) { fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING * info->sample_rate * bits_per_sample * popcount(info->channel_mask))/1000; } else if (info->has_video) { fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV * info->sample_rate * bits_per_sample * popcount(info->channel_mask))/1000; } fragment_size = ALIGN( fragment_size, 1024); if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE) fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE; else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE) fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE; ALOGV("%s: fragment_size %d", __func__, fragment_size); return fragment_size; }
hal/platform_api.h +5 −1 Original line number Diff line number Diff line Loading @@ -57,4 +57,8 @@ int platform_update_usecase_from_source(int source, audio_usecase_t usecase); bool platform_listen_update_status(snd_device_t snd_device); #endif // QCOM_AUDIO_PLATFORM_API_H struct audio_offload_info_t; uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info); uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info); #endif // AUDIO_PLATFORM_API_H
policy_hal/AudioPolicyManager.cpp +123 −0 Original line number Diff line number Diff line Loading @@ -881,6 +881,129 @@ float AudioPolicyManager::computeVolume(int stream, #endif return AudioPolicyManagerBase::computeVolume(stream, index, output, device); } // This function checks for the parameters which can be offloaded. // This can be enhanced depending on the capability of the DSP and policy // of the system. bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo) { ALOGV(" isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d," " BitRate=%u, duration=%lld us, has_video=%d", offloadInfo.sample_rate, offloadInfo.channel_mask, offloadInfo.format, offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us, offloadInfo.has_video); #ifdef VOICE_CONCURRENCY if(isInCall()) { ALOGD("\n blocking compress offload on call mode\n"); return false; } #endif // Check if stream type is music, then only allow offload as of now. if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC) { ALOGV("isOffloadSupported: stream_type != MUSIC, returning false"); return false; } char propValue[PROPERTY_VALUE_MAX]; bool pcmOffload = false; if (audio_is_offload_pcm(offloadInfo.format)) { if(property_get("audio.offload.pcm.enable", propValue, NULL)) { bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); if (prop_enabled) { ALOGW("PCM offload property is enabled"); pcmOffload = true; } } if (!pcmOffload) { ALOGV("PCM offload disabled by property audio.offload.pcm.enable"); return false; } } if (!pcmOffload) { // Check if offload has been disabled if (property_get("audio.offload.disable", propValue, "0")) { if (atoi(propValue) != 0) { ALOGV("offload disabled by audio.offload.disable=%s", propValue ); return false; } } //check if it's multi-channel AAC format if (AudioSystem::popCount(offloadInfo.channel_mask) > 2 && offloadInfo.format == AUDIO_FORMAT_AAC) { ALOGV("offload disabled for multi-channel AAC format"); return false; } if (offloadInfo.has_video) { if(property_get("av.offload.enable", propValue, NULL)) { bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); if (!prop_enabled) { ALOGW("offload disabled by av.offload.enable = %s ", propValue ); return false; } } else { return false; } if(offloadInfo.is_streaming) { if (property_get("av.streaming.offload.enable", propValue, NULL)) { bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); if (!prop_enabled) { ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue ); return false; } } else { //Do not offload AV streamnig if the property is not defined return false; } } ALOGV("isOffloadSupported: has_video == true, property\ set to enable offload"); } } //If duration is less than minimum value defined in property, return false if (property_get("audio.offload.min.duration.secs", propValue, NULL)) { if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) { ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue); return false; } } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) { ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS); //duration checks only valid for MP3/AAC formats, //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats if (offloadInfo.format == AUDIO_FORMAT_MP3 || offloadInfo.format == AUDIO_FORMAT_AAC || pcmOffload) return false; } // Do not allow offloading if one non offloadable effect is enabled. This prevents from // creating an offloaded track and tearing it down immediately after start when audioflinger // detects there is an active non offloadable effect. // FIXME: We should check the audio session here but we do not have it in this context. // This may prevent offloading in rare situations where effects are left active by apps // in the background. if (isNonOffloadableEffectEnabled()) { return false; } // See if there is a profile to support this. // AUDIO_DEVICE_NONE IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, offloadInfo.sample_rate, offloadInfo.format, offloadInfo.channel_mask, AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); ALOGV("isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT "); return (profile != NULL); } extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface) { return new AudioPolicyManager(clientInterface); Loading
policy_hal/AudioPolicyManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ public: uint32_t format, uint32_t channels, AudioSystem::audio_in_acoustics acoustics); virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo); protected: // return the strategy corresponding to a given stream type static routing_strategy getStrategy(AudioSystem::stream_type stream); Loading