-
Notifications
You must be signed in to change notification settings - Fork 460
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
Not selecting the correct video track for the video exported from Pixel8 captured motion JPEG #1051
Comments
Are you extracting the MP4 data yourself? If you pass the motion photo jpeg directly to ExoPlayer with a default configuration, then it should be handled by media/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/JpegMotionPhotoExtractor.java Lines 247 to 249 in b930b40
If you need to extract the MP4 data yourself then you should ensure you either only keep the first track and discard the rest, or use If you're already using |
I use GooglePhoto app's own extraction function to get the video mp4 out of the jpeg file. The extracted mp4 file contains 2 video tracks, with one track has only 1 frame. Let's put the issue this way, regardless where the mp4 file comes from, what if we just use ExoPlayer to open a mp4 file that contains 2 video track, one track is normal but another one has only 1 frame but 'better' resolution? The current impl of the default track selector will select the 1-frame track, which might not be the good choice. So, this is a bug to be fixed, right? |
Ah interesting - in that case then I agree with your original comment, this looks like a bug in the Photos app. The additional low-fps HEVC track is only used as an efficient way to encode some other images - these are only intended to be consumed in a 'photo' context, not a 'video' one, so when exporting the file as a video there's no reason to include this additional track. I was able to repro the issue on a Pixel 7a with Photos 6.69.0.602445611, but only when disabling 'stabilization' during export (which imo further confirms this is a Photos bug, since I wouldn't expect disabling stabilization to change the number of tracks included in the video). I captured a motion photo and confirmed (by playing the jpeg with ExoPlayer) that it contains two HEVC tracks (and you can see the
In the Photos app I then did:
The resulting video has only a single video track and plays fine with ExoPlayer:
Then re-doing the export with 'keep stabilization' unticked, the resulting video has multiple video tracks and ExoPlayer selects the high-res, low-fps one:
Thanks for flagging, I'll file an internal bug against the Photos team and see what they say. I will keep this issue open for now while we discuss whether ExoPlayer should also add a workaround for files like this (since any fix in Photos export logic obviously won't affect the files already created with this problem). I think some options are roughly:
We would also need to discuss whether we should keep the new change in |
I filed internal b/324844971 against the Photos app for this issue. |
This change aims to prioritise tracks that have a 'smooth enough for video' frame rate, without always selecting the track with the highest frame rate. In particular MP4 files extracted from motion photos sometimes have two HEVC tracks, with the higher-res one having a very low frame rate (not intended for use in video playback). Before this change `DefaultTrackSelector` would pick the low-fps, high-res track. This change adds a somewhat arbitrary 10fps threshold for "smooth video playback", meaning any tracks above this threshold are selected in preference to tracks below it. Within the tracks above the threshold other attributes are used to select the preferred track. We deliberately don't pick the highest-fps track (over pixel count and bitrate), because most users would prefer to see a 30fps 4k track over a 60fps 720p track. This change also includes a test MP4 file, extracted from the existing `jpeg/pixel-motion-photo-2-hevc-tracks.jpg` file by logging `mp4StartPosition` in [`MotionPhotoDescription.getMotionPhotoMetadata`](https://github.com/androidx/media/blob/b930b40a16c06318e43c81771fa2b1024bdb3f29/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/MotionPhotoDescription.java#L123) and then using `dd`: ``` mp4StartPosition=2603594 $ dd if=jpeg/pixel-motion-photo-2-hevc-tracks.jpg \ of=mp4/pixel-motion-photo-2-hevc-tracks.mp4 \ bs=1 \ skip=2603594 ``` ---- This solution is in addition to the `JpegMotionPhotoExtractor` change made specifically for these two-track motion photos in 5266c71. We will keep both changes, even though that change is not strictly needed after this one, because adding the role flags helps to communicate more clearly the intended usage of these tracks. This change to consider FPS seems like a generally useful improvement to `DefaultTrackSelector`, since it seems unlikely we would prefer a 5fps video track over a 30fps one. Issue: #1051 PiperOrigin-RevId: 611015459
A follow-up change will add the frame rate to the single-frame track. Issue: #1051 PiperOrigin-RevId: 611018319
This change aims to prioritise tracks that have a 'smooth enough for video' frame rate, without always selecting the track with the highest frame rate. In particular MP4 files extracted from motion photos sometimes have two HEVC tracks, with the higher-res one having a very low frame rate (not intended for use in video playback). Before this change `DefaultTrackSelector` would pick the low-fps, high-res track. This change adds a somewhat arbitrary 10fps threshold for "smooth video playback", meaning any tracks above this threshold are selected in preference to tracks below it. Within the tracks above the threshold other attributes are used to select the preferred track. We deliberately don't pick the highest-fps track (over pixel count and bitrate), because most users would prefer to see a 30fps 4k track over a 60fps 720p track. This change also includes a test MP4 file, extracted from the existing `jpeg/pixel-motion-photo-2-hevc-tracks.jpg` file by logging `mp4StartPosition` in [`MotionPhotoDescription.getMotionPhotoMetadata`](https://github.com/androidx/media/blob/b930b40a16c06318e43c81771fa2b1024bdb3f29/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/MotionPhotoDescription.java#L123) and then using `dd`: ``` mp4StartPosition=2603594 $ dd if=jpeg/pixel-motion-photo-2-hevc-tracks.jpg \ of=mp4/pixel-motion-photo-2-hevc-tracks.mp4 \ bs=1 \ skip=2603594 ``` ---- This solution is in addition to the `JpegMotionPhotoExtractor` change made specifically for these two-track motion photos in 146bf6f. We will keep both changes, even though that change is not strictly needed after this one, because adding the role flags helps to communicate more clearly the intended usage of these tracks. This change to consider FPS seems like a generally useful improvement to `DefaultTrackSelector`, since it seems unlikely we would prefer a 5fps video track over a 30fps one. Issue: androidx/media#1051 PiperOrigin-RevId: 611015459
A follow-up change will add the frame rate to the single-frame track. Issue: androidx/media#1051 PiperOrigin-RevId: 611018319
The commits above change the behaviour of |
Issue: #1051 PiperOrigin-RevId: 613516802
Issue: androidx/media#1051 PiperOrigin-RevId: 613516802
This change aims to prioritise tracks that have a 'smooth enough for video' frame rate, without always selecting the track with the highest frame rate. In particular MP4 files extracted from motion photos sometimes have two HEVC tracks, with the higher-res one having a very low frame rate (not intended for use in video playback). Before this change `DefaultTrackSelector` would pick the low-fps, high-res track. This change adds a somewhat arbitrary 10fps threshold for "smooth video playback", meaning any tracks above this threshold are selected in preference to tracks below it. Within the tracks above the threshold other attributes are used to select the preferred track. We deliberately don't pick the highest-fps track (over pixel count and bitrate), because most users would prefer to see a 30fps 4k track over a 60fps 720p track. This change also includes a test MP4 file, extracted from the existing `jpeg/pixel-motion-photo-2-hevc-tracks.jpg` file by logging `mp4StartPosition` in [`MotionPhotoDescription.getMotionPhotoMetadata`](https://github.com/androidx/media/blob/b930b40a16c06318e43c81771fa2b1024bdb3f29/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/MotionPhotoDescription.java#L123) and then using `dd`: ``` mp4StartPosition=2603594 $ dd if=jpeg/pixel-motion-photo-2-hevc-tracks.jpg \ of=mp4/pixel-motion-photo-2-hevc-tracks.mp4 \ bs=1 \ skip=2603594 ``` ---- This solution is in addition to the `JpegMotionPhotoExtractor` change made specifically for these two-track motion photos in 5266c71. We will keep both changes, even though that change is not strictly needed after this one, because adding the role flags helps to communicate more clearly the intended usage of these tracks. This change to consider FPS seems like a generally useful improvement to `DefaultTrackSelector`, since it seems unlikely we would prefer a 5fps video track over a 30fps one. Issue: #1051 PiperOrigin-RevId: 611015459 (cherry picked from commit c7e00b1)
Version
Media3 1.2.1
More version details
No response
Devices that reproduce the issue
Pixel8 Android 14, Galaxy S23 Android 14
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
Analyze:
Suggestion:
if (trackDurationUs > 0 && trackSampleTable.sampleCount > 0)
Since one frame is still a frame, dividing by the duration, we can always have a value.
Expected result
The correct video track should be selected by default
Actual result
The single-frame video track is selected by default
Media
Please use Pixel8 to capture a motion-jpeg and extract the video from it.
Bug Report
adb bugreport
to android-media-github@google.com after filing this issue.The text was updated successfully, but these errors were encountered: