Merge "hal: Add support for low latency compress capture"

This commit is contained in:
qctecmdr 2019-07-08 01:35:40 -07:00 committed by Gerrit - the friendly Code Review server
commit 65ddcddb67
5 changed files with 136 additions and 10 deletions

View File

@ -104,7 +104,7 @@ void cin_close_input_stream(struct stream_in *in);
void cin_free_input_stream_resources(struct stream_in *in);
int cin_read(struct stream_in *in, void *buffer,
size_t bytes, size_t *bytes_read);
int cin_configure_input_stream(struct stream_in *in);
int cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config);
void audio_extn_set_snd_card_split(const char* in_snd_card_name)
{
@ -5086,9 +5086,9 @@ int audio_extn_cin_read(struct stream_in *in, void *buffer,
return (audio_extn_compress_in_enabled?
cin_read(in, buffer, bytes, bytes_read): -1);
}
int audio_extn_cin_configure_input_stream(struct stream_in *in)
int audio_extn_cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config)
{
return (audio_extn_compress_in_enabled? cin_configure_input_stream(in): -1);
return (audio_extn_compress_in_enabled? cin_configure_input_stream(in, in_config): -1);
}
// END: COMPRESS_IN ====================================================

View File

@ -216,6 +216,9 @@ bool audio_extn_qdsp_supported_usb();
//END: EXTN_QDSP_PLUGIN ===========================================
#define MIN_OFFLOAD_BUFFER_DURATION_MS 5 /* 5ms */
#define MAX_OFFLOAD_BUFFER_DURATION_MS (100 * 1000) /* 100s */
void audio_extn_set_parameters(struct audio_device *adev,
struct str_parms *parms);
@ -1072,7 +1075,7 @@ void audio_extn_cin_close_input_stream(struct stream_in *in);
void audio_extn_cin_free_input_stream_resources(struct stream_in *in);
int audio_extn_cin_read(struct stream_in *in, void *buffer,
size_t bytes, size_t *bytes_read);
int audio_extn_cin_configure_input_stream(struct stream_in *in);
int audio_extn_cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config);
// END: COMPRESS_INPUT_ENABLED ===============================
//START: SOURCE_TRACKING_FEATURE ==============================================
@ -1147,6 +1150,7 @@ int audio_extn_utils_compress_get_dsp_presentation_pos(struct stream_out *out,
uint64_t *frames, struct timespec *timestamp, int32_t clock_id);
int audio_extn_utils_pcm_get_dsp_presentation_pos(struct stream_out *out,
uint64_t *frames, struct timespec *timestamp, int32_t clock_id);
size_t audio_extn_utils_get_input_buffer_size(uint32_t, audio_format_t, int, int64_t, bool);
#ifdef AUDIO_HW_LOOPBACK_ENABLED
/* API to create audio patch */
int audio_extn_hw_loopback_create_audio_patch(struct audio_hw_device *dev,

View File

@ -100,7 +100,7 @@ bool cin_applicable_stream(struct stream_in *in)
* only after validating that input against cin_attached_usecase
* except below calls
* 1. cin_applicable_stream(in)
* 2. cin_configure_input_stream(in)
* 2. cin_configure_input_stream(in, in_config)
*/
bool cin_attached_usecase(audio_usecase_t uc_id)
@ -276,9 +276,8 @@ int cin_read(struct stream_in *in, void *buffer,
return ret;
}
int cin_configure_input_stream(struct stream_in *in)
int cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config)
{
struct audio_device *adev = in->dev;
struct audio_config config = {.format = 0};
int ret = 0, buffer_size = 0, meta_size = sizeof(struct snd_codec_metadata);
cin_private_data_t *cin_data = NULL;
@ -315,7 +314,8 @@ int cin_configure_input_stream(struct stream_in *in)
config.channel_mask = in->channel_mask;
config.format = in->format;
in->config.channels = audio_channel_count_from_in_mask(in->channel_mask);
buffer_size = adev->device.get_input_buffer_size(&adev->device, &config);
buffer_size = audio_extn_utils_get_input_buffer_size(config.sample_rate, config.format,
in->config.channels, in_config->offload_info.duration_us / 1000, false);
cin_data->compr_config.fragment_size = buffer_size;
cin_data->compr_config.codec->id = get_snd_codec_id(in->format);

View File

@ -37,6 +37,7 @@
#include "platform.h"
#include "platform_api.h"
#include "audio_extn.h"
#include "voice_extn.h"
#include "voice.h"
#include <sound/compress_params.h>
#include <sound/compress_offload.h>
@ -1249,6 +1250,88 @@ exit_send_app_type_cfg:
return rc;
}
static int audio_extn_utils_check_input_parameters(uint32_t sample_rate,
audio_format_t format,
int channel_count)
{
int ret = 0;
if (((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT) &&
(format != AUDIO_FORMAT_PCM_24_BIT_PACKED) && (format != AUDIO_FORMAT_PCM_32_BIT) &&
(format != AUDIO_FORMAT_PCM_FLOAT)) &&
!voice_extn_compress_voip_is_format_supported(format) &&
!audio_extn_compr_cap_format_supported(format) &&
!audio_extn_cin_format_supported(format))
ret = -EINVAL;
switch (channel_count) {
case 1:
case 2:
case 3:
case 4:
case 6:
case 8:
break;
default:
ret = -EINVAL;
}
switch (sample_rate) {
case 8000:
case 11025:
case 12000:
case 16000:
case 22050:
case 24000:
case 32000:
case 44100:
case 48000:
case 88200:
case 96000:
case 176400:
case 192000:
break;
default:
ret = -EINVAL;
}
return ret;
}
static inline uint32_t audio_extn_utils_nearest_multiple(uint32_t num, uint32_t multiplier)
{
uint32_t remainder = 0;
if (!multiplier)
return num;
remainder = num % multiplier;
if (remainder)
num += (multiplier - remainder);
return num;
}
static inline uint32_t audio_extn_utils_lcm(uint32_t num1, uint32_t num2)
{
uint32_t high = num1, low = num2, temp = 0;
if (!num1 || !num2)
return 0;
if (num1 < num2) {
high = num2;
low = num1;
}
while (low != 0) {
temp = low;
low = high % low;
high = temp;
}
return (num1 * num2)/high;
}
int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
struct audio_usecase *usecase)
{
@ -2860,3 +2943,42 @@ int audio_extn_utils_is_vendor_enhanced_fwk()
return is_running_with_enhanced_fwk;
}
size_t audio_extn_utils_get_input_buffer_size(uint32_t sample_rate,
audio_format_t format,
int channel_count,
int64_t duration_ms,
bool is_low_latency)
{
size_t size = 0;
size_t capture_duration = AUDIO_CAPTURE_PERIOD_DURATION_MSEC;
uint32_t bytes_per_period_sample = 0;
if (audio_extn_utils_check_input_parameters(sample_rate, format, channel_count) != 0)
return 0;
if (duration_ms >= MIN_OFFLOAD_BUFFER_DURATION_MS && duration_ms <= MAX_OFFLOAD_BUFFER_DURATION_MS)
capture_duration = duration_ms;
size = (sample_rate * capture_duration) / 1000;
if (is_low_latency)
size = LOW_LATENCY_CAPTURE_PERIOD_SIZE;
bytes_per_period_sample = audio_bytes_per_sample(format) * channel_count;
size *= bytes_per_period_sample;
/* make sure the size is multiple of 32 bytes and additionally multiple of
* the frame_size (required for 24bit samples and non-power-of-2 channel counts)
* At 48 kHz mono 16-bit PCM:
* 5.000 ms = 240 frames = 15*16*1*2 = 480, a whole multiple of 32 (15)
* 3.333 ms = 160 frames = 10*16*1*2 = 320, a whole multiple of 32 (10)
*
* The loop reaches result within 32 iterations, as initial size is
* already a multiple of frame_size
*/
size = audio_extn_utils_nearest_multiple(size, audio_extn_utils_lcm(32, bytes_per_period_sample));
return size;
}

View File

@ -8845,7 +8845,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
(in->dev->mode != AUDIO_MODE_IN_COMMUNICATION)) {
audio_extn_compr_cap_init(in);
} else if (audio_extn_cin_applicable_stream(in)) {
ret = audio_extn_cin_configure_input_stream(in);
ret = audio_extn_cin_configure_input_stream(in, config);
if (ret)
goto err_open;
} else {
@ -8896,7 +8896,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
ALOGV("%s: overriding usecase with USECASE_AUDIO_RECORD_COMPRESS2 and appending compress flag", __func__);
if (audio_extn_cin_applicable_stream(in)) {
in->sample_rate = config->sample_rate;
ret = audio_extn_cin_configure_input_stream(in);
ret = audio_extn_cin_configure_input_stream(in, config);
if (ret)
goto err_open;
}