Some videos include zero length NAL units in the
length-delimited MP4 samples.
Empty NAL units are not spec-compliant (see ISO/IEC 14496-15 section 4.3.3.3),
but other players are able to play these videos (with warnings or errors).
With this change, we check track.sampleTable.sizes[sampleIndex] before
reading a byte from the NAL unit itself.
PiperOrigin-RevId: 711720621
Replaced an existing APV file as bitstream syntax has now changed and
previous clip is not a valid bitstream anymore.
This clip was provided by the openAPV team and is under BSD-3 license.
PiperOrigin-RevId: 711318578
AMR-NB and AMR-WB are inherently mono, so channel count is set to 1. Sample rate is also hard-coded to adhere to codec standards.
Also removed unused parameter `hasAdditionalViews` in `StriData`.
#cherrypick
PiperOrigin-RevId: 707606245
`Parcelable` is not safe for IPCs between binaries with potentially
different class definitions (e.g. two apps built from different versions
of media3).
If we get a use case to bundle metadata, then the `Metadata` and
`Metadata.Entry` classes needs to provide a `toBundle()` method.
PiperOrigin-RevId: 706678892
Before this change, the value of the `dwLength` in the stream header was
interpreted as the number of chunks in the file. Seeking and timestamp
calculation use the media duration and total chunk count. However, in some
files the `dwLength` field appears not to store the number of chunks. For
example, there are CBR MP3 and AC3 files where this field seems to store the
total number of bytes of compressed media instead. That caused seeking and
timestamp calculation to give much smaller values than expected (because the
`dwLength` is very large), which broke seeking.
Work around this using the `idx1` index header if present. We only support
audio formats where every audio sample is a sync sample in AVI, and all chunks
should therefore be listed in this index. Based on testing on many sample AVI
files this gives a reliable total chunk count and fixes seeking.
The test media file is a transcoded version of Big Buck Bunny but manually
edited to overwrite the length, rate and sample size header files to simulate
the error case.
PiperOrigin-RevId: 705103651
AAC is the only format where the codec data buffer is actually used.
Invalid or obscure versions of the relevant syntax can break extraction when we
try to read the codec data, so it's better to read it only when it's required.
PiperOrigin-RevId: 704308925
This means we can complete preparation (and trigger track selection)
before opening a `DataSource`, which then means we only end up loading
the data for a selected subtitle track (instead of all tracks as
currently happens).
By making preparation trivial in this case (with no reasonable cause
of error), we can also remove the `suppressPrepareError` option added in
b3290eff10.
This change also fixes the implementation of
`ProgressiveMediaPeriod.maybeStartDeferredRetry` to only short-circuit
return `false` if the chosen track is not audio or video **and** there
is at least one audio or video track in this period.
Issue: androidx/media#1721
PiperOrigin-RevId: 702275968
Add missing ones for `ForwardingExtractorInput` and `ForwardingSeekMap`.
`ForwardingTimeline` is a bit more fiddly, so it's left for a follow-up
change.
PiperOrigin-RevId: 701988492
The previous code assumed that the `VBRI` Table of Contents (ToC)
covers all the MP3 data in the file. In a file with an invalid VBRI ToC
where this isn't the case, this results in playback silently stopping
mid-playback (and either advancing to the next item, or continuing to
count up the playback clock forever). This change considers the `bytes`
field to determine the end of the MP3 data, in addition to deriving it
from the ToC. If they disagree we log a warning and take the max value.
This is because we handle accidentally reading non-MP3 data at the end
(or hitting EoF) better than stopping reading valid MP3 data partway
through.
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700319250
The current code assumes that the first Table of Contents segment
includes the `VBRI` frame, but I don't think this is correct and it
should only include real/audible MP3 ata - so this change updates the
logic to assume the first ToC segment starts at the frame **after** the
`VBRI` frame.
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700269811
This was hand-crafted with a 4-entry ToC by modifying
`bear-vbr-xing-header.mp3` in a hex editor.
The output difference from 117 samples to 116 samples is due to the
calculation in `VbriSeeker` assuming that the ToC includes the VBRI
frame itself, which I don't think is correct (fix is in a follow-up
change).
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700254516
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