mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
FMP4: Correctly handle multiple sbgp and sgpd boxes
Find sbgp and sgpd boxes with grouping_type == seig in the case they don't come first. Previoulsy we would only find them if they came first. Issue: Issue: #7716 PiperOrigin-RevId: 325407819
This commit is contained in:
parent
36efdc7492
commit
62829be1ce
2 changed files with 37 additions and 23 deletions
|
|
@ -8,9 +8,12 @@
|
||||||
* Add support for `piff` and `isml` brands
|
* Add support for `piff` and `isml` brands
|
||||||
([#7584](https://github.com/google/ExoPlayer/issues/7584)).
|
([#7584](https://github.com/google/ExoPlayer/issues/7584)).
|
||||||
* Fix playback of very short MP4 files.
|
* Fix playback of very short MP4 files.
|
||||||
* FMP4: Fix `saiz` and `senc` sample count checks, resolving a "length
|
* FMP4:
|
||||||
mismatch" `ParserException` when playing certain protected FMP4 streams
|
* Fix `saiz` and `senc` sample count checks, resolving a "length
|
||||||
([#7592](https://github.com/google/ExoPlayer/issues/7592)).
|
mismatch" `ParserException` when playing certain protected FMP4 streams
|
||||||
|
([#7592](https://github.com/google/ExoPlayer/issues/7592)).
|
||||||
|
* Fix handling of `traf` boxes containing multiple `sbgp` or `sgpd`
|
||||||
|
boxes.
|
||||||
* FLV: Ignore SCRIPTDATA segments with invalid name types, rather than failing
|
* FLV: Ignore SCRIPTDATA segments with invalid name types, rather than failing
|
||||||
playback ([#7675](https://github.com/google/ExoPlayer/issues/7675)).
|
playback ([#7675](https://github.com/google/ExoPlayer/issues/7675)).
|
||||||
* Workaround an issue on Broadcom based devices where playbacks would not
|
* Workaround an issue on Broadcom based devices where playbacks would not
|
||||||
|
|
|
||||||
|
|
@ -735,12 +735,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
parseSenc(senc.data, fragment);
|
parseSenc(senc.data, fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeafAtom sbgp = traf.getLeafAtomOfType(Atom.TYPE_sbgp);
|
parseSampleGroups(traf, encryptionBox != null ? encryptionBox.schemeType : null, fragment);
|
||||||
LeafAtom sgpd = traf.getLeafAtomOfType(Atom.TYPE_sgpd);
|
|
||||||
if (sbgp != null && sgpd != null) {
|
|
||||||
parseSgpd(sbgp.data, sgpd.data, encryptionBox != null ? encryptionBox.schemeType : null,
|
|
||||||
fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
int leafChildrenSize = traf.leafChildren.size();
|
int leafChildrenSize = traf.leafChildren.size();
|
||||||
for (int i = 0; i < leafChildrenSize; i++) {
|
for (int i = 0; i < leafChildrenSize; i++) {
|
||||||
|
|
@ -1081,28 +1076,43 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
out.fillEncryptionData(senc);
|
out.fillEncryptionData(senc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseSgpd(ParsableByteArray sbgp, ParsableByteArray sgpd, String schemeType,
|
private static void parseSampleGroups(
|
||||||
TrackFragment out) throws ParserException {
|
ContainerAtom traf, @Nullable String schemeType, TrackFragment out) throws ParserException {
|
||||||
sbgp.setPosition(Atom.HEADER_SIZE);
|
// Find sbgp and sgpd boxes with grouping_type == seig.
|
||||||
int sbgpFullAtom = sbgp.readInt();
|
@Nullable ParsableByteArray sbgp = null;
|
||||||
if (sbgp.readInt() != SAMPLE_GROUP_TYPE_seig) {
|
@Nullable ParsableByteArray sgpd = null;
|
||||||
// Only seig grouping type is supported.
|
for (int i = 0; i < traf.leafChildren.size(); i++) {
|
||||||
|
LeafAtom leafAtom = traf.leafChildren.get(i);
|
||||||
|
ParsableByteArray leafAtomData = leafAtom.data;
|
||||||
|
if (leafAtom.type == Atom.TYPE_sbgp) {
|
||||||
|
leafAtomData.setPosition(Atom.FULL_HEADER_SIZE);
|
||||||
|
if (leafAtomData.readInt() == SAMPLE_GROUP_TYPE_seig) {
|
||||||
|
sbgp = leafAtomData;
|
||||||
|
}
|
||||||
|
} else if (leafAtom.type == Atom.TYPE_sgpd) {
|
||||||
|
leafAtomData.setPosition(Atom.FULL_HEADER_SIZE);
|
||||||
|
if (leafAtomData.readInt() == SAMPLE_GROUP_TYPE_seig) {
|
||||||
|
sgpd = leafAtomData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sbgp == null || sgpd == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Atom.parseFullAtomVersion(sbgpFullAtom) == 1) {
|
|
||||||
sbgp.skipBytes(4); // default_length.
|
sbgp.setPosition(Atom.HEADER_SIZE);
|
||||||
|
int sbgpVersion = Atom.parseFullAtomVersion(sbgp.readInt());
|
||||||
|
sbgp.skipBytes(4); // grouping_type == seig.
|
||||||
|
if (sbgpVersion == 1) {
|
||||||
|
sbgp.skipBytes(4); // grouping_type_parameter.
|
||||||
}
|
}
|
||||||
if (sbgp.readInt() != 1) { // entry_count.
|
if (sbgp.readInt() != 1) { // entry_count.
|
||||||
throw new ParserException("Entry count in sbgp != 1 (unsupported).");
|
throw new ParserException("Entry count in sbgp != 1 (unsupported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
sgpd.setPosition(Atom.HEADER_SIZE);
|
sgpd.setPosition(Atom.HEADER_SIZE);
|
||||||
int sgpdFullAtom = sgpd.readInt();
|
int sgpdVersion = Atom.parseFullAtomVersion(sgpd.readInt());
|
||||||
if (sgpd.readInt() != SAMPLE_GROUP_TYPE_seig) {
|
sgpd.skipBytes(4); // grouping_type == seig.
|
||||||
// Only seig grouping type is supported.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int sgpdVersion = Atom.parseFullAtomVersion(sgpdFullAtom);
|
|
||||||
if (sgpdVersion == 1) {
|
if (sgpdVersion == 1) {
|
||||||
if (sgpd.readUnsignedInt() == 0) {
|
if (sgpd.readUnsignedInt() == 0) {
|
||||||
throw new ParserException("Variable length description in sgpd found (unsupported)");
|
throw new ParserException("Variable length description in sgpd found (unsupported)");
|
||||||
|
|
@ -1113,6 +1123,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
if (sgpd.readUnsignedInt() != 1) { // entry_count.
|
if (sgpd.readUnsignedInt() != 1) { // entry_count.
|
||||||
throw new ParserException("Entry count in sgpd != 1 (unsupported).");
|
throw new ParserException("Entry count in sgpd != 1 (unsupported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
// CencSampleEncryptionInformationGroupEntry
|
// CencSampleEncryptionInformationGroupEntry
|
||||||
sgpd.skipBytes(1); // reserved = 0.
|
sgpd.skipBytes(1); // reserved = 0.
|
||||||
int patternByte = sgpd.readUnsignedByte();
|
int patternByte = sgpd.readUnsignedByte();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue