Skip to content

Commit f05a9e5

Browse files
committed
Refactor and add tests
# Conflicts: # libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java
1 parent 45fbe39 commit f05a9e5

File tree

12 files changed

+624
-307
lines changed

12 files changed

+624
-307
lines changed

demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,12 @@
3434
import androidx.appcompat.app.AppCompatActivity;
3535
import androidx.media3.common.AudioAttributes;
3636
import androidx.media3.common.C;
37-
import androidx.media3.common.CodecParameter;
38-
import androidx.media3.common.CodecParameters;
39-
import androidx.media3.common.CodecParametersChangeListener;
4037
import androidx.media3.common.ErrorMessageProvider;
4138
import androidx.media3.common.MediaItem;
4239
import androidx.media3.common.PlaybackException;
4340
import androidx.media3.common.Player;
4441
import androidx.media3.common.TrackSelectionParameters;
4542
import androidx.media3.common.Tracks;
46-
import androidx.media3.common.util.Log;
4743
import androidx.media3.common.util.UnstableApi;
4844
import androidx.media3.common.util.Util;
4945
import androidx.media3.datasource.DataSchemeDataSource;
@@ -65,7 +61,6 @@
6561
import androidx.media3.ui.PlayerView;
6662
import java.util.ArrayList;
6763
import java.util.Collections;
68-
import java.util.HashMap;
6964
import java.util.List;
7065
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
7166

@@ -266,7 +261,6 @@ protected void setContentView() {
266261
/**
267262
* @return Whether initialization was successful.
268263
*/
269-
@OptIn(markerClass = UnstableApi.class)
270264
protected boolean initializePlayer() {
271265
Intent intent = getIntent();
272266
if (player == null) {
@@ -283,56 +277,6 @@ protected boolean initializePlayer() {
283277
setRenderersFactory(
284278
playerBuilder, intent.getBooleanExtra(IntentUtil.PREFER_EXTENSION_DECODERS_EXTRA, false));
285279
player = playerBuilder.build();
286-
287-
// --------------------------- TESTING CODE ONLY -- REMOVE AGAIN ----------------------------
288-
player.setCodecParametersChangeListener(new CodecParametersChangeListener() {
289-
@Override
290-
public void onCodecParametersChanged(CodecParameters codecParameters) {
291-
HashMap<String, CodecParameter> parameters = codecParameters.get();
292-
for (String key : parameters.keySet()) {
293-
Log.e("PlayerActivity", "key = " + key + " value = " + parameters.get(key).value);
294-
}
295-
}
296-
297-
@Override
298-
public ArrayList<String> getFilterKeys() {
299-
ArrayList<String> filterKeys = new ArrayList<>();
300-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
301-
filterKeys.add(CodecParameter.KEY_AAC_DRC_OUTPUT_LOUDNESS);
302-
}
303-
return filterKeys;
304-
}
305-
});
306-
307-
CodecParameter codecParameter;
308-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
309-
// For testing set initial targetLoudness to -16 LUFS
310-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 64,
311-
CodecParameter.VALUETYPE_INT);
312-
player.setCodecParameter(codecParameter);
313-
// For testing set initial BoostFactor to 32
314-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_BOOST_FACTOR, 32,
315-
CodecParameter.VALUETYPE_INT);
316-
player.setCodecParameter(codecParameter);
317-
// For testing set initial AttenuationFactor to 16
318-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_ATTENUATION_FACTOR, 16,
319-
CodecParameter.VALUETYPE_INT);
320-
player.setCodecParameter(codecParameter);
321-
}
322-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
323-
// For testing set initial EffectType to NOISY_ENVIRONMENT
324-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_EFFECT_TYPE, 2,
325-
CodecParameter.VALUETYPE_INT);
326-
player.setCodecParameter(codecParameter);
327-
}
328-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
329-
// For testing set initial AlbumMode to ENABLED
330-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_ALBUM_MODE, 1,
331-
CodecParameter.VALUETYPE_INT);
332-
player.setCodecParameter(codecParameter);
333-
}
334-
// --------------------------- TESTING CODE ONLY -- REMOVE AGAIN ----------------------------
335-
336280
player.setTrackSelectionParameters(trackSelectionParameters);
337281
player.addListener(new PlayerEventListener());
338282
player.addAnalyticsListener(new EventLogger());
@@ -354,44 +298,6 @@ public ArrayList<String> getFilterKeys() {
354298
player.setRepeatMode(IntentUtil.parseRepeatModeExtra(repeatModeExtra));
355299
}
356300
updateButtonVisibility();
357-
358-
// --------------------------- TESTING CODE ONLY -- REMOVE AGAIN ----------------------------
359-
// Simulate sleep so the MPEG-D DRC can change during runtime
360-
try {
361-
Thread.sleep(2000);
362-
} catch (InterruptedException e) {
363-
e.printStackTrace();
364-
}
365-
366-
CodecParameter codecParameter;
367-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
368-
// Testing a change to the targetLoudness during codec runtime (set to -24 LUFS)
369-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96,
370-
CodecParameter.VALUETYPE_INT);
371-
player.setCodecParameter(codecParameter);
372-
// Testing a change to the boost factor during codec runtime (set to 96)
373-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_BOOST_FACTOR, 96,
374-
CodecParameter.VALUETYPE_INT);
375-
player.setCodecParameter(codecParameter);
376-
// Testing a change to the attenuation factor during codec runtime (set to 64)
377-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_ATTENUATION_FACTOR, 64,
378-
CodecParameter.VALUETYPE_INT);
379-
player.setCodecParameter(codecParameter);
380-
}
381-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
382-
// Testing a change to the EffectType during codec runtime (set to OFF)
383-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_EFFECT_TYPE, -1,
384-
CodecParameter.VALUETYPE_INT);
385-
player.setCodecParameter(codecParameter);
386-
}
387-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
388-
// Testing a change to the album mode during codec runtime (set to DISABLED)
389-
codecParameter = new CodecParameter(CodecParameter.KEY_AAC_DRC_ALBUM_MODE, 0,
390-
CodecParameter.VALUETYPE_INT);
391-
player.setCodecParameter(codecParameter);
392-
}
393-
// --------------------------- TESTING CODE ONLY -- REMOVE AGAIN ----------------------------
394-
395301
return true;
396302
}
397303

libraries/common/src/main/java/androidx/media3/common/CodecParameter.java

Lines changed: 101 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,175 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package androidx.media3.common;
217

318
import static java.lang.annotation.ElementType.TYPE_USE;
419

520
import android.media.MediaFormat;
621
import android.os.Build;
7-
822
import androidx.annotation.IntDef;
923
import androidx.annotation.Nullable;
1024
import androidx.annotation.RequiresApi;
11-
25+
import androidx.media3.common.util.UnstableApi;
1226
import java.lang.annotation.Documented;
1327
import java.lang.annotation.Retention;
1428
import java.lang.annotation.RetentionPolicy;
1529
import java.lang.annotation.Target;
1630

1731
/**
18-
* A {@link CodecParameter} holds the key, value and the value type for signalling a parameter change to a
19-
* decoder. The key can be an arbitrary string which must be known by the decoder instance.
32+
* A parameter for configuring an underlying {@link android.media.MediaCodec}.
33+
*
34+
* <p>The key must be a key that is understood by the underlying decoder instance.
2035
*/
21-
public class CodecParameter {
22-
23-
private static final String TAG = "CodecParameter";
36+
@UnstableApi
37+
public final class CodecParameter {
2438

2539
/**
26-
* @see MediaFormat#KEY_AAC_DRC_ALBUM_MODE
40+
* Value types for a {@link CodecParameter}. One of {@link #TYPE_NULL}, {@link #TYPE_INT}, {@link
41+
* #TYPE_LONG}, {@link #TYPE_FLOAT}, {@link #TYPE_STRING} or {@link #TYPE_BYTE_BUFFER}.
2742
*/
28-
@RequiresApi(api = Build.VERSION_CODES.R)
29-
public final static String KEY_AAC_DRC_ALBUM_MODE = MediaFormat.KEY_AAC_DRC_ALBUM_MODE;
43+
@Documented
44+
@Retention(RetentionPolicy.SOURCE)
45+
@Target(TYPE_USE)
46+
@IntDef({TYPE_NULL, TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_STRING, TYPE_BYTE_BUFFER})
47+
public @interface ValueType {}
3048

3149
/**
32-
* @see MediaFormat#KEY_AAC_DRC_ATTENUATION_FACTOR
50+
* @see MediaFormat#TYPE_NULL
3351
*/
34-
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
35-
public final static String KEY_AAC_DRC_ATTENUATION_FACTOR = MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR;
52+
public static final int TYPE_NULL = 0;
3653

3754
/**
38-
* @see MediaFormat#KEY_AAC_DRC_BOOST_FACTOR
55+
* @see MediaFormat#TYPE_INTEGER
3956
*/
40-
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
41-
public final static String KEY_AAC_DRC_BOOST_FACTOR = MediaFormat.KEY_AAC_DRC_BOOST_FACTOR;
57+
public static final int TYPE_INT = 1;
4258

4359
/**
44-
* @see MediaFormat#KEY_AAC_DRC_EFFECT_TYPE
60+
* @see MediaFormat#TYPE_LONG
4561
*/
46-
@RequiresApi(api = Build.VERSION_CODES.P)
47-
public final static String KEY_AAC_DRC_EFFECT_TYPE = MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
62+
public static final int TYPE_LONG = 2;
4863

4964
/**
50-
* @see MediaFormat#KEY_AAC_DRC_TARGET_REFERENCE_LEVEL
65+
* @see MediaFormat#TYPE_FLOAT
5166
*/
52-
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
53-
public final static String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
67+
public static final int TYPE_FLOAT = 3;
5468

5569
/**
56-
* @see MediaFormat#KEY_AAC_DRC_OUTPUT_LOUDNESS
70+
* @see MediaFormat#TYPE_STRING
5771
*/
58-
@RequiresApi(api = Build.VERSION_CODES.R)
59-
public final static String KEY_AAC_DRC_OUTPUT_LOUDNESS = MediaFormat.KEY_AAC_DRC_OUTPUT_LOUDNESS;
60-
72+
public static final int TYPE_STRING = 4;
6173

6274
/**
63-
* Key to set the MPEG-H output mode.
64-
* The corresponding value must be of value type {@link ValueType#VALUETYPE_INT}.
65-
* Possible values are:
66-
* 0 for PCM output (decoding the MPEG-H bitstream with a certain MPEG-H target layout CICP index)
67-
* 1 for MPEG-H bitstream bypass (using IEC61937-13 with a sample rate factor of 4)
68-
* 2 for MPEG-H bitstream bypass (using IEC61937-13 with a sample rate factor of 16)
75+
* @see MediaFormat#TYPE_BYTE_BUFFER
6976
*/
70-
public final static String KEY_MPEGH_OUTPUT_MODE = "mpegh-output-mode";
77+
public static final int TYPE_BYTE_BUFFER = 5;
7178

7279
/**
73-
* Key to set the MPEG-H target layout CICP index.
74-
* The corresponding value must be of value type {@link ValueType#VALUETYPE_INT}.
75-
* It must be set before decoder initialization. A change during runtime does not have any effect.
76-
* Supported values are: 0, 1, 2, 6, 8, 10, 12
77-
* A value of 0 tells the decoder to create binauralized output.
80+
* @see MediaFormat#KEY_AAC_DRC_ALBUM_MODE
7881
*/
79-
public final static String KEY_MPEGH_TARGET_LAYOUT = "mpegh-target-layout";
82+
@RequiresApi(api = Build.VERSION_CODES.R)
83+
public static final String KEY_AAC_DRC_ALBUM_MODE = MediaFormat.KEY_AAC_DRC_ALBUM_MODE;
8084

8185
/**
82-
* Key to set the MPEG-H UI configuration.
83-
* The corresponding value must be of value type {@link ValueType#VALUETYPE_STRING}.
84-
* This key is returned from the MPEG-H UI manager.
86+
* @see MediaFormat#KEY_AAC_DRC_ATTENUATION_FACTOR
8587
*/
86-
public final static String KEY_MPEGH_UI_CONFIG = "mpegh-ui-config";
88+
public static final String KEY_AAC_DRC_ATTENUATION_FACTOR =
89+
MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR;
8790

8891
/**
89-
* Key to set the MPEG-H UI command.
90-
* The corresponding value must be of value type {@link ValueType#VALUETYPE_STRING}.
91-
* This key is passed to the MPEG-H UI manager.
92+
* @see MediaFormat#KEY_AAC_DRC_BOOST_FACTOR
9293
*/
93-
public final static String KEY_MPEGH_UI_COMMAND = "mpegh-ui-command";
94+
public static final String KEY_AAC_DRC_BOOST_FACTOR = MediaFormat.KEY_AAC_DRC_BOOST_FACTOR;
9495

9596
/**
96-
* Key to set the MPEG-H UI persistence storage path.
97-
* The corresponding value must be of value type {@link ValueType#VALUETYPE_STRING}.
98-
* This key is passed to the MPEG-H UI manager.
97+
* @see MediaFormat#KEY_AAC_DRC_EFFECT_TYPE
9998
*/
100-
public final static String KEY_MPEGH_UI_PERSISTENCESTORAGE_PATH = "mpegh-ui-persistencestorage-path";
99+
@RequiresApi(api = Build.VERSION_CODES.P)
100+
public static final String KEY_AAC_DRC_EFFECT_TYPE = MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
101101

102102
/**
103-
* @see MediaFormat#TYPE_NULL
103+
* @see MediaFormat#KEY_AAC_DRC_TARGET_REFERENCE_LEVEL
104104
*/
105-
public static final int VALUETYPE_NULL = 0; // MediaFormat.TYPE_NULL;
105+
public static final String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL =
106+
MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
107+
106108
/**
107-
* @see MediaFormat#TYPE_INTEGER
109+
* @see MediaFormat#KEY_AAC_DRC_OUTPUT_LOUDNESS
108110
*/
109-
public static final int VALUETYPE_INT = 1; // MediaFormat.TYPE_INTEGER;
111+
@RequiresApi(api = Build.VERSION_CODES.R)
112+
public static final String KEY_AAC_DRC_OUTPUT_LOUDNESS = MediaFormat.KEY_AAC_DRC_OUTPUT_LOUDNESS;
113+
110114
/**
111-
* @see MediaFormat#TYPE_LONG
115+
* Key to set the MPEG-H output mode. The corresponding value must be of value type {@link
116+
* ValueType#TYPE_INT}.
117+
*
118+
* <p>Possible values are:
119+
*
120+
* <ul>
121+
* <li>0 for PCM output (decoding the MPEG-H bitstream with a certain MPEG-H target layout CICP
122+
* index)
123+
* <li>1 for MPEG-H bitstream bypass (using IEC61937-13 with a sample rate factor of 4)
124+
* <li>2 for MPEG-H bitstream bypass (using IEC61937-13 with a sample rate factor of 16)
125+
* </ul>
112126
*/
113-
public static final int VALUETYPE_LONG = 2; // MediaFormat.TYPE_LONG;
127+
public static final String KEY_MPEGH_OUTPUT_MODE = "mpegh-output-mode";
128+
114129
/**
115-
* @see MediaFormat#TYPE_FLOAT
130+
* Key to set the MPEG-H target layout CICP index. The corresponding value must be of value type
131+
* {@link ValueType#TYPE_INT}. It must be set before decoder initialization. A change during
132+
* runtime does not have any effect.
133+
*
134+
* <p>Supported values are: 0, 1, 2, 6, 8, 10, 12. A value of 0 tells the decoder to create
135+
* binauralized output.
116136
*/
117-
public static final int VALUETYPE_FLOAT = 3; // MediaFormat.TYPE_FLOAT;
137+
public static final String KEY_MPEGH_TARGET_LAYOUT = "mpegh-target-layout";
138+
118139
/**
119-
* @see MediaFormat#TYPE_STRING
140+
* Key to set the MPEG-H UI configuration. The corresponding value must be of value type {@link
141+
* ValueType#TYPE_STRING}. This key is returned from the MPEG-H UI manager.
120142
*/
121-
public static final int VALUETYPE_STRING = 4; // MediaFormat.TYPE_STRING;
143+
public static final String KEY_MPEGH_UI_CONFIG = "mpegh-ui-config";
144+
122145
/**
123-
* @see MediaFormat#TYPE_BYTE_BUFFER
146+
* Key to set the MPEG-H UI command. The corresponding value must be of value type {@link
147+
* ValueType#TYPE_STRING}. This key is passed to the MPEG-H UI manager.
124148
*/
125-
public static final int VALUETYPE_BYTE_BUFFER = 5; // MediaFormat.TYPE_BYTE_BUFFER;
149+
public static final String KEY_MPEGH_UI_COMMAND = "mpegh-ui-command";
126150

127151
/**
128-
* Value types for a {@link CodecParameter}.
129-
* One of {@link #VALUETYPE_NULL}, {@link #VALUETYPE_INT}, {@link #VALUETYPE_LONG},
130-
* {@link #VALUETYPE_FLOAT}, {@link #VALUETYPE_STRING} or {@link #VALUETYPE_BYTE_BUFFER}.
152+
* Key to set the MPEG-H UI persistence storage path. The corresponding value must be of value
153+
* type {@link ValueType#TYPE_STRING}. This key is passed to the MPEG-H UI manager.
131154
*/
132-
@Documented
133-
@Retention(RetentionPolicy.SOURCE)
134-
@Target(TYPE_USE)
135-
@IntDef({
136-
VALUETYPE_NULL,
137-
VALUETYPE_INT,
138-
VALUETYPE_LONG,
139-
VALUETYPE_FLOAT,
140-
VALUETYPE_STRING,
141-
VALUETYPE_BYTE_BUFFER
142-
})
143-
public @interface ValueType {
144-
145-
}
155+
public static final String KEY_MPEGH_UI_PERSISTENCESTORAGE_PATH =
156+
"mpegh-ui-persistencestorage-path";
146157

158+
/** The key of the codec parameter. */
159+
public final String key;
147160

148-
public String key;
149-
public @Nullable Object value;
150-
public @ValueType int valueType;
161+
/** The value of the codec parameter. */
162+
public final @Nullable Object value;
151163

164+
/** The {@link ValueType} of the value object. */
165+
public final @ValueType int valueType;
152166

153167
/**
154-
* Creates a new codec parameter.
168+
* Creates an instance.
155169
*
156-
* @param key A string holding the key of the codec parameter.
157-
* @param value An object representing the value of the codec parameter.
158-
* @param valueType The value type of the value object.
170+
* @param key The key of the codec parameter.
171+
* @param value The value of the codec parameter.
172+
* @param valueType The {@link ValueType} of the value object.
159173
*/
160174
public CodecParameter(String key, @Nullable Object value, @ValueType int valueType) {
161175
this.key = key;

0 commit comments

Comments
 (0)