diff --git a/libraries/container/src/main/java/androidx/media3/container/Mp4TimestampData.java b/libraries/container/src/main/java/androidx/media3/container/Mp4TimestampData.java
index 92c1ad5b81..26893496ca 100644
--- a/libraries/container/src/main/java/androidx/media3/container/Mp4TimestampData.java
+++ b/libraries/container/src/main/java/androidx/media3/container/Mp4TimestampData.java
@@ -18,7 +18,6 @@ package androidx.media3.container;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Nullable;
-import androidx.media3.common.C;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.UnstableApi;
import com.google.common.primitives.Longs;
@@ -29,6 +28,13 @@ public final class Mp4TimestampData implements Metadata.Entry {
/** Represents an unset or unknown timescale. */
public static final int TIMESCALE_UNSET = -1;
+ /**
+ * The delta between a Unix epoch timestamp (in milliseconds since midnight, January 1, 1970) and
+ * an MP4 timestamp (in seconds since midnight, January 1, 1904).
+ */
+ private static final int UNIX_EPOCH_TO_MP4_TIME_DELTA_SECONDS =
+ ((1970 - 1904) * 365 + 17 /* leap year */) * (24 * 60 * 60);
+
/** The creation timestamp. */
public final long creationTimestampSeconds;
@@ -41,13 +47,16 @@ public final class Mp4TimestampData implements Metadata.Entry {
/**
* Creates an instance.
*
+ *
The {@link #timescale} is set to {@link Mp4TimestampData#TIMESCALE_UNSET}.
+ *
* @param creationTimestampSeconds The creation time UTC in seconds since midnight, January 1,
- * 1904. The {@link #modificationTimestampSeconds} is set to {@link C#TIME_UNSET} and {@link
- * #timescale} is set to {@link Mp4TimestampData#TIMESCALE_UNSET}.
+ * 1904.
+ * @param modificationTimestampSeconds The modification time UTC in seconds since midnight,
+ * January 1, 1904.
*/
- public Mp4TimestampData(long creationTimestampSeconds) {
+ public Mp4TimestampData(long creationTimestampSeconds, long modificationTimestampSeconds) {
this.creationTimestampSeconds = creationTimestampSeconds;
- this.modificationTimestampSeconds = C.TIME_UNSET;
+ this.modificationTimestampSeconds = modificationTimestampSeconds;
this.timescale = TIMESCALE_UNSET;
}
@@ -73,6 +82,14 @@ public final class Mp4TimestampData implements Metadata.Entry {
this.timescale = in.readLong();
}
+ /**
+ * Returns an MP4 timestamp (in seconds since midnight, January 1, 1904) from a Unix epoch
+ * timestamp (in milliseconds since midnight, January 1, 1970).
+ */
+ public static long unixTimeToMp4TimeSeconds(long unixTimestampMs) {
+ return (unixTimestampMs / 1_000L) + UNIX_EPOCH_TO_MP4_TIME_DELTA_SECONDS;
+ }
+
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
diff --git a/libraries/container/src/main/java/androidx/media3/container/Mp4Util.java b/libraries/container/src/main/java/androidx/media3/container/Mp4Util.java
deleted file mode 100644
index 7963171da1..0000000000
--- a/libraries/container/src/main/java/androidx/media3/container/Mp4Util.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package androidx.media3.container;
-
-import androidx.media3.common.util.UnstableApi;
-
-/** Utilities for MP4 container. */
-@UnstableApi
-public final class Mp4Util {
- private static final int UNIX_EPOCH_TO_MP4_TIME_DELTA_SECONDS =
- ((1970 - 1904) * 365 + 17 /* leap year */) * (24 * 60 * 60);
-
- private Mp4Util() {}
-
- /**
- * Returns an MP4 timestamp (in seconds since midnight, January 1, 1904) from a Unix epoch
- * timestamp (in milliseconds since midnight, January 1, 1970).
- */
- public static long unixTimeToMp4TimeSeconds(long unixTimestampMs) {
- return (unixTimestampMs / 1000L + UNIX_EPOCH_TO_MP4_TIME_DELTA_SECONDS);
- }
-
- /**
- * Returns a Unix epoch timestamp (in milliseconds since midnight, January 1, 1970) from an MP4
- * timestamp (in seconds since midnight, January 1, 1904).
- */
- public static long mp4TimeToUnixTimeMs(long mp4TimestampSeconds) {
- return (mp4TimestampSeconds - UNIX_EPOCH_TO_MP4_TIME_DELTA_SECONDS) * 1000L;
- }
-}
diff --git a/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java b/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java
index 22482bcb2c..a35cb33e6e 100644
--- a/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java
+++ b/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java
@@ -23,6 +23,7 @@ import android.media.MediaCodec;
import android.media.MediaExtractor;
import androidx.annotation.Nullable;
import androidx.media3.common.util.MediaFormatUtil;
+import androidx.media3.container.Mp4TimestampData;
import androidx.media3.extractor.mp4.FragmentedMp4Extractor;
import androidx.media3.extractor.mp4.Mp4Extractor;
import androidx.media3.test.utils.DumpFileAsserts;
@@ -85,7 +86,10 @@ public class Mp4MuxerEndToEndTest {
try {
mp4Muxer = new Mp4Muxer.Builder(checkNotNull(outputStream)).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
feedInputDataToMuxer(mp4Muxer, checkNotNull(inputFile));
} finally {
if (mp4Muxer != null) {
@@ -106,7 +110,10 @@ public class Mp4MuxerEndToEndTest {
// ensure some data has been written after taking all the inputs but before closing the muxer.
assumeTrue(checkNotNull(inputFile).equals(H265_HDR10_MP4));
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(checkNotNull(outputStream)).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
feedInputDataToMuxer(mp4Muxer, inputFile);
// Muxer not closed.
@@ -132,7 +139,10 @@ public class Mp4MuxerEndToEndTest {
try {
mp4Muxer =
new Mp4Muxer.Builder(checkNotNull(outputStream)).setFragmentedMp4Enabled(true).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
feedInputDataToMuxer(mp4Muxer, inputFile);
} finally {
if (mp4Muxer != null) {
@@ -160,7 +170,10 @@ public class Mp4MuxerEndToEndTest {
try {
mp4Muxer =
new Mp4Muxer.Builder(checkNotNull(outputStream)).setFragmentedMp4Enabled(true).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
feedInputDataToMuxer(mp4Muxer, inputFile);
} finally {
if (mp4Muxer != null) {
diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
index de393a5849..62d75056d9 100644
--- a/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
+++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
@@ -93,14 +93,15 @@ import java.util.Locale;
public static ByteBuffer tkhd(
int trackId,
int trackDurationVu,
+ int creationTimestampSeconds,
int modificationTimestampSeconds,
int orientation,
Format format) {
ByteBuffer contents = ByteBuffer.allocate(Mp4Utils.MAX_FIXED_LEAF_BOX_SIZE);
contents.putInt(0x00000007); // version and flags; allow presentation, etc.
- contents.putInt(modificationTimestampSeconds); // creation_time
- contents.putInt(modificationTimestampSeconds); // modification_time
+ contents.putInt(creationTimestampSeconds); // creation_time; unsigned int(32)
+ contents.putInt(modificationTimestampSeconds); // modification_time; unsigned int(32)
contents.putInt(trackId);
contents.putInt(0); // reserved
@@ -132,12 +133,15 @@ import java.util.Locale;
*
This is the movie header for the entire MP4 file.
*/
public static ByteBuffer mvhd(
- int nextEmptyTrackId, int modificationTimestampSeconds, long videoDurationUs) {
+ int nextEmptyTrackId,
+ int creationTimestampSeconds,
+ int modificationTimestampSeconds,
+ long videoDurationUs) {
ByteBuffer contents = ByteBuffer.allocate(Mp4Utils.MAX_FIXED_LEAF_BOX_SIZE);
contents.putInt(0); // version and flags
- contents.putInt(modificationTimestampSeconds); // creation_time
- contents.putInt(modificationTimestampSeconds); // modification_time
+ contents.putInt(creationTimestampSeconds); // creation_time; unsigned int(32)
+ contents.putInt(modificationTimestampSeconds); // modification_time; unsigned int(32)
contents.putInt((int) MVHD_TIMEBASE); // The per-track timescales might be different.
contents.putInt(
(int) Mp4Utils.vuFromUs(videoDurationUs, MVHD_TIMEBASE)); // Duration of the entire video.
@@ -175,13 +179,14 @@ import java.util.Locale;
public static ByteBuffer mdhd(
long trackDurationVu,
int videoUnitTimebase,
+ int creationTimestampSeconds,
int modificationTimestampSeconds,
@Nullable String languageCode) {
ByteBuffer contents = ByteBuffer.allocate(Mp4Utils.MAX_FIXED_LEAF_BOX_SIZE);
contents.putInt(0x0); // version and flags
- contents.putInt(modificationTimestampSeconds); // creation_time
- contents.putInt(modificationTimestampSeconds); // modification_time
+ contents.putInt(creationTimestampSeconds); // creation_time; unsigned int(32)
+ contents.putInt(modificationTimestampSeconds); // modification_time; unsigned int(32)
contents.putInt(videoUnitTimebase);
diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/MetadataCollector.java b/libraries/muxer/src/main/java/androidx/media3/muxer/MetadataCollector.java
index ed02a57cfe..9bf3f3629f 100644
--- a/libraries/muxer/src/main/java/androidx/media3/muxer/MetadataCollector.java
+++ b/libraries/muxer/src/main/java/androidx/media3/muxer/MetadataCollector.java
@@ -15,11 +15,10 @@
*/
package androidx.media3.muxer;
-import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkState;
-import static androidx.media3.muxer.Mp4Utils.UNSIGNED_INT_MAX_VALUE;
+import static androidx.media3.container.Mp4TimestampData.unixTimeToMp4TimeSeconds;
-import androidx.media3.container.Mp4Util;
+import androidx.media3.container.Mp4TimestampData;
import java.nio.ByteBuffer;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -30,14 +29,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public int orientation;
public @MonotonicNonNull Mp4Location location;
public Map metadataPairs;
- public int modificationTimestampSeconds;
+ public Mp4TimestampData timestampData;
public @MonotonicNonNull ByteBuffer xmpData;
public MetadataCollector() {
orientation = 0;
metadataPairs = new LinkedHashMap<>();
- modificationTimestampSeconds =
- (int) Mp4Util.unixTimeToMp4TimeSeconds(System.currentTimeMillis());
+ long currentTimeInMp4TimeSeconds = unixTimeToMp4TimeSeconds(System.currentTimeMillis());
+ timestampData =
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ currentTimeInMp4TimeSeconds,
+ /* modificationTimestampSeconds= */ currentTimeInMp4TimeSeconds);
}
public void addXmp(ByteBuffer xmpData) {
@@ -61,10 +63,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
metadataPairs.put(key, value);
}
- public void setModificationTime(long unixTimestampMs) {
- long timestampSeconds = Mp4Util.unixTimeToMp4TimeSeconds(unixTimestampMs);
- checkArgument(
- timestampSeconds <= UNSIGNED_INT_MAX_VALUE, "Only 32-bit long timestamp supported");
- this.modificationTimestampSeconds = (int) timestampSeconds;
+ public void setTimestampData(Mp4TimestampData timestampData) {
+ this.timestampData = timestampData;
}
}
diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4MoovStructure.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4MoovStructure.java
index ffacb22326..1f5837aa4e 100644
--- a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4MoovStructure.java
+++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4MoovStructure.java
@@ -60,6 +60,12 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
@SuppressWarnings("InlinedApi")
public ByteBuffer moovMetadataHeader(
List extends TrackMetadataProvider> tracks, long minInputPtsUs, boolean isFragmentedMp4) {
+ // The timestamp will always fit into a 32-bit integer. This is already validated in the
+ // Mp4Muxer.setTimestampData() API. The value after type casting might be negative, but it is
+ // still valid because it is meant to be read as an unsigned integer.
+ int creationTimestampSeconds = (int) metadataCollector.timestampData.creationTimestampSeconds;
+ int modificationTimestampSeconds =
+ (int) metadataCollector.timestampData.modificationTimestampSeconds;
List trakBoxes = new ArrayList<>();
List trexBoxes = new ArrayList<>();
@@ -149,14 +155,16 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
// Using the time base of the entire file, not that of the track; otherwise,
// Quicktime will stretch the audio accordingly, see b/158120042.
(int) Mp4Utils.vuFromUs(trackDurationUs, MVHD_TIMEBASE),
- metadataCollector.modificationTimestampSeconds,
+ creationTimestampSeconds,
+ modificationTimestampSeconds,
metadataCollector.orientation,
format),
Boxes.mdia(
Boxes.mdhd(
trackDurationInTrackUnitsVu,
track.videoUnitTimebase(),
- metadataCollector.modificationTimestampSeconds,
+ creationTimestampSeconds,
+ modificationTimestampSeconds,
languageCode),
Boxes.hdlr(handlerType, handlerName),
Boxes.minf(mhdBox, Boxes.dinf(Boxes.dref(Boxes.localUrl())), stblBox)));
@@ -168,7 +176,8 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
}
ByteBuffer mvhdBox =
- Boxes.mvhd(nextTrackId, metadataCollector.modificationTimestampSeconds, videoDurationUs);
+ Boxes.mvhd(
+ nextTrackId, creationTimestampSeconds, modificationTimestampSeconds, videoDurationUs);
ByteBuffer udtaBox = Boxes.udta(metadataCollector.location);
ByteBuffer metaBox =
metadataCollector.metadataPairs.isEmpty()
diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java
index 5b277b4f74..577261310c 100644
--- a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java
+++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java
@@ -15,7 +15,9 @@
*/
package androidx.media3.muxer;
+import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
+import static androidx.media3.muxer.Mp4Utils.UNSIGNED_INT_MAX_VALUE;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.media.MediaCodec.BufferInfo;
@@ -25,6 +27,7 @@ import androidx.annotation.Nullable;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi;
+import androidx.media3.container.Mp4TimestampData;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.FileOutputStream;
@@ -233,12 +236,17 @@ public final class Mp4Muxer {
}
/**
- * Sets the file modification time.
+ * Sets the timestamp data (creation time and modification time) for the output file.
*
- * @param timestampMs The modification time UTC in milliseconds since the Unix epoch.
+ * If this method is not called, the file creation time and modification time will be when the
+ * {@link Mp4Muxer} was {@linkplain Builder#build() created}.
*/
- public void setModificationTime(long timestampMs) {
- metadataCollector.setModificationTime(timestampMs);
+ public void setTimestampData(Mp4TimestampData timestampData) {
+ checkArgument(
+ timestampData.creationTimestampSeconds <= UNSIGNED_INT_MAX_VALUE
+ && timestampData.modificationTimestampSeconds <= UNSIGNED_INT_MAX_VALUE,
+ "Only 32-bit long timestamp is supported");
+ metadataCollector.setTimestampData(timestampData);
}
/**
diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
index 2f38b53878..eee73c6dd7 100644
--- a/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
+++ b/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
@@ -66,7 +66,8 @@ public class BoxesTest {
Boxes.tkhd(
/* trackId= */ 1,
/* trackDurationVu= */ 5_000_000,
- /* modificationTimestampSeconds= */ 1_000_000_000,
+ /* creationTimestampSeconds= */ 1_000_000_000,
+ /* modificationTimestampSeconds= */ 2_000_000_000,
/* orientation= */ 90,
FAKE_VIDEO_FORMAT);
@@ -81,7 +82,8 @@ public class BoxesTest {
Boxes.tkhd(
/* trackId= */ 1,
/* trackDurationVu= */ 5_000_000,
- /* modificationTimestampSeconds= */ 1_000_000_000,
+ /* creationTimestampSeconds= */ 1_000_000_000,
+ /* modificationTimestampSeconds= */ 2_000_000_000,
/* orientation= */ 90,
FAKE_AUDIO_FORMAT);
@@ -95,7 +97,8 @@ public class BoxesTest {
ByteBuffer mvhdBox =
Boxes.mvhd(
/* nextEmptyTrackId= */ 3,
- /* modificationTimestampSeconds= */ 1_000_000_000,
+ /* creationTimestampSeconds= */ 1_000_000_000,
+ /* modificationTimestampSeconds= */ 2_000_000_000,
/* videoDurationUs= */ 5_000_000);
DumpableMp4Box dumpableBox = new DumpableMp4Box(mvhdBox);
@@ -108,7 +111,8 @@ public class BoxesTest {
Boxes.mdhd(
/* trackDurationVu= */ 5_000_000,
VU_TIMEBASE,
- /* modificationTimestampSeconds= */ 1_000_000_000,
+ /* creationTimestampSeconds= */ 1_000_000_000,
+ /* modificationTimestampSeconds= */ 2_000_000_000,
/* languageCode= */ "und");
DumpableMp4Box dumpableBox = new DumpableMp4Box(mdhdBox);
diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java
index 430993e75e..43029dc257 100644
--- a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java
+++ b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertThrows;
import android.media.MediaCodec.BufferInfo;
import android.util.Pair;
+import androidx.media3.container.Mp4TimestampData;
import androidx.media3.extractor.mp4.Mp4Extractor;
import androidx.media3.muxer.Mp4Muxer.TrackToken;
import androidx.media3.test.utils.DumpFileAsserts;
@@ -63,7 +64,10 @@ public class Mp4MuxerEndToEndTest {
public void createMp4File_withSameTracksOffset_matchesExpected() throws IOException {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
Pair track1Sample1 =
MuxerTestUtil.getFakeSampleAndSampleInfo(/* presentationTimeUs= */ 100L);
Pair track1Sample2 =
@@ -103,7 +107,10 @@ public class Mp4MuxerEndToEndTest {
public void createMp4File_withDifferentTracksOffset_matchesExpected() throws IOException {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
Pair track1Sample1 =
MuxerTestUtil.getFakeSampleAndSampleInfo(/* presentationTimeUs= */ 0L);
Pair track1Sample2 =
@@ -162,7 +169,10 @@ public class Mp4MuxerEndToEndTest {
public void createMp4File_withOneTrackEmpty_doesNotWriteEmptyTrack() throws Exception {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
- mp4Muxer.setModificationTime(/* timestampMs= */ 500_000_000L);
+ mp4Muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 100_000_000L,
+ /* modificationTimestampSeconds= */ 500_000_000L));
Pair track1Sample1 =
MuxerTestUtil.getFakeSampleAndSampleInfo(/* presentationTimeUs= */ 0L);
Pair track1Sample2 =
diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java
index 2b0127ef46..ed5a1e7906 100644
--- a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java
+++ b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java
@@ -20,6 +20,7 @@ import static androidx.media3.muxer.MuxerTestUtil.FAKE_VIDEO_FORMAT;
import android.content.Context;
import android.media.MediaCodec.BufferInfo;
import android.util.Pair;
+import androidx.media3.container.Mp4TimestampData;
import androidx.media3.extractor.mp4.Mp4Extractor;
import androidx.media3.muxer.Mp4Muxer.TrackToken;
import androidx.media3.test.utils.DumpFileAsserts;
@@ -53,7 +54,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
} finally {
@@ -75,7 +79,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
@@ -99,7 +106,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
@@ -123,7 +133,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
@@ -147,7 +160,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
muxer.setLocation(33.0f, -120f);
@@ -170,7 +186,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
} finally {
@@ -192,7 +211,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
muxer.setCaptureFps(120.0f);
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
@@ -215,7 +237,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
muxer.addMetadata("SomeStringKey", "Some Random String");
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
@@ -238,7 +263,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
muxer.addMetadata("SomeStringKey", 10.0f);
TrackToken token = muxer.addTrack(/* sortKey= */ 0, FAKE_VIDEO_FORMAT);
muxer.writeSampleData(token, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
@@ -261,7 +289,10 @@ public class Mp4MuxerMetadataTest {
Mp4Muxer muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
try {
- muxer.setModificationTime(/* timestampMs= */ 5_000_000L);
+ muxer.setTimestampData(
+ new Mp4TimestampData(
+ /* creationTimestampSeconds= */ 1_000_000L,
+ /* modificationTimestampSeconds= */ 5_000_000L));
Context context = ApplicationProvider.getApplicationContext();
byte[] xmpBytes = TestUtil.getByteArray(context, XMP_SAMPLE_DATA);
ByteBuffer xmp = ByteBuffer.wrap(xmpBytes);
diff --git a/libraries/test_data/src/test/assets/muxerdumps/audio_track_tkhd_box.dump b/libraries/test_data/src/test/assets/muxerdumps/audio_track_tkhd_box.dump
index 5b1c2f92e7..195989c244 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/audio_track_tkhd_box.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/audio_track_tkhd_box.dump
@@ -1,2 +1,2 @@
tkhd (92 bytes):
- Data = length 84, hash 8F9E5354
+ Data = length 84, hash C3AC4BE9
diff --git a/libraries/test_data/src/test/assets/muxerdumps/h265_with_metadata_track.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/h265_with_metadata_track.mp4.dump
index a17d501929..a472ffc0e1 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/h265_with_metadata_track.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/h265_with_metadata_track.mp4.dump
@@ -13,7 +13,7 @@ track 0:
id = 1
sampleMimeType = application/meta
maxInputSize = 161
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
sample 0:
time = 0
flags = 1
@@ -39,7 +39,7 @@ track 1:
channelCount = 2
sampleRate = 48000
language = ```
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 2, hash 560
sample 0:
@@ -71,7 +71,7 @@ track 2:
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 85, hash 6F3CAA16
sample 0:
diff --git a/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4.dump
index d62b694803..2707c7a9aa 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4.dump
@@ -23,7 +23,7 @@ track 0:
colorTransfer = 6
lumaBitdepth = 10
chromaBitdepth = 10
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 99, hash 99842E5A
sample 0:
@@ -547,7 +547,7 @@ track 1:
channelCount = 2
sampleRate = 48000
language = ```
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 2, hash 560
sample 0:
diff --git a/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4_fragmented_box_structure.dump b/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4_fragmented_box_structure.dump
index 737a6b591a..e2baf278d6 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4_fragmented_box_structure.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/hdr10-720p.mp4_fragmented_box_structure.dump
@@ -2,13 +2,13 @@ ftyp (28 bytes):
Data = length 20, hash EF896440
moov (1209 bytes):
mvhd (108 bytes):
- Data = length 100, hash 5CF3AC6F
+ Data = length 100, hash 2FE65289
trak (610 bytes):
tkhd (92 bytes):
- Data = length 84, hash 112173F4
+ Data = length 84, hash 7E478E0E
mdia (510 bytes):
mdhd (32 bytes):
- Data = length 24, hash 42753A93
+ Data = length 24, hash 87E287AD
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (426 bytes):
@@ -31,10 +31,10 @@ moov (1209 bytes):
Data = length 8, hash 94446F01
trak (411 bytes):
tkhd (92 bytes):
- Data = length 84, hash 34D7906B
+ Data = length 84, hash A1FDAA85
mdia (311 bytes):
mdhd (32 bytes):
- Data = length 24, hash EA3D1FE6
+ Data = length 24, hash 2FAA6D00
hdlr (44 bytes):
Data = length 36, hash 49FC755F
minf (227 bytes):
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mdhd_box.dump b/libraries/test_data/src/test/assets/muxerdumps/mdhd_box.dump
index 12a2a4804f..c14ad8b130 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mdhd_box.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mdhd_box.dump
@@ -1,2 +1,2 @@
mdhd (32 bytes):
- Data = length 24, hash D0792E76
+ Data = length 24, hash 71B9FC8B
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_0_orientation.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_0_orientation.mp4.dump
index 0022672c9e..c253c89465 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_0_orientation.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_0_orientation.mp4.dump
@@ -20,7 +20,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_180_orientation.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_180_orientation.mp4.dump
index 16b9c1b912..e873336bb5 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_180_orientation.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_180_orientation.mp4.dump
@@ -21,7 +21,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_270_orientation.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_270_orientation.mp4.dump
index edd0ab5765..ec6cecc4f0 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_270_orientation.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_270_orientation.mp4.dump
@@ -21,7 +21,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_90_orientation.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_90_orientation.mp4.dump
index 2bf7d547e3..0b7b8ee4af 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_90_orientation.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_90_orientation.mp4.dump
@@ -21,7 +21,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_different_tracks_offset.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_different_tracks_offset.mp4.dump
index 0fc8fe0a83..e9c10110cc 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_different_tracks_offset.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_different_tracks_offset.mp4.dump
@@ -21,7 +21,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
@@ -48,7 +48,7 @@ track 1:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_float_metadata.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_float_metadata.mp4.dump
index f22ab25741..97fb3af1ae 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_float_metadata.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_float_metadata.mp4.dump
@@ -20,7 +20,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[mdta: key=SomeStringKey, value=10.0, Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[mdta: key=SomeStringKey, value=10.0, Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_frame_rate.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_frame_rate.mp4.dump
index 2811d53d40..ff6af8caf2 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_frame_rate.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_frame_rate.mp4.dump
@@ -20,7 +20,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[mdta: key=com.android.capture.fps, value=120.0, Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[mdta: key=com.android.capture.fps, value=120.0, Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_location.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_location.mp4.dump
index 762f6a9037..1464f93898 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_location.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_location.mp4.dump
@@ -20,7 +20,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[xyz: latitude=33.0, longitude=-120.0, Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[xyz: latitude=33.0, longitude=-120.0, Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_null_location.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_null_location.mp4.dump
index 0022672c9e..c253c89465 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_null_location.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_null_location.mp4.dump
@@ -20,7 +20,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_same_tracks_offset.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_same_tracks_offset.mp4.dump
index 0fc8fe0a83..e9c10110cc 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_same_tracks_offset.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_same_tracks_offset.mp4.dump
@@ -21,7 +21,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
@@ -48,7 +48,7 @@ track 1:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_string_metadata.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_string_metadata.mp4.dump
index 37551fdca5..413c2b18f9 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_string_metadata.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_string_metadata.mp4.dump
@@ -20,7 +20,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[mdta: key=SomeStringKey, value=Some Random String, Mp4Timestamp: creation time=2082849800, modification time=2082849800, timescale=10000]
+ metadata = entries=[mdta: key=SomeStringKey, value=Some Random String, Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_xmp.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_xmp.mp4.dump
index b82a76ff6c..749009974e 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_with_xmp.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_with_xmp.mp4.dump
@@ -4,13 +4,13 @@ mdat (71 bytes):
Data = length 55, hash 6B19F4A7
moov (658 bytes):
mvhd (108 bytes):
- Data = length 100, hash A5ADE288
+ Data = length 100, hash 2613A5C
trak (542 bytes):
tkhd (92 bytes):
- Data = length 84, hash 8893F5BB
+ Data = length 84, hash 3D79758F
mdia (442 bytes):
mdhd (32 bytes):
- Data = length 24, hash 50217AD
+ Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (358 bytes):
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mp4_without_empty_track.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/mp4_without_empty_track.mp4.dump
index 40d8ae50c6..a08fe51c0f 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mp4_without_empty_track.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mp4_without_empty_track.mp4.dump
@@ -4,13 +4,13 @@ mdat (126 bytes):
Data = length 110, hash 48173D41
moov (674 bytes):
mvhd (108 bytes):
- Data = length 100, hash 3D6D026F
+ Data = length 100, hash 105FA889
trak (558 bytes):
tkhd (92 bytes):
- Data = length 84, hash 3EFBEC22
+ Data = length 84, hash AC22063C
mdia (458 bytes):
mdhd (32 bytes):
- Data = length 24, hash 42F40E1C
+ Data = length 24, hash 88615B36
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (374 bytes):
diff --git a/libraries/test_data/src/test/assets/muxerdumps/mvhd_box.dump b/libraries/test_data/src/test/assets/muxerdumps/mvhd_box.dump
index 42578f37bd..4f1ac04e00 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/mvhd_box.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/mvhd_box.dump
@@ -1,2 +1,2 @@
mvhd (108 bytes):
- Data = length 100, hash 22E47B06
+ Data = length 100, hash 1EE0A99B
diff --git a/libraries/test_data/src/test/assets/muxerdumps/partial_hdr10-720p.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/partial_hdr10-720p.mp4.dump
index 6d5031acc9..6507a08ee5 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/partial_hdr10-720p.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/partial_hdr10-720p.mp4.dump
@@ -23,7 +23,7 @@ track 0:
colorTransfer = 6
lumaBitdepth = 10
chromaBitdepth = 10
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 99, hash 99842E5A
sample 0:
@@ -415,7 +415,7 @@ track 1:
channelCount = 2
sampleRate = 48000
language = ```
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 2, hash 560
sample 0:
diff --git a/libraries/test_data/src/test/assets/muxerdumps/sample_av1.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/sample_av1.mp4.dump
index 6d923bf2df..0c0b8c43ff 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/sample_av1.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/sample_av1.mp4.dump
@@ -19,7 +19,7 @@ track 0:
colorInfo:
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
sample 0:
time = 0
flags = 1
@@ -153,7 +153,7 @@ track 1:
channelCount = 1
sampleRate = 44100
language = und
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 5, hash 2B7623A
sample 0:
diff --git a/libraries/test_data/src/test/assets/muxerdumps/sample_no_bframes.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/sample_no_bframes.mp4.dump
index 8a46920b0c..1a3b7e3047 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/sample_no_bframes.mp4.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/sample_no_bframes.mp4.dump
@@ -17,7 +17,7 @@ track 0:
channelCount = 1
sampleRate = 44100
language = und
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 2, hash 5F7
sample 0:
@@ -217,7 +217,7 @@ track 1:
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[Mp4Timestamp: creation time=2083344800, modification time=2083344800, timescale=10000]
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
initializationData:
data = length 23, hash 33E412EE
data = length 9, hash FBAFBC0C
diff --git a/libraries/test_data/src/test/assets/muxerdumps/video_track_tkhd_box.dump b/libraries/test_data/src/test/assets/muxerdumps/video_track_tkhd_box.dump
index acf4f75d5a..080742f716 100644
--- a/libraries/test_data/src/test/assets/muxerdumps/video_track_tkhd_box.dump
+++ b/libraries/test_data/src/test/assets/muxerdumps/video_track_tkhd_box.dump
@@ -1,2 +1,2 @@
tkhd (92 bytes):
- Data = length 84, hash D09E9E0B
+ Data = length 84, hash 4AC96A0
diff --git a/libraries/test_data/src/test/assets/transformerdumps/mp4/sample_no_bframes.mp4/transmuxed_with_inappmuxer.dump b/libraries/test_data/src/test/assets/transformerdumps/mp4/sample_no_bframes.mp4/transmuxed_with_inappmuxer.dump
index afe5517c88..d9678a62bf 100644
--- a/libraries/test_data/src/test/assets/transformerdumps/mp4/sample_no_bframes.mp4/transmuxed_with_inappmuxer.dump
+++ b/libraries/test_data/src/test/assets/transformerdumps/mp4/sample_no_bframes.mp4/transmuxed_with_inappmuxer.dump
@@ -23,7 +23,7 @@ track 0:
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
- metadata = entries=[mdta: key=com.android.version, value=13, xyz: latitude=40.68, longitude=-74.4999, Mp4Timestamp: creation time=2000000000, modification time=2000000000, timescale=10000]
+ metadata = entries=[mdta: key=com.android.version, value=13, xyz: latitude=40.68, longitude=-74.4999, Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000]
initializationData:
data = length 23, hash 33E412EE
data = length 9, hash FBAFBC0C
@@ -158,7 +158,7 @@ track 1:
channelCount = 1
sampleRate = 44100
language = und
- metadata = entries=[mdta: key=com.android.version, value=13, xyz: latitude=40.68, longitude=-74.4999, Mp4Timestamp: creation time=2000000000, modification time=2000000000, timescale=10000]
+ metadata = entries=[mdta: key=com.android.version, value=13, xyz: latitude=40.68, longitude=-74.4999, Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000]
initializationData:
data = length 2, hash 5F7
sample 0:
diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java
index c7b670d520..8759071fb2 100644
--- a/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java
+++ b/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java
@@ -28,7 +28,6 @@ import androidx.media3.common.util.Util;
import androidx.media3.container.MdtaMetadataEntry;
import androidx.media3.container.Mp4LocationData;
import androidx.media3.container.Mp4TimestampData;
-import androidx.media3.container.Mp4Util;
import androidx.media3.container.XmpData;
import androidx.media3.muxer.Mp4Muxer;
import androidx.media3.muxer.Mp4Muxer.TrackToken;
@@ -290,9 +289,7 @@ public final class InAppMuxer implements Muxer {
} else if (entry instanceof XmpData) {
mp4Muxer.addXmp(ByteBuffer.wrap(((XmpData) entry).data));
} else if (entry instanceof Mp4TimestampData) {
- // TODO: b/285281716 - Use creation time specific API.
- mp4Muxer.setModificationTime(
- Mp4Util.mp4TimeToUnixTimeMs(((Mp4TimestampData) entry).creationTimestampSeconds));
+ mp4Muxer.setTimestampData((Mp4TimestampData) entry);
} else if (entry instanceof MdtaMetadataEntry) {
MdtaMetadataEntry mdtaMetadataEntry = (MdtaMetadataEntry) entry;
if (mdtaMetadataEntry.key.equals(MdtaMetadataEntry.KEY_ANDROID_CAPTURE_FPS)) {
diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerWithInAppMuxerEndToEndTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerWithInAppMuxerEndToEndTest.java
index b957108ba0..3e33519024 100644
--- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerWithInAppMuxerEndToEndTest.java
+++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerWithInAppMuxerEndToEndTest.java
@@ -16,7 +16,6 @@
package androidx.media3.transformer;
import static androidx.media3.common.util.Assertions.checkState;
-import static androidx.media3.container.Mp4TimestampData.TIMESCALE_UNSET;
import static androidx.media3.test.utils.FileUtil.retrieveTrackFormat;
import static com.google.common.truth.Truth.assertThat;
@@ -70,9 +69,8 @@ public class TransformerWithInAppMuxerEndToEndTest {
// Add timestamp to make output file deterministic.
metadataEntries.add(
new Mp4TimestampData(
- /* creationTimestampSeconds= */ 2_000_000_000L,
- /* modificationTimestampSeconds= */ 2_000_000_000L,
- TIMESCALE_UNSET)))
+ /* creationTimestampSeconds= */ 3_000_000_000L,
+ /* modificationTimestampSeconds= */ 4_000_000_000L)))
.build();
Transformer transformer =
@@ -183,12 +181,10 @@ public class TransformerWithInAppMuxerEndToEndTest {
@Test
public void transmux_withTimestampData_writesSameTimestampData() throws Exception {
- // TODO: b/285281716 - Use different value for modification timestamp.
Mp4TimestampData expectedTimestampData =
new Mp4TimestampData(
- /* creationTimestampSeconds= */ 2_000_000_000L,
- /* modificationTimestampSeconds= */ 2_000_000_000L,
- TIMESCALE_UNSET);
+ /* creationTimestampSeconds= */ 3_000_000_000L,
+ /* modificationTimestampSeconds= */ 4_000_000_000L);
Muxer.Factory inAppMuxerFactory =
new InAppMuxer.Factory.Builder()
.setMetadataProvider(metadataEntries -> metadataEntries.add(expectedTimestampData))