VolumeShaper: Initial implementation
The VolumeShaper is used to apply a volume
envelope to an AudioTrack or a MediaPlayer.
Test: CTS
Bug: 30920125
Bug: 31015569
Change-Id: I42e2f13bd6879299dc780e60d143c2d465483a44
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 966267a..5222a42 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -70,6 +70,8 @@
SET_RETRANSMIT_ENDPOINT,
GET_RETRANSMIT_ENDPOINT,
SET_NEXT_PLAYER,
+ APPLY_VOLUME_SHAPER,
+ GET_VOLUME_SHAPER_STATE,
// ModDrm
PREPARE_DRM,
RELEASE_DRM,
@@ -468,6 +470,57 @@
return err;
}
+ virtual VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+
+ status_t tmp;
+ status_t status = configuration.get() == nullptr
+ ? data.writeInt32(0)
+ : (tmp = data.writeInt32(1)) != NO_ERROR
+ ? tmp : configuration->writeToParcel(&data);
+ if (status != NO_ERROR) {
+ return VolumeShaper::Status(status);
+ }
+
+ status = operation.get() == nullptr
+ ? status = data.writeInt32(0)
+ : (tmp = data.writeInt32(1)) != NO_ERROR
+ ? tmp : operation->writeToParcel(&data);
+ if (status != NO_ERROR) {
+ return VolumeShaper::Status(status);
+ }
+
+ int32_t remoteVolumeShaperStatus;
+ status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32(&remoteVolumeShaperStatus);
+ }
+ if (status != NO_ERROR) {
+ return VolumeShaper::Status(status);
+ }
+ return VolumeShaper::Status(remoteVolumeShaperStatus);
+ }
+
+ virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+
+ data.writeInt32(id);
+ status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
+ if (status != NO_ERROR) {
+ return nullptr;
+ }
+ sp<VolumeShaper::State> state = new VolumeShaper::State();
+ status = state->readFromParcel(reply);
+ if (status != NO_ERROR) {
+ return nullptr;
+ }
+ return state;
+ }
+
// ModDrm
status_t prepareDrm(const uint8_t uuid[16], const int mode)
{
@@ -893,6 +946,43 @@
return NO_ERROR;
} break;
+ case APPLY_VOLUME_SHAPER: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ sp<VolumeShaper::Configuration> configuration;
+ sp<VolumeShaper::Operation> operation;
+
+ int32_t present;
+ status_t status = data.readInt32(&present);
+ if (status == NO_ERROR && present != 0) {
+ configuration = new VolumeShaper::Configuration();
+ status = configuration->readFromParcel(data);
+ }
+ if (status == NO_ERROR) {
+ status = data.readInt32(&present);
+ }
+ if (status == NO_ERROR && present != 0) {
+ operation = new VolumeShaper::Operation();
+ status = operation->readFromParcel(data);
+ }
+ if (status == NO_ERROR) {
+ status = (status_t)applyVolumeShaper(configuration, operation);
+ }
+ reply->writeInt32(status);
+ return NO_ERROR;
+ } break;
+ case GET_VOLUME_SHAPER_STATE: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ int id;
+ status_t status = data.readInt32(&id);
+ if (status == NO_ERROR) {
+ sp<VolumeShaper::State> state = getVolumeShaperState(id);
+ if (state.get() != nullptr) {
+ status = state->writeToParcel(reply);
+ }
+ }
+ return NO_ERROR;
+ } break;
+
// ModDrm
case PREPARE_DRM: {
CHECK_INTERFACE(IMediaPlayer, data, reply);