Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Multiple renderer media clocks enabled" when setting selection override #9675

Closed
moneytoo opened this issue Nov 9, 2021 · 2 comments
Closed
Assignees
Labels

Comments

@moneytoo
Copy link
Contributor

moneytoo commented Nov 9, 2021

I'm migrating to TrackSelectionOverrides for "track" selection in ExoPlayer 2.16.0. I'm using it with TrackSelectionParameters and it seems to be working (I set the overrides when Player.STATE_READY).

...
TrackSelectionParameters.Builder trackSelectionParametersBuilder = new TrackSelectionParameters.Builder(this)
		.setTrackSelectionOverrides(overridesBuilder.build());
player.setTrackSelectionParameters(trackSelectionParametersBuilder.build());

However when overrides get set for a media file utilizing multiple audio renderers (the default one as well as ffmpeg; for example file containing AC3 & TrueHD or AC3 & MP2), I receive following error:

E/ExoPlayerImplInternal: Playback error
      com.google.android.exoplayer2.ExoPlaybackException: Unexpected runtime error
        at com.google.android.exoplayer2.DefaultMediaClock.onRendererEnabled(DefaultMediaClock.java:96)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.enableRenderer(ExoPlayerImplInternal.java:2454)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.enableRenderers(ExoPlayerImplInternal.java:2402)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.reselectTracksInternal(ExoPlayerImplInternal.java:1709)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:511)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:214)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: java.lang.IllegalStateException: Multiple renderer media clocks enabled.
        at com.google.android.exoplayer2.DefaultMediaClock.onRendererEnabled(DefaultMediaClock.java:96) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.enableRenderer(ExoPlayerImplInternal.java:2454) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.enableRenderers(ExoPlayerImplInternal.java:2402) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.reselectTracksInternal(ExoPlayerImplInternal.java:1709) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:511) 
        at android.os.Handler.dispatchMessage(Handler.java:103) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
  • ExoPlayer version number: 2.16.0 with applied patch eb678a7
  • Android version: Android 10
  • Android device: OnePlus 7
@tonihei
Copy link
Collaborator

tonihei commented Nov 10, 2021

I don't think this ever worked when setting overrides for the extension renderer only. The reason is that the DefaultTrackSelector assigns one audio track to the default renderer, and the override just assigns the second audio track to the extension renderer in addition to the first one. To make this work, the default selection needs to be removed specifically by making an empty override for the first renderer. See #2618 where this came up in the past (and we prevented it from happening for cases without overrides).

However, the good thing is that the contract of the new TrackSelectionOverride.Builder.setOverrideForType actually allows us to do this internally because the method promises to only select the provided override for its type. So we can simplify such use cases by automatically disabling all other selections for the same track type.

p.s.: Thanks for finding all these tricky edge case problems with our new track selection API! This is extremely helpful, although we should have caught them ourselves before releasing :)

@krocard
Copy link
Contributor

krocard commented Nov 10, 2021

However, the good thing is that the contract of the new TrackSelectionOverride.Builder.setOverrideForType actually allows us to do this internally because the method promises to only select the provided override for its type. So we can simplify such use cases by automatically disabling all other selections for the same track type.

Yes this is what I had in mind when I introduced the API. It makes for a much simpler usage for the client to only have to set one override per type.

The cl adding the logic of disabling every over track of the same type is still pending as it complexify the logic significantly due to backward compatibility for legacy overrides.

I did not realize that it would cause an actual issue in multi audio renders. Sorry about that @moneytoo.

tonihei added a commit that referenced this issue Nov 11, 2021
Currently, TrackSelectionOverrides are documented as being applied
per track type, meaning that one override for a type disables all
other selections for the same track type. However, the actual
implementation only applies it per track group, relying on the
track selector to never select another renderer of the same type.

This change fixes DefaultTrackSelector to fully adhere to the
TrackSelectionsOverride definition. This solves problems when
overriding tracks for extension renderers (see Issue: #9675)
and also simplifies a workaround added to StyledPlayerView.

#minor-release

PiperOrigin-RevId: 409121711
tonihei added a commit that referenced this issue Nov 11, 2021
Currently, TrackSelectionOverrides are documented as being applied
per track type, meaning that one override for a type disables all
other selections for the same track type. However, the actual
implementation only applies it per track group, relying on the
track selector to never select another renderer of the same type.

This change fixes DefaultTrackSelector to fully adhere to the
TrackSelectionsOverride definition. This solves problems when
overriding tracks for extension renderers (see Issue: #9675)
and also simplifies a workaround added to StyledPlayerView.

#minor-release

PiperOrigin-RevId: 409121711
@tonihei tonihei closed this as completed Nov 15, 2021
icbaker pushed a commit to androidx/media that referenced this issue Nov 19, 2021
Currently, TrackSelectionOverrides are documented as being applied
per track type, meaning that one override for a type disables all
other selections for the same track type. However, the actual
implementation only applies it per track group, relying on the
track selector to never select another renderer of the same type.

This change fixes DefaultTrackSelector to fully adhere to the
TrackSelectionsOverride definition. This solves problems when
overriding tracks for extension renderers (see Issue: google/ExoPlayer#9675)
and also simplifies a workaround added to StyledPlayerView.

#minor-release

PiperOrigin-RevId: 409121711
@google google locked and limited conversation to collaborators Jan 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants