Merge "Revert "Bugfix: Trimmed iPhone HDR file has wrong playback durat..."" into main
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index cb2994e..b3707c8 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -1615,6 +1615,39 @@
 
             mLastTrack->timescale = ntohl(timescale);
 
+            // 14496-12 says all ones means indeterminate, but some files seem to use
+            // 0 instead. We treat both the same.
+            int64_t duration = 0;
+            if (version == 1) {
+                if (mDataSource->readAt(
+                            timescale_offset + 4, &duration, sizeof(duration))
+                        < (ssize_t)sizeof(duration)) {
+                    return ERROR_IO;
+                }
+                if (duration != -1) {
+                    duration = ntoh64(duration);
+                }
+            } else {
+                uint32_t duration32;
+                if (mDataSource->readAt(
+                            timescale_offset + 4, &duration32, sizeof(duration32))
+                        < (ssize_t)sizeof(duration32)) {
+                    return ERROR_IO;
+                }
+                if (duration32 != 0xffffffff) {
+                    duration = ntohl(duration32);
+                }
+            }
+            if (duration != 0 && mLastTrack->timescale != 0) {
+                long double durationUs = ((long double)duration * 1000000) / mLastTrack->timescale;
+                if (durationUs < 0 || durationUs > INT64_MAX) {
+                    ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
+                          (long long) duration, (long long) mLastTrack->timescale);
+                    return ERROR_MALFORMED;
+                }
+                AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
+            }
+
             uint8_t lang[2];
             off64_t lang_offset;
             if (version == 1) {
@@ -3874,18 +3907,17 @@
     }
 
     int32_t id;
-    int64_t duration;
 
     if (version == 1) {
         // we can get ctime value from U64_AT(&buffer[4])
         // we can get mtime value from U64_AT(&buffer[12])
         id = U32_AT(&buffer[20]);
-        duration = U64_AT(&buffer[28]);
+        // we can get duration value from U64_AT(&buffer[28])
     } else if (version == 0) {
         // we can get ctime value from U32_AT(&buffer[4])
         // we can get mtime value from U32_AT(&buffer[8])
         id = U32_AT(&buffer[12]);
-        duration = U32_AT(&buffer[20]);
+        // we can get duration value from U32_AT(&buffer[20])
     } else {
         return ERROR_UNSUPPORTED;
     }
@@ -3894,15 +3926,6 @@
         return ERROR_MALFORMED;
 
     AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_TRACK_ID, id);
-    if (duration != 0 && mHeaderTimescale != 0) {
-        long double durationUs = ((long double)duration * 1000000) / mHeaderTimescale;
-        if (durationUs < 0 || durationUs > INT64_MAX) {
-            ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
-                  (long long) duration, (long long) mHeaderTimescale);
-            return ERROR_MALFORMED;
-        }
-        AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
-    }
 
     size_t matrixOffset = dynSize + 16;
     int32_t a00 = U32_AT(&buffer[matrixOffset]);