use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.
the class DefaultRenderersFactory method buildAudioRenderers.
/**
* Builds audio renderers for use by the player.
*
* @param context The {@link Context} associated with the player.
* @param extensionRendererMode The extension renderer mode.
* @param mediaCodecSelector A decoder selector.
* @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
* initialization fails. This may result in using a decoder that is slower/less efficient than
* the primary decoder.
* @param audioSink A sink to which the renderers will output.
* @param eventHandler A handler to use when invoking event listeners and outputs.
* @param eventListener An event listener.
* @param out An array to which the built renderers should be appended.
*/
protected void buildAudioRenderers(Context context, @ExtensionRendererMode int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {
MediaCodecAudioRenderer audioRenderer = new MediaCodecAudioRenderer(context, getCodecAdapterFactory(), mediaCodecSelector, enableDecoderFallback, eventHandler, eventListener, audioSink);
out.add(audioRenderer);
if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) {
return;
}
int extensionRendererIndex = out.size();
if (extensionRendererMode == EXTENSION_RENDERER_MODE_PREFER) {
extensionRendererIndex--;
}
try {
// Full class names used for constructor args so the LINT rule triggers if any of them move.
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer");
Constructor<?> constructor = clazz.getConstructor(android.os.Handler.class, com.google.android.exoplayer2.audio.AudioRendererEventListener.class, com.google.android.exoplayer2.audio.AudioSink.class);
Renderer renderer = (Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded LibopusAudioRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
// The extension is present, but instantiation failed.
throw new RuntimeException("Error instantiating Opus extension", e);
}
try {
// Full class names used for constructor args so the LINT rule triggers if any of them move.
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer");
Constructor<?> constructor = clazz.getConstructor(android.os.Handler.class, com.google.android.exoplayer2.audio.AudioRendererEventListener.class, com.google.android.exoplayer2.audio.AudioSink.class);
Renderer renderer = (Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded LibflacAudioRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
// The extension is present, but instantiation failed.
throw new RuntimeException("Error instantiating FLAC extension", e);
}
try {
// Full class names used for constructor args so the LINT rule triggers if any of them move.
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer");
Constructor<?> constructor = clazz.getConstructor(android.os.Handler.class, com.google.android.exoplayer2.audio.AudioRendererEventListener.class, com.google.android.exoplayer2.audio.AudioSink.class);
Renderer renderer = (Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded FfmpegAudioRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
// The extension is present, but instantiation failed.
throw new RuntimeException("Error instantiating FFmpeg extension", e);
}
}
use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.
the class MediaCodecAudioRendererTest method setUp.
@Before
public void setUp() throws Exception {
// audioSink isEnded can always be true because the MediaCodecAudioRenderer isEnded =
// super.isEnded && audioSink.isEnded.
when(audioSink.isEnded()).thenReturn(true);
when(audioSink.handleBuffer(any(), anyLong(), anyInt())).thenReturn(true);
when(audioSink.supportsFormat(any())).thenAnswer(invocation -> {
Format format = invocation.getArgument(/* index= */
0, Format.class);
return MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) && format.pcmEncoding == C.ENCODING_PCM_16BIT;
});
mediaCodecSelector = (mimeType, requiresSecureDecoder, requiresTunnelingDecoder) -> Collections.singletonList(MediaCodecInfo.newInstance(/* name= */
"name", /* mimeType= */
mimeType, /* codecMimeType= */
mimeType, /* capabilities= */
null, /* hardwareAccelerated= */
false, /* softwareOnly= */
true, /* vendor= */
false, /* forceDisableAdaptive= */
false, /* forceSecure= */
false));
Handler eventHandler = new Handler(Looper.getMainLooper());
mediaCodecAudioRenderer = new MediaCodecAudioRenderer(ApplicationProvider.getApplicationContext(), mediaCodecSelector, /* enableDecoderFallback= */
false, eventHandler, audioRendererEventListener, audioSink);
mediaCodecAudioRenderer.init(/* index= */
0, PlayerId.UNSET);
}
use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.
the class MediaCodecAudioRendererTest method render_callsAudioRendererEventListener_whenAudioSinkListenerOnAudioSinkErrorIsCalled.
@Test
public void render_callsAudioRendererEventListener_whenAudioSinkListenerOnAudioSinkErrorIsCalled() {
final ArgumentCaptor<AudioSink.Listener> listenerCaptor = ArgumentCaptor.forClass(AudioSink.Listener.class);
verify(audioSink, atLeastOnce()).setListener(listenerCaptor.capture());
AudioSink.Listener audioSinkListener = listenerCaptor.getValue();
Exception error = new AudioSink.WriteException(/* errorCode= */
1, new Format.Builder().build(), /* isRecoverable= */
true);
audioSinkListener.onAudioSinkError(error);
shadowOf(Looper.getMainLooper()).idle();
verify(audioRendererEventListener).onAudioSinkError(error);
}
use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.
the class MediaCodecAudioRendererTest method render_configuresAudioSink_afterGaplessFormatChange.
@Test
public void render_configuresAudioSink_afterGaplessFormatChange() throws Exception {
Format changedFormat = AUDIO_AAC.buildUpon().setEncoderDelay(400).setEncoderPadding(232).build();
FakeSampleStream fakeSampleStream = new FakeSampleStream(new DefaultAllocator(/* trimOnReset= */
true, /* individualAllocationSize= */
1024), /* mediaSourceEventDispatcher= */
null, DrmSessionManager.DRM_UNSUPPORTED, new DrmSessionEventListener.EventDispatcher(), /* initialFormat= */
AUDIO_AAC, ImmutableList.of(oneByteSample(/* timeUs= */
0, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(/* timeUs= */
50, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(/* timeUs= */
100, C.BUFFER_FLAG_KEY_FRAME), format(changedFormat), oneByteSample(/* timeUs= */
150, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(/* timeUs= */
200, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(/* timeUs= */
250, C.BUFFER_FLAG_KEY_FRAME), END_OF_STREAM_ITEM));
fakeSampleStream.writeData(/* startPositionUs= */
0);
mediaCodecAudioRenderer.enable(RendererConfiguration.DEFAULT, new Format[] { AUDIO_AAC, changedFormat }, fakeSampleStream, /* positionUs= */
0, /* joining= */
false, /* mayRenderStartOfStream= */
false, /* startPositionUs= */
0, /* offsetUs */
0);
mediaCodecAudioRenderer.start();
mediaCodecAudioRenderer.render(/* positionUs= */
0, SystemClock.elapsedRealtime() * 1000);
mediaCodecAudioRenderer.render(/* positionUs= */
250, SystemClock.elapsedRealtime() * 1000);
mediaCodecAudioRenderer.setCurrentStreamFinal();
int positionUs = 500;
do {
mediaCodecAudioRenderer.render(positionUs, SystemClock.elapsedRealtime() * 1000);
positionUs += 250;
} while (!mediaCodecAudioRenderer.isEnded());
verify(audioSink).configure(getAudioSinkFormat(AUDIO_AAC), /* specifiedBufferSize= */
0, /* outputChannels= */
null);
verify(audioSink).configure(getAudioSinkFormat(changedFormat), /* specifiedBufferSize= */
0, /* outputChannels= */
null);
}
use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.
the class MediaCodecAudioRendererTest method supportsFormat_withEac3JocMediaAndEac3Decoder_returnsTrue.
@Test
public void supportsFormat_withEac3JocMediaAndEac3Decoder_returnsTrue() throws Exception {
Format mediaFormat = new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_E_AC3_JOC).setCodecs(MimeTypes.CODEC_E_AC3_JOC).build();
MediaCodecSelector mediaCodecSelector = (mimeType, requiresSecureDecoder, requiresTunnelingDecoder) -> !mimeType.equals(MimeTypes.AUDIO_E_AC3) ? ImmutableList.of() : ImmutableList.of(MediaCodecInfo.newInstance(/* name= */
"eac3-codec", /* mimeType= */
mimeType, /* codecMimeType= */
mimeType, /* capabilities= */
null, /* hardwareAccelerated= */
false, /* softwareOnly= */
true, /* vendor= */
false, /* forceDisableAdaptive= */
false, /* forceSecure= */
false));
MediaCodecAudioRenderer renderer = new MediaCodecAudioRenderer(ApplicationProvider.getApplicationContext(), mediaCodecSelector, /* enableDecoderFallback= */
false, /* eventHandler= */
new Handler(Looper.getMainLooper()), audioRendererEventListener, audioSink);
renderer.init(/* index= */
0, PlayerId.UNSET);
@Capabilities int capabilities = renderer.supportsFormat(mediaFormat);
assertThat(RendererCapabilities.getFormatSupport(capabilities)).isEqualTo(C.FORMAT_HANDLED);
}
Aggregations