Fix media duration parsing in mdhd box of MP4 files to handle -1 values

Treats the media duration as unknown (`C.TIME_UNSET`) when all bytes are `-1` to prevent exceptions during playback.

Issue: androidx/media#1819

#cherrypick

PiperOrigin-RevId: 688103949
This commit is contained in:
rohks 2024-10-21 05:51:49 -07:00 committed by Copybara-Service
parent 40cd64ab19
commit 457bc55a4d
2 changed files with 22 additions and 5 deletions

View File

@ -5,6 +5,9 @@
* Common Library: * Common Library:
* ExoPlayer: * ExoPlayer:
* Transformer: * Transformer:
* Extractors:
* Fix media duration parsing in `mdhd` box of MP4 files to handle `-1`
values ([#1819](https://github.com/androidx/media/issues/1819)).
* DataSource: * DataSource:
* `DataSourceContractTest`: Assert that `DataSource.getUri()` returns the * `DataSourceContractTest`: Assert that `DataSource.getUri()` returns the
resolved URI (as documented). Where this is different to the requested resolved URI (as documented). Where this is different to the requested

View File

@ -958,8 +958,21 @@ public final class BoxParser {
int version = parseFullBoxVersion(fullAtom); int version = parseFullBoxVersion(fullAtom);
mdhd.skipBytes(version == 0 ? 8 : 16); mdhd.skipBytes(version == 0 ? 8 : 16);
long timescale = mdhd.readUnsignedInt(); long timescale = mdhd.readUnsignedInt();
long mediaDuration = version == 0 ? mdhd.readUnsignedInt() : mdhd.readUnsignedLongToLong(); boolean mediaDurationUnknown = true;
int mediaDurationPosition = mdhd.getPosition();
int mediaDurationByteCount = version == 0 ? 4 : 8;
for (int i = 0; i < mediaDurationByteCount; i++) {
if (mdhd.getData()[mediaDurationPosition + i] != -1) {
mediaDurationUnknown = false;
break;
}
}
long mediaDurationUs; long mediaDurationUs;
if (mediaDurationUnknown) {
mdhd.skipBytes(mediaDurationByteCount);
mediaDurationUs = C.TIME_UNSET;
} else {
long mediaDuration = version == 0 ? mdhd.readUnsignedInt() : mdhd.readUnsignedLongToLong();
if (mediaDuration == 0) { if (mediaDuration == 0) {
// 0 duration normally indicates that the file is fully fragmented (i.e. all of the media // 0 duration normally indicates that the file is fully fragmented (i.e. all of the media
// samples are in fragments). Treat as unknown. // samples are in fragments). Treat as unknown.
@ -967,6 +980,7 @@ public final class BoxParser {
} else { } else {
mediaDurationUs = Util.scaleLargeTimestamp(mediaDuration, C.MICROS_PER_SECOND, timescale); mediaDurationUs = Util.scaleLargeTimestamp(mediaDuration, C.MICROS_PER_SECOND, timescale);
} }
}
int languageCode = mdhd.readUnsignedShort(); int languageCode = mdhd.readUnsignedShort();
String language = String language =
"" ""