Merge "hal: Add support for low latency compress capture"
This commit is contained in:
commit
65ddcddb67
|
@ -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 ====================================================
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue