# Flags

Artifact: [androidx.media3:media3-common](https://developer.android.com/jetpack/androidx/releases/media3) [View Source](https://cs.android.com/search?q=file:androidx/media3/common/Flags.java+class:androidx.media3.common.Flags)

*** ** * ** ***


```
@UnstableApi
public final class Flags
```

<br />

*** ** * ** ***

Central registry for Media3 experimental feature flags.

This class provides a mechanism to control experimental features in Media3 via global canary mode and individual flag overrides, enabling safe, gradual rollout of new library behaviors.

**Canary mode**

Canary mode is enabled by default. Only flags that are considered safe for production usage are included in canary mode. When canary mode is disabled, these flags are inactive.

**Individual overrides**

Individual flags can be explicitly `https://developer.android.com/reference/androidx/media3/common/Flags#enableFlag(int)` or `https://developer.android.com/reference/androidx/media3/common/Flags#disableFlag(int)`, regardless of the canary mode state. An explicit override always takes precedence over the canary mode default.

**Threading**

Flag configuration must be done on the application thread before creating any Media3 components (e.g., `ExoPlayer`, `Transformer`). Flag queries from other threads (e.g., the playback thread) rely on happens-before relationships established by `https://developer.android.com/reference/java/lang/Thread.html#start()` and `https://developer.android.com/reference/android/os/Handler.html` message posting during component setup.

**Testing**

In unit tests, `androidx.media3.test.utils.Media3FlagsRule` is the preferred way to manage flag states and automatically reset all flag overrides and canary mode after each test.

## Summary

| ### Nested types |
|---|
| `@https://developer.android.com/reference/java/lang/annotation/Documented.html @https://developer.android.com/reference/java/lang/annotation/Retention.html(value = https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html#SOURCE) @https://developer.android.com/reference/java/lang/annotation/Target.html(value = https://developer.android.com/reference/java/lang/annotation/ElementType.html#TYPE_USE) @https://developer.android.com/reference/androidx/annotation/IntDef(open = true, value = ) public annotation https://developer.android.com/reference/androidx/media3/common/Flags.Flag` Flags for experimental features in Media3. |

| ### Constants |
|---|---|
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_DYNAMIC_SCHEDULING() = 3` Flag to enable dynamic scheduling in ExoPlayer. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_ENABLE_CLIPPING_IN_MEDIA_PERIOD() = 5` Flag to enable delegating end-position clipping to `MediaPeriod` instances in ExoPlayer. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_ENABLE_MEDIACODEC_BUFFER_DECODE_ONLY() = 6` Flag to enable passing `https://developer.android.com/reference/android/media/MediaCodec.html#BUFFER_FLAG_DECODE_ONLY` to `https://developer.android.com/reference/android/media/MediaCodec.html` on API 34+. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_ENABLE_STUCK_PLAYING_DETECTION() = 4` Flag to enable stuck playing detection in ExoPlayer. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_ENFORCE_PARSABLE_BYTE_ARRAY_LIMIT() = 8` Flag to enable enforcing that read and peek methods in `https://developer.android.com/reference/androidx/media3/common/util/ParsableByteArray` do not read beyond `https://developer.android.com/reference/androidx/media3/common/util/ParsableByteArray#limit()`. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_PARSE_DASH_ALTERNATIVE_MPD_EVENTS() = 11` Flag to enable parsing DASH Alternative MPD events into `Period.alternativeMpdEvents` in `DashManifestParser`. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_PER_STREAM_MEDIA_PROGRESSION() = 1` Flag to enable per-stream media progression in ExoPlayer. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_PLAY_PAUSE_AUDIO_TRACK_ON_INIT() = 10` Flag to enable calling `https://developer.android.com/reference/android/media/AudioTrack.html#play()` and `https://developer.android.com/reference/android/media/AudioTrack.html#pause()` immediately after creating an `https://developer.android.com/reference/android/media/AudioTrack.html`. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_PROCESSED_STREAM_CHANGED_AT_START() = 2` Flag to enable invoking `MediaCodecRenderer.onProcessedStreamChange()` on the first stream. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_SKIP_AUDIO_TRACK_FLUSH_BEFORE_RELEASE() = 9` Flag to skip calling `https://developer.android.com/reference/android/media/AudioTrack.html#flush()` before `https://developer.android.com/reference/android/media/AudioTrack.html#release()` on API 29+. |
| `static final int` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_VIDEO_RENDERER_DURATION_TO_PROGRESS() = 7` Flag to enable calculating duration-to-progress based on next output buffer presentation time in `MediaCodecVideoRenderer`. |

| ### Public methods |
|---|---|
| `synchronized static void` | `https://developer.android.com/reference/androidx/media3/common/Flags#disableFlag(int)(@https://developer.android.com/reference/androidx/media3/common/Flags.Flag int flag)` Explicitly disables a flag, overriding the canary mode default. |
| `synchronized static void` | `https://developer.android.com/reference/androidx/media3/common/Flags#enableFlag(int)(@https://developer.android.com/reference/androidx/media3/common/Flags.Flag int flag)` Explicitly enables a flag, overriding the canary mode default. |
| `static int[]` | `@https://developer.android.com/reference/androidx/media3/common/Flags.Flag https://developer.android.com/reference/androidx/media3/common/Flags#getDisabledOverrides()()` Returns the flag identifiers that are explicitly disabled via `https://developer.android.com/reference/androidx/media3/common/Flags#disableFlag(int)`, overriding the canary mode default. |
| `static int[]` | `@https://developer.android.com/reference/androidx/media3/common/Flags.Flag https://developer.android.com/reference/androidx/media3/common/Flags#getEnabledOverrides()()` Returns the flag identifiers that are explicitly enabled via `https://developer.android.com/reference/androidx/media3/common/Flags#enableFlag(int)`, overriding the canary mode default. |
| `static https://developer.android.com/reference/java/lang/String.html` | `https://developer.android.com/reference/androidx/media3/common/Flags#getLogString()()` Returns a log string describing the current canary mode and flag override state. |
| `static boolean` | `https://developer.android.com/reference/androidx/media3/common/Flags#isCanaryModeEnabled()()` Returns whether canary mode is currently enabled. |
| `static boolean` | `https://developer.android.com/reference/androidx/media3/common/Flags#isEnabled(int)(@https://developer.android.com/reference/androidx/media3/common/Flags.Flag int flag)` Checks if a specific flag is enabled. |
| `synchronized static void` | `@https://developer.android.com/reference/androidx/annotation/VisibleForTesting https://developer.android.com/reference/androidx/media3/common/Flags#resetForTesting()()` Resets the flag registry to its default configuration (all overrides cleared, canary mode enabled). |
| `synchronized static void` | `https://developer.android.com/reference/androidx/media3/common/Flags#setCanaryModeEnabled(boolean)(boolean enabled)` Sets whether canary mode is enabled globally. |

## Constants

### FLAG_DYNAMIC_SCHEDULING

```
@ExperimentalApi
public static final int FLAG_DYNAMIC_SCHEDULING = 3
```

Flag to enable dynamic scheduling in ExoPlayer.

When enabled, ExoPlayer uses dynamic scheduling for its playback loop.

This flag is statically enabled and defaults to `true`.

### FLAG_ENABLE_CLIPPING_IN_MEDIA_PERIOD

```
@ExperimentalApi
public static final int FLAG_ENABLE_CLIPPING_IN_MEDIA_PERIOD = 5
```

Flag to enable delegating end-position clipping to `MediaPeriod` instances in ExoPlayer.

When enabled, clipping of the end position is delegated to the wrapped `MediaPeriod` rather than being handled at the media source level.

This flag is not yet covered by canary mode and defaults to `false`.

### FLAG_ENABLE_MEDIACODEC_BUFFER_DECODE_ONLY

```
@ExperimentalApi
public static final int FLAG_ENABLE_MEDIACODEC_BUFFER_DECODE_ONLY = 6
```

Flag to enable passing `https://developer.android.com/reference/android/media/MediaCodec.html#BUFFER_FLAG_DECODE_ONLY` to `https://developer.android.com/reference/android/media/MediaCodec.html` on API 34+.

When enabled on API 34+, buffers before the start time in non-tunneling mode are queued with `BUFFER_FLAG_DECODE_ONLY` rather than being dropped after decoding.

This flag is not yet covered by canary mode and defaults to `false`.

### FLAG_ENABLE_STUCK_PLAYING_DETECTION

```
@ExperimentalApi
public static final int FLAG_ENABLE_STUCK_PLAYING_DETECTION = 4
```

Flag to enable stuck playing detection in ExoPlayer.

When enabled, ExoPlayer detects when playback is stuck without making progress or without ending, and triggers a playback error.

### FLAG_ENFORCE_PARSABLE_BYTE_ARRAY_LIMIT

```
@ExperimentalApi
public static final int FLAG_ENFORCE_PARSABLE_BYTE_ARRAY_LIMIT = 8
```

Flag to enable enforcing that read and peek methods in `https://developer.android.com/reference/androidx/media3/common/util/ParsableByteArray` do not read beyond `https://developer.android.com/reference/androidx/media3/common/util/ParsableByteArray#limit()`.

When enabled, reading or peeking beyond the limit throws an `https://developer.android.com/reference/java/lang/IndexOutOfBoundsException.html` (or `https://developer.android.com/reference/java/nio/BufferOverflowException.html`) even if the read is within the bounds of the underlying byte array.

### FLAG_PARSE_DASH_ALTERNATIVE_MPD_EVENTS

```
@ExperimentalApi
public static final int FLAG_PARSE_DASH_ALTERNATIVE_MPD_EVENTS = 11
```

Flag to enable parsing DASH Alternative MPD events into `Period.alternativeMpdEvents` in `DashManifestParser`.

When enabled, `DashManifestParser` parses Alternative MPD `EventStream`s into both `Period.eventStreams` and `Period.alternativeMpdEvents`. When disabled, only `Period.eventStreams` is populated using standard `EventStream` parsing.

### FLAG_PER_STREAM_MEDIA_PROGRESSION

```
@ExperimentalApi
public static final int FLAG_PER_STREAM_MEDIA_PROGRESSION = 1
```

Flag to enable per-stream media progression in ExoPlayer.

When enabled, ExoPlayer may advance processing on a per-stream basis, potentially starting to process the next item in the playlist before finishing the current one. This can reduce startup latency between media items.

This flag is not yet covered by canary mode and defaults to `false`.

### FLAG_PLAY_PAUSE_AUDIO_TRACK_ON_INIT

```
@ExperimentalApi
public static final int FLAG_PLAY_PAUSE_AUDIO_TRACK_ON_INIT = 10
```

Flag to enable calling `https://developer.android.com/reference/android/media/AudioTrack.html#play()` and `https://developer.android.com/reference/android/media/AudioTrack.html#pause()` immediately after creating an `https://developer.android.com/reference/android/media/AudioTrack.html`.

When enabled, calling `play()` and `pause()` at initialization time triggers internal `https://developer.android.com/reference/android/media/AudioTrack.html` initialization to reduce startup latency on the first actual playback.

This flag is not yet covered by canary mode and defaults to `false`.

### FLAG_PROCESSED_STREAM_CHANGED_AT_START

```
@ExperimentalApi
public static final int FLAG_PROCESSED_STREAM_CHANGED_AT_START = 2
```

Flag to enable invoking `MediaCodecRenderer.onProcessedStreamChange()` on the first stream.

When enabled, `onProcessedStreamChange()` is invoked starting from the first stream. When disabled (the default), it is invoked from the second stream onwards.

This flag is not yet covered by canary mode and defaults to `false`.

### FLAG_SKIP_AUDIO_TRACK_FLUSH_BEFORE_RELEASE

```
@ExperimentalApi
public static final int FLAG_SKIP_AUDIO_TRACK_FLUSH_BEFORE_RELEASE = 9
```

Flag to skip calling `https://developer.android.com/reference/android/media/AudioTrack.html#flush()` before `https://developer.android.com/reference/android/media/AudioTrack.html#release()` on API 29+.

When enabled on API 29+, `AudioTrackAudioOutput` releases the underlying `https://developer.android.com/reference/android/media/AudioTrack.html` without calling `flush()` first.

### FLAG_VIDEO_RENDERER_DURATION_TO_PROGRESS

```
@ExperimentalApi
public static final int FLAG_VIDEO_RENDERER_DURATION_TO_PROGRESS = 7
```

Flag to enable calculating duration-to-progress based on next output buffer presentation time in `MediaCodecVideoRenderer`.

When enabled along with `https://developer.android.com/reference/androidx/media3/common/Flags#FLAG_DYNAMIC_SCHEDULING()`, `MediaCodecVideoRenderer` returns duration-to-progress aligned with when its next output buffer can be rendered when in asynchronous mode.

This flag is not yet covered by canary mode and defaults to `false`.

## Public methods

### disableFlag

```
synchronized public static void disableFlag(@Flags.Flag int flag)
```

Explicitly disables a flag, overriding the canary mode default.

This must be called before creating any Media3 components.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/media3/common/Flags.Flag int flag` | The `https://developer.android.com/reference/androidx/media3/common/Flags.Flag`. |

### enableFlag

```
synchronized public static void enableFlag(@Flags.Flag int flag)
```

Explicitly enables a flag, overriding the canary mode default.

This must be called before creating any Media3 components.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/media3/common/Flags.Flag int flag` | The `https://developer.android.com/reference/androidx/media3/common/Flags.Flag`. |

### getDisabledOverrides

```
@Flags.Flag
public static int[] getDisabledOverrides()
```

Returns the flag identifiers that are explicitly disabled via `https://developer.android.com/reference/androidx/media3/common/Flags#disableFlag(int)`, overriding the canary mode default.

### getEnabledOverrides

```
@Flags.Flag
public static int[] getEnabledOverrides()
```

Returns the flag identifiers that are explicitly enabled via `https://developer.android.com/reference/androidx/media3/common/Flags#enableFlag(int)`, overriding the canary mode default.

### getLogString

```
public static String getLogString()
```

Returns a log string describing the current canary mode and flag override state.

The format is `[Canary:<state>, Overrides: enabled=[<ids>], disabled=[<ids>]]`, or `[Canary:<state>]` if there are no overrides. Only deviations from the default state are listed.

### isCanaryModeEnabled

```
public static boolean isCanaryModeEnabled()
```

Returns whether canary mode is currently enabled.

### isEnabled

```
public static boolean isEnabled(@Flags.Flag int flag)
```

Checks if a specific flag is enabled.

The resolution order is:

1. If the flag has an explicit override (via `https://developer.android.com/reference/androidx/media3/common/Flags#enableFlag(int)` or `https://developer.android.com/reference/androidx/media3/common/Flags#disableFlag(int)`), the override value is returned.
2. If the flag has a static value not part of canary mode, that static value is returned.
3. Otherwise, the flag is enabled if canary mode is enabled.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/media3/common/Flags.Flag int flag` | The `https://developer.android.com/reference/androidx/media3/common/Flags.Flag`. |

| Returns |
|---|---|
| `boolean` | Whether the flag is enabled. |

### resetForTesting

```
@VisibleForTesting
synchronized public static void resetForTesting()
```

Resets the flag registry to its default configuration (all overrides cleared, canary mode enabled).

This is intended for use in tests only to avoid test pollution. In unit tests, `
androidx.media3.test.utils.Media3FlagsRule` is the preferred alternative to calling this method directly.

### setCanaryModeEnabled

```
synchronized public static void setCanaryModeEnabled(boolean enabled)
```

Sets whether canary mode is enabled globally.

Canary mode is enabled by default.

When enabled, all flags that are not statically excluded are active by default. Individual overrides set via `https://developer.android.com/reference/androidx/media3/common/Flags#enableFlag(int)` or `https://developer.android.com/reference/androidx/media3/common/Flags#disableFlag(int)` take precedence.

This must be called before creating any Media3 components.

| Parameters |
|---|---|
| `boolean enabled` | Whether to enable canary mode. |