Allow specifying the AudioTrack's stream type.

Issue: #755
This commit is contained in:
Oliver Woodman 2015-09-07 13:58:54 +01:00
parent ab2aac9d3f
commit 5d1052f6ec
2 changed files with 41 additions and 15 deletions

View file

@ -22,6 +22,7 @@ import com.google.android.exoplayer.drm.DrmSessionManager;
import com.google.android.exoplayer.util.MimeTypes;
import android.annotation.TargetApi;
import android.media.AudioManager;
import android.media.MediaCodec;
import android.media.audiofx.Virtualizer;
import android.os.Handler;
@ -89,7 +90,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisision. This parameter specifies whether the renderer is
* begin in parallel with key acquisition. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
*/
@ -115,7 +116,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisision. This parameter specifies whether the renderer is
* begin in parallel with key acquisition. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
@ -134,7 +135,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisision. This parameter specifies whether the renderer is
* begin in parallel with key acquisition. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
@ -146,10 +147,33 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager,
boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener,
AudioCapabilities audioCapabilities) {
this(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener,
audioCapabilities, AudioManager.STREAM_MUSIC);
}
/**
* @param source The upstream source from which the renderer obtains samples.
* @param drmSessionManager For use with encrypted content. May be null if support for encrypted
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisition. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @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.
* @param streamType The type of audio stream for the {@link AudioTrack}.
*/
public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager,
boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener,
AudioCapabilities audioCapabilities, int streamType) {
super(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener);
this.eventListener = eventListener;
this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
this.audioTrack = new AudioTrack(audioCapabilities);
this.audioTrack = new AudioTrack(audioCapabilities, streamType);
}
@Override

View file

@ -165,6 +165,7 @@ public final class AudioTrack {
public static boolean failOnSpuriousAudioTimestamp = false;
private final AudioCapabilities audioCapabilities;
private final int streamType;
private final ConditionVariable releasingConditionVariable;
private final long[] playheadOffsets;
private final AudioTrackUtil audioTrackUtil;
@ -208,16 +209,18 @@ public final class AudioTrack {
* Creates an audio track with default audio capabilities (no encoded audio passthrough support).
*/
public AudioTrack() {
this(null);
this(null, AudioManager.STREAM_MUSIC);
}
/**
* Creates an audio track using the specified audio capabilities.
* Creates an audio track using the specified audio capabilities and stream type.
*
* @param audioCapabilities The current audio playback capabilities.
* @param streamType The type of audio stream for the underlying {@link android.media.AudioTrack}.
*/
public AudioTrack(AudioCapabilities audioCapabilities) {
public AudioTrack(AudioCapabilities audioCapabilities, int streamType) {
this.audioCapabilities = audioCapabilities;
this.streamType = streamType;
releasingConditionVariable = new ConditionVariable(true);
if (Util.SDK_INT >= 18) {
try {
@ -326,19 +329,19 @@ public final class AudioTrack {
releasingConditionVariable.block();
if (sessionId == SESSION_ID_NOT_SET) {
audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM);
audioTrack = new android.media.AudioTrack(streamType, sampleRate, channelConfig, encoding,
bufferSize, android.media.AudioTrack.MODE_STREAM);
} else {
// Re-attach to the same audio session.
audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId);
audioTrack = new android.media.AudioTrack(streamType, sampleRate, channelConfig, encoding,
bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId);
}
checkAudioTrackInitialized();
sessionId = audioTrack.getAudioSessionId();
if (enablePreV21AudioSessionWorkaround) {
if (Util.SDK_INT < 21) {
// The workaround creates an audio track with a one byte buffer on the same session, and
// The workaround creates an audio track with a two byte buffer on the same session, and
// does not release it until this object is released, which keeps the session active.
if (keepSessionIdAudioTrack != null
&& sessionId != keepSessionIdAudioTrack.getAudioSessionId()) {
@ -349,9 +352,8 @@ public final class AudioTrack {
int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
int encoding = AudioFormat.ENCODING_PCM_16BIT;
int bufferSize = 2; // Use a two byte buffer, as it is not actually used for playback.
keepSessionIdAudioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC,
sessionId);
keepSessionIdAudioTrack = new android.media.AudioTrack(streamType, sampleRate,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, sessionId);
}
}
}