summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yixiao Luo <yixiaoluo@google.com> 2025-03-15 12:36:42 -0700
committer Yixiao Luo <yixiaoluo@google.com> 2025-03-21 15:34:24 -0700
commit9075f39fca1e800d786ce4974214424bf74588cd (patch)
tree97a45e1318281154b2fd9e81751d0e78ca76cf50
parentf4740b3635e7ebe7750aff0b3e92b4295e149867 (diff)
[Media Quality] Picture profile application
Support the following use cases: - Applying app-selected picture profile using KEY_PICTURE_PROFILE_INSTANCE or KEY_PICTURE_PROFILE_ID on MediaCodec.configure() - Applying app-selected picture profile using KEY_PICTURE_PROFILE_INSTANCE or KEY_PICTURE_PROFILE_ID on MediaCodec.setParameters() - Applying app-default picture profile from MediaQualityService on MediaCodec.configure() Bug: 391947448, 394391342 Test: m Flag: android.media.tv.flags.apply_picture_profiles Change-Id: Iaaa8a7f3ee6e3a3dbe8d208da7a63bbbb0ab9197
-rw-r--r--media/java/android/media/MediaCodec.java72
-rw-r--r--media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl3
-rw-r--r--services/core/java/com/android/server/media/quality/MediaQualityService.java33
3 files changed, 104 insertions, 4 deletions
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 15c832392a22..d0676e693b95 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -50,6 +50,7 @@ import android.os.Message;
import android.os.PersistableBundle;
import android.os.Trace;
import android.view.Surface;
+import android.util.Log;
import java.io.IOException;
import java.lang.annotation.Retention;
@@ -1656,6 +1657,7 @@ import java.util.function.Supplier;
</table>
*/
final public class MediaCodec {
+ private static final String TAG = "MediaCodec";
/**
* Per buffer metadata includes an offset and size specifying
@@ -2496,6 +2498,49 @@ final public class MediaCodec {
}
keys[i] = "audio-hw-sync";
values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
+ } else if (applyPictureProfiles() && mediaQualityFw()
+ && entry.getKey().equals(MediaFormat.KEY_PICTURE_PROFILE_INSTANCE)) {
+ PictureProfile pictureProfile = null;
+ try {
+ pictureProfile = (PictureProfile) entry.getValue();
+ } catch (ClassCastException e) {
+ throw new IllegalArgumentException(
+ "Cannot cast the instance parameter to PictureProfile!");
+ } catch (Exception e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ throw new IllegalArgumentException("Unexpected exception when casting the "
+ + "instance parameter to PictureProfile!");
+ }
+ if (pictureProfile == null) {
+ throw new IllegalArgumentException(
+ "Picture profile instance parameter is null!");
+ }
+ PictureProfileHandle handle = pictureProfile.getHandle();
+ if (handle != PictureProfileHandle.NONE) {
+ keys[i] = PARAMETER_KEY_PICTURE_PROFILE_HANDLE;
+ values[i] = Long.valueOf(handle.getId());
+ }
+ } else if (applyPictureProfiles() && mediaQualityFw()
+ && entry.getKey().equals(MediaFormat.KEY_PICTURE_PROFILE_ID)) {
+ String pictureProfileId = null;
+ try {
+ pictureProfileId = (String) entry.getValue();
+ } catch (ClassCastException e) {
+ throw new IllegalArgumentException(
+ "Cannot cast the KEY_PICTURE_PROFILE_ID parameter to String!");
+ } catch (Exception e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ throw new IllegalArgumentException("Unexpected exception when casting the "
+ + "KEY_PICTURE_PROFILE_ID parameter!");
+ }
+ if (pictureProfileId == null) {
+ throw new IllegalArgumentException(
+ "KEY_PICTURE_PROFILE_ID parameter is null!");
+ }
+ if (!pictureProfileId.isEmpty()) {
+ keys[i] = MediaFormat.KEY_PICTURE_PROFILE_ID;
+ values[i] = pictureProfileId;
+ }
} else {
keys[i] = entry.getKey();
values[i] = entry.getValue();
@@ -5424,7 +5469,7 @@ final public class MediaCodec {
throw new IllegalArgumentException(
"Cannot cast the instance parameter to PictureProfile!");
} catch (Exception e) {
- android.util.Log.getStackTraceString(e);
+ Log.e(TAG, Log.getStackTraceString(e));
throw new IllegalArgumentException("Unexpected exception when casting the "
+ "instance parameter to PictureProfile!");
}
@@ -5437,6 +5482,26 @@ final public class MediaCodec {
keys[i] = PARAMETER_KEY_PICTURE_PROFILE_HANDLE;
values[i] = Long.valueOf(handle.getId());
}
+ } else if (applyPictureProfiles() && mediaQualityFw()
+ && key.equals(MediaFormat.KEY_PICTURE_PROFILE_ID)) {
+ String pictureProfileId = null;
+ try {
+ pictureProfileId = (String) params.get(key);
+ } catch (ClassCastException e) {
+ throw new IllegalArgumentException(
+ "Cannot cast the KEY_PICTURE_PROFILE_ID parameter to String!");
+ } catch (Exception e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ throw new IllegalArgumentException("Unexpected exception when casting the "
+ + "KEY_PICTURE_PROFILE_ID parameter!");
+ }
+ if (pictureProfileId == null) {
+ throw new IllegalArgumentException("KEY_PICTURE_PROFILE_ID parameter is null!");
+ }
+ if (!pictureProfileId.isEmpty()) {
+ keys[i] = MediaFormat.KEY_PICTURE_PROFILE_ID;
+ values[i] = pictureProfileId;
+ }
} else {
keys[i] = key;
Object value = params.get(key);
@@ -5455,10 +5520,9 @@ final public class MediaCodec {
}
private void logAndRun(String message, Runnable r) {
- final String TAG = "MediaCodec";
- android.util.Log.d(TAG, "enter: " + message);
+ Log.d(TAG, "enter: " + message);
r.run();
- android.util.Log.d(TAG, "exit : " + message);
+ Log.d(TAG, "exit : " + message);
}
/**
diff --git a/media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl
index 6ac1656b77aa..4f24d8c5cc48 100644
--- a/media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/aidl/android/media/quality/IMediaQualityManager.aidl
@@ -46,6 +46,9 @@ interface IMediaQualityManager {
List<String> getPictureProfileAllowList(int userId);
void setPictureProfileAllowList(in List<String> packages, int userId);
List<PictureProfileHandle> getPictureProfileHandle(in String[] id, int userId);
+ long getPictureProfileHandleValue(in String id, int userId);
+ long getDefaultPictureProfileHandleValue(int userId);
+ void notifyPictureProfileHandleSelection(in long handle, int userId);
void createSoundProfile(in SoundProfile pp, int userId);
void updateSoundProfile(in String id, in SoundProfile pp, int userId);
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index 4c61e226a574..d1dcd9d9fa75 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -105,6 +105,7 @@ public class MediaQualityService extends SystemService {
private final MediaQualityDbHelper mMediaQualityDbHelper;
private final BiMap<Long, String> mPictureProfileTempIdMap;
private final BiMap<Long, String> mSoundProfileTempIdMap;
+ private final Map<String, Long> mPackageDefaultPictureProfileHandleMap = new HashMap<>();
private IMediaQuality mMediaQuality;
private PictureProfileAdjustmentListenerImpl mPictureProfileAdjListener;
private SoundProfileAdjustmentListenerImpl mSoundProfileAdjListener;
@@ -184,6 +185,8 @@ public class MediaQualityService extends SystemService {
mMediaQuality.setPictureProfileAdjustmentListener(mPictureProfileAdjListener);
mMediaQuality.setSoundProfileAdjustmentListener(mSoundProfileAdjListener);
+ // TODO: populate mPackageDefaultPictureProfileHandleMap
+
} catch (RemoteException e) {
Slog.e(TAG, "Failed to set ambient backlight detector callback", e);
}
@@ -443,6 +446,36 @@ public class MediaQualityService extends SystemService {
return toReturn;
}
+ @GuardedBy("mPictureProfileLock")
+ @Override
+ public long getPictureProfileHandleValue(String id, int userId) {
+ synchronized (mPictureProfileLock) {
+ Long value = mPictureProfileTempIdMap.getKey(id);
+ return value != null ? value : -1;
+ }
+ }
+
+ @GuardedBy("mPictureProfileLock")
+ @Override
+ public long getDefaultPictureProfileHandleValue(int userId) {
+ synchronized (mPictureProfileLock) {
+ String packageName = getPackageOfCallingUid();
+ Long value = null;
+ if (packageName != null) {
+ value = mPackageDefaultPictureProfileHandleMap.get(packageName);
+ }
+ return value != null ? value : -1;
+ }
+ }
+
+ @GuardedBy("mPictureProfileLock")
+ @Override
+ public void notifyPictureProfileHandleSelection(long handle, int userId) {
+ PictureProfile profile = mMqDatabaseUtils.getPictureProfile(handle);
+ if (profile != null) {
+ mHalNotifier.notifyHalOnPictureProfileChange(handle, profile.getParameters());
+ }
+ }
@GuardedBy("mSoundProfileLock")
@Override