The content in Issue: androidx/media#1863 has every sample incorrectly marked as a
sync sample in the MP4 metadata, which results in flushing the
re-ordering queue on every sample, so nothing gets re-ordered, so the
subtitles are garbled.
There are currently two "uses" for this call on every keyframe:
1. It offers a safety valve if we don't read a `maxNumReorderSamples`
value from the video. Without this, the queue will just keep growing
and end up swallowing all subtitle data (similar to the bug fixed by
39c734963f).
2. When we do read (or infer) a `maxNumReorderSamples` it means we can
emit samples from the queue slightly earlier - but this is pretty
marginal, given i think the max possible value for
`maxNumReorderSamples` is 16, so the most benefit we would get is 16
frames (~0.53s at 30fps) - in most cases we will have more than 0.5s
of buffer ahead of the playback position, so the subtitles will still
get shown at the right time with no problem.
(1) is resolved in this change by setting the queue size to zero (no
reordering) if we don't have a value for `maxNumReorderSamples`.
(2) has minimal impact, so we just accept it.
We may be able to inspect the NAL unit to determine IDR vs non-IDR
instead - we will consider this as a follow-up change, but given the
minimal impact of (2) we may not pursue this.
#cherrypick
PiperOrigin-RevId: 696583702
The behaviour was changed in 1.4.0 with 0f42dd4752,
so that the buffer timestamp is compared to `outputStartTimeUs` when
deciding whether to discard a "decode only" buffer before decoding
(instead of the deprecated/removed `isDecodeOnly` property). This breaks
when the buffer timestamp is `TIME_END_OF_SOURCE` (which is
`Long.MIN_VALUE`), because `TIME_END_OF_SOURCE < outputStartTimeUs` is
always true, so the end-of-stream buffer is never passed to the decoder
and on to `TextRenderer` where it is used to
[set `inputStreamEnded = true`](40f187e4b4/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/TextRenderer.java (L434-L436))
and so playback hangs.
#cherrypick
Issue: androidx/media#1863
PiperOrigin-RevId: 695767247
Adjusted logic to accurately calculate sizes and durations for the last valid cue point when cue timestamps are greater than the total duration.
Fixes the issue where the reported duration of the MKV file was greater than the total duration specified by the duration element. Verified this using `mkvinfo` and `mediainfo` tools.
PiperOrigin-RevId: 690961276
This method is already called below in the
`else if (sps.isCompleted())` block which applies when
`hasOutputFormat == true`, but this is only ever entered if we are
parsing SPS and PPS NAL units **after** we've emitted a format, which
is only the case if
`DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS` is set (which
it isn't by default).
The equivalent call in `H265Reader` is already inside the
`if (!hasOutputFormat)` block, so doesn't need a similar fix.
#cherrypick
PiperOrigin-RevId: 689809529
The duration is now correctly calculated as the maximum of all track durations, instead of being overwritten by the last track's value. This aligns with how other Extractor implementations handle durations for multiple tracks.
PiperOrigin-RevId: 688896743
The method allows extractors to set track duration when available. The `default` implementation does nothing, allowing implementers of `TrackOutput` to override it if they need to handle track duration.
Implemented it in `FakeExtractor` to print track duration in dump files.
PiperOrigin-RevId: 688110288
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 allows users to extend and customize specific methods of the `TrackOutput` implementation while inheriting default behaviors for others.
PiperOrigin-RevId: 686454360
Updated logic to walk forward in the timestamps array to include all frames within the valid edit duration, accounting for out-of-order frames. This ensures that no frames with timestamps less than `editMediaTime` + `editDuration` are incorrectly excluded.
Issue: androidx/media#1797
PiperOrigin-RevId: 686075680
This was missed in da724c8cc4
I tried to write a test for this, but got stuck crafting valid test
data. I was able to create a new fragmented MP4 file containing only a
TTML track:
```shell
$ MP4Box -add simple.ttml -frag 2000 sample_fragmented_ttml.mp4
```
Then I tried naively removing the `ftyp` and `moov` boxes with a hex
editor, but using this in `FragmentedMp4ExtractorNoSniffingTest` gave
me an `EOFException` that I didn't get to the root cause of.
Issue: androidx/media#1779
#cherrypick
PiperOrigin-RevId: 683667850
This change is a no-op, because
`SubtitleTranscodingExtractorOutput.seekMap` forwards directly to the
delegate implementation, but it seems clearer to always use the
wrapper.
Also remove a no-op assignment in `MatroskaExtractor`.
This is a follow-up to Issue: androidx/media#1779 where I manually checked every
implementation of `Extractor.init` for a similar mistake.
#cherrypick
PiperOrigin-RevId: 683607090
- Added logic to parse media duration from the `mdhd` box for accurate frame rate calculation.
- Fallbacks to track duration from `tkhd` when `mdhd` contains invalid or missing data.
- Avoids incorrect frame rate calculations in MP4 files with an edit list (`elst`) box.
- Adds frame rate calculations for partially fragmented MP4 files.
- Verified accuracy with tools like `mediainfo` and `ffprobe`.
Issue: androidx/media#1531
**Note**: The slight difference in frame rate values in dump files that aren’t MP4s with an edit list or fragmented MP4s isn’t due to differences in `tkhd` and `mdhd` duration values (which should be identical for non-edited or non-fragmented files). Rather, it’s because they are calculated using different timescales. The `mvhd` box defines a global movie timescale, which is used for the track's `tkhd` duration. Meanwhile, each track’s `mdhd` box defines its own timescale specific to its content type, which we now use for more accurate frame rate calculation.
PiperOrigin-RevId: 676046744
When processing edit lists in MP4 files, the media start position may be a non-keyframe. To ensure proper playback, the decoder must preroll to the preceding keyframe, as these preroll samples are essential for decoding but are not rendered.
Issue: google/ExoPlayer#1659
#cherrypick
PiperOrigin-RevId: 673457615
The `bear-cbr-no-seek-table-trailing-garbage.mp3` test file was generated by appending 150kB of `0xDEADBEEF` onto the end of `bear-cbr-variable-frame-size-no-seek-table.mp3`.
Issue: androidx/media#1563
#cherrypick
PiperOrigin-RevId: 670131828
This allows seek operations in files that were previously unseekable, particularly those with variable bitrate (VBR) or constant bitrate (CBR) with silence frames.
New samples for tests were created by adding silence frames to existing narrowband and wideband versions.
PiperOrigin-RevId: 665349241