Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73022a3e authored by Vlad Popa's avatar Vlad Popa Committed by Android (Google) Code Review
Browse files

Merge "CTA2075: create loudness params for AAC MPEG-4 and MPEG-D" into main

parents 2e57a8fa 9b83cc27
Loading
Loading
Loading
Loading
+62 −8
Original line number Diff line number Diff line
@@ -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")
+122 −0
Original line number Diff line number Diff line
@@ -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();