mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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
PiperOrigin-RevId: 688103949
(cherry picked from commit 457bc55a4d)
This commit is contained in:
parent
7da2161a7b
commit
cc947dc690
2 changed files with 63 additions and 5 deletions
|
|
@ -1,5 +1,44 @@
|
||||||
# Release notes
|
# Release notes
|
||||||
|
|
||||||
|
### Unreleased changes
|
||||||
|
|
||||||
|
* Common Library:
|
||||||
|
* ExoPlayer:
|
||||||
|
* 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:
|
||||||
|
* `DataSourceContractTest`: Assert that `DataSource.getUri()` returns the
|
||||||
|
resolved URI (as documented). Where this is different to the requested
|
||||||
|
URI, tests can indicate this using the new
|
||||||
|
`DataSourceContractTest.TestResource.Builder.setResolvedUri()` method.
|
||||||
|
* Audio:
|
||||||
|
* Video:
|
||||||
|
* Text:
|
||||||
|
* Metadata:
|
||||||
|
* Image:
|
||||||
|
* DRM:
|
||||||
|
* Effect:
|
||||||
|
* Muxers:
|
||||||
|
* IMA extension:
|
||||||
|
* UI:
|
||||||
|
* Downloads:
|
||||||
|
* OkHttp Extension:
|
||||||
|
* Cronet Extension:
|
||||||
|
* RTMP Extension:
|
||||||
|
* HLS Extension:
|
||||||
|
* DASH Extension:
|
||||||
|
* Smooth Streaming Extension:
|
||||||
|
* RTSP Extension:
|
||||||
|
* Decoder Extensions (FFmpeg, VP9, AV1, etc.):
|
||||||
|
* MIDI extension:
|
||||||
|
* Leanback extension:
|
||||||
|
* Cast Extension:
|
||||||
|
* Test Utilities:
|
||||||
|
* Demo app:
|
||||||
|
* Remove deprecated symbols:
|
||||||
|
|
||||||
## 1.5
|
## 1.5
|
||||||
|
|
||||||
### 1.5.0-beta01 (2024-10-30)
|
### 1.5.0-beta01 (2024-10-30)
|
||||||
|
|
@ -122,6 +161,11 @@ This release includes the following changes since the
|
||||||
* Fix `IllegalStateException` from
|
* Fix `IllegalStateException` from
|
||||||
`DefaultDrmSession.requiresSecureDecoder` after opening a DRM session
|
`DefaultDrmSession.requiresSecureDecoder` after opening a DRM session
|
||||||
failed. This issue was introduced in `1.5.0-alpha01`.
|
failed. This issue was introduced in `1.5.0-alpha01`.
|
||||||
|
* Effect:
|
||||||
|
* Moved the functionality of `OverlaySettings` into
|
||||||
|
`StaticOverlaySettings`. `OverlaySettings` can be subclassed to allow
|
||||||
|
dynamic overlay settings.
|
||||||
|
* Muxers:
|
||||||
* IMA extension:
|
* IMA extension:
|
||||||
* Fix bug where server-side inserted DAI streams without a preroll can
|
* Fix bug where server-side inserted DAI streams without a preroll can
|
||||||
result in an `ArrayIndexOutOfBoundsException` when playing past the last
|
result in an `ArrayIndexOutOfBoundsException` when playing past the last
|
||||||
|
|
|
||||||
|
|
@ -958,14 +958,28 @@ 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 (mediaDuration == 0) {
|
if (mediaDurationUnknown) {
|
||||||
// 0 duration normally indicates that the file is fully fragmented (i.e. all of the media
|
mdhd.skipBytes(mediaDurationByteCount);
|
||||||
// samples are in fragments). Treat as unknown.
|
|
||||||
mediaDurationUs = C.TIME_UNSET;
|
mediaDurationUs = C.TIME_UNSET;
|
||||||
} else {
|
} else {
|
||||||
mediaDurationUs = Util.scaleLargeTimestamp(mediaDuration, C.MICROS_PER_SECOND, timescale);
|
long mediaDuration = version == 0 ? mdhd.readUnsignedInt() : mdhd.readUnsignedLongToLong();
|
||||||
|
if (mediaDuration == 0) {
|
||||||
|
// 0 duration normally indicates that the file is fully fragmented (i.e. all of the media
|
||||||
|
// samples are in fragments). Treat as unknown.
|
||||||
|
mediaDurationUs = C.TIME_UNSET;
|
||||||
|
} else {
|
||||||
|
mediaDurationUs = Util.scaleLargeTimestamp(mediaDuration, C.MICROS_PER_SECOND, timescale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int languageCode = mdhd.readUnsignedShort();
|
int languageCode = mdhd.readUnsignedShort();
|
||||||
String language =
|
String language =
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue