audio: compress offload enhancements
1) Parse and set encoder metadata (delay, padding)
2) Call compress_next_track to allow partial drain
3) Do not flush output on returning succesfully from partial drain
Change-Id: I0fa1a2c968a5590dff9b6c58bd52bb111dcf3e9b
Bug: 8174410
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9f554fa..4f92ea3 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -661,6 +661,7 @@
{
out->offload_state = OFFLOAD_STATE_IDLE;
out->playback_started = 0;
+ out->send_new_metadata = 1;
if (out->compr != NULL) {
compress_stop(out->compr);
while (out->offload_thread_blocked) {
@@ -725,8 +726,8 @@
event = STREAM_CBK_EVENT_WRITE_READY;
break;
case OFFLOAD_CMD_PARTIAL_DRAIN:
- compress_drain(out->compr);
-//FIXME compress_partial_drain(out->compr);
+ compress_next_track(out->compr);
+ compress_partial_drain(out->compr);
send_callback = true;
event = STREAM_CBK_EVENT_DRAIN_READY;
break;
@@ -743,8 +744,6 @@
out->offload_thread_blocked = false;
pthread_cond_signal(&out->cond);
if (send_callback) {
- if (event == STREAM_CBK_EVENT_DRAIN_READY)
- stop_compressed_output_l(out);
out->offload_callback(event, NULL, out->offload_cookie);
}
free(cmd);
@@ -1094,6 +1093,8 @@
}
} else {
stop_compressed_output_l(out);
+ out->gapless_mdata.encoder_delay = 0;
+ out->gapless_mdata.encoder_padding = 0;
if (out->compr != NULL) {
compress_close(out->compr);
out->compr = NULL;
@@ -1113,6 +1114,39 @@
return 0;
}
+static int parse_compress_metadata(struct stream_out *out, struct str_parms *parms)
+{
+ int ret = 0;
+ char value[32];
+ struct compr_gapless_mdata tmp_mdata;
+
+ if (!out || !parms) {
+ return -EINVAL;
+ }
+
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value));
+ if (ret >= 0) {
+ tmp_mdata.encoder_delay = atoi(value); //whats a good limit check?
+ } else {
+ return -EINVAL;
+ }
+
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value));
+ if (ret >= 0) {
+ tmp_mdata.encoder_padding = atoi(value);
+ } else {
+ return -EINVAL;
+ }
+
+ out->gapless_mdata = tmp_mdata;
+ out->send_new_metadata = 1;
+ ALOGV("%s new encoder delay %u and padding %u", __func__,
+ out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding);
+
+ return 0;
+}
+
+
static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
struct stream_out *out = (struct stream_out *)stream;
@@ -1186,6 +1220,11 @@
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
}
+
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ parse_compress_metadata(out, parms);
+ }
+
str_parms_destroy(parms);
ALOGV("%s: exit: code(%d)", __func__, ret);
return ret;
@@ -1292,8 +1331,15 @@
}
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
+ if (out->send_new_metadata) {
+ ALOGVV("send new gapless metadata");
+ compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
+ out->send_new_metadata = 0;
+ }
+
ret = compress_write(out->compr, buffer, bytes);
- ALOGVV("%s: writing buffer (%d bytes) to pcm device returned %d", __func__, bytes, ret);
+ ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
if (ret >= 0 && ret < (ssize_t)bytes) {
send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
}
@@ -1771,6 +1817,8 @@
if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
out->non_blocking = 1;
+
+ out->send_new_metadata = 1;
create_offload_callback_thread(out);
ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
__func__, config->offload_info.version,