diff options
8 files changed, 91 insertions, 79 deletions
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index d14775fa9ad9..5c8758a6aa73 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -739,7 +739,7 @@ interface IAudioService { oneway void stopLoudnessCodecUpdates(int piid); - oneway void addLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo); + oneway void addLoudnessCodecInfo(int piid, int mediaCodecHash, in LoudnessCodecInfo codecInfo); oneway void removeLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo); diff --git a/media/java/android/media/LoudnessCodecConfigurator.java b/media/java/android/media/LoudnessCodecConfigurator.java index 92f337244daf..c879179f7082 100644 --- a/media/java/android/media/LoudnessCodecConfigurator.java +++ b/media/java/android/media/LoudnessCodecConfigurator.java @@ -30,7 +30,6 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -284,7 +283,7 @@ public class LoudnessCodecConfigurator { } if (piid != PLAYER_PIID_INVALID) { - mLcDispatcher.addLoudnessCodecInfo(piid, mcInfo); + mLcDispatcher.addLoudnessCodecInfo(piid, mediaCodec.hashCode(), mcInfo); } } } @@ -305,7 +304,7 @@ public class LoudnessCodecConfigurator { public void removeMediaCodec(@NonNull MediaCodec mediaCodec) { int piid = PLAYER_PIID_INVALID; LoudnessCodecInfo mcInfo; - AtomicBoolean removed = new AtomicBoolean(false); + AtomicBoolean removeInfo = new AtomicBoolean(false); mcInfo = getCodecInfo(Objects.requireNonNull(mediaCodec, "MediaCodec for removeMediaCodec cannot be null")); @@ -316,16 +315,17 @@ public class LoudnessCodecConfigurator { piid = mAudioTrack.getPlayerIId(); } mMediaCodecs.computeIfPresent(mcInfo, (format, mcs) -> { - removed.set(mcs.remove(mediaCodec)); + mcs.remove(mediaCodec); if (mcs.isEmpty()) { // remove the entry + removeInfo.set(true); return null; } return mcs; }); } - if (piid != PLAYER_PIID_INVALID && removed.get()) { + if (piid != PLAYER_PIID_INVALID && removeInfo.get()) { mLcDispatcher.removeLoudnessCodecInfo(piid, mcInfo); } } @@ -375,9 +375,9 @@ public class LoudnessCodecConfigurator { } /** @hide */ - /*package*/ List<MediaCodec> getRegisteredMediaCodecList() { + /*package*/ HashMap<LoudnessCodecInfo, Set<MediaCodec>> getRegisteredMediaCodecs() { synchronized (mConfiguratorLock) { - return mMediaCodecs.values().stream().flatMap(Collection::stream).toList(); + return mMediaCodecs; } } @@ -429,8 +429,6 @@ public class LoudnessCodecConfigurator { lci.isDownmixing = outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT) < inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT); - lci.mediaCodecHashCode = mediaCodec.hashCode(); - return lci; } } diff --git a/media/java/android/media/LoudnessCodecDispatcher.java b/media/java/android/media/LoudnessCodecDispatcher.java index 5237caed27d3..0da1a497a8fd 100644 --- a/media/java/android/media/LoudnessCodecDispatcher.java +++ b/media/java/android/media/LoudnessCodecDispatcher.java @@ -35,6 +35,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Objects; +import java.util.Set; import java.util.concurrent.Executor; /** @@ -71,33 +72,49 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub { @Override public void dispatchLoudnessCodecParameterChange(int piid, PersistableBundle params) { + if (DEBUG) { + Log.d(TAG, "dispatchLoudnessCodecParameterChange for piid " + piid + + " persistable bundle: " + params); + } mLoudnessListenerMgr.callListeners(listener -> { synchronized (mLock) { mConfiguratorListener.computeIfPresent(listener, (l, lcConfig) -> { // send the appropriate bundle for the user to update if (lcConfig.getAssignedTrackPiid() == piid) { - final List<MediaCodec> mediaCodecs = - lcConfig.getRegisteredMediaCodecList(); - for (MediaCodec mediaCodec : mediaCodecs) { - final String infoKey = Integer.toString(mediaCodec.hashCode()); + final HashMap<LoudnessCodecInfo, Set<MediaCodec>> mediaCodecsMap = + lcConfig.getRegisteredMediaCodecs(); + for (LoudnessCodecInfo codecInfo : mediaCodecsMap.keySet()) { + final String infoKey = Integer.toString(codecInfo.hashCode()); + Bundle bundle = null; if (params.containsKey(infoKey)) { - Bundle bundle = new Bundle( - params.getPersistableBundle(infoKey)); - if (DEBUG) { - Log.d(TAG, - "Received for piid " + piid + " bundle: " + bundle); + bundle = new Bundle(params.getPersistableBundle(infoKey)); + } + + final Set<MediaCodec> mediaCodecs = mediaCodecsMap.get(codecInfo); + for (MediaCodec mediaCodec : mediaCodecs) { + final String mediaCodecKey = Integer.toString( + mediaCodec.hashCode()); + if (bundle == null && !params.containsKey(mediaCodecKey)) { + continue; + } + boolean canBreak = false; + if (bundle == null) { + // key was set by media codec hash to update single codec + bundle = new Bundle( + params.getPersistableBundle(mediaCodecKey)); + canBreak = true; } bundle = LoudnessCodecUpdatesDispatcherStub.filterLoudnessParams( - l.onLoudnessCodecUpdate(mediaCodec, bundle)); - if (DEBUG) { - Log.d(TAG, "User changed for piid " + piid - + " to filtered bundle: " + bundle); - } + l.onLoudnessCodecUpdate(mediaCodec, + bundle)); if (!bundle.isDefinitelyEmpty()) { mediaCodec.setParameters(bundle); } + if (canBreak) { + break; + } } } } @@ -221,9 +238,10 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub { } /** @hide */ - public void addLoudnessCodecInfo(int piid, @NonNull LoudnessCodecInfo mcInfo) { + public void addLoudnessCodecInfo(int piid, int mediaCodecHash, + @NonNull LoudnessCodecInfo mcInfo) { try { - mAudioService.addLoudnessCodecInfo(piid, mcInfo); + mAudioService.addLoudnessCodecInfo(piid, mediaCodecHash, mcInfo); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/media/java/android/media/LoudnessCodecInfo.aidl b/media/java/android/media/LoudnessCodecInfo.aidl index fd695179057d..d9fb9629ab48 100644 --- a/media/java/android/media/LoudnessCodecInfo.aidl +++ b/media/java/android/media/LoudnessCodecInfo.aidl @@ -37,7 +37,6 @@ parcelable LoudnessCodecInfo { CODEC_METADATA_TYPE_DTS_UHD = 6 } - int mediaCodecHashCode; CodecMetadataType metadataType; boolean isDownmixing; }
\ No newline at end of file diff --git a/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java b/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java index 65a9799431e7..c9e36b7f10bd 100644 --- a/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java +++ b/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java @@ -208,7 +208,7 @@ public class LoudnessCodecConfiguratorTest { verify(mAudioService).startLoudnessCodecUpdates(eq(track.getPlayerIId()), anyList()); mLcc.addMediaCodec(createAndConfigureMediaCodec()); - verify(mAudioService).addLoudnessCodecInfo(eq(track.getPlayerIId()), any()); + verify(mAudioService).addLoudnessCodecInfo(eq(track.getPlayerIId()), anyInt(), any()); } @Test diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 3f27ca024f15..5b6f919ead5f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -10667,8 +10667,8 @@ public class AudioService extends IAudioService.Stub /** @see LoudnessCodecConfigurator#addMediaCodec(MediaCodec) */ @Override - public void addLoudnessCodecInfo(int piid, LoudnessCodecInfo codecInfo) { - mLoudnessCodecHelper.addLoudnessCodecInfo(piid, codecInfo); + public void addLoudnessCodecInfo(int piid, int mediaCodecHash, LoudnessCodecInfo codecInfo) { + mLoudnessCodecHelper.addLoudnessCodecInfo(piid, mediaCodecHash, codecInfo); } /** @see LoudnessCodecConfigurator#removeMediaCodec(MediaCodec) */ diff --git a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java index c306e3c07ac0..31c0d4f78dd6 100644 --- a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java +++ b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java @@ -281,13 +281,13 @@ public class LoudnessCodecHelper { if (DEBUG) { Log.d(TAG, "startLoudnessCodecUpdates: piid " + piid + " codecInfos " + codecInfoList); } - Set<LoudnessCodecInfo> infoSet; + synchronized (mLock) { if (mStartedPiids.contains(piid)) { Log.w(TAG, "Already started loudness updates for piid " + piid); return; } - infoSet = new HashSet<>(codecInfoList); + Set<LoudnessCodecInfo> infoSet = new HashSet<>(codecInfoList); mStartedPiids.put(piid, infoSet); mPiidToPidCache.put(piid, Binder.getCallingPid()); @@ -296,7 +296,7 @@ public class LoudnessCodecHelper { try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { mAudioService.getActivePlaybackConfigurations().stream().filter( conf -> conf.getPlayerInterfaceId() == piid).findFirst().ifPresent( - apc -> updateCodecParametersForConfiguration(apc, infoSet)); + this::updateCodecParametersForConfiguration); } } @@ -315,9 +315,10 @@ public class LoudnessCodecHelper { } } - void addLoudnessCodecInfo(int piid, LoudnessCodecInfo info) { + void addLoudnessCodecInfo(int piid, int mediaCodecHash, LoudnessCodecInfo info) { if (DEBUG) { - Log.d(TAG, "addLoudnessCodecInfo: piid " + piid + " info " + info); + Log.d(TAG, "addLoudnessCodecInfo: piid " + piid + " mcHash " + mediaCodecHash + " info " + + info); } Set<LoudnessCodecInfo> infoSet; @@ -334,7 +335,20 @@ public class LoudnessCodecHelper { try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { mAudioService.getActivePlaybackConfigurations().stream().filter( conf -> conf.getPlayerInterfaceId() == piid).findFirst().ifPresent( - apc -> updateCodecParametersForConfiguration(apc, Set.of(info))); + apc -> { + final AudioDeviceInfo deviceInfo = apc.getAudioDeviceInfo(); + if (deviceInfo != null) { + PersistableBundle updateBundle = new PersistableBundle(); + synchronized (mLock) { + updateBundle.putPersistableBundle( + Integer.toString(mediaCodecHash), + getCodecBundle_l(deviceInfo, info)); + } + if (!updateBundle.isDefinitelyEmpty()) { + dispatchNewLoudnessParameters(piid, updateBundle); + } + } + }); } } @@ -435,48 +449,41 @@ public class LoudnessCodecHelper { } } - updateApcList.forEach(apc -> updateCodecParametersForConfiguration(apc, null)); + updateApcList.forEach(apc -> updateCodecParametersForConfiguration(apc)); } - /** Updates and dispatches the new loudness parameters for the {@code codecInfos} set. + /** Updates and dispatches the new loudness parameters for all its registered codecs. * * @param apc the player configuration for which the loudness parameters are updated. - * @param codecInfos the codec info for which the parameters are updated. If {@code null}, - * send updates for all the started codecs assigned to {@code apc} */ - private void updateCodecParametersForConfiguration(AudioPlaybackConfiguration apc, - Set<LoudnessCodecInfo> codecInfos) { + private void updateCodecParametersForConfiguration(AudioPlaybackConfiguration apc) { if (DEBUG) { - Log.d(TAG, "updateCodecParametersForConfiguration apc:" + apc + " codecInfos: " - + codecInfos); + Log.d(TAG, "updateCodecParametersForConfiguration apc:" + apc); } + final PersistableBundle allBundles = new PersistableBundle(); final int piid = apc.getPlayerInterfaceId(); + synchronized (mLock) { - if (codecInfos == null) { - codecInfos = mStartedPiids.get(piid); - } + final Set<LoudnessCodecInfo> codecInfos = mStartedPiids.get(piid); final AudioDeviceInfo deviceInfo = apc.getAudioDeviceInfo(); if (codecInfos != null && deviceInfo != null) { for (LoudnessCodecInfo info : codecInfos) { - allBundles.putPersistableBundle(Integer.toString(info.mediaCodecHashCode), + allBundles.putPersistableBundle(Integer.toString(info.hashCode()), getCodecBundle_l(deviceInfo, info)); } } } if (!allBundles.isDefinitelyEmpty()) { - if (DEBUG) { - Log.d(TAG, "Dispatching for piid: " + piid + " bundle: " + allBundles); - } dispatchNewLoudnessParameters(piid, allBundles); } } private void dispatchNewLoudnessParameters(int piid, PersistableBundle bundle) { if (DEBUG) { - Log.d(TAG, "dispatchNewLoudnessParameters: piid " + piid); + Log.d(TAG, "dispatchNewLoudnessParameters: piid " + piid + " bundle: " + bundle); } final int nbDispatchers = mLoudnessUpdateDispatchers.beginBroadcast(); for (int i = 0; i < nbDispatchers; ++i) { 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 42c5205455ca..9c8276aac4dd 100644 --- a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java @@ -98,8 +98,7 @@ public class LoudnessCodecHelperTest { mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, - List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_4))); + List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4))); verify(mDispatcher).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any()); } @@ -110,8 +109,7 @@ public class LoudnessCodecHelperTest { mLoudnessHelper.unregisterLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, - List.of(getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/false, - CODEC_METADATA_TYPE_MPEG_D))); + List.of(getLoudnessInfo(/*isDownmixing=*/false, CODEC_METADATA_TYPE_MPEG_D))); verify(mDispatcher, times(0)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any()); @@ -122,11 +120,9 @@ public class LoudnessCodecHelperTest { mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, - List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_4))); - mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, - getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_D)); + List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4))); + mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, /*mediaCodecHash=*/222, + getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D)); verify(mDispatcher, times(2)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any()); @@ -138,11 +134,10 @@ public class LoudnessCodecHelperTest { mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, - List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true, + List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4))); - mLoudnessHelper.addLoudnessCodecInfo(newPiid, - getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_D)); + mLoudnessHelper.addLoudnessCodecInfo(newPiid, /*mediaCodecHash=*/222, + getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D)); verify(mDispatcher, times(1)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any()); @@ -154,12 +149,10 @@ public class LoudnessCodecHelperTest { mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, - List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_4))); + List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4))); //does not trigger dispatch since active apc list does not contain newPiid mLoudnessHelper.startLoudnessCodecUpdates(newPiid, - List.of(getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_D))); + List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D))); verify(mDispatcher, times(1)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any()); @@ -171,9 +164,8 @@ public class LoudnessCodecHelperTest { @Test public void updateCodecParameters_noStartedPiids_noDispatch() throws Exception { mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); - mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, - getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true, - CODEC_METADATA_TYPE_MPEG_D)); + mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, /*mediaCodecHash=*/222, + getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D)); mLoudnessHelper.updateCodecParameters(getApcListForPiids(mInitialApcPiid)); @@ -184,8 +176,8 @@ public class LoudnessCodecHelperTest { @Test public void updateCodecParameters_removedCodecInfo_noDispatch() throws Exception { - final LoudnessCodecInfo info = getLoudnessInfo(/*mediaCodecHash=*/111, - /*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4); + final LoudnessCodecInfo info = getLoudnessInfo(/*isDownmixing=*/true, + CODEC_METADATA_TYPE_MPEG_4); mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, List.of(info)); @@ -200,8 +192,8 @@ public class LoudnessCodecHelperTest { @Test public void updateCodecParameters_stoppedPiids_noDispatch() throws Exception { - final LoudnessCodecInfo info = getLoudnessInfo(/*mediaCodecHash=*/111, - /*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4); + final LoudnessCodecInfo info = getLoudnessInfo(/*isDownmixing=*/true, + CODEC_METADATA_TYPE_MPEG_4); mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher); mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, List.of(info)); @@ -342,11 +334,9 @@ public class LoudnessCodecHelperTest { metadataType).setIsDownmixing(isDownmixing).setDeviceSplRange(splRange).build(); } - private static LoudnessCodecInfo getLoudnessInfo(int mediaCodecHash, boolean isDownmixing, - int metadataType) { + private static LoudnessCodecInfo getLoudnessInfo(boolean isDownmixing, int metadataType) { LoudnessCodecInfo info = new LoudnessCodecInfo(); info.isDownmixing = isDownmixing; - info.mediaCodecHashCode = mediaCodecHash; info.metadataType = metadataType; return info; |