Commit 5d1052f6 by Oliver Woodman

Allow specifying the AudioTrack's stream type.

Issue: #755
parent ab2aac9d
...@@ -22,6 +22,7 @@ import com.google.android.exoplayer.drm.DrmSessionManager; ...@@ -22,6 +22,7 @@ import com.google.android.exoplayer.drm.DrmSessionManager;
import com.google.android.exoplayer.util.MimeTypes; import com.google.android.exoplayer.util.MimeTypes;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.media.AudioManager;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.audiofx.Virtualizer; import android.media.audiofx.Virtualizer;
import android.os.Handler; import android.os.Handler;
...@@ -89,7 +90,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -89,7 +90,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* content is not required. * content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. * @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 * 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} * permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media. * has obtained the keys necessary to decrypt encrypted regions of the media.
*/ */
...@@ -115,7 +116,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -115,7 +116,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* content is not required. * content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. * @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 * 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} * permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media. * 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 * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
...@@ -134,7 +135,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -134,7 +135,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* content is not required. * content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. * @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 * 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} * permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media. * 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 * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
...@@ -146,10 +147,33 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -146,10 +147,33 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager, public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager,
boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener, boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener,
AudioCapabilities audioCapabilities) { 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); super(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener);
this.eventListener = eventListener; this.eventListener = eventListener;
this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET; this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
this.audioTrack = new AudioTrack(audioCapabilities); this.audioTrack = new AudioTrack(audioCapabilities, streamType);
} }
@Override @Override
......
...@@ -165,6 +165,7 @@ public final class AudioTrack { ...@@ -165,6 +165,7 @@ public final class AudioTrack {
public static boolean failOnSpuriousAudioTimestamp = false; public static boolean failOnSpuriousAudioTimestamp = false;
private final AudioCapabilities audioCapabilities; private final AudioCapabilities audioCapabilities;
private final int streamType;
private final ConditionVariable releasingConditionVariable; private final ConditionVariable releasingConditionVariable;
private final long[] playheadOffsets; private final long[] playheadOffsets;
private final AudioTrackUtil audioTrackUtil; private final AudioTrackUtil audioTrackUtil;
...@@ -208,16 +209,18 @@ public final class AudioTrack { ...@@ -208,16 +209,18 @@ public final class AudioTrack {
* Creates an audio track with default audio capabilities (no encoded audio passthrough support). * Creates an audio track with default audio capabilities (no encoded audio passthrough support).
*/ */
public AudioTrack() { 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 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.audioCapabilities = audioCapabilities;
this.streamType = streamType;
releasingConditionVariable = new ConditionVariable(true); releasingConditionVariable = new ConditionVariable(true);
if (Util.SDK_INT >= 18) { if (Util.SDK_INT >= 18) {
try { try {
...@@ -326,19 +329,19 @@ public final class AudioTrack { ...@@ -326,19 +329,19 @@ public final class AudioTrack {
releasingConditionVariable.block(); releasingConditionVariable.block();
if (sessionId == SESSION_ID_NOT_SET) { if (sessionId == SESSION_ID_NOT_SET) {
audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, audioTrack = new android.media.AudioTrack(streamType, sampleRate, channelConfig, encoding,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM); bufferSize, android.media.AudioTrack.MODE_STREAM);
} else { } else {
// Re-attach to the same audio session. // Re-attach to the same audio session.
audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, audioTrack = new android.media.AudioTrack(streamType, sampleRate, channelConfig, encoding,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId); bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId);
} }
checkAudioTrackInitialized(); checkAudioTrackInitialized();
sessionId = audioTrack.getAudioSessionId(); sessionId = audioTrack.getAudioSessionId();
if (enablePreV21AudioSessionWorkaround) { if (enablePreV21AudioSessionWorkaround) {
if (Util.SDK_INT < 21) { 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. // does not release it until this object is released, which keeps the session active.
if (keepSessionIdAudioTrack != null if (keepSessionIdAudioTrack != null
&& sessionId != keepSessionIdAudioTrack.getAudioSessionId()) { && sessionId != keepSessionIdAudioTrack.getAudioSessionId()) {
...@@ -349,9 +352,8 @@ public final class AudioTrack { ...@@ -349,9 +352,8 @@ public final class AudioTrack {
int channelConfig = AudioFormat.CHANNEL_OUT_MONO; int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
int encoding = AudioFormat.ENCODING_PCM_16BIT; int encoding = AudioFormat.ENCODING_PCM_16BIT;
int bufferSize = 2; // Use a two byte buffer, as it is not actually used for playback. int bufferSize = 2; // Use a two byte buffer, as it is not actually used for playback.
keepSessionIdAudioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, keepSessionIdAudioTrack = new android.media.AudioTrack(streamType, sampleRate,
sampleRate, channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, sessionId);
sessionId);
} }
} }
} }
......
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