Commit 265462bc by olly Committed by Oliver Woodman

Support Opus and Flac in MP4/DASH

Issue: #4883

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=222392621
parent 42cb2c0d
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
### dev-v2 (not yet released) ### ### 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 * DASH: Fix detecting the end of live events
([#4780](https://github.com/google/ExoPlayer/issues/4780)). ([#4780](https://github.com/google/ExoPlayer/issues/4780)).
* Support seeking for a wider range of MPEG-TS streams * Support seeking for a wider range of MPEG-TS streams
......
...@@ -145,6 +145,10 @@ import java.util.List; ...@@ -145,6 +145,10 @@ import java.util.List;
public static final int TYPE_alac = Util.getIntegerCodeForString("alac"); public static final int TYPE_alac = Util.getIntegerCodeForString("alac");
public static final int TYPE_alaw = Util.getIntegerCodeForString("alaw"); public static final int TYPE_alaw = Util.getIntegerCodeForString("alaw");
public static final int TYPE_ulaw = Util.getIntegerCodeForString("ulaw"); 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; public final int type;
......
...@@ -58,6 +58,9 @@ import java.util.List; ...@@ -58,6 +58,9 @@ import java.util.List;
*/ */
private static final int MAX_GAPLESS_TRIM_SIZE_SAMPLES = 3; 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). * Parses a trak atom (defined in 14496-12).
* *
...@@ -679,7 +682,9 @@ import java.util.List; ...@@ -679,7 +682,9 @@ import java.util.List;
|| childAtomType == Atom.TYPE__mp3 || childAtomType == Atom.TYPE__mp3
|| childAtomType == Atom.TYPE_alac || childAtomType == Atom.TYPE_alac
|| childAtomType == Atom.TYPE_alaw || 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, parseAudioSampleEntry(stsd, childAtomType, childStartPosition, childAtomSize, trackId,
language, isQuickTime, drmInitData, out, i); language, isQuickTime, drmInitData, out, i);
} else if (childAtomType == Atom.TYPE_TTML || childAtomType == Atom.TYPE_tx3g } else if (childAtomType == Atom.TYPE_TTML || childAtomType == Atom.TYPE_tx3g
...@@ -976,6 +981,10 @@ import java.util.List; ...@@ -976,6 +981,10 @@ import java.util.List;
mimeType = MimeTypes.AUDIO_ALAW; mimeType = MimeTypes.AUDIO_ALAW;
} else if (atomType == Atom.TYPE_ulaw) { } else if (atomType == Atom.TYPE_ulaw) {
mimeType = MimeTypes.AUDIO_MLAW; 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; byte[] initializationData = null;
...@@ -1016,7 +1025,20 @@ import java.util.List; ...@@ -1016,7 +1025,20 @@ import java.util.List;
} else if (childAtomType == Atom.TYPE_alac) { } else if (childAtomType == Atom.TYPE_alac) {
initializationData = new byte[childAtomSize]; initializationData = new byte[childAtomSize];
parent.setPosition(childPosition); 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; childPosition += childAtomSize;
} }
......
...@@ -207,7 +207,7 @@ public final class MimeTypes { ...@@ -207,7 +207,7 @@ public final class MimeTypes {
if (codec == null) { if (codec == null) {
return null; return null;
} }
codec = codec.trim(); codec = Util.toLowerInvariant(codec.trim());
if (codec.startsWith("avc1") || codec.startsWith("avc3")) { if (codec.startsWith("avc1") || codec.startsWith("avc3")) {
return MimeTypes.VIDEO_H264; return MimeTypes.VIDEO_H264;
} else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) { } else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) {
...@@ -245,6 +245,8 @@ public final class MimeTypes { ...@@ -245,6 +245,8 @@ public final class MimeTypes {
return MimeTypes.AUDIO_OPUS; return MimeTypes.AUDIO_OPUS;
} else if (codec.startsWith("vorbis")) { } else if (codec.startsWith("vorbis")) {
return MimeTypes.AUDIO_VORBIS; return MimeTypes.AUDIO_VORBIS;
} else if (codec.startsWith("flac")) {
return MimeTypes.AUDIO_FLAC;
} else { } else {
return getCustomMimeTypeForCodec(codec); return getCustomMimeTypeForCodec(codec);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment