Search in sources :

Example 86 with Nullable

use of androidx.annotation.Nullable in project ExoPlayer by google.

the class BaseMediaSource method prepareSource.

@Override
public final void prepareSource(MediaSourceCaller caller, @Nullable TransferListener mediaTransferListener, PlayerId playerId) {
    Looper looper = Looper.myLooper();
    Assertions.checkArgument(this.looper == null || this.looper == looper);
    this.playerId = playerId;
    @Nullable Timeline timeline = this.timeline;
    mediaSourceCallers.add(caller);
    if (this.looper == null) {
        this.looper = looper;
        enabledMediaSourceCallers.add(caller);
        prepareSourceInternal(mediaTransferListener);
    } else if (timeline != null) {
        enable(caller);
        caller.onSourceInfoRefreshed(/* source= */
        this, timeline);
    }
}
Also used : Looper(android.os.Looper) Timeline(com.google.android.exoplayer2.Timeline) Nullable(androidx.annotation.Nullable)

Example 87 with Nullable

use of androidx.annotation.Nullable in project ExoPlayer by google.

the class MediaCodecRenderer method drmNeedsCodecReinitialization.

/**
 * Returns whether it's necessary to re-initialize the codec to handle a DRM change. If {@code
 * false} is returned then either {@code oldSession == newSession} (i.e., there was no change), or
 * it's possible to update the existing codec using MediaCrypto.setMediaDrmSession.
 */
private boolean drmNeedsCodecReinitialization(MediaCodecInfo codecInfo, Format newFormat, @Nullable DrmSession oldSession, @Nullable DrmSession newSession) throws ExoPlaybackException {
    if (oldSession == newSession) {
        // No need to re-initialize if the old and new sessions are the same.
        return false;
    }
    if (newSession == null || oldSession == null) {
        // Changing from DRM to no DRM and vice-versa always requires re-initialization.
        return true;
    }
    if (Util.SDK_INT < 23) {
        // required to switch to newSession on older API levels.
        return true;
    }
    if (C.PLAYREADY_UUID.equals(oldSession.getSchemeUuid()) || C.PLAYREADY_UUID.equals(newSession.getSchemeUuid())) {
        // TODO: Add an API check once [Internal ref: b/128835874] is fixed.
        return true;
    }
    @Nullable FrameworkCryptoConfig newCryptoConfig = getFrameworkCryptoConfig(newSession);
    if (newCryptoConfig == null) {
        // the case is to occur, so we re-initialize in this case.
        return true;
    }
    boolean requiresSecureDecoder;
    if (newCryptoConfig.forceAllowInsecureDecoderComponents) {
        requiresSecureDecoder = false;
    } else {
        requiresSecureDecoder = newSession.requiresSecureDecoder(newFormat.sampleMimeType);
    }
    if (!codecInfo.secure && requiresSecureDecoder) {
        // output path.
        return true;
    }
    return false;
}
Also used : FrameworkCryptoConfig(com.google.android.exoplayer2.drm.FrameworkCryptoConfig) Nullable(androidx.annotation.Nullable)

Example 88 with Nullable

use of androidx.annotation.Nullable in project ExoPlayer by google.

the class MediaCodecUtil method getAv1ProfileAndLevel.

@Nullable
private static Pair<Integer, Integer> getAv1ProfileAndLevel(String codec, String[] parts, @Nullable ColorInfo colorInfo) {
    if (parts.length < 4) {
        Log.w(TAG, "Ignoring malformed AV1 codec string: " + codec);
        return null;
    }
    int profileInteger;
    int levelInteger;
    int bitDepthInteger;
    try {
        profileInteger = Integer.parseInt(parts[1]);
        levelInteger = Integer.parseInt(parts[2].substring(0, 2));
        bitDepthInteger = Integer.parseInt(parts[3]);
    } catch (NumberFormatException e) {
        Log.w(TAG, "Ignoring malformed AV1 codec string: " + codec);
        return null;
    }
    if (profileInteger != 0) {
        Log.w(TAG, "Unknown AV1 profile: " + profileInteger);
        return null;
    }
    if (bitDepthInteger != 8 && bitDepthInteger != 10) {
        Log.w(TAG, "Unknown AV1 bit depth: " + bitDepthInteger);
        return null;
    }
    int profile;
    if (bitDepthInteger == 8) {
        profile = CodecProfileLevel.AV1ProfileMain8;
    } else if (colorInfo != null && (colorInfo.hdrStaticInfo != null || colorInfo.colorTransfer == C.COLOR_TRANSFER_HLG || colorInfo.colorTransfer == C.COLOR_TRANSFER_ST2084)) {
        profile = CodecProfileLevel.AV1ProfileMain10HDR10;
    } else {
        profile = CodecProfileLevel.AV1ProfileMain10;
    }
    int level = av1LevelNumberToConst(levelInteger);
    if (level == -1) {
        Log.w(TAG, "Unknown AV1 level: " + levelInteger);
        return null;
    }
    return new Pair<>(profile, level);
}
Also used : SuppressLint(android.annotation.SuppressLint) Pair(android.util.Pair) Nullable(androidx.annotation.Nullable)

Example 89 with Nullable

use of androidx.annotation.Nullable in project ExoPlayer by google.

the class MediaCodecUtil method maxH264DecodableFrameSize.

/**
 * Returns the maximum frame size supported by the default H264 decoder.
 *
 * @return The maximum frame size for an H264 stream that can be decoded on the device.
 */
public static int maxH264DecodableFrameSize() throws DecoderQueryException {
    if (maxH264DecodableFrameSize == -1) {
        int result = 0;
        @Nullable MediaCodecInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, /* secure= */
        false, /* tunneling= */
        false);
        if (decoderInfo != null) {
            for (CodecProfileLevel profileLevel : decoderInfo.getProfileLevels()) {
                result = max(avcLevelToMaxFrameSize(profileLevel.level), result);
            }
            // We assume support for at least 480p (SDK_INT >= 21) or 360p (SDK_INT < 21), which are
            // the levels mandated by the Android CDD.
            result = max(result, Util.SDK_INT >= 21 ? (720 * 480) : (480 * 360));
        }
        maxH264DecodableFrameSize = result;
    }
    return maxH264DecodableFrameSize;
}
Also used : CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) SuppressLint(android.annotation.SuppressLint) Nullable(androidx.annotation.Nullable)

Example 90 with Nullable

use of androidx.annotation.Nullable in project ExoPlayer by google.

the class MediaCodecUtil method getDecoderInfosInternal.

// Internal methods.
/**
 * Returns {@link MediaCodecInfo}s for the given codec {@link CodecKey} in the order given by
 * {@code mediaCodecList}.
 *
 * @param key The codec key.
 * @param mediaCodecList The codec list.
 * @return The codec information for usable codecs matching the specified key.
 * @throws DecoderQueryException If there was an error querying the available decoders.
 */
private static ArrayList<MediaCodecInfo> getDecoderInfosInternal(CodecKey key, MediaCodecListCompat mediaCodecList) throws DecoderQueryException {
    try {
        ArrayList<MediaCodecInfo> decoderInfos = new ArrayList<>();
        String mimeType = key.mimeType;
        int numberOfCodecs = mediaCodecList.getCodecCount();
        boolean secureDecodersExplicit = mediaCodecList.secureDecodersExplicit();
        // Note: MediaCodecList is sorted by the framework such that the best decoders come first.
        for (int i = 0; i < numberOfCodecs; i++) {
            android.media.MediaCodecInfo codecInfo = mediaCodecList.getCodecInfoAt(i);
            if (isAlias(codecInfo)) {
                // names.
                continue;
            }
            String name = codecInfo.getName();
            if (!isCodecUsableDecoder(codecInfo, name, secureDecodersExplicit, mimeType)) {
                continue;
            }
            @Nullable String codecMimeType = getCodecMimeType(codecInfo, name, mimeType);
            if (codecMimeType == null) {
                continue;
            }
            try {
                CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(codecMimeType);
                boolean tunnelingSupported = mediaCodecList.isFeatureSupported(CodecCapabilities.FEATURE_TunneledPlayback, codecMimeType, capabilities);
                boolean tunnelingRequired = mediaCodecList.isFeatureRequired(CodecCapabilities.FEATURE_TunneledPlayback, codecMimeType, capabilities);
                if ((!key.tunneling && tunnelingRequired) || (key.tunneling && !tunnelingSupported)) {
                    continue;
                }
                boolean secureSupported = mediaCodecList.isFeatureSupported(CodecCapabilities.FEATURE_SecurePlayback, codecMimeType, capabilities);
                boolean secureRequired = mediaCodecList.isFeatureRequired(CodecCapabilities.FEATURE_SecurePlayback, codecMimeType, capabilities);
                if ((!key.secure && secureRequired) || (key.secure && !secureSupported)) {
                    continue;
                }
                boolean hardwareAccelerated = isHardwareAccelerated(codecInfo, mimeType);
                boolean softwareOnly = isSoftwareOnly(codecInfo, mimeType);
                boolean vendor = isVendor(codecInfo);
                if ((secureDecodersExplicit && key.secure == secureSupported) || (!secureDecodersExplicit && !key.secure)) {
                    decoderInfos.add(MediaCodecInfo.newInstance(name, mimeType, codecMimeType, capabilities, hardwareAccelerated, softwareOnly, vendor, /* forceDisableAdaptive= */
                    false, /* forceSecure= */
                    false));
                } else if (!secureDecodersExplicit && secureSupported) {
                    decoderInfos.add(MediaCodecInfo.newInstance(name + ".secure", mimeType, codecMimeType, capabilities, hardwareAccelerated, softwareOnly, vendor, /* forceDisableAdaptive= */
                    false, /* forceSecure= */
                    true));
                    // It only makes sense to have one synthesized secure decoder, return immediately.
                    return decoderInfos;
                }
            } catch (Exception e) {
                if (Util.SDK_INT <= 23 && !decoderInfos.isEmpty()) {
                    // Suppress error querying secondary codec capabilities up to API level 23.
                    Log.e(TAG, "Skipping codec " + name + " (failed to query capabilities)");
                } else {
                    // Rethrow error querying primary codec capabilities, or secondary codec
                    // capabilities if API level is greater than 23.
                    Log.e(TAG, "Failed to query codec " + name + " (" + codecMimeType + ")");
                    throw e;
                }
            }
        }
        return decoderInfos;
    } catch (Exception e) {
        // or an IllegalArgumentException here.
        throw new DecoderQueryException(e);
    }
}
Also used : ArrayList(java.util.ArrayList) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) SuppressLint(android.annotation.SuppressLint) Nullable(androidx.annotation.Nullable)

Aggregations

Nullable (androidx.annotation.Nullable)1124 View (android.view.View)188 Bundle (android.os.Bundle)111 IOException (java.io.IOException)99 NonNull (androidx.annotation.NonNull)96 ArrayList (java.util.ArrayList)95 Context (android.content.Context)93 TextView (android.widget.TextView)92 Cursor (android.database.Cursor)71 SuppressLint (android.annotation.SuppressLint)69 Uri (android.net.Uri)66 RecyclerView (androidx.recyclerview.widget.RecyclerView)59 List (java.util.List)58 ViewGroup (android.view.ViewGroup)56 Test (org.junit.Test)55 Intent (android.content.Intent)53 Recipient (org.thoughtcrime.securesms.recipients.Recipient)52 R (org.thoughtcrime.securesms.R)46 LayoutInflater (android.view.LayoutInflater)45 ImageView (android.widget.ImageView)43