Support Opus and Flac in MP4/DASH

Issue: #4883

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=222392621
This commit is contained in:
olly 2018-11-21 05:09:46 -08:00 committed by Oliver Woodman
parent 42cb2c0d62
commit 265462bcbd
4 changed files with 33 additions and 3 deletions

View file

@ -2,6 +2,8 @@
### dev-v2 (not yet released) ###
* MP4: Support Opus and FLAC in the MP4 container, and in DASH
([#4883](https://github.com/google/ExoPlayer/issues/4883)).
* DASH: Fix detecting the end of live events
([#4780](https://github.com/google/ExoPlayer/issues/4780)).
* Support seeking for a wider range of MPEG-TS streams

View file

@ -145,6 +145,10 @@ import java.util.List;
public static final int TYPE_alac = Util.getIntegerCodeForString("alac");
public static final int TYPE_alaw = Util.getIntegerCodeForString("alaw");
public static final int TYPE_ulaw = Util.getIntegerCodeForString("ulaw");
public static final int TYPE_Opus = Util.getIntegerCodeForString("Opus");
public static final int TYPE_dOps = Util.getIntegerCodeForString("dOps");
public static final int TYPE_fLaC = Util.getIntegerCodeForString("fLaC");
public static final int TYPE_dfLa = Util.getIntegerCodeForString("dfLa");
public final int type;

View file

@ -58,6 +58,9 @@ import java.util.List;
*/
private static final int MAX_GAPLESS_TRIM_SIZE_SAMPLES = 3;
/** The magic signature for an Opus Identification header, as defined in RFC-7845. */
private static final byte[] opusMagic = Util.getUtf8Bytes("OpusHead");
/**
* Parses a trak atom (defined in 14496-12).
*
@ -679,7 +682,9 @@ import java.util.List;
|| childAtomType == Atom.TYPE__mp3
|| childAtomType == Atom.TYPE_alac
|| childAtomType == Atom.TYPE_alaw
|| childAtomType == Atom.TYPE_ulaw) {
|| childAtomType == Atom.TYPE_ulaw
|| childAtomType == Atom.TYPE_Opus
|| childAtomType == Atom.TYPE_fLaC) {
parseAudioSampleEntry(stsd, childAtomType, childStartPosition, childAtomSize, trackId,
language, isQuickTime, drmInitData, out, i);
} else if (childAtomType == Atom.TYPE_TTML || childAtomType == Atom.TYPE_tx3g
@ -976,6 +981,10 @@ import java.util.List;
mimeType = MimeTypes.AUDIO_ALAW;
} else if (atomType == Atom.TYPE_ulaw) {
mimeType = MimeTypes.AUDIO_MLAW;
} else if (atomType == Atom.TYPE_Opus) {
mimeType = MimeTypes.AUDIO_OPUS;
} else if (atomType == Atom.TYPE_fLaC) {
mimeType = MimeTypes.AUDIO_FLAC;
}
byte[] initializationData = null;
@ -1016,7 +1025,20 @@ import java.util.List;
} else if (childAtomType == Atom.TYPE_alac) {
initializationData = new byte[childAtomSize];
parent.setPosition(childPosition);
parent.readBytes(initializationData, 0, childAtomSize);
parent.readBytes(initializationData, /* offset= */ 0, childAtomSize);
} else if (childAtomType == Atom.TYPE_dOps) {
// Build an Opus Identification Header (defined in RFC-7845) by concatenating the Opus Magic
// Signature and the body of the dOps atom.
int childAtomBodySize = childAtomSize - Atom.HEADER_SIZE;
initializationData = new byte[opusMagic.length + childAtomBodySize];
System.arraycopy(opusMagic, 0, initializationData, 0, opusMagic.length);
parent.setPosition(childPosition + Atom.HEADER_SIZE);
parent.readBytes(initializationData, opusMagic.length, childAtomBodySize);
} else if (childAtomSize == Atom.TYPE_dfLa) {
int childAtomBodySize = childAtomSize - Atom.FULL_HEADER_SIZE;
initializationData = new byte[childAtomBodySize];
parent.setPosition(childPosition + Atom.FULL_HEADER_SIZE);
parent.readBytes(initializationData, /* offset= */ 0, childAtomBodySize);
}
childPosition += childAtomSize;
}

View file

@ -207,7 +207,7 @@ public final class MimeTypes {
if (codec == null) {
return null;
}
codec = codec.trim();
codec = Util.toLowerInvariant(codec.trim());
if (codec.startsWith("avc1") || codec.startsWith("avc3")) {
return MimeTypes.VIDEO_H264;
} else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) {
@ -245,6 +245,8 @@ public final class MimeTypes {
return MimeTypes.AUDIO_OPUS;
} else if (codec.startsWith("vorbis")) {
return MimeTypes.AUDIO_VORBIS;
} else if (codec.startsWith("flac")) {
return MimeTypes.AUDIO_FLAC;
} else {
return getCustomMimeTypeForCodec(codec);
}