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

Scaling Bug in media3 with Android 14 #1184

Closed
1 task
sunnat629 opened this issue Mar 14, 2024 · 4 comments
Closed
1 task

Scaling Bug in media3 with Android 14 #1184

sunnat629 opened this issue Mar 14, 2024 · 4 comments

Comments

@sunnat629
Copy link

Version

Media3 main branch

More version details

When using the media3-exoplayer library to play videos in a Jetpack Compose application with PlayerView inside an AndroidView, the video content does not scale correctly on devices running Android 14. The issue is observable on a Pixel 7 Pro where using RESIZE_MODE_FIT leads to the video not filling the PlayerView as expected. This issue does not occur with RESIZE_MODE_FILL, but it is present in all other resize modes, including RESIZE_MODE_FIXED_HEIGHT, RESIZE_MODE_FIXED_WIDTH, and RESIZE_MODE_ZOOM.

Reproducible in the demo app?

The issue is not reproducible in the standard demo app but can be observed in a custom Jetpack Compose setup. in Linked demo app, if you use MainActivity2 I use xml and there is no issue there.

Using: RESIZE_MODE_FILL
RESIZE_MODE_FILL

Using: RESIZE_MODE_FIT
RESIZE_MODE_FIT

Devices that reproduce the issue

  • Pixel 7 Pro running Android 14 (90% time)
  • Galaxy S22, Android 14 (70-80% time)

Devices that do not reproduce the issue

  • Samsung S10 running Android 12 (around 30% time)
    • Motorola G7 Power running Android 10 (0%)

Reproducible in the demo app?

Yes

Reproduction steps

  1. Create a PlayerView with resizeMode set to RESIZE_MODE_FIT.
  2. Play a video.
  3. Observe that the video content does not fill the PlayerView.

Expected result

The video content should scale to fit within the PlayerView without any cropping or letterboxing, maintaining the video's aspect ratio.

Actual result

The video content does not scale properly, and parts of the video are cropped or do not fill the PlayerView.

Media

Link to test content

Github: https://github.com/sunnat629/Media3ExoplayerScale

Version of the library

Media3 version: 1.3.0

implementation("androidx.media3:media3-exoplayer:1.3.0")
implementation("androidx.media3:media3-exoplayer-hls:1.3.0")
implementation("androidx.media3:media3-ui:1.3.0")

Bug Report

@oceanjules
Copy link
Contributor

I think the library is doing what should be expected from documentation. Let me paste the relevant code snippet:

int width = getMeasuredWidth();
int height = getMeasuredHeight();
float viewAspectRatio = (float) width / height;
float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
if (Math.abs(aspectDeformation) <= MAX_ASPECT_RATIO_DEFORMATION_FRACTION) {
// We're within the allowed tolerance.
aspectRatioUpdateDispatcher.scheduleUpdate(videoAspectRatio, viewAspectRatio, false);
return;
}
switch (resizeMode) {
case RESIZE_MODE_FIXED_WIDTH:
height = (int) (width / videoAspectRatio);
break;
case RESIZE_MODE_FIXED_HEIGHT:
width = (int) (height * videoAspectRatio);
break;
case RESIZE_MODE_ZOOM:
if (aspectDeformation > 0) {
width = (int) (height * videoAspectRatio);
} else {
height = (int) (width / videoAspectRatio);
}
break;
case RESIZE_MODE_FIT:
if (aspectDeformation > 0) {
height = (int) (width / videoAspectRatio);
} else {
width = (int) (height * videoAspectRatio);
}
break;
case RESIZE_MODE_FILL:
default:
// Ignore target aspect ratio
break;
}

  1. The reason RESIZE_MODE_FILL as you say "works" is that it's actually not doing any resizing at all ("Ignore target aspect ratio" branch)
  2. RESIZE_MODE_FIT is documented to DECREASE one of the dimensions:
    /** Either the width or height is decreased to obtain the desired aspect ratio. */
    public static final int RESIZE_MODE_FIT = 0;
  3. RESIZE_MODE_ZOOM is documented to INCREASE one of the dimensions:
    /** Either the width or height is increased to obtain the desired aspect ratio. */
    public static final int RESIZE_MODE_ZOOM = 4;

Now back to your particular video sample:

  • 1100k video is 1680x750, i.e. videoAspectRatio = 2.24
  • 2200k video is 3360x1500, i.e. videoAspectRatio = 2.24
  • Pixel 7 positions the video in a view with width=2984 and height=1272
  • viewAspectRatio = 2.34
  • aspectDeformation = videoAspectRatio / viewAspectRatio - 1 is NEGATIVE
  • For "FILL" that means: height stays the same, width shrinks (as per your screenshot)

Attaching my own reproduction screenshot below. Feel free to debug yourself - AspectRatioFrameLayout is the place

Screenshot 2024-03-14 at 17 30 58

Note, however, there is currently a problem with using SurfaceView and AspectRatioFrameLayout where FIT will work, but ZOOM will leak the contents of the video to outside of the FrameLayout (#1123, #1120, #1107)

@Junaid17
Copy link

@oceanjules Iam using RESIZE_MODE_FIT and still able to see the above on Pixel 14 devices. Is there any possible work around for this to work with compose?

@anushagif
Copy link

I have same issue but when switching the orientation to landscape will solve the problem.

@oceanjules
Copy link
Contributor

@Junaid17
The OP was also struggling with RESIZE_MODE_FIT and I documented above as to why the scaling is dependent on the video aspect ratio AND the phone size.

RESIZE_MODE_FIT looks at aspectDeformation = videoAspectRatio / viewAspectRatio - 1 to decide whether to shrink width or height. With the same media (i.e. videoAspectRatio), you might be seeing different scaling behaviour depending on the phone size (i.e. viewAspectRatio)

@androidx androidx locked and limited conversation to collaborators May 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants