From 7ae3d69e001d0a138f3ebe406b050bc06bd24724 Mon Sep 17 00:00:00 2001 From: ibaker Date: Tue, 6 Feb 2024 10:19:27 -0800 Subject: [PATCH] JpegMotionPhotoExtractor: Don't emit an image track with no metadata The current implementation of `JpegMotionPhotoExtractor.sniff` returns `true` for any image with Exif data (not just motion photos). Improving this is tracked by b/324033919. In the meantime, when we 'extract' a non-motion photo with `JpegMotionPhotoExtractor`, the result is currently a single empty image track and no video track (since there's no video, since this isn't a motion photo). This 'empty' image track is usually used to transmit metadata about the video parts of the image file (in the form of `MotionPhotoMetadata`), but this metadata is also (understandably) absent for non-motion photos. Therefore there's no need to emit this image track at all, and it's clearer to emit no tracks at all when extracting a non-motion photo using `JpegMotionPhotoExtractor`. This change also removes a `TODO` that is misplaced, since there's no image bytes being emitted here (and never was). PiperOrigin-RevId: 604688053 --- .../extractor/jpeg/JpegMotionPhotoExtractor.java | 14 ++++++-------- .../jpeg/non-motion-photo-shortened.jpg.0.dump | 8 +------- ...-motion-photo-shortened.jpg.unknown_length.dump | 8 +------- ...ion-photo-2-hevc-tracks.jpg.unknown_length.dump | 8 +------- ...-jfif-segment-shortened.jpg.unknown_length.dump | 8 +------- ...-motion-photo-shortened.jpg.unknown_length.dump | 8 +------- ...motion-photo-video-removed-shortened.jpg.0.dump | 8 +------- ...video-removed-shortened.jpg.unknown_length.dump | 8 +------- ...-motion-photo-shortened.jpg.unknown_length.dump | 8 +------- 9 files changed, 14 insertions(+), 64 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/JpegMotionPhotoExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/JpegMotionPhotoExtractor.java index 70c1133390..2795f4128b 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/JpegMotionPhotoExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/JpegMotionPhotoExtractor.java @@ -202,7 +202,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; if (mp4StartPosition != C.INDEX_UNSET) { state = STATE_SNIFFING_MOTION_PHOTO_VIDEO; } else { - endReadingWithImageTrack(); + endReading(); } } else if ((marker < 0xFFD0 || marker > 0xFFD9) && marker != 0xFF01) { state = STATE_READING_SEGMENT_LENGTH; @@ -242,7 +242,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; input.peekFully( scratch.getData(), /* offset= */ 0, /* length= */ 1, /* allowEndOfInput= */ true); if (!peekedData) { - endReadingWithImageTrack(); + endReading(); } else { input.resetPeekPosition(); if (mp4Extractor == null) { @@ -257,7 +257,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; new StartOffsetExtractorOutput(mp4StartPosition, checkNotNull(extractorOutput))); startReadingMotionPhoto(); } else { - endReadingWithImageTrack(); + endReading(); } } } @@ -267,21 +267,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; state = STATE_READING_MOTION_PHOTO_VIDEO; } - private void endReadingWithImageTrack() { - outputImageTrack(); + private void endReading() { checkNotNull(extractorOutput).endTracks(); extractorOutput.seekMap(new SeekMap.Unseekable(/* durationUs= */ C.TIME_UNSET)); state = STATE_ENDED; } - private void outputImageTrack(Metadata.Entry... metadataEntries) { + private void outputImageTrack(MotionPhotoMetadata motionPhotoMetadata) { TrackOutput imageTrackOutput = checkNotNull(extractorOutput).track(IMAGE_TRACK_ID, C.TRACK_TYPE_IMAGE); - // TODO(b/289989902): Set the rotationDegrees in format so images can be decoded correctly. imageTrackOutput.format( new Format.Builder() .setContainerMimeType(MimeTypes.IMAGE_JPEG) - .setMetadata(new Metadata(metadataEntries)) + .setMetadata(new Metadata(motionPhotoMetadata)) .build()); } diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.0.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.0.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.0.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.unknown_length.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/non-motion-photo-shortened.jpg.unknown_length.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-2-hevc-tracks.jpg.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-2-hevc-tracks.jpg.unknown_length.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-2-hevc-tracks.jpg.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-2-hevc-tracks.jpg.unknown_length.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-jfif-segment-shortened.jpg.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-jfif-segment-shortened.jpg.unknown_length.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-jfif-segment-shortened.jpg.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-jfif-segment-shortened.jpg.unknown_length.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-shortened.jpg.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-shortened.jpg.unknown_length.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-shortened.jpg.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-shortened.jpg.unknown_length.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.0.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.0.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.0.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.unknown_length.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/pixel-motion-photo-video-removed-shortened.jpg.unknown_length.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/jpeg/ss-motion-photo-shortened.jpg.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/jpeg/ss-motion-photo-shortened.jpg.unknown_length.dump index 02c10855b5..62796e9eec 100644 --- a/libraries/test_data/src/test/assets/extractordumps/jpeg/ss-motion-photo-shortened.jpg.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/jpeg/ss-motion-photo-shortened.jpg.unknown_length.dump @@ -2,11 +2,5 @@ seekMap: isSeekable = false duration = UNSET TIME getPosition(0) = [[timeUs=0, position=0]] -numberOfTracks = 1 -track 1024: - total output bytes = 0 - sample count = 0 - format 0: - containerMimeType = image/jpeg - metadata = entries=[] +numberOfTracks = 0 tracksEnded = true