mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Cleanup merged pull requests
This commit is contained in:
parent
4d2e0bf122
commit
d098effa69
@ -66,8 +66,12 @@
|
|||||||
* Fix ID3 context reuse across segment format changes
|
* Fix ID3 context reuse across segment format changes
|
||||||
([#3622](https://github.com/google/ExoPlayer/issues/3622)).
|
([#3622](https://github.com/google/ExoPlayer/issues/3622)).
|
||||||
* New Cast extension: Simplifies toggling between local and Cast playbacks.
|
* New Cast extension: Simplifies toggling between local and Cast playbacks.
|
||||||
* Audio: Support TrueHD passthrough for rechunked samples in Matroska files
|
* Audio:
|
||||||
([#2147](https://github.com/google/ExoPlayer/issues/2147)).
|
* Support TrueHD passthrough for rechunked samples in Matroska files
|
||||||
|
([#2147](https://github.com/google/ExoPlayer/issues/2147)).
|
||||||
|
* Support resampling 24-bit and 32-bit integer to 32-bit float for high
|
||||||
|
resolution output in `DefaultAudioSink`
|
||||||
|
([#3635](https://github.com/google/ExoPlayer/pull/3635)).
|
||||||
* Captions: Initial support for PGS subtitles
|
* Captions: Initial support for PGS subtitles
|
||||||
([#3008](https://github.com/google/ExoPlayer/issues/3008)).
|
([#3008](https://github.com/google/ExoPlayer/issues/3008)).
|
||||||
* CacheDataSource: Check periodically if it's possible to read from/write to
|
* CacheDataSource: Check periodically if it's possible to read from/write to
|
||||||
|
@ -164,7 +164,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
public static boolean failOnSpuriousAudioTimestamp = false;
|
public static boolean failOnSpuriousAudioTimestamp = false;
|
||||||
|
|
||||||
@Nullable private final AudioCapabilities audioCapabilities;
|
@Nullable private final AudioCapabilities audioCapabilities;
|
||||||
private final boolean canConvertHiResPcmToFloat;
|
private final boolean enableConvertHighResIntPcmToFloat;
|
||||||
private final ChannelMappingAudioProcessor channelMappingAudioProcessor;
|
private final ChannelMappingAudioProcessor channelMappingAudioProcessor;
|
||||||
private final TrimmingAudioProcessor trimmingAudioProcessor;
|
private final TrimmingAudioProcessor trimmingAudioProcessor;
|
||||||
private final SonicAudioProcessor sonicAudioProcessor;
|
private final SonicAudioProcessor sonicAudioProcessor;
|
||||||
@ -182,14 +182,14 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
private AudioTrack keepSessionIdAudioTrack;
|
private AudioTrack keepSessionIdAudioTrack;
|
||||||
private AudioTrack audioTrack;
|
private AudioTrack audioTrack;
|
||||||
private boolean isInputPcm;
|
private boolean isInputPcm;
|
||||||
private boolean shouldUpResPCMAudio;
|
private boolean shouldConvertHighResIntPcmToFloat;
|
||||||
private int inputSampleRate;
|
private int inputSampleRate;
|
||||||
private int sampleRate;
|
private int sampleRate;
|
||||||
private int channelConfig;
|
private int channelConfig;
|
||||||
private @C.Encoding int outputEncoding;
|
private @C.Encoding int outputEncoding;
|
||||||
private AudioAttributes audioAttributes;
|
private AudioAttributes audioAttributes;
|
||||||
private boolean processingEnabled;
|
private boolean processingEnabled;
|
||||||
private boolean canApplyPlaybackParams;
|
private boolean canApplyPlaybackParameters;
|
||||||
private int bufferSize;
|
private int bufferSize;
|
||||||
private long bufferSizeUs;
|
private long bufferSizeUs;
|
||||||
|
|
||||||
@ -237,8 +237,6 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
private boolean hasData;
|
private boolean hasData;
|
||||||
private long lastFeedElapsedRealtimeMs;
|
private long lastFeedElapsedRealtimeMs;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param audioCapabilities The audio capabilities for playback on this device. May be null if the
|
* @param audioCapabilities The audio capabilities for playback on this device. May be null if the
|
||||||
* default capabilities (no encoded audio passthrough support) should be assumed.
|
* default capabilities (no encoded audio passthrough support) should be assumed.
|
||||||
@ -247,7 +245,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
*/
|
*/
|
||||||
public DefaultAudioSink(@Nullable AudioCapabilities audioCapabilities,
|
public DefaultAudioSink(@Nullable AudioCapabilities audioCapabilities,
|
||||||
AudioProcessor[] audioProcessors) {
|
AudioProcessor[] audioProcessors) {
|
||||||
this(audioCapabilities, audioProcessors, false);
|
this(audioCapabilities, audioProcessors, /* enableConvertHighResIntPcmToFloat= */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,15 +253,17 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
* default capabilities (no encoded audio passthrough support) should be assumed.
|
* default capabilities (no encoded audio passthrough support) should be assumed.
|
||||||
* @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio before
|
* @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio before
|
||||||
* output. May be empty.
|
* output. May be empty.
|
||||||
* @param canConvertHiResPcmToFloat Flag to convert > 16bit PCM Audio to 32bit Float PCM Audio to
|
* @param enableConvertHighResIntPcmToFloat Whether to enable conversion of high resolution
|
||||||
* avoid dithering the input audio. If enabled other audio processors that expect 16bit PCM
|
* integer PCM to 32-bit float for output, if possible. Functionality that uses 16-bit integer
|
||||||
* are disabled
|
* audio processing (for example, speed and pitch adjustment) will not be available when float
|
||||||
|
* output is in use.
|
||||||
*/
|
*/
|
||||||
public DefaultAudioSink(@Nullable AudioCapabilities audioCapabilities,
|
public DefaultAudioSink(
|
||||||
AudioProcessor[] audioProcessors, boolean canConvertHiResPcmToFloat) {
|
@Nullable AudioCapabilities audioCapabilities,
|
||||||
|
AudioProcessor[] audioProcessors,
|
||||||
|
boolean enableConvertHighResIntPcmToFloat) {
|
||||||
this.audioCapabilities = audioCapabilities;
|
this.audioCapabilities = audioCapabilities;
|
||||||
this.canConvertHiResPcmToFloat = canConvertHiResPcmToFloat;
|
this.enableConvertHighResIntPcmToFloat = enableConvertHighResIntPcmToFloat;
|
||||||
releasingConditionVariable = new ConditionVariable(true);
|
releasingConditionVariable = new ConditionVariable(true);
|
||||||
if (Util.SDK_INT >= 18) {
|
if (Util.SDK_INT >= 18) {
|
||||||
try {
|
try {
|
||||||
@ -285,10 +285,10 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
toIntPcmAvailableAudioProcessors[0] = new ResamplingAudioProcessor();
|
toIntPcmAvailableAudioProcessors[0] = new ResamplingAudioProcessor();
|
||||||
toIntPcmAvailableAudioProcessors[1] = channelMappingAudioProcessor;
|
toIntPcmAvailableAudioProcessors[1] = channelMappingAudioProcessor;
|
||||||
toIntPcmAvailableAudioProcessors[2] = trimmingAudioProcessor;
|
toIntPcmAvailableAudioProcessors[2] = trimmingAudioProcessor;
|
||||||
System.arraycopy(audioProcessors, 0, toIntPcmAvailableAudioProcessors, 3, audioProcessors.length);
|
System.arraycopy(
|
||||||
|
audioProcessors, 0, toIntPcmAvailableAudioProcessors, 3, audioProcessors.length);
|
||||||
toIntPcmAvailableAudioProcessors[3 + audioProcessors.length] = sonicAudioProcessor;
|
toIntPcmAvailableAudioProcessors[3 + audioProcessors.length] = sonicAudioProcessor;
|
||||||
toFloatPcmAvailableAudioProcessors = new AudioProcessor[1];
|
toFloatPcmAvailableAudioProcessors = new AudioProcessor[] {new FloatResamplingAudioProcessor()};
|
||||||
toFloatPcmAvailableAudioProcessors[0] = new FloatResamplingAudioProcessor();
|
|
||||||
playheadOffsets = new long[MAX_PLAYHEAD_OFFSET_COUNT];
|
playheadOffsets = new long[MAX_PLAYHEAD_OFFSET_COUNT];
|
||||||
volume = 1.0f;
|
volume = 1.0f;
|
||||||
startMediaTimeState = START_NOT_SET;
|
startMediaTimeState = START_NOT_SET;
|
||||||
@ -366,20 +366,20 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
int channelCount = inputChannelCount;
|
int channelCount = inputChannelCount;
|
||||||
int sampleRate = inputSampleRate;
|
int sampleRate = inputSampleRate;
|
||||||
isInputPcm = isEncodingPcm(inputEncoding);
|
isInputPcm = isEncodingPcm(inputEncoding);
|
||||||
shouldUpResPCMAudio = canConvertHiResPcmToFloat &&
|
shouldConvertHighResIntPcmToFloat =
|
||||||
(inputEncoding == C.ENCODING_PCM_24BIT || inputEncoding == C.ENCODING_PCM_32BIT);
|
enableConvertHighResIntPcmToFloat
|
||||||
|
&& isEncodingSupported(C.ENCODING_PCM_32BIT)
|
||||||
|
&& Util.isEncodingHighResolutionIntegerPcm(inputEncoding);
|
||||||
if (isInputPcm) {
|
if (isInputPcm) {
|
||||||
pcmFrameSize = Util.getPcmFrameSize(inputEncoding, channelCount);
|
pcmFrameSize = Util.getPcmFrameSize(inputEncoding, channelCount);
|
||||||
}
|
}
|
||||||
@C.Encoding int encoding = inputEncoding;
|
@C.Encoding int encoding = inputEncoding;
|
||||||
boolean processingEnabled = isInputPcm && inputEncoding != C.ENCODING_PCM_FLOAT;
|
boolean processingEnabled = isInputPcm && inputEncoding != C.ENCODING_PCM_FLOAT;
|
||||||
canApplyPlaybackParams = processingEnabled && !shouldUpResPCMAudio;
|
canApplyPlaybackParameters = processingEnabled && !shouldConvertHighResIntPcmToFloat;
|
||||||
if (processingEnabled) {
|
if (processingEnabled) {
|
||||||
AudioProcessor[] availableAudioProcessors = shouldUpResPCMAudio ?
|
|
||||||
toFloatPcmAvailableAudioProcessors : toIntPcmAvailableAudioProcessors;
|
|
||||||
trimmingAudioProcessor.setTrimSampleCount(trimStartSamples, trimEndSamples);
|
trimmingAudioProcessor.setTrimSampleCount(trimStartSamples, trimEndSamples);
|
||||||
channelMappingAudioProcessor.setChannelMap(outputChannels);
|
channelMappingAudioProcessor.setChannelMap(outputChannels);
|
||||||
for (AudioProcessor audioProcessor : availableAudioProcessors) {
|
for (AudioProcessor audioProcessor : getAvailableAudioProcessors()) {
|
||||||
try {
|
try {
|
||||||
flush |= audioProcessor.configure(sampleRate, channelCount, encoding);
|
flush |= audioProcessor.configure(sampleRate, channelCount, encoding);
|
||||||
} catch (AudioProcessor.UnhandledFormatException e) {
|
} catch (AudioProcessor.UnhandledFormatException e) {
|
||||||
@ -489,9 +489,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
|
|
||||||
private void resetAudioProcessors() {
|
private void resetAudioProcessors() {
|
||||||
ArrayList<AudioProcessor> newAudioProcessors = new ArrayList<>();
|
ArrayList<AudioProcessor> newAudioProcessors = new ArrayList<>();
|
||||||
AudioProcessor[] availableAudioProcessors = shouldUpResPCMAudio ?
|
for (AudioProcessor audioProcessor : getAvailableAudioProcessors()) {
|
||||||
toFloatPcmAvailableAudioProcessors : toIntPcmAvailableAudioProcessors;
|
|
||||||
for (AudioProcessor audioProcessor : availableAudioProcessors) {
|
|
||||||
if (audioProcessor.isActive()) {
|
if (audioProcessor.isActive()) {
|
||||||
newAudioProcessors.add(audioProcessor);
|
newAudioProcessors.add(audioProcessor);
|
||||||
} else {
|
} else {
|
||||||
@ -839,8 +837,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlaybackParameters setPlaybackParameters(PlaybackParameters playbackParameters) {
|
public PlaybackParameters setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||||
if (isInitialized() && !canApplyPlaybackParams) {
|
if (isInitialized() && !canApplyPlaybackParameters) {
|
||||||
// The playback parameters are always the default if processing is disabled.
|
|
||||||
this.playbackParameters = PlaybackParameters.DEFAULT;
|
this.playbackParameters = PlaybackParameters.DEFAULT;
|
||||||
return this.playbackParameters;
|
return this.playbackParameters;
|
||||||
}
|
}
|
||||||
@ -1256,6 +1253,12 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
MODE_STATIC, audioSessionId);
|
MODE_STATIC, audioSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AudioProcessor[] getAvailableAudioProcessors() {
|
||||||
|
return shouldConvertHighResIntPcmToFloat
|
||||||
|
? toFloatPcmAvailableAudioProcessors
|
||||||
|
: toIntPcmAvailableAudioProcessors;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isEncodingPcm(@C.Encoding int encoding) {
|
private static boolean isEncodingPcm(@C.Encoding int encoding) {
|
||||||
return encoding == C.ENCODING_PCM_8BIT || encoding == C.ENCODING_PCM_16BIT
|
return encoding == C.ENCODING_PCM_8BIT || encoding == C.ENCODING_PCM_16BIT
|
||||||
|| encoding == C.ENCODING_PCM_24BIT || encoding == C.ENCODING_PCM_32BIT
|
|| encoding == C.ENCODING_PCM_24BIT || encoding == C.ENCODING_PCM_32BIT
|
||||||
|
@ -15,31 +15,30 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.audio;
|
package com.google.android.exoplayer2.audio;
|
||||||
|
|
||||||
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AudioProcessor} that converts audio data to {@link C#ENCODING_PCM_16BIT}.
|
* An {@link AudioProcessor} that converts 24-bit and 32-bit integer PCM audio to 32-bit float PCM
|
||||||
|
* audio.
|
||||||
*/
|
*/
|
||||||
/* package */ final class FloatResamplingAudioProcessor implements AudioProcessor {
|
/* package */ final class FloatResamplingAudioProcessor implements AudioProcessor {
|
||||||
|
|
||||||
private int sampleRateHz;
|
private static final int FLOAT_NAN_AS_INT = Float.floatToIntBits(Float.NaN);
|
||||||
private static final double PCM_INT32_FLOAT = 1.0 / 0x7fffffff;
|
private static final double PCM_32_BIT_INT_TO_PCM_32_BIT_FLOAT_FACTOR = 1.0 / 0x7FFFFFFF;
|
||||||
|
|
||||||
|
private int sampleRateHz;
|
||||||
private int channelCount;
|
private int channelCount;
|
||||||
@C.PcmEncoding
|
private @C.PcmEncoding int sourceEncoding;
|
||||||
private int sourceEncoding;
|
|
||||||
private ByteBuffer buffer;
|
private ByteBuffer buffer;
|
||||||
private ByteBuffer outputBuffer;
|
private ByteBuffer outputBuffer;
|
||||||
private boolean inputEnded;
|
private boolean inputEnded;
|
||||||
|
|
||||||
/**
|
/** Creates a new audio processor that converts audio data to {@link C#ENCODING_PCM_FLOAT}. */
|
||||||
* Creates a new audio processor that converts audio data to {@link C#ENCODING_PCM_16BIT}.
|
|
||||||
*/
|
|
||||||
public FloatResamplingAudioProcessor() {
|
public FloatResamplingAudioProcessor() {
|
||||||
sampleRateHz = Format.NO_VALUE;
|
sampleRateHz = Format.NO_VALUE;
|
||||||
channelCount = Format.NO_VALUE;
|
channelCount = Format.NO_VALUE;
|
||||||
@ -50,31 +49,35 @@ import java.nio.ByteOrder;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configure(int sampleRateHz, int channelCount, @C.Encoding int encoding)
|
public boolean configure(int sampleRateHz, int channelCount, @C.Encoding int encoding)
|
||||||
throws AudioProcessor.UnhandledFormatException {
|
throws UnhandledFormatException {
|
||||||
if (encoding != C.ENCODING_PCM_24BIT && encoding != C.ENCODING_PCM_32BIT) {
|
if (!Util.isEncodingHighResolutionIntegerPcm(encoding)) {
|
||||||
throw new AudioProcessor.UnhandledFormatException(sampleRateHz, channelCount, encoding);
|
throw new UnhandledFormatException(sampleRateHz, channelCount, encoding);
|
||||||
}
|
}
|
||||||
if (this.sampleRateHz == sampleRateHz && this.channelCount == channelCount
|
if (this.sampleRateHz == sampleRateHz
|
||||||
&& this.sourceEncoding == encoding) {
|
&& this.channelCount == channelCount
|
||||||
|
&& sourceEncoding == encoding) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.sampleRateHz = sampleRateHz;
|
this.sampleRateHz = sampleRateHz;
|
||||||
this.channelCount = channelCount;
|
this.channelCount = channelCount;
|
||||||
this.sourceEncoding = encoding;
|
sourceEncoding = encoding;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return sourceEncoding == C.ENCODING_PCM_24BIT || sourceEncoding == C.ENCODING_PCM_32BIT;
|
return Util.isEncodingHighResolutionIntegerPcm(sourceEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOutputChannelCount() { return channelCount; }
|
public int getOutputChannelCount() {
|
||||||
|
return channelCount;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOutputEncoding() { return C.ENCODING_PCM_FLOAT; }
|
public int getOutputEncoding() {
|
||||||
|
return C.ENCODING_PCM_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOutputSampleRateHz() {
|
public int getOutputSampleRateHz() {
|
||||||
@ -83,60 +86,36 @@ import java.nio.ByteOrder;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void queueInput(ByteBuffer inputBuffer) {
|
public void queueInput(ByteBuffer inputBuffer) {
|
||||||
int offset = inputBuffer.position();
|
Assertions.checkState(isActive());
|
||||||
|
|
||||||
|
boolean isInput32Bit = sourceEncoding == C.ENCODING_PCM_32BIT;
|
||||||
|
int position = inputBuffer.position();
|
||||||
int limit = inputBuffer.limit();
|
int limit = inputBuffer.limit();
|
||||||
int size = limit - offset;
|
int size = limit - position;
|
||||||
|
|
||||||
int resampledSize;
|
|
||||||
switch (sourceEncoding) {
|
|
||||||
case C.ENCODING_PCM_24BIT:
|
|
||||||
resampledSize = (size / 3) * 4;
|
|
||||||
break;
|
|
||||||
case C.ENCODING_PCM_32BIT:
|
|
||||||
resampledSize = size;
|
|
||||||
break;
|
|
||||||
case C.ENCODING_PCM_8BIT:
|
|
||||||
case C.ENCODING_PCM_16BIT:
|
|
||||||
case C.ENCODING_PCM_FLOAT:
|
|
||||||
case C.ENCODING_INVALID:
|
|
||||||
case Format.NO_VALUE:
|
|
||||||
default:
|
|
||||||
// Never happens.
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int resampledSize = isInput32Bit ? size : (size / 3) * 4;
|
||||||
if (buffer.capacity() < resampledSize) {
|
if (buffer.capacity() < resampledSize) {
|
||||||
buffer = ByteBuffer.allocateDirect(resampledSize).order(ByteOrder.nativeOrder());
|
buffer = ByteBuffer.allocateDirect(resampledSize).order(ByteOrder.nativeOrder());
|
||||||
} else {
|
} else {
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
|
if (isInput32Bit) {
|
||||||
// Samples are little endian.
|
for (int i = position; i < limit; i += 4) {
|
||||||
switch (sourceEncoding) {
|
int pcm32BitInteger =
|
||||||
case C.ENCODING_PCM_24BIT:
|
(inputBuffer.get(i) & 0xFF)
|
||||||
// 24->32 bit resampling.
|
| ((inputBuffer.get(i + 1) & 0xFF) << 8)
|
||||||
for (int i = offset; i < limit; i += 3) {
|
| ((inputBuffer.get(i + 2) & 0xFF) << 16)
|
||||||
int val = (inputBuffer.get(i) << 8) & 0x0000ff00 | (inputBuffer.get(i + 1) << 16) & 0x00ff0000 |
|
| ((inputBuffer.get(i + 3) & 0xFF) << 24);
|
||||||
(inputBuffer.get(i + 2) << 24) & 0xff000000;
|
writePcm32BitFloat(pcm32BitInteger, buffer);
|
||||||
writePcm32bitFloat(val, buffer);
|
}
|
||||||
}
|
} else {
|
||||||
break;
|
for (int i = position; i < limit; i += 3) {
|
||||||
case C.ENCODING_PCM_32BIT:
|
int pcm32BitInteger =
|
||||||
// 32->32 bit conversion.
|
((inputBuffer.get(i) & 0xFF) << 8)
|
||||||
for (int i = offset; i < limit; i += 4) {
|
| ((inputBuffer.get(i + 1) & 0xFF) << 16)
|
||||||
int val = inputBuffer.get(i) & 0x000000ff | (inputBuffer.get(i) << 8) & 0x0000ff00 |
|
| ((inputBuffer.get(i + 2) & 0xFF) << 24);
|
||||||
(inputBuffer.get(i + 1) << 16) & 0x00ff0000 | (inputBuffer.get(i + 2) << 24) & 0xff000000;
|
writePcm32BitFloat(pcm32BitInteger, buffer);
|
||||||
writePcm32bitFloat(val, buffer);
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
case C.ENCODING_PCM_8BIT:
|
|
||||||
case C.ENCODING_PCM_16BIT:
|
|
||||||
case C.ENCODING_PCM_FLOAT:
|
|
||||||
case C.ENCODING_INVALID:
|
|
||||||
case Format.NO_VALUE:
|
|
||||||
default:
|
|
||||||
// Never happens.
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inputBuffer.position(inputBuffer.limit());
|
inputBuffer.position(inputBuffer.limit());
|
||||||
@ -178,17 +157,17 @@ import java.nio.ByteOrder;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the provided value into 32-bit float PCM and writes to buffer.
|
* Converts the provided 32-bit integer to a 32-bit float value and writes it to {@code buffer}.
|
||||||
*
|
*
|
||||||
* @param val 32-bit int value to convert to 32-bit float [-1.0, 1.0]
|
* @param pcm32BitInt The 32-bit integer value to convert to 32-bit float in [-1.0, 1.0].
|
||||||
* @param buffer The output buffer.
|
* @param buffer The output buffer.
|
||||||
*/
|
*/
|
||||||
private static void writePcm32bitFloat(int val, ByteBuffer buffer) {
|
private static void writePcm32BitFloat(int pcm32BitInt, ByteBuffer buffer) {
|
||||||
float convVal = (float) (PCM_INT32_FLOAT * val);
|
float pcm32BitFloat = (float) (PCM_32_BIT_INT_TO_PCM_32_BIT_FLOAT_FACTOR * pcm32BitInt);
|
||||||
int bits = Float.floatToIntBits(convVal);
|
int floatBits = Float.floatToIntBits(pcm32BitFloat);
|
||||||
if (bits == 0x7fc00000)
|
if (floatBits == FLOAT_NAN_AS_INT) {
|
||||||
bits = Float.floatToIntBits((float) 0.0);
|
floatBits = Float.floatToIntBits((float) 0.0);
|
||||||
buffer.putInt(bits);
|
}
|
||||||
|
buffer.putInt(floatBits);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
@ -21,7 +21,8 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AudioProcessor} that converts audio data to {@link C#ENCODING_PCM_16BIT}.
|
* An {@link AudioProcessor} that converts 8-bit, 24-bit and 32-bit integer PCM audio to 16-bit
|
||||||
|
* integer PCM audio.
|
||||||
*/
|
*/
|
||||||
/* package */ final class ResamplingAudioProcessor implements AudioProcessor {
|
/* package */ final class ResamplingAudioProcessor implements AudioProcessor {
|
||||||
|
|
||||||
|
@ -27,21 +27,21 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
* A {@link DataSource} that supports multiple URI schemes. The supported schemes are:
|
* A {@link DataSource} that supports multiple URI schemes. The supported schemes are:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>file: For fetching data from a local file (e.g. file:///path/to/media/media.mp4, or just
|
* <li>file: For fetching data from a local file (e.g. file:///path/to/media/media.mp4, or just
|
||||||
* /path/to/media/media.mp4 because the implementation assumes that a URI without a scheme is a
|
* /path/to/media/media.mp4 because the implementation assumes that a URI without a scheme is
|
||||||
* local file URI).
|
* a local file URI).
|
||||||
* <li>asset: For fetching data from an asset in the application's apk (e.g. asset:///media.mp4).
|
* <li>asset: For fetching data from an asset in the application's apk (e.g. asset:///media.mp4).
|
||||||
* <li>rawresource: For fetching data from a raw resource in the applications' apk
|
* <li>rawresource: For fetching data from a raw resource in the application's apk (e.g.
|
||||||
* (e.g. rawresource:///resourceId, where rawResourceId is the integer identifier of the raw
|
* rawresource:///resourceId, where rawResourceId is the integer identifier of the raw
|
||||||
* resource).</li>
|
* resource).
|
||||||
* <li>content: For fetching data from a content URI (e.g. content://authority/path/123).
|
* <li>content: For fetching data from a content URI (e.g. content://authority/path/123).
|
||||||
* <li>rtmp: For fetching data over RTMP. Only supported if the project using ExoPlayer has an
|
* <li>rtmp: For fetching data over RTMP. Only supported if the project using ExoPlayer has an
|
||||||
* explicit dependency on ExoPlayer's RTMP extension.</li>
|
* explicit dependency on ExoPlayer's RTMP extension.
|
||||||
* <li>data: For parsing data inlined in the URI as defined in RFC 2397.</li>
|
* <li>data: For parsing data inlined in the URI as defined in RFC 2397.
|
||||||
* <li>http(s): For fetching data over HTTP and HTTPS (e.g. https://www.something.com/media.mp4), if
|
* <li>http(s): For fetching data over HTTP and HTTPS (e.g. https://www.something.com/media.mp4),
|
||||||
* constructed using {@link #DefaultDataSource(Context, TransferListener, String, boolean)}, or
|
* if constructed using {@link #DefaultDataSource(Context, TransferListener, String,
|
||||||
* any other schemes supported by a base data source if constructed using
|
* boolean)}, or any other schemes supported by a base data source if constructed using {@link
|
||||||
* {@link #DefaultDataSource(Context, TransferListener, DataSource)}.</li>
|
* #DefaultDataSource(Context, TransferListener, DataSource)}.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public final class DefaultDataSource implements DataSource {
|
public final class DefaultDataSource implements DataSource {
|
||||||
|
@ -58,6 +58,7 @@ public final class RawResourceDataSource implements DataSource {
|
|||||||
return Uri.parse(RAW_RESOURCE_SCHEME + ":///" + rawResourceId);
|
return Uri.parse(RAW_RESOURCE_SCHEME + ":///" + rawResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The scheme part of a raw resource URI. */
|
||||||
public static final String RAW_RESOURCE_SCHEME = "rawresource";
|
public static final String RAW_RESOURCE_SCHEME = "rawresource";
|
||||||
|
|
||||||
private final Resources resources;
|
private final Resources resources;
|
||||||
|
@ -941,6 +941,16 @@ public final class Util {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether {@code encoding} is high resolution (> 16-bit) integer PCM.
|
||||||
|
*
|
||||||
|
* @param encoding The encoding of the audio data.
|
||||||
|
* @return Whether the encoding is high resolution integer PCM.
|
||||||
|
*/
|
||||||
|
public static boolean isEncodingHighResolutionIntegerPcm(@C.PcmEncoding int encoding) {
|
||||||
|
return encoding == C.ENCODING_PCM_24BIT || encoding == C.ENCODING_PCM_32BIT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the frame size for audio with {@code channelCount} channels in the specified encoding.
|
* Returns the frame size for audio with {@code channelCount} channels in the specified encoding.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user