diff options
author | ybai <ybai@dolby.com> | 2024-03-12 16:37:34 +0800 |
---|---|---|
committer | ybai <ybai@dolby.com> | 2024-05-14 15:51:38 +0800 |
commit | a7486486e90598c89700c900539c952531487d4d (patch) | |
tree | 7e42b69803c82a746fe8e18c8dbb69b7eb360c43 | |
parent | 7e2f3933d7412bfd33b5d3183fa9065e42ec1b0b (diff) | |
download | av-a7486486e90598c89700c900539c952531487d4d.tar.gz |
Bugfix: Trimmed iPhone HDR file has wrong playback duration on Android device
Bug: 329121650
Change-Id: I6bc7baf5bf6bdc3272650bdcdf18f8ad132c172e
-rw-r--r-- | media/module/extractors/mp4/MPEG4Extractor.cpp | 47 |
1 files changed, 12 insertions, 35 deletions
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp index b3707c8d18..cb2994ea58 100644 --- a/media/module/extractors/mp4/MPEG4Extractor.cpp +++ b/media/module/extractors/mp4/MPEG4Extractor.cpp @@ -1615,39 +1615,6 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 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) { @@ -3907,17 +3874,18 @@ status_t MPEG4Extractor::parseTrackHeader( } 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]); - // we can get duration value from U64_AT(&buffer[28]) + duration = 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]); - // we can get duration value from U32_AT(&buffer[20]) + duration = U32_AT(&buffer[20]); } else { return ERROR_UNSUPPORTED; } @@ -3926,6 +3894,15 @@ status_t MPEG4Extractor::parseTrackHeader( 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]); |