diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6d62ea3e01..07bb6914ab 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -21,6 +21,8 @@ speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)). * Allow `AdtsExtractor` to encounter EoF when calculating average frame size ([#6700](https://github.com/google/ExoPlayer/issues/6700)). +* In MP4 streams, store the Android capture frame rate only in + `Format.metadata`. `Format.frameRate` now stores the calculated frame rate. * Make media session connector dispatch ACTION_SET_CAPTIONING_ENABLED. * Add support for position and overlapping start/end times in SSA/ASS subtitles ([#6320](https://github.com/google/ExoPlayer/issues/6320)). diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/MetadataUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/MetadataUtil.java index bec2cdbb5f..174ae821ac 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/MetadataUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/MetadataUtil.java @@ -27,7 +27,6 @@ import com.google.android.exoplayer2.metadata.id3.InternalFrame; import com.google.android.exoplayer2.metadata.id3.TextInformationFrame; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.ParsableByteArray; -import java.nio.ByteBuffer; /** Utilities for handling metadata in MP4. */ /* package */ final class MetadataUtil { @@ -108,7 +107,6 @@ import java.nio.ByteBuffer; private static final int TYPE_TOP_BYTE_REPLACEMENT = 0xFD; // Truncated value of \uFFFD. private static final String MDTA_KEY_ANDROID_CAPTURE_FPS = "com.android.capture.fps"; - private static final int MDTA_TYPE_INDICATOR_FLOAT = 23; private MetadataUtil() {} @@ -138,15 +136,8 @@ import java.nio.ByteBuffer; Metadata.Entry entry = mdtaMetadata.get(i); if (entry instanceof MdtaMetadataEntry) { MdtaMetadataEntry mdtaMetadataEntry = (MdtaMetadataEntry) entry; - if (MDTA_KEY_ANDROID_CAPTURE_FPS.equals(mdtaMetadataEntry.key) - && mdtaMetadataEntry.typeIndicator == MDTA_TYPE_INDICATOR_FLOAT) { - try { - float fps = ByteBuffer.wrap(mdtaMetadataEntry.value).asFloatBuffer().get(); - format = format.copyWithFrameRate(fps); - format = format.copyWithMetadata(new Metadata(mdtaMetadataEntry)); - } catch (NumberFormatException e) { - Log.w(TAG, "Ignoring invalid framerate"); - } + if (MDTA_KEY_ANDROID_CAPTURE_FPS.equals(mdtaMetadataEntry.key)) { + format = format.copyWithMetadata(new Metadata(mdtaMetadataEntry)); } } } diff --git a/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4 b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4 new file mode 100644 index 0000000000..e5594c83e1 Binary files /dev/null and b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4 differ diff --git a/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.0.dump b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.0.dump new file mode 100644 index 0000000000..2880b9493f --- /dev/null +++ b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.0.dump @@ -0,0 +1,61 @@ +seekMap: + isSeekable = true + duration = 526000 + getPosition(0) = [[timeUs=0, position=1161]] +numberOfTracks = 1 +track 0: + format: + bitrate = -1 + id = 1 + containerMimeType = null + sampleMimeType = video/avc + maxInputSize = 34686 + width = 1280 + height = 720 + frameRate = 13.307984 + rotationDegrees = 0 + pixelWidthHeightRatio = 1.0 + channelCount = -1 + sampleRate = -1 + pcmEncoding = -1 + encoderDelay = 0 + encoderPadding = 0 + subsampleOffsetUs = 9223372036854775807 + selectionFlags = 0 + language = null + drmInitData = - + metadata = entries=[mdta: key=com.android.capture.fps] + initializationData: + data = length 22, hash 4CF81805 + data = length 9, hash FBAFBA1C + total output bytes = 42320 + sample count = 7 + sample 0: + time = 0 + flags = 1 + data = length 34656, hash D92B66FF + sample 1: + time = 325344 + flags = 0 + data = length 768, hash D0C3B229 + sample 2: + time = 358677 + flags = 0 + data = length 1184, hash C598EFC0 + sample 3: + time = 392011 + flags = 0 + data = length 576, hash 667AEC2C + sample 4: + time = 425344 + flags = 0 + data = length 1456, hash 430D1498 + sample 5: + time = 458677 + flags = 0 + data = length 1280, hash 12267E0E + sample 6: + time = 492011 + flags = 536870912 + data = length 2400, hash FBCB42C +tracksEnded = true diff --git a/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.1.dump b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.1.dump new file mode 100644 index 0000000000..2880b9493f --- /dev/null +++ b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.1.dump @@ -0,0 +1,61 @@ +seekMap: + isSeekable = true + duration = 526000 + getPosition(0) = [[timeUs=0, position=1161]] +numberOfTracks = 1 +track 0: + format: + bitrate = -1 + id = 1 + containerMimeType = null + sampleMimeType = video/avc + maxInputSize = 34686 + width = 1280 + height = 720 + frameRate = 13.307984 + rotationDegrees = 0 + pixelWidthHeightRatio = 1.0 + channelCount = -1 + sampleRate = -1 + pcmEncoding = -1 + encoderDelay = 0 + encoderPadding = 0 + subsampleOffsetUs = 9223372036854775807 + selectionFlags = 0 + language = null + drmInitData = - + metadata = entries=[mdta: key=com.android.capture.fps] + initializationData: + data = length 22, hash 4CF81805 + data = length 9, hash FBAFBA1C + total output bytes = 42320 + sample count = 7 + sample 0: + time = 0 + flags = 1 + data = length 34656, hash D92B66FF + sample 1: + time = 325344 + flags = 0 + data = length 768, hash D0C3B229 + sample 2: + time = 358677 + flags = 0 + data = length 1184, hash C598EFC0 + sample 3: + time = 392011 + flags = 0 + data = length 576, hash 667AEC2C + sample 4: + time = 425344 + flags = 0 + data = length 1456, hash 430D1498 + sample 5: + time = 458677 + flags = 0 + data = length 1280, hash 12267E0E + sample 6: + time = 492011 + flags = 536870912 + data = length 2400, hash FBCB42C +tracksEnded = true diff --git a/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.2.dump b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.2.dump new file mode 100644 index 0000000000..2880b9493f --- /dev/null +++ b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.2.dump @@ -0,0 +1,61 @@ +seekMap: + isSeekable = true + duration = 526000 + getPosition(0) = [[timeUs=0, position=1161]] +numberOfTracks = 1 +track 0: + format: + bitrate = -1 + id = 1 + containerMimeType = null + sampleMimeType = video/avc + maxInputSize = 34686 + width = 1280 + height = 720 + frameRate = 13.307984 + rotationDegrees = 0 + pixelWidthHeightRatio = 1.0 + channelCount = -1 + sampleRate = -1 + pcmEncoding = -1 + encoderDelay = 0 + encoderPadding = 0 + subsampleOffsetUs = 9223372036854775807 + selectionFlags = 0 + language = null + drmInitData = - + metadata = entries=[mdta: key=com.android.capture.fps] + initializationData: + data = length 22, hash 4CF81805 + data = length 9, hash FBAFBA1C + total output bytes = 42320 + sample count = 7 + sample 0: + time = 0 + flags = 1 + data = length 34656, hash D92B66FF + sample 1: + time = 325344 + flags = 0 + data = length 768, hash D0C3B229 + sample 2: + time = 358677 + flags = 0 + data = length 1184, hash C598EFC0 + sample 3: + time = 392011 + flags = 0 + data = length 576, hash 667AEC2C + sample 4: + time = 425344 + flags = 0 + data = length 1456, hash 430D1498 + sample 5: + time = 458677 + flags = 0 + data = length 1280, hash 12267E0E + sample 6: + time = 492011 + flags = 536870912 + data = length 2400, hash FBCB42C +tracksEnded = true diff --git a/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.3.dump b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.3.dump new file mode 100644 index 0000000000..2880b9493f --- /dev/null +++ b/library/core/src/test/assets/mp4/sample_android_slow_motion.mp4.3.dump @@ -0,0 +1,61 @@ +seekMap: + isSeekable = true + duration = 526000 + getPosition(0) = [[timeUs=0, position=1161]] +numberOfTracks = 1 +track 0: + format: + bitrate = -1 + id = 1 + containerMimeType = null + sampleMimeType = video/avc + maxInputSize = 34686 + width = 1280 + height = 720 + frameRate = 13.307984 + rotationDegrees = 0 + pixelWidthHeightRatio = 1.0 + channelCount = -1 + sampleRate = -1 + pcmEncoding = -1 + encoderDelay = 0 + encoderPadding = 0 + subsampleOffsetUs = 9223372036854775807 + selectionFlags = 0 + language = null + drmInitData = - + metadata = entries=[mdta: key=com.android.capture.fps] + initializationData: + data = length 22, hash 4CF81805 + data = length 9, hash FBAFBA1C + total output bytes = 42320 + sample count = 7 + sample 0: + time = 0 + flags = 1 + data = length 34656, hash D92B66FF + sample 1: + time = 325344 + flags = 0 + data = length 768, hash D0C3B229 + sample 2: + time = 358677 + flags = 0 + data = length 1184, hash C598EFC0 + sample 3: + time = 392011 + flags = 0 + data = length 576, hash 667AEC2C + sample 4: + time = 425344 + flags = 0 + data = length 1456, hash 430D1498 + sample 5: + time = 458677 + flags = 0 + data = length 1280, hash 12267E0E + sample 6: + time = 492011 + flags = 536870912 + data = length 2400, hash FBCB42C +tracksEnded = true diff --git a/library/core/src/test/java/com/google/android/exoplayer2/extractor/mp4/Mp4ExtractorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/extractor/mp4/Mp4ExtractorTest.java index 981ee17e92..a653af3a46 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/extractor/mp4/Mp4ExtractorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/extractor/mp4/Mp4ExtractorTest.java @@ -28,4 +28,9 @@ public final class Mp4ExtractorTest { public void testMp4Sample() throws Exception { ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample.mp4"); } + + @Test + public void testMp4SampleWithSlowMotionMetadata() throws Exception { + ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_android_slow_motion.mp4"); + } }