Search in sources :

Example 1 with AudioSink

use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.

the class MediaCodecAudioRenderer method supportsFormat.

@Override
@Capabilities
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format) throws DecoderQueryException {
    if (!MimeTypes.isAudio(format.sampleMimeType)) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
    }
    @TunnelingSupport int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
    boolean formatHasDrm = format.cryptoType != C.CRYPTO_TYPE_NONE;
    boolean supportsFormatDrm = supportsFormatDrm(format);
    // Else we don't don't need a decoder at all.
    if (supportsFormatDrm && audioSink.supportsFormat(format) && (!formatHasDrm || MediaCodecUtil.getDecryptOnlyDecoderInfo() != null)) {
        return RendererCapabilities.create(C.FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
    }
    // the input format directly.
    if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) && !audioSink.supportsFormat(format)) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
    }
    // For all other input formats, we expect the decoder to output 16-bit PCM.
    if (!audioSink.supportsFormat(Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate))) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
    }
    List<MediaCodecInfo> decoderInfos = getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */
    false, audioSink);
    if (decoderInfos.isEmpty()) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
    }
    if (!supportsFormatDrm) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_DRM);
    }
    // Check whether the first decoder supports the format. This is the preferred decoder for the
    // format's MIME type, according to the MediaCodecSelector.
    MediaCodecInfo decoderInfo = decoderInfos.get(0);
    boolean isFormatSupported = decoderInfo.isFormatSupported(format);
    boolean isPreferredDecoder = true;
    if (!isFormatSupported) {
        // Check whether any of the other decoders support the format.
        for (int i = 1; i < decoderInfos.size(); i++) {
            MediaCodecInfo otherDecoderInfo = decoderInfos.get(i);
            if (otherDecoderInfo.isFormatSupported(format)) {
                decoderInfo = otherDecoderInfo;
                isFormatSupported = true;
                isPreferredDecoder = false;
                break;
            }
        }
    }
    @C.FormatSupport int formatSupport = isFormatSupported ? C.FORMAT_HANDLED : C.FORMAT_EXCEEDS_CAPABILITIES;
    @AdaptiveSupport int adaptiveSupport = isFormatSupported && decoderInfo.isSeamlessAdaptationSupported(format) ? ADAPTIVE_SEAMLESS : ADAPTIVE_NOT_SEAMLESS;
    @HardwareAccelerationSupport int hardwareAccelerationSupport = decoderInfo.hardwareAccelerated ? HARDWARE_ACCELERATION_SUPPORTED : HARDWARE_ACCELERATION_NOT_SUPPORTED;
    @DecoderSupport int decoderSupport = isPreferredDecoder ? DECODER_SUPPORT_PRIMARY : DECODER_SUPPORT_FALLBACK;
    return RendererCapabilities.create(formatSupport, adaptiveSupport, tunnelingSupport, hardwareAccelerationSupport, decoderSupport);
}
Also used : MediaCodecInfo(com.google.android.exoplayer2.mediacodec.MediaCodecInfo) SuppressLint(android.annotation.SuppressLint) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities)

Example 2 with AudioSink

use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.

the class DefaultRenderersFactory method createRenderers.

@Override
public Renderer[] createRenderers(Handler eventHandler, VideoRendererEventListener videoRendererEventListener, AudioRendererEventListener audioRendererEventListener, TextOutput textRendererOutput, MetadataOutput metadataRendererOutput) {
    ArrayList<Renderer> renderersList = new ArrayList<>();
    buildVideoRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, eventHandler, videoRendererEventListener, allowedVideoJoiningTimeMs, renderersList);
    @Nullable AudioSink audioSink = buildAudioSink(context, enableFloatOutput, enableAudioTrackPlaybackParams, enableOffload);
    if (audioSink != null) {
        buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, audioRendererEventListener, renderersList);
    }
    buildTextRenderers(context, textRendererOutput, eventHandler.getLooper(), extensionRendererMode, renderersList);
    buildMetadataRenderers(context, metadataRendererOutput, eventHandler.getLooper(), extensionRendererMode, renderersList);
    buildCameraMotionRenderers(context, extensionRendererMode, renderersList);
    buildMiscellaneousRenderers(context, eventHandler, extensionRendererMode, renderersList);
    return renderersList.toArray(new Renderer[0]);
}
Also used : DefaultAudioSink(com.google.android.exoplayer2.audio.DefaultAudioSink) AudioSink(com.google.android.exoplayer2.audio.AudioSink) CameraMotionRenderer(com.google.android.exoplayer2.video.spherical.CameraMotionRenderer) MediaCodecAudioRenderer(com.google.android.exoplayer2.audio.MediaCodecAudioRenderer) MetadataRenderer(com.google.android.exoplayer2.metadata.MetadataRenderer) MediaCodecVideoRenderer(com.google.android.exoplayer2.video.MediaCodecVideoRenderer) TextRenderer(com.google.android.exoplayer2.text.TextRenderer) ArrayList(java.util.ArrayList) Nullable(androidx.annotation.Nullable)

Example 3 with AudioSink

use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.

the class LibflacAudioRenderer method supportsFormatInternal.

@Override
@C.FormatSupport
protected int supportsFormatInternal(Format format) {
    if (!FlacLibrary.isAvailable() || !MimeTypes.AUDIO_FLAC.equalsIgnoreCase(format.sampleMimeType)) {
        return C.FORMAT_UNSUPPORTED_TYPE;
    }
    // Compute the format that the FLAC decoder will output.
    Format outputFormat;
    if (format.initializationData.isEmpty()) {
        // The initialization data might not be set if the format was obtained from a manifest (e.g.
        // for DASH playbacks) rather than directly from the media. In this case we assume
        // ENCODING_PCM_16BIT. If the actual encoding is different then playback will still succeed as
        // long as the AudioSink supports it, which will always be true when using DefaultAudioSink.
        outputFormat = Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate);
    } else {
        int streamMetadataOffset = STREAM_MARKER_SIZE + METADATA_BLOCK_HEADER_SIZE;
        FlacStreamMetadata streamMetadata = new FlacStreamMetadata(format.initializationData.get(0), streamMetadataOffset);
        outputFormat = getOutputFormat(streamMetadata);
    }
    if (!sinkSupportsFormat(outputFormat)) {
        return C.FORMAT_UNSUPPORTED_SUBTYPE;
    } else if (format.cryptoType != C.CRYPTO_TYPE_NONE) {
        return C.FORMAT_UNSUPPORTED_DRM;
    } else {
        return C.FORMAT_HANDLED;
    }
}
Also used : Format(com.google.android.exoplayer2.Format) FlacStreamMetadata(com.google.android.exoplayer2.extractor.FlacStreamMetadata)

Example 4 with AudioSink

use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.

the class FlacPlaybackTest method playAndAssertAudioSinkInput.

private static void playAndAssertAudioSinkInput(String fileName) throws Exception {
    CapturingAudioSink audioSink = new CapturingAudioSink(new DefaultAudioSink.Builder().build());
    TestPlaybackRunnable testPlaybackRunnable = new TestPlaybackRunnable(Uri.parse("asset:///media/" + fileName), ApplicationProvider.getApplicationContext(), audioSink);
    Thread thread = new Thread(testPlaybackRunnable);
    thread.start();
    thread.join();
    if (testPlaybackRunnable.playbackException != null) {
        throw testPlaybackRunnable.playbackException;
    }
    DumpFileAsserts.assertOutput(ApplicationProvider.getApplicationContext(), audioSink, "audiosinkdumps/" + fileName + ".audiosink.dump");
}
Also used : CapturingAudioSink(com.google.android.exoplayer2.testutil.CapturingAudioSink)

Example 5 with AudioSink

use of com.google.android.exoplayer2.audio.AudioSink in project ExoPlayer by google.

the class MediaCodecAudioRenderer method getDecoderInfos.

/**
 * Returns a list of decoders that can decode media in the specified format, in the priority order
 * specified by the {@link MediaCodecSelector}. Note that since the {@link MediaCodecSelector}
 * only has access to {@link Format#sampleMimeType}, the list is not ordered to account for
 * whether each decoder supports the details of the format (e.g., taking into account the format's
 * profile, level, channel count and so on). {@link
 * MediaCodecUtil#getDecoderInfosSortedByFormatSupport} can be used to further sort the list into
 * an order where decoders that fully support the format come first.
 *
 * @param mediaCodecSelector The decoder selector.
 * @param format The {@link Format} for which a decoder is required.
 * @param requiresSecureDecoder Whether a secure decoder is required.
 * @param audioSink The {@link AudioSink} to which audio will be output.
 * @return A list of {@link MediaCodecInfo}s corresponding to decoders. May be empty.
 * @throws DecoderQueryException Thrown if there was an error querying decoders.
 */
private static List<MediaCodecInfo> getDecoderInfos(MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder, AudioSink audioSink) throws DecoderQueryException {
    @Nullable String mimeType = format.sampleMimeType;
    if (mimeType == null) {
        return ImmutableList.of();
    }
    if (audioSink.supportsFormat(format)) {
        // The format is supported directly, so a codec is only needed for decryption.
        @Nullable MediaCodecInfo codecInfo = MediaCodecUtil.getDecryptOnlyDecoderInfo();
        if (codecInfo != null) {
            return ImmutableList.of(codecInfo);
        }
    }
    List<MediaCodecInfo> decoderInfos = mediaCodecSelector.getDecoderInfos(mimeType, requiresSecureDecoder, /* requiresTunnelingDecoder= */
    false);
    @Nullable String alternativeMimeType = MediaCodecUtil.getAlternativeCodecMimeType(format);
    if (alternativeMimeType == null) {
        return ImmutableList.copyOf(decoderInfos);
    }
    List<MediaCodecInfo> alternativeDecoderInfos = mediaCodecSelector.getDecoderInfos(alternativeMimeType, requiresSecureDecoder, /* requiresTunnelingDecoder= */
    false);
    return ImmutableList.<MediaCodecInfo>builder().addAll(decoderInfos).addAll(alternativeDecoderInfos).build();
}
Also used : MediaCodecInfo(com.google.android.exoplayer2.mediacodec.MediaCodecInfo) Nullable(androidx.annotation.Nullable)

Aggregations

Format (com.google.android.exoplayer2.Format)5 MediaFormat (android.media.MediaFormat)4 DrmSessionEventListener (com.google.android.exoplayer2.drm.DrmSessionEventListener)4 Test (org.junit.Test)4 Nullable (androidx.annotation.Nullable)3 MediaCodecInfo (com.google.android.exoplayer2.mediacodec.MediaCodecInfo)3 FakeSampleStream (com.google.android.exoplayer2.testutil.FakeSampleStream)3 DefaultAllocator (com.google.android.exoplayer2.upstream.DefaultAllocator)3 Handler (android.os.Handler)2 ExoPlaybackException (com.google.android.exoplayer2.ExoPlaybackException)2 PlaybackException (com.google.android.exoplayer2.PlaybackException)2 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)2 MediaCodecAudioRenderer (com.google.android.exoplayer2.audio.MediaCodecAudioRenderer)2 MetadataRenderer (com.google.android.exoplayer2.metadata.MetadataRenderer)2 TextRenderer (com.google.android.exoplayer2.text.TextRenderer)2 MediaCodecVideoRenderer (com.google.android.exoplayer2.video.MediaCodecVideoRenderer)2 CameraMotionRenderer (com.google.android.exoplayer2.video.spherical.CameraMotionRenderer)2 Before (org.junit.Before)2 SuppressLint (android.annotation.SuppressLint)1 Looper (android.os.Looper)1