libaudiohal@aidl: Implement HW AV Sync operations
Implement DeviceHalAidl::getHwAvSync and
StreamHalAidl::setParameters for keyStreamHwAvSync.
Factor out common code in parameters filtering
from 'setParameters'.
Bug: 205884982
Test: m, launch CF w/AIDL enabled
Change-Id: I7af12f2425983a6b0ff8d828539722f314cbfcf2
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 5f62ad8..49afc11 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -119,11 +119,45 @@
return OK;
}
-status_t StreamHalAidl::setParameters(const String8& kvPairs __unused) {
- ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+namespace {
+
+// 'action' must accept a value of type 'T' and return 'status_t'.
+// The function returns 'true' if the parameter was found, and the action has succeeded.
+// The function returns 'false' if the parameter was not found.
+// Any errors get propagated, if there are errors it means the parameter was found.
+template<typename T, typename F>
+error::Result<bool> filterOutAndProcessParameter(
+ AudioParameter& parameters, const String8& key, const F& action) {
+ if (parameters.containsKey(key)) {
+ T value;
+ status_t status = parameters.get(key, value);
+ if (status == OK) {
+ parameters.remove(key);
+ status = action(value);
+ if (status == OK) return true;
+ }
+ return base::unexpected(status);
+ }
+ return false;
+}
+
+} // namespace
+
+status_t StreamHalAidl::setParameters(const String8& kvPairs) {
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+
+ AudioParameter parameters(kvPairs);
+ ALOGD("%s: parameters: %s", __func__, parameters.toString().c_str());
+
+ (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyStreamHwAvSync),
+ [&](int hwAvSyncId) {
+ return statusTFromBinderStatus(mStream->updateHwAvSyncId(hwAvSyncId));
+ }));
+
+ ALOGW_IF(parameters.size() != 0, "%s: unknown parameters, ignored: %s",
+ __func__, parameters.toString().c_str());
return OK;
}
@@ -734,70 +768,57 @@
status_t StreamOutHalAidl::filterAndUpdateOffloadMetadata(AudioParameter ¶meters) {
TIME_CHECK();
-
- if (parameters.containsKey(String8(AudioParameter::keyOffloadCodecAverageBitRate)) ||
- parameters.containsKey(String8(AudioParameter::keyOffloadCodecSampleRate)) ||
- parameters.containsKey(String8(AudioParameter::keyOffloadCodecChannels)) ||
- parameters.containsKey(String8(AudioParameter::keyOffloadCodecDelaySamples)) ||
- parameters.containsKey(String8(AudioParameter::keyOffloadCodecPaddingSamples))) {
- int value = 0;
- if (parameters.getInt(String8(AudioParameter::keyOffloadCodecAverageBitRate), value)
- == NO_ERROR) {
- if (value <= 0) {
- return BAD_VALUE;
- }
- mOffloadMetadata.averageBitRatePerSecond = value;
- parameters.remove(String8(AudioParameter::keyOffloadCodecAverageBitRate));
- }
-
- if (parameters.getInt(String8(AudioParameter::keyOffloadCodecSampleRate), value)
- == NO_ERROR) {
- if (value <= 0) {
- return BAD_VALUE;
- }
- mOffloadMetadata.sampleRate = value;
- parameters.remove(String8(AudioParameter::keyOffloadCodecSampleRate));
- }
-
- if (parameters.getInt(String8(AudioParameter::keyOffloadCodecChannels), value)
- == NO_ERROR) {
- if (value <= 0) {
- return BAD_VALUE;
- }
- audio_channel_mask_t channel_mask =
- audio_channel_out_mask_from_count(static_cast<uint32_t>(value));
- if (channel_mask == AUDIO_CHANNEL_INVALID) {
- return BAD_VALUE;
- }
- mOffloadMetadata.channelMask =
- VALUE_OR_RETURN_STATUS(
- ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
- channel_mask, false));
- parameters.remove(String8(AudioParameter::keyOffloadCodecChannels));
- }
-
- // The legacy keys are misnamed. The delay and padding are in frame.
- if (parameters.getInt(String8(AudioParameter::keyOffloadCodecDelaySamples), value)
- == NO_ERROR) {
- if (value < 0) {
- return BAD_VALUE;
- }
- mOffloadMetadata.delayFrames = value;
- parameters.remove(String8(AudioParameter::keyOffloadCodecDelaySamples));
- }
-
- if (parameters.getInt(String8(AudioParameter::keyOffloadCodecPaddingSamples), value)
- == NO_ERROR) {
- if (value < 0) {
- return BAD_VALUE;
- }
- mOffloadMetadata.paddingFrames = value;
- parameters.remove(String8(AudioParameter::keyOffloadCodecPaddingSamples));
- }
-
+ bool updateMetadata = false;
+ if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyOffloadCodecAverageBitRate),
+ [&](int value) {
+ return value > 0 ?
+ mOffloadMetadata.averageBitRatePerSecond = value, OK : BAD_VALUE;
+ }))) {
+ updateMetadata = true;
+ }
+ if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyOffloadCodecSampleRate),
+ [&](int value) {
+ return value > 0 ? mOffloadMetadata.sampleRate = value, OK : BAD_VALUE;
+ }))) {
+ updateMetadata = true;
+ }
+ if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyOffloadCodecChannels),
+ [&](int value) -> status_t {
+ if (value > 0) {
+ audio_channel_mask_t channel_mask = audio_channel_out_mask_from_count(
+ static_cast<uint32_t>(value));
+ if (channel_mask == AUDIO_CHANNEL_INVALID) return BAD_VALUE;
+ mOffloadMetadata.channelMask = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ channel_mask, false /*isInput*/));
+ }
+ return BAD_VALUE;
+ }))) {
+ updateMetadata = true;
+ }
+ if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyOffloadCodecDelaySamples),
+ [&](int value) {
+ // The legacy keys are misnamed, the value is in frames.
+ return value > 0 ? mOffloadMetadata.delayFrames = value, OK : BAD_VALUE;
+ }))) {
+ updateMetadata = true;
+ }
+ if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyOffloadCodecPaddingSamples),
+ [&](int value) {
+ // The legacy keys are misnamed, the value is in frames.
+ return value > 0 ? mOffloadMetadata.paddingFrames = value, OK : BAD_VALUE;
+ }))) {
+ updateMetadata = true;
+ }
+ if (updateMetadata) {
ALOGD("%s set offload metadata %s", __func__, mOffloadMetadata.toString().c_str());
- status_t status = statusTFromBinderStatus(mStream->updateOffloadMetadata(mOffloadMetadata));
- if (status != OK) {
+ if (status_t status = statusTFromBinderStatus(
+ mStream->updateOffloadMetadata(mOffloadMetadata)); status != OK) {
ALOGE("%s: updateOffloadMetadata failed %d", __func__, status);
return status;
}