Spatializer: add several methods to ISpatializer
Add sevreal methods to Ispatializer interface:
- setParameter() and getParameter() for vendor specific configuration
by engine implementor.
- getOutput() method to query on which output stream
the spatializer is attached to.
- isHeadTrackingSupported() to query if the engine supports head tracking.
Bug: 188502620
Test: make
Change-Id: Ifbded2cf17a45f40d5b6407b8afb4c68c0718ecf
diff --git a/media/libaudioclient/aidl/android/media/ISpatializer.aidl b/media/libaudioclient/aidl/android/media/ISpatializer.aidl
index 6355b46..b871238 100644
--- a/media/libaudioclient/aidl/android/media/ISpatializer.aidl
+++ b/media/libaudioclient/aidl/android/media/ISpatializer.aidl
@@ -50,9 +50,15 @@
/** Gets the selected spatialization level (see SpatializationLevel.aidl) */
SpatializationLevel getLevel();
+ /** Reports if the spatializer engine supports head tracking or not.
+ * This is a pre condition independent of the fact that a head tracking sensor is
+ * registered or not.
+ */
+ boolean isHeadTrackingSupported();
+
/** Reports the list of supported head tracking modes (see SpatializerHeadTrackingMode.aidl).
* The list can be empty if the spatializer implementation does not support head tracking or if
- * no head tracking device is connected.
+ * no head tracking sensor is registered (see setHeadSensor() and setScreenSensor()).
*/
SpatializerHeadTrackingMode[] getSupportedHeadTrackingModes();
@@ -113,4 +119,20 @@
*/
void registerHeadTrackingCallback(@nullable ISpatializerHeadTrackingCallback callback);
+ /**
+ * Sets a parameter to the spatializer engine. Used by effect implementor for vendor
+ * specific configuration.
+ */
+ void setParameter(int key, in byte[] value);
+
+ /**
+ * Gets a parameter from the spatializer engine. Used by effect implementor for vendor
+ * specific configuration.
+ */
+ void getParameter(int key, inout byte[] value);
+
+ /**
+ * Gets the io handle of the output stream the spatializer is connected to.
+ */
+ int getOutput();
}
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index ddc08c1..0ecfad4 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -58,12 +58,6 @@
if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \
std::move(_tmp.value()); })
-#define RETURN_IF_BINDER_ERROR(x) \
- { \
- binder::Status _tmp = (x); \
- if (!_tmp.isOk()) return _tmp; \
- }
-
// ---------------------------------------------------------------------------
class Spatializer::EngineCallbackHandler : public AHandler {
@@ -332,6 +326,16 @@
return Status::ok();
}
+Status Spatializer::isHeadTrackingSupported(bool *supports) {
+ ALOGV("%s mSupportsHeadTracking %d", __func__, mSupportsHeadTracking);
+ if (supports == nullptr) {
+ return binderStatusFromStatusT(BAD_VALUE);
+ }
+ std::lock_guard lock(mLock);
+ *supports = mSupportsHeadTracking;
+ return Status::ok();
+}
+
Status Spatializer::getSupportedHeadTrackingModes(
std::vector<SpatializerHeadTrackingMode>* modes) {
std::lock_guard lock(mLock);
@@ -521,6 +525,41 @@
return Status::ok();
}
+Status Spatializer::setParameter(int key, const std::vector<unsigned char>& value) {
+ ALOGV("%s key %d", __func__, key);
+ std::lock_guard lock(mLock);
+ status_t status = INVALID_OPERATION;
+ if (mEngine != nullptr) {
+ status = setEffectParameter_l(key, value);
+ }
+ return binderStatusFromStatusT(status);
+}
+
+Status Spatializer::getParameter(int key, std::vector<unsigned char> *value) {
+ ALOGV("%s key %d value size %d", __func__, key, (int)value->size());
+ if (value == nullptr) {
+ binderStatusFromStatusT(BAD_VALUE);
+ }
+ std::lock_guard lock(mLock);
+ status_t status = INVALID_OPERATION;
+ if (mEngine != nullptr) {
+ ALOGV("%s key %d mEngine %p", __func__, key, mEngine.get());
+ status = getEffectParameter_l(key, value);
+ }
+ return binderStatusFromStatusT(status);
+}
+
+Status Spatializer::getOutput(int *output) {
+ ALOGV("%s", __func__);
+ if (output == nullptr) {
+ binderStatusFromStatusT(BAD_VALUE);
+ }
+ std::lock_guard lock(mLock);
+ *output = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_io_handle_t_int32_t(mOutput));
+ ALOGV("%s got output %d", __func__, *output);
+ return Status::ok();
+}
+
// SpatializerPoseController::Listener
void Spatializer::onHeadToStagePose(const Pose3f& headToStage) {
ALOGV("%s", __func__);
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 61daf01..136a467 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -100,6 +100,7 @@
binder::Status getSupportedLevels(std::vector<media::SpatializationLevel>* levels) override;
binder::Status setLevel(media::SpatializationLevel level) override;
binder::Status getLevel(media::SpatializationLevel *level) override;
+ binder::Status isHeadTrackingSupported(bool *supports);
binder::Status getSupportedHeadTrackingModes(
std::vector<media::SpatializerHeadTrackingMode>* modes) override;
binder::Status setDesiredHeadTrackingMode(
@@ -115,6 +116,9 @@
binder::Status getSupportedModes(std::vector<media::SpatializationMode>* modes) override;
binder::Status registerHeadTrackingCallback(
const sp<media::ISpatializerHeadTrackingCallback>& callback) override;
+ binder::Status setParameter(int key, const std::vector<unsigned char>& value) override;
+ binder::Status getParameter(int key, std::vector<unsigned char> *value) override;
+ binder::Status getOutput(int *output);
/** IBinder::DeathRecipient. Listen to the death of the INativeSpatializerCallback. */
virtual void binderDied(const wp<IBinder>& who);
@@ -209,6 +213,7 @@
if (numParams > kMaxEffectParamValues) {
return BAD_VALUE;
}
+ (*values).clear();
std::copy(¶ms[0], ¶ms[numParams], back_inserter(*values));
return NO_ERROR;
}
@@ -229,7 +234,46 @@
*(uint32_t *)p->data = type;
memcpy((uint32_t *)p->data + 1, values.data(), sizeof(T) * values.size());
- return mEngine->setParameter(p);
+ status_t status = mEngine->setParameter(p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ if (p->status != NO_ERROR) {
+ return p->status;
+ }
+ return NO_ERROR;
+ }
+
+ /**
+ * Get a parameter from spatializer engine by calling getParameter on AudioEffect object.
+ * It is possible to read more than one value of type T according to the parameter type
+ * by specifying values vector size.
+ */
+ template<typename T>
+ status_t getEffectParameter_l(uint32_t type, std::vector<T> *values) REQUIRES(mLock) {
+ static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits");
+
+ uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + values->size()];
+ effect_param_t *p = (effect_param_t *)cmd;
+ p->psize = sizeof(uint32_t);
+ p->vsize = sizeof(T) * values->size();
+ *(uint32_t *)p->data = type;
+
+ status_t status = mEngine->getParameter(p);
+
+ if (status != NO_ERROR) {
+ return status;
+ }
+ if (p->status != NO_ERROR) {
+ return p->status;
+ }
+
+ int numValues = std::min(p->vsize / sizeof(T), values->size());
+ (*values).clear();
+ T *retValues = (T *)((uint8_t *)p->data + sizeof(uint32_t));
+ std::copy(&retValues[0], &retValues[numValues], back_inserter(*values));
+
+ return NO_ERROR;
}
void postFramesProcessedMsg(int frames);