hal: support compressed capture with variable size packets
Compressed IEC 61937 capture uses variable size packets for data
transfer
Change-Id: I8e6baaf870f5f504c0c642cf44795334097bddbf
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
old mode 100755
new mode 100644
index 1b34c53..0e1848e
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -113,6 +113,7 @@
*/
#define AUDIO_INPUT_FLAG_TIMESTAMP 0x80000000
#define AUDIO_INPUT_FLAG_COMPRESS 0x40000000
+#define AUDIO_INPUT_FLAG_PASSTHROUGH 0x20000000
/* MAX SECTORS for sourcetracking feature */
#define MAX_SECTORS 8
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
old mode 100755
new mode 100644
index a14366d..6c5d0e1
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -876,6 +876,7 @@
#ifdef COMPRESS_INPUT_ENABLED
bool audio_extn_cin_applicable_stream(struct stream_in *in);
bool audio_extn_cin_attached_usecase(audio_usecase_t uc_id);
+bool audio_extn_cin_format_supported(audio_format_t format);
size_t audio_extn_cin_get_buffer_size(struct stream_in *in);
int audio_extn_cin_start_input_stream(struct stream_in *in);
void audio_extn_cin_stop_input_stream(struct stream_in *in);
@@ -886,6 +887,7 @@
#else
#define audio_extn_cin_applicable_stream(in) (false)
#define audio_extn_cin_attached_usecase(uc_id) (false)
+#define audio_extn_cin_format_supported(format) (false)
#define audio_extn_cin_get_buffer_size(in) (0)
#define audio_extn_cin_start_input_stream(in) (0)
#define audio_extn_cin_stop_input_stream(in) (0)
diff --git a/hal/audio_extn/compress_in.c b/hal/audio_extn/compress_in.c
index 305ed5b..3066f3c 100644
--- a/hal/audio_extn/compress_in.c
+++ b/hal/audio_extn/compress_in.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -157,13 +157,22 @@
pthread_mutex_unlock(&cin_lock);
}
+bool audio_extn_cin_format_supported(audio_format_t format)
+{
+ if (format == AUDIO_FORMAT_IEC61937)
+ return true;
+ else
+ return false;
+}
+
size_t audio_extn_cin_get_buffer_size(struct stream_in *in)
{
size_t sz = 0;
cin_private_data_t *cin_data = (cin_private_data_t *) in->cin_extn;
sz = cin_data->compr_config.fragment_size;
- if (in->flags & AUDIO_INPUT_FLAG_TIMESTAMP)
+ if ((in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) ||
+ (in->flags & AUDIO_INPUT_FLAG_PASSTHROUGH))
sz -= sizeof(struct snd_codec_metadata);
ALOGV("%s: in %p, flags 0x%x, cin_data %p, size %zd",
@@ -230,7 +239,7 @@
if (!is_compress_running(cin_data->compr))
compress_start(cin_data->compr);
- if (!(in->flags & AUDIO_INPUT_FLAG_TIMESTAMP))
+ if (!(in->flags & (AUDIO_INPUT_FLAG_TIMESTAMP | AUDIO_INPUT_FLAG_PASSTHROUGH)))
mdata_size = 0;
if (buffer && read_size) {
@@ -265,7 +274,7 @@
cin_private_data_t *cin_data = NULL;
if (!COMPRESSED_TIMESTAMP_FLAG &&
- (in->flags & AUDIO_INPUT_FLAG_TIMESTAMP)) {
+ (in->flags & (AUDIO_INPUT_FLAG_TIMESTAMP | AUDIO_INPUT_FLAG_PASSTHROUGH))) {
ALOGE("%s: timestamp mode not supported!", __func__);
return -EINVAL;
}
@@ -305,7 +314,16 @@
cin_data->compr_config.codec->ch_in = in->config.channels;
cin_data->compr_config.codec->ch_out = in->config.channels;
cin_data->compr_config.codec->format = hal_format_to_alsa(in->format);
- if (in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) {
+
+ if (cin_data->compr_config.codec->id == SND_AUDIOCODEC_PCM)
+ cin_data->compr_config.codec->compr_passthr = LEGACY_PCM;
+ else if (cin_data->compr_config.codec->id == SND_AUDIOCODEC_IEC61937)
+ cin_data->compr_config.codec->compr_passthr = PASSTHROUGH_IEC61937;
+ else
+ cin_data->compr_config.codec->compr_passthr = PASSTHROUGH_GEN;
+
+ if ((in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) ||
+ (in->flags & AUDIO_INPUT_FLAG_PASSTHROUGH)) {
compress_config_set_timstamp_flag(&cin_data->compr_config);
cin_data->compr_config.fragment_size += meta_size;
}
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
old mode 100755
new mode 100644
index 8a585df..6aab347
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -140,6 +140,7 @@
STRING_TO_ENUM(AUDIO_INPUT_FLAG_SYNC),
STRING_TO_ENUM(AUDIO_INPUT_FLAG_TIMESTAMP),
STRING_TO_ENUM(AUDIO_INPUT_FLAG_COMPRESS),
+ STRING_TO_ENUM(AUDIO_INPUT_FLAG_PASSTHROUGH),
};
const struct string_to_enum s_format_name_to_enum_table[] = {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 523cdc9..16ac7f4 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3253,7 +3253,8 @@
(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_compr_cap_format_supported(format) &&
+ !audio_extn_cin_format_supported(format))
ret = -EINVAL;
switch (channel_count) {
@@ -3262,6 +3263,7 @@
case 3:
case 4:
case 6:
+ case 8:
break;
default:
ret = -EINVAL;
diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c
old mode 100755
new mode 100644
index 550a06b..f5e0659
--- a/hal/audio_hw_extn_api.c
+++ b/hal/audio_hw_extn_api.c
@@ -204,7 +204,8 @@
return -EINVAL;
}
if (COMPRESSED_TIMESTAMP_FLAG &&
- (in->flags & AUDIO_INPUT_FLAG_TIMESTAMP)) {
+ ((in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) ||
+ (in->flags & AUDIO_INPUT_FLAG_PASSTHROUGH))) {
if (bytes != in->stream.common.get_buffer_size(&stream->common)) {
ALOGE("%s: bytes requested must be fragment size in timestamp mode!", __func__);
return -EINVAL;
@@ -213,10 +214,15 @@
buf = (char *) in->qahwi_in.ibuf;
ret = in->qahwi_in.base.read(&in->stream, (void *)buf, bytes + mdata_size);
if (ret == bytes + mdata_size) {
- bytes_read = bytes;
- memcpy(buffer, buf + mdata_size, bytes);
+ mdata = (struct snd_codec_metadata *) buf;
+ bytes_read = mdata->length;
+ if (bytes_read > bytes) {
+ ALOGE("%s: bytes requested to small (given %zu, required %zu)",
+ __func__, bytes, bytes_read);
+ return -EINVAL;
+ }
+ memcpy(buffer, buf + mdata_size, bytes_read);
if (timestamp) {
- mdata = (struct snd_codec_metadata *) buf;
*timestamp = mdata->timestamp;
}
} else {
@@ -281,7 +287,8 @@
in->qahwi_in.is_inititalized = true;
if (COMPRESSED_TIMESTAMP_FLAG &&
- (flags & AUDIO_INPUT_FLAG_TIMESTAMP)) {
+ ((in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) ||
+ (in->flags & AUDIO_INPUT_FLAG_PASSTHROUGH))) {
// set read to NULL as this is not supported in timestamp mode
in->stream.read = NULL;