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

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

Merge "CTA2075: Finalize the loudness configurator API" into main

parents 7fd1bda9 2f3da615
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -22036,6 +22036,19 @@ package android.media {
    method public void onJetUserIdUpdate(android.media.JetPlayer, int, int);
  }
  @FlaggedApi("android.media.audio.loudness_configurator_api") public class LoudnessCodecConfigurator {
    method @FlaggedApi("android.media.audio.loudness_configurator_api") public void addMediaCodec(@NonNull android.media.MediaCodec);
    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public static android.media.LoudnessCodecConfigurator create();
    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public static android.media.LoudnessCodecConfigurator create(@NonNull java.util.concurrent.Executor, @NonNull android.media.LoudnessCodecConfigurator.OnLoudnessCodecUpdateListener);
    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public android.os.Bundle getLoudnessCodecParams(@NonNull android.media.AudioTrack, @NonNull android.media.MediaCodec);
    method @FlaggedApi("android.media.audio.loudness_configurator_api") public void removeMediaCodec(@NonNull android.media.MediaCodec);
    method @FlaggedApi("android.media.audio.loudness_configurator_api") public void setAudioTrack(@Nullable android.media.AudioTrack);
  }
  @FlaggedApi("android.media.audio.loudness_configurator_api") public static interface LoudnessCodecConfigurator.OnLoudnessCodecUpdateListener {
    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public default android.os.Bundle onLoudnessCodecUpdate(@NonNull android.media.MediaCodec, @NonNull android.os.Bundle);
  }
  public class MediaActionSound {
    ctor public MediaActionSound();
    method public void load(int);
+88 −95
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import androidx.annotation.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -46,9 +47,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 * parameter updates are defined by the CTA-2075 standard.
 * <p>A new object should be instantiated for each {@link AudioTrack} with the help
 * of {@link #create()} or {@link #create(Executor, OnLoudnessCodecUpdateListener)}.
 *
 * TODO: remove hide once API is final
 * @hide
 */
@FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
public class LoudnessCodecConfigurator {
@@ -56,9 +54,6 @@ public class LoudnessCodecConfigurator {

    /**
     * Listener used for receiving asynchronous loudness metadata updates.
     *
     * TODO: remove hide once API is final
     * @hide
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    public interface OnLoudnessCodecUpdateListener {
@@ -75,9 +70,6 @@ public class LoudnessCodecConfigurator {
         * @return a Bundle which contains the original computed codecValues
         * aggregated with user edits. The platform will configure the associated
         * MediaCodecs with the returned Bundle params.
         *
         * TODO: remove hide once API is final
         * @hide
         */
        @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
        @NonNull
@@ -111,9 +103,6 @@ public class LoudnessCodecConfigurator {
     * Otherwise, use {@link #create(Executor, OnLoudnessCodecUpdateListener)}.
     *
     * @return the {@link LoudnessCodecConfigurator} instance
     *
     * TODO: remove hide once API is final
     * @hide
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    public static @NonNull LoudnessCodecConfigurator create() {
@@ -132,9 +121,6 @@ public class LoudnessCodecConfigurator {
     * @param listener used for receiving updates
     *
     * @return the {@link LoudnessCodecConfigurator} instance
     *
     * TODO: remove hide once API is final
     * @hide
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    public static @NonNull LoudnessCodecConfigurator create(
@@ -199,12 +185,9 @@ public class LoudnessCodecConfigurator {
     *                   method will have the effect of clearing the existing set
     *                   {@link AudioTrack} and will stop receiving asynchronous
     *                   loudness updates
     *
     * TODO: remove hide once API is final
     * @hide
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    public void setAudioTrack(AudioTrack audioTrack) {
    public void setAudioTrack(@Nullable AudioTrack audioTrack) {
        List<LoudnessCodecInfo> codecInfos;
        int piid = PLAYER_PIID_INVALID;
        int oldPiid = PLAYER_PIID_INVALID;
@@ -249,10 +232,11 @@ public class LoudnessCodecConfigurator {
     * previously added.
     *
     * @param mediaCodec the codec to start receiving asynchronous loudness
     *                   updates
     *
     * TODO: remove hide once API is final
     * @hide
     *                   updates. The codec has to be in a configured or started
     *                   state in order to add it for loudness updates.
     * @throws IllegalArgumentException if the {@code mediaCodec} was not configured,
     *                                  does not contain loudness metadata or if it
     *                                  was already added before
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    public void addMediaCodec(@NonNull MediaCodec mediaCodec) {
@@ -261,7 +245,9 @@ public class LoudnessCodecConfigurator {
        int piid = PLAYER_PIID_INVALID;
        final LoudnessCodecInfo mcInfo = getCodecInfo(mc);

        if (mcInfo != null) {
        if (mcInfo == null) {
            throw new IllegalArgumentException("Could not extract codec loudness information");
        }
        synchronized (mConfiguratorLock) {
            final AtomicBoolean containsCodec = new AtomicBoolean(false);
            Set<MediaCodec> newSet = mMediaCodecs.computeIfPresent(mcInfo, (info, codecSet) -> {
@@ -274,8 +260,8 @@ public class LoudnessCodecConfigurator {
                mMediaCodecs.put(mcInfo, newSet);
            }
            if (containsCodec.get()) {
                    Log.v(TAG, "Loudness configurator already added media codec " + mediaCodec);
                    return;
                throw new IllegalArgumentException(
                        "Loudness configurator already added " + mediaCodec);
            }
            if (mAudioTrack != null) {
                piid = mAudioTrack.getPlayerIId();
@@ -286,7 +272,6 @@ public class LoudnessCodecConfigurator {
            mLcDispatcher.addLoudnessCodecInfo(piid, mediaCodec.hashCode(), mcInfo);
        }
    }
    }

    /**
     * Removes the {@link MediaCodec} from receiving loudness updates.
@@ -296,26 +281,29 @@ public class LoudnessCodecConfigurator {
     * <p>No elements will be removed if the passed mediaCodec was not added before.
     *
     * @param mediaCodec the element to remove for receiving asynchronous updates
     *
     * TODO: remove hide once API is final
     * @hide
     * @throws IllegalArgumentException if the {@code mediaCodec} was not configured,
     *                                  does not contain loudness metadata or if it
     *                                  was not added before
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    public void removeMediaCodec(@NonNull MediaCodec mediaCodec) {
        int piid = PLAYER_PIID_INVALID;
        LoudnessCodecInfo mcInfo;
        AtomicBoolean removedMc = new AtomicBoolean(false);
        AtomicBoolean removeInfo = new AtomicBoolean(false);

        mcInfo = getCodecInfo(Objects.requireNonNull(mediaCodec,
                "MediaCodec for removeMediaCodec cannot be null"));

        if (mcInfo != null) {
        if (mcInfo == null) {
            throw new IllegalArgumentException("Could not extract codec loudness information");
        }
        synchronized (mConfiguratorLock) {
            if (mAudioTrack != null) {
                piid = mAudioTrack.getPlayerIId();
            }
            mMediaCodecs.computeIfPresent(mcInfo, (format, mcs) -> {
                    mcs.remove(mediaCodec);
                removedMc.set(mcs.remove(mediaCodec));
                if (mcs.isEmpty()) {
                    // remove the entry
                    removeInfo.set(true);
@@ -323,13 +311,16 @@ public class LoudnessCodecConfigurator {
                }
                return mcs;
            });
            if (!removedMc.get()) {
                throw new IllegalArgumentException(
                        "Loudness configurator does not contain " + mediaCodec);
            }
        }

        if (piid != PLAYER_PIID_INVALID && removeInfo.get()) {
            mLcDispatcher.removeLoudnessCodecInfo(piid, mcInfo);
        }
    }
    }

    /**
     * Gets synchronous loudness updates when no listener is required. The provided
@@ -342,9 +333,6 @@ public class LoudnessCodecConfigurator {
     *
     * @return the {@link Bundle} containing the current loudness parameters. Caller is
     * responsible to update the {@link MediaCodec}
     *
     * TODO: remove hide once API is final
     * @hide
     */
    @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
    @NonNull
@@ -375,7 +363,7 @@ public class LoudnessCodecConfigurator {
    }

    /** @hide */
    /*package*/ HashMap<LoudnessCodecInfo, Set<MediaCodec>> getRegisteredMediaCodecs() {
    /*package*/ Map<LoudnessCodecInfo, Set<MediaCodec>> getRegisteredMediaCodecs() {
        synchronized (mConfiguratorLock) {
            return mMediaCodecs;
        }
@@ -397,11 +385,12 @@ public class LoudnessCodecConfigurator {
            return null;
        }

        try {
            final MediaFormat inputFormat = mediaCodec.getInputFormat();
            final String mimeType = inputFormat.getString(MediaFormat.KEY_MIME);
            if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mimeType)) {
            // check both KEY_AAC_PROFILE and KEY_PROFILE as some codecs may only recognize one of
            // these two keys
                // check both KEY_AAC_PROFILE and KEY_PROFILE as some codecs may only recognize
                // one of these two keys
                int aacProfile = -1;
                int profile = -1;
                try {
@@ -428,6 +417,10 @@ public class LoudnessCodecConfigurator {
            final MediaFormat outputFormat = mediaCodec.getOutputFormat();
            lci.isDownmixing = outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
                    < inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
        } catch (IllegalStateException e) {
            Log.e(TAG, "MediaCodec is not configured", e);
            return null;
        }

        return lci;
    }
+2 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import androidx.annotation.NonNull;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
@@ -81,7 +82,7 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
                    mConfiguratorListener.computeIfPresent(listener, (l, lcConfig) -> {
                        // send the appropriate bundle for the user to update
                        if (lcConfig.getAssignedTrackPiid() == piid) {
                            final HashMap<LoudnessCodecInfo, Set<MediaCodec>> mediaCodecsMap =
                            final Map<LoudnessCodecInfo, Set<MediaCodec>> mediaCodecsMap =
                                    lcConfig.getRegisteredMediaCodecs();
                            for (LoudnessCodecInfo codecInfo : mediaCodecsMap.keySet()) {
                                final String infoKey = Integer.toString(codecInfo.hashCode());