diff options
| -rw-r--r-- | services/core/java/com/android/server/audio/LoudnessCodecHelper.java | 70 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java | 122 |
2 files changed, 184 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java index 3c67e9dd116b..c306e3c07ac0 100644 --- a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java +++ b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java @@ -21,6 +21,11 @@ import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES; import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEARING_AID; import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_WATCH; import static android.media.AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID; +import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4; +import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D; +import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE; +import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION; +import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL; import android.annotation.IntDef; import android.annotation.NonNull; @@ -41,6 +46,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -70,10 +76,14 @@ public class LoudnessCodecHelper { private static final String SYSTEM_PROPERTY_SPEAKER_SPL_RANGE_SIZE = "audio.loudness.builtin-speaker-spl-range-size"; - private static final int SPL_RANGE_UNKNOWN = 0; - private static final int SPL_RANGE_SMALL = 1; - private static final int SPL_RANGE_MEDIUM = 2; - private static final int SPL_RANGE_LARGE = 3; + @VisibleForTesting + static final int SPL_RANGE_UNKNOWN = 0; + @VisibleForTesting + static final int SPL_RANGE_SMALL = 1; + @VisibleForTesting + static final int SPL_RANGE_MEDIUM = 2; + @VisibleForTesting + static final int SPL_RANGE_LARGE = 3; /** The possible transducer SPL ranges as defined in CTA2075 */ @IntDef({ @@ -125,7 +135,8 @@ public class LoudnessCodecHelper { private final AudioService mAudioService; /** Contains the properties necessary to compute the codec loudness related parameters. */ - private static final class LoudnessCodecInputProperties { + @VisibleForTesting + static final class LoudnessCodecInputProperties { private final int mMetadataType; private final boolean mIsDownmixing; @@ -200,10 +211,53 @@ public class LoudnessCodecHelper { } PersistableBundle createLoudnessParameters() { - // TODO: create bundle with new parameters - return new PersistableBundle(); - } + PersistableBundle loudnessParams = new PersistableBundle(); + + switch (mDeviceSplRange) { + case SPL_RANGE_LARGE: + // corresponds to -31dB attenuation + loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 124); + if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) { + loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 0); + } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) { + // general compression + loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6); + } + break; + case SPL_RANGE_MEDIUM: + // corresponds to -24dB attenuation + loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96); + if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) { + loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0); + } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) { + // general compression + loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6); + } + break; + case SPL_RANGE_SMALL: + // corresponds to -16dB attenuation + loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 64); + if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) { + loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 1); + } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) { + // limited playback range compression + loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 3); + } + break; + default: + // corresponds to -24dB attenuation + loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96); + if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) { + loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0); + } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) { + // general compression + loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6); + } + break; + } + return loudnessParams; + } } @GuardedBy("mLock") diff --git a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java index 749b07d16ebe..42c5205455ca 100644 --- a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java @@ -19,6 +19,16 @@ import static android.media.AudioManager.GET_DEVICES_OUTPUTS; import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_DEVICE_ID; import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4; import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D; +import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE; +import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION; +import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL; + +import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_LARGE; +import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_MEDIUM; +import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_SMALL; +import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_UNKNOWN; + +import static junit.framework.Assert.assertEquals; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; @@ -34,11 +44,15 @@ import android.media.ILoudnessCodecUpdatesDispatcher; import android.media.LoudnessCodecInfo; import android.media.PlayerBase; import android.os.IBinder; +import android.os.PersistableBundle; import android.platform.test.annotations.Presubmit; import android.util.Log; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.server.audio.LoudnessCodecHelper.DeviceSplRange; +import com.android.server.audio.LoudnessCodecHelper.LoudnessCodecInputProperties; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -200,6 +214,108 @@ public class LoudnessCodecHelperTest { any()); } + @Test + public void checkParcelableBundle_forMpeg4CodecInputProperties() { + PersistableBundle loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true, + SPL_RANGE_SMALL).createLoudnessParameters(); + assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false, + SPL_RANGE_SMALL).createLoudnessParameters(); + assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true, + SPL_RANGE_MEDIUM).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false, + SPL_RANGE_MEDIUM).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true, + SPL_RANGE_LARGE).createLoudnessParameters(); + assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false, + SPL_RANGE_LARGE).createLoudnessParameters(); + assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true, + SPL_RANGE_UNKNOWN).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false, + SPL_RANGE_UNKNOWN).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION)); + } + + @Test + public void checkParcelableBundle_forMpegDCodecInputProperties() { + PersistableBundle loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true, + SPL_RANGE_SMALL).createLoudnessParameters(); + assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false, + SPL_RANGE_SMALL).createLoudnessParameters(); + assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true, + SPL_RANGE_MEDIUM).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false, + SPL_RANGE_MEDIUM).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true, + SPL_RANGE_LARGE).createLoudnessParameters(); + assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false, + SPL_RANGE_LARGE).createLoudnessParameters(); + assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true, + SPL_RANGE_UNKNOWN).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + + loudnessParameters = createInputProperties( + CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false, + SPL_RANGE_UNKNOWN).createLoudnessParameters(); + assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL)); + assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE)); + } + private List<AudioPlaybackConfiguration> getApcListForPiids(int... piids) { final ArrayList<AudioPlaybackConfiguration> apcList = new ArrayList<>(); @@ -220,6 +336,12 @@ public class LoudnessCodecHelperTest { return apcList; } + private static LoudnessCodecInputProperties createInputProperties( + int metadataType, boolean isDownmixing, @DeviceSplRange int splRange) { + return new LoudnessCodecInputProperties.Builder().setMetadataType( + metadataType).setIsDownmixing(isDownmixing).setDeviceSplRange(splRange).build(); + } + private static LoudnessCodecInfo getLoudnessInfo(int mediaCodecHash, boolean isDownmixing, int metadataType) { LoudnessCodecInfo info = new LoudnessCodecInfo(); |