Commit b6477ddd by tonihei Committed by christosts

Add configuration to support OPUS offload

To support OPUS offload, we need to provide a few configuration values
that are currently not set due to the lack of devices supporting
OPUS offload.

PiperOrigin-RevId: 491613716
(cherry picked from commit 4cf877b8)
parent 69ded0f2
...@@ -194,7 +194,7 @@ public final class C { ...@@ -194,7 +194,7 @@ public final class C {
* #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT}, * #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
* {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_MP3}, {@link #ENCODING_AC3}, {@link * {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_MP3}, {@link #ENCODING_AC3}, {@link
* #ENCODING_E_AC3}, {@link #ENCODING_E_AC3_JOC}, {@link #ENCODING_AC4}, {@link #ENCODING_DTS}, * #ENCODING_E_AC3}, {@link #ENCODING_E_AC3_JOC}, {@link #ENCODING_AC4}, {@link #ENCODING_DTS},
* {@link #ENCODING_DTS_HD} or {@link #ENCODING_DOLBY_TRUEHD}. * {@link #ENCODING_DTS_HD}, {@link #ENCODING_DOLBY_TRUEHD} or {@link #ENCODING_OPUS}.
*/ */
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
...@@ -221,7 +221,8 @@ public final class C { ...@@ -221,7 +221,8 @@ public final class C {
ENCODING_AC4, ENCODING_AC4,
ENCODING_DTS, ENCODING_DTS,
ENCODING_DTS_HD, ENCODING_DTS_HD,
ENCODING_DOLBY_TRUEHD ENCODING_DOLBY_TRUEHD,
ENCODING_OPUS,
}) })
public @interface Encoding {} public @interface Encoding {}
...@@ -321,6 +322,10 @@ public final class C { ...@@ -321,6 +322,10 @@ public final class C {
* @see AudioFormat#ENCODING_DOLBY_TRUEHD * @see AudioFormat#ENCODING_DOLBY_TRUEHD
*/ */
public static final int ENCODING_DOLBY_TRUEHD = AudioFormat.ENCODING_DOLBY_TRUEHD; public static final int ENCODING_DOLBY_TRUEHD = AudioFormat.ENCODING_DOLBY_TRUEHD;
/**
* @see AudioFormat#ENCODING_OPUS
*/
public static final int ENCODING_OPUS = AudioFormat.ENCODING_OPUS;
/** Represents the behavior affecting whether spatialization will be used. */ /** Represents the behavior affecting whether spatialization will be used. */
@Documented @Documented
......
...@@ -567,6 +567,8 @@ public final class MimeTypes { ...@@ -567,6 +567,8 @@ public final class MimeTypes {
return C.ENCODING_DTS_HD; return C.ENCODING_DTS_HD;
case MimeTypes.AUDIO_TRUEHD: case MimeTypes.AUDIO_TRUEHD:
return C.ENCODING_DOLBY_TRUEHD; return C.ENCODING_DOLBY_TRUEHD;
case MimeTypes.AUDIO_OPUS:
return C.ENCODING_OPUS;
default: default:
return C.ENCODING_INVALID; return C.ENCODING_INVALID;
} }
......
...@@ -1778,6 +1778,8 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1778,6 +1778,8 @@ public final class DefaultAudioSink implements AudioSink {
? 0 ? 0
: (Ac3Util.parseTrueHdSyncframeAudioSampleCount(buffer, syncframeOffset) : (Ac3Util.parseTrueHdSyncframeAudioSampleCount(buffer, syncframeOffset)
* Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT); * Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT);
case C.ENCODING_OPUS:
return OpusUtil.parsePacketAudioSampleCount(buffer);
case C.ENCODING_PCM_16BIT: case C.ENCODING_PCM_16BIT:
case C.ENCODING_PCM_16BIT_BIG_ENDIAN: case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
case C.ENCODING_PCM_24BIT: case C.ENCODING_PCM_24BIT:
......
...@@ -248,6 +248,8 @@ public class DefaultAudioTrackBufferSizeProvider ...@@ -248,6 +248,8 @@ public class DefaultAudioTrackBufferSizeProvider
return DtsUtil.DTS_HD_MAX_RATE_BYTES_PER_SECOND; return DtsUtil.DTS_HD_MAX_RATE_BYTES_PER_SECOND;
case C.ENCODING_DOLBY_TRUEHD: case C.ENCODING_DOLBY_TRUEHD:
return Ac3Util.TRUEHD_MAX_RATE_BYTES_PER_SECOND; return Ac3Util.TRUEHD_MAX_RATE_BYTES_PER_SECOND;
case C.ENCODING_OPUS:
return OpusUtil.MAX_BYTES_PER_SECOND;
case C.ENCODING_PCM_16BIT: case C.ENCODING_PCM_16BIT:
case C.ENCODING_PCM_16BIT_BIG_ENDIAN: case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
case C.ENCODING_PCM_24BIT: case C.ENCODING_PCM_24BIT:
......
...@@ -27,6 +27,9 @@ public class OpusUtil { ...@@ -27,6 +27,9 @@ public class OpusUtil {
/** Opus streams are always 48000 Hz. */ /** Opus streams are always 48000 Hz. */
public static final int SAMPLE_RATE = 48_000; public static final int SAMPLE_RATE = 48_000;
/** Maximum achievable Opus bitrate. */
public static final int MAX_BYTES_PER_SECOND = 510 * 1000 / 8; // See RFC 6716. Section 2.1.1
private static final int DEFAULT_SEEK_PRE_ROLL_SAMPLES = 3840; private static final int DEFAULT_SEEK_PRE_ROLL_SAMPLES = 3840;
private static final int FULL_CODEC_INITIALIZATION_DATA_BUFFER_COUNT = 3; private static final int FULL_CODEC_INITIALIZATION_DATA_BUFFER_COUNT = 3;
...@@ -61,6 +64,62 @@ public class OpusUtil { ...@@ -61,6 +64,62 @@ public class OpusUtil {
return initializationData; return initializationData;
} }
/**
* Returns the number of audio samples in the given audio packet.
*
* <p>The buffer's position is not modified.
*
* @param buffer The audio packet.
* @return Returns the number of audio samples in the packet.
*/
public static int parsePacketAudioSampleCount(ByteBuffer buffer) {
long packetDurationUs =
getPacketDurationUs(buffer.get(0), buffer.limit() > 1 ? buffer.get(1) : 0);
return (int) (packetDurationUs * SAMPLE_RATE / C.MICROS_PER_SECOND);
}
/**
* Returns the duration of the given audio packet.
*
* @param buffer The audio packet.
* @return Returns the duration of the given audio packet, in microseconds.
*/
public static long getPacketDurationUs(byte[] buffer) {
return getPacketDurationUs(buffer[0], buffer.length > 1 ? buffer[1] : 0);
}
private static long getPacketDurationUs(byte packetByte0, byte packetByte1) {
// See RFC6716, Sections 3.1 and 3.2.
int toc = packetByte0 & 0xFF;
int frames;
switch (toc & 0x3) {
case 0:
frames = 1;
break;
case 1:
case 2:
frames = 2;
break;
default:
frames = packetByte1 & 0x3F;
break;
}
int config = toc >> 3;
int length = config & 0x3;
int frameDurationUs;
if (config >= 16) {
frameDurationUs = 2500 << length;
} else if (config >= 12) {
frameDurationUs = 10000 << (length & 0x1);
} else if (length == 3) {
frameDurationUs = 60000;
} else {
frameDurationUs = 10000 << length;
}
return (long) frames * frameDurationUs;
}
private static int getPreSkipSamples(byte[] header) { private static int getPreSkipSamples(byte[] header) {
return ((header[11] & 0xFF) << 8) | (header[10] & 0xFF); return ((header[11] & 0xFF) << 8) | (header[10] & 0xFF);
} }
......
...@@ -54,7 +54,7 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; ...@@ -54,7 +54,7 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
@Override @Override
protected long preparePayload(ParsableByteArray packet) { protected long preparePayload(ParsableByteArray packet) {
return convertTimeToGranule(getPacketDurationUs(packet.getData())); return convertTimeToGranule(OpusUtil.getPacketDurationUs(packet.getData()));
} }
@Override @Override
...@@ -122,42 +122,6 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; ...@@ -122,42 +122,6 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
} }
/** /**
* Returns the duration of the given audio packet.
*
* @param packet Contains audio data.
* @return Returns the duration of the given audio packet.
*/
private long getPacketDurationUs(byte[] packet) {
int toc = packet[0] & 0xFF;
int frames;
switch (toc & 0x3) {
case 0:
frames = 1;
break;
case 1:
case 2:
frames = 2;
break;
default:
frames = packet[1] & 0x3F;
break;
}
int config = toc >> 3;
int length = config & 0x3;
if (config >= 16) {
length = 2500 << length;
} else if (config >= 12) {
length = 10000 << (length & 0x1);
} else if (length == 3) {
length = 60000;
} else {
length = 10000 << length;
}
return (long) frames * length;
}
/**
* Returns true if the given {@link ParsableByteArray} starts with {@code expectedPrefix}. Does * Returns true if the given {@link ParsableByteArray} starts with {@code expectedPrefix}. Does
* not change the {@link ParsableByteArray#getPosition() position} of {@code packet}. * not change the {@link ParsableByteArray#getPosition() position} of {@code packet}.
* *
......
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