Commit d9b3582b by Oliver Woodman

Use OMX.google.raw.decoder for passthrough playback.

The OMX component needs to be configured with a format that has a
MIME type of audio/raw. Remove Ac3PassthroughAudioTrackRenderer,
which is no longer used.
parent ed1dbddc
......@@ -15,7 +15,7 @@
*/
package com.google.android.exoplayer.demo.player;
import com.google.android.exoplayer.Ac3PassthroughAudioTrackRenderer;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.DefaultLoadControl;
import com.google.android.exoplayer.LoadControl;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
......@@ -61,6 +61,7 @@ import com.google.android.exoplayer.util.MimeTypes;
import com.google.android.exoplayer.util.Util;
import android.annotation.TargetApi;
import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.UnsupportedSchemeException;
import android.os.Handler;
......@@ -298,13 +299,8 @@ public class DashRendererBuilder implements RendererBuilder,
// TODO: There needs to be some logic to filter out non-AC3 tracks when selecting to use AC3.
boolean useAc3Passthrough = haveAc3Tracks && audioCapabilities != null
&& (audioCapabilities.supportsAc3() || audioCapabilities.supportsEAc3());
if (useAc3Passthrough) {
audioRenderer =
new Ac3PassthroughAudioTrackRenderer(audioSampleSource, mainHandler, player);
} else {
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true,
mainHandler, player);
}
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true,
mainHandler, player, useAc3Passthrough ? C.ENCODING_AC3 : AudioFormat.ENCODING_DEFAULT);
}
// Build the text chunk sources.
......
......@@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer.demo.player;
import com.google.android.exoplayer.Ac3PassthroughAudioTrackRenderer;
import com.google.android.exoplayer.DummyTrackRenderer;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
......@@ -51,8 +50,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventListener,
HlsSampleSource.EventListener, DefaultBandwidthMeter.EventListener,
MediaCodecVideoTrackRenderer.EventListener, MediaCodecAudioTrackRenderer.EventListener,
Ac3PassthroughAudioTrackRenderer.EventListener, StreamingDrmSessionManager.EventListener,
TextRenderer {
StreamingDrmSessionManager.EventListener, TextRenderer {
/**
* Builds renderers for the player.
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer;
import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.MediaExtractor;
......@@ -50,6 +51,12 @@ public final class C {
public static final int CRYPTO_MODE_AES_CTR = MediaCodec.CRYPTO_MODE_AES_CTR;
/**
* @see AudioFormat#ENCODING_AC3
*/
@SuppressWarnings("InlinedApi")
public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3;
/**
* @see MediaExtractor#SAMPLE_FLAG_SYNC
*/
@SuppressWarnings("InlinedApi")
......
......@@ -15,11 +15,13 @@
*/
package com.google.android.exoplayer;
import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer.audio.AudioTrack;
import com.google.android.exoplayer.drm.DrmSessionManager;
import com.google.android.exoplayer.util.MimeTypes;
import android.annotation.TargetApi;
import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.media.audiofx.Virtualizer;
......@@ -62,8 +64,14 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
*/
public static final int MSG_SET_VOLUME = 1;
/**
* The name for the raw (passthrough) decoder OMX component.
*/
private static final String RAW_DECODER_NAME = "OMX.google.raw.decoder";
private final EventListener eventListener;
private final AudioTrack audioTrack;
private final int encoding;
private int audioSessionId;
private long currentPositionUs;
......@@ -116,10 +124,56 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
*/
public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager,
boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener) {
this(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener,
AudioFormat.ENCODING_DEFAULT);
}
/**
* @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 acquisision. 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 encoding One of the {@code AudioFormat.ENCODING_*} constants specifying the audio
* encoding.
*/
public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager,
boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener,
int encoding) {
super(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener);
this.eventListener = eventListener;
this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
this.audioTrack = new AudioTrack();
this.encoding = encoding;
}
@Override
protected DecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder)
throws DecoderQueryException {
if (encoding == AudioFormat.ENCODING_AC3 || encoding == AudioFormat.ENCODING_E_AC3) {
return new DecoderInfo(RAW_DECODER_NAME, true);
}
return super.getDecoderInfo(mimeType, requiresSecureDecoder);
}
@Override
protected void configureCodec(MediaCodec codec, String codecName, MediaFormat format,
android.media.MediaCrypto crypto) {
if (RAW_DECODER_NAME.equals(codecName)) {
// Override the MIME type used to configure the codec if we are using a passthrough decoder.
String mimeType = format.getString(MediaFormat.KEY_MIME);
format.setString(android.media.MediaFormat.KEY_MIME, MimeTypes.AUDIO_RAW);
codec.configure(format, null, crypto, 0);
format.setString(android.media.MediaFormat.KEY_MIME, mimeType);
} else {
codec.configure(format, null, crypto, 0);
}
}
@Override
......@@ -140,7 +194,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
@Override
protected void onOutputFormatChanged(MediaFormat format) {
audioTrack.reconfigure(format);
audioTrack.reconfigure(format, encoding, 0);
}
/**
......
......@@ -289,12 +289,25 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
/**
* Configures a newly created {@link MediaCodec}. Sub-classes should
* override this method if they wish to configure the codec with a
* non-null surface.
**/
protected void configureCodec(MediaCodec codec, android.media.MediaFormat x, MediaCrypto crypto) {
codec.configure(x, null, crypto, 0);
* Returns a {@link DecoderInfo} for decoding media in the specified MIME type.
*
* @param mimeType The type of media to decode.
* @param requiresSecureDecoder Whether a secure decoder is needed for decoding {@code mimeType}.
* @return {@link DecoderInfo} for decoding media in the specified MIME type, or {@code null} if
* no suitable decoder is available.
*/
protected DecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder)
throws DecoderQueryException {
return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder);
}
/**
* Configures a newly created {@link MediaCodec}. Sub-classes should override this method if they
* wish to configure the codec with a non-null surface.
*/
protected void configureCodec(MediaCodec codec, String codecName,
android.media.MediaFormat format, MediaCrypto crypto) {
codec.configure(format, null, crypto, 0);
}
@SuppressWarnings("deprecation")
......@@ -329,7 +342,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
DecoderInfo decoderInfo = null;
try {
decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder);
decoderInfo = getDecoderInfo(mimeType, requiresSecureDecoder);
} catch (DecoderQueryException e) {
notifyAndThrowDecoderInitError(new DecoderInitializationException(format, e,
DecoderInitializationException.DECODER_QUERY_ERROR));
......@@ -345,7 +358,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
try {
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
codec = MediaCodec.createByCodecName(decoderName);
configureCodec(codec, format.getFrameworkMediaFormatV16(), mediaCrypto);
configureCodec(codec, decoderName, format.getFrameworkMediaFormatV16(), mediaCrypto);
codec.start();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
notifyDecoderInitialized(decoderName, codecInitializedTimestamp,
......
......@@ -358,8 +358,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
// Override configureCodec to provide the surface.
@Override
protected void configureCodec(MediaCodec codec, android.media.MediaFormat format,
MediaCrypto crypto) {
protected void configureCodec(MediaCodec codec, String codecName,
android.media.MediaFormat format, MediaCrypto crypto) {
codec.configure(format, surface, crypto, 0);
codec.setVideoScalingMode(videoScalingMode);
}
......
......@@ -313,10 +313,10 @@ public final class AudioTrack {
/**
* Reconfigures the audio track to play back media in {@code format}. The encoding is assumed to
* be {@link AudioFormat#ENCODING_PCM_16BIT}.
* be {@link AudioFormat#ENCODING_DEFAULT}.
*/
public void reconfigure(MediaFormat format) {
reconfigure(format, AudioFormat.ENCODING_PCM_16BIT, 0);
reconfigure(format, AudioFormat.ENCODING_DEFAULT, 0);
}
/**
......
......@@ -33,13 +33,15 @@ public class MimeTypes {
public static final String AUDIO_MP4 = BASE_TYPE_AUDIO + "/mp4";
public static final String AUDIO_AAC = BASE_TYPE_AUDIO + "/mp4a-latm";
public static final String AUDIO_AC3 = BASE_TYPE_AUDIO + "/ac3";
public static final String AUDIO_EC3 = BASE_TYPE_AUDIO + "/eac3";
public static final String AUDIO_WEBM = BASE_TYPE_AUDIO + "/webm";
public static final String AUDIO_MPEG = BASE_TYPE_AUDIO + "/mpeg";
public static final String AUDIO_MPEG_L1 = BASE_TYPE_AUDIO + "/mpeg-L1";
public static final String AUDIO_MPEG_L2 = BASE_TYPE_AUDIO + "/mpeg-L2";
public static final String AUDIO_RAW = BASE_TYPE_AUDIO + "/raw";
public static final String AUDIO_AC3 = BASE_TYPE_AUDIO + "/ac3";
public static final String AUDIO_EC3 = BASE_TYPE_AUDIO + "/eac3";
public static final String AUDIO_VORBIS = BASE_TYPE_AUDIO + "/vorbis";
public static final String AUDIO_OPUS = BASE_TYPE_AUDIO + "/opus";
......
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