Search in sources :

Example 11 with ExoPlaybackException

use of com.google.android.exoplayer2.ExoPlaybackException in project ExoPlayer by google.

the class LibvpxVideoRenderer method render.

@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
    if (outputStreamEnded) {
        return;
    }
    if (format == null) {
        // We don't have a format yet, so try and read one.
        flagsOnlyBuffer.clear();
        int result = readSource(formatHolder, flagsOnlyBuffer, true);
        if (result == C.RESULT_FORMAT_READ) {
            onInputFormatChanged(formatHolder.format);
        } else if (result == C.RESULT_BUFFER_READ) {
            // End of stream read having not read a format.
            Assertions.checkState(flagsOnlyBuffer.isEndOfStream());
            inputStreamEnded = true;
            outputStreamEnded = true;
            return;
        } else {
            // We still don't have a format and can't make progress without one.
            return;
        }
    }
    if (isRendererAvailable()) {
        drmSession = pendingDrmSession;
        ExoMediaCrypto mediaCrypto = null;
        if (drmSession != null) {
            int drmSessionState = drmSession.getState();
            if (drmSessionState == DrmSession.STATE_ERROR) {
                throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
            } else if (drmSessionState == DrmSession.STATE_OPENED || drmSessionState == DrmSession.STATE_OPENED_WITH_KEYS) {
                mediaCrypto = drmSession.getMediaCrypto();
            } else {
                // The drm session isn't open yet.
                return;
            }
        }
        try {
            if (decoder == null) {
                // If we don't have a decoder yet, we need to instantiate one.
                long codecInitializingTimestamp = SystemClock.elapsedRealtime();
                TraceUtil.beginSection("createVpxDecoder");
                decoder = new VpxDecoder(NUM_BUFFERS, NUM_BUFFERS, INITIAL_INPUT_BUFFER_SIZE, mediaCrypto);
                decoder.setOutputMode(outputMode);
                TraceUtil.endSection();
                long codecInitializedTimestamp = SystemClock.elapsedRealtime();
                eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp);
                decoderCounters.decoderInitCount++;
            }
            TraceUtil.beginSection("drainAndFeed");
            while (drainOutputBuffer(positionUs)) {
            }
            while (feedInputBuffer()) {
            }
            TraceUtil.endSection();
        } catch (VpxDecoderException e) {
            throw ExoPlaybackException.createForRenderer(e, getIndex());
        }
    } else {
        skipToKeyframeBefore(positionUs);
    }
    decoderCounters.ensureUpdated();
}
Also used : ExoMediaCrypto(com.google.android.exoplayer2.drm.ExoMediaCrypto)

Example 12 with ExoPlaybackException

use of com.google.android.exoplayer2.ExoPlaybackException in project ExoPlayer by google.

the class PlayerActivity method onPlayerError.

@Override
public void onPlayerError(ExoPlaybackException e) {
    String errorString = null;
    if (e.type == ExoPlaybackException.TYPE_RENDERER) {
        Exception cause = e.getRendererException();
        if (cause instanceof DecoderInitializationException) {
            // Special case for decoder initialization failures.
            DecoderInitializationException decoderInitializationException = (DecoderInitializationException) cause;
            if (decoderInitializationException.decoderName == null) {
                if (decoderInitializationException.getCause() instanceof DecoderQueryException) {
                    errorString = getString(R.string.error_querying_decoders);
                } else if (decoderInitializationException.secureDecoderRequired) {
                    errorString = getString(R.string.error_no_secure_decoder, decoderInitializationException.mimeType);
                } else {
                    errorString = getString(R.string.error_no_decoder, decoderInitializationException.mimeType);
                }
            } else {
                errorString = getString(R.string.error_instantiating_decoder, decoderInitializationException.decoderName);
            }
        }
    }
    if (errorString != null) {
        showToast(errorString);
    }
    needRetrySource = true;
    if (isBehindLiveWindow(e)) {
        clearResumePosition();
        initializePlayer();
    } else {
        updateResumePosition();
        updateButtonVisibilities();
        showControls();
    }
}
Also used : DecoderQueryException(com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException) DecoderInitializationException(com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException) ExoPlaybackException(com.google.android.exoplayer2.ExoPlaybackException) UnsupportedDrmException(com.google.android.exoplayer2.drm.UnsupportedDrmException) DecoderInitializationException(com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException) DecoderQueryException(com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException) BehindLiveWindowException(com.google.android.exoplayer2.source.BehindLiveWindowException)

Example 13 with ExoPlaybackException

use of com.google.android.exoplayer2.ExoPlaybackException in project ExoPlayer by google.

the class DefaultTrackSelector method selectAdaptiveVideoTrack.

private static TrackSelection selectAdaptiveVideoTrack(RendererCapabilities rendererCapabilities, TrackGroupArray groups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, int maxVideoBitrate, boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness, int viewportWidth, int viewportHeight, boolean orientationMayChange, TrackSelection.Factory adaptiveVideoTrackSelectionFactory) throws ExoPlaybackException {
    int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness ? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS) : RendererCapabilities.ADAPTIVE_SEAMLESS;
    boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness && (rendererCapabilities.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0;
    for (int i = 0; i < groups.length; i++) {
        TrackGroup group = groups.get(i);
        int[] adaptiveTracks = getAdaptiveTracksForGroup(group, formatSupport[i], allowMixedMimeTypes, requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight, maxVideoBitrate, viewportWidth, viewportHeight, orientationMayChange);
        if (adaptiveTracks.length > 0) {
            return adaptiveVideoTrackSelectionFactory.createTrackSelection(group, adaptiveTracks);
        }
    }
    return null;
}
Also used : TrackGroup(com.google.android.exoplayer2.source.TrackGroup) Point(android.graphics.Point)

Example 14 with ExoPlaybackException

use of com.google.android.exoplayer2.ExoPlaybackException in project ExoPlayer by google.

the class MappingTrackSelector method selectTracks.

// TrackSelector implementation.
@Override
public final TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups) throws ExoPlaybackException {
    // Structures into which data will be written during the selection. The extra item at the end
    // of each array is to store data associated with track groups that cannot be associated with
    // any renderer.
    int[] rendererTrackGroupCounts = new int[rendererCapabilities.length + 1];
    TrackGroup[][] rendererTrackGroups = new TrackGroup[rendererCapabilities.length + 1][];
    int[][][] rendererFormatSupports = new int[rendererCapabilities.length + 1][][];
    for (int i = 0; i < rendererTrackGroups.length; i++) {
        rendererTrackGroups[i] = new TrackGroup[trackGroups.length];
        rendererFormatSupports[i] = new int[trackGroups.length][];
    }
    // Determine the extent to which each renderer supports mixed mimeType adaptation.
    int[] mixedMimeTypeAdaptationSupport = getMixedMimeTypeAdaptationSupport(rendererCapabilities);
    // renderer provides for each track in the group.
    for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
        TrackGroup group = trackGroups.get(groupIndex);
        // Associate the group to a preferred renderer.
        int rendererIndex = findRenderer(rendererCapabilities, group);
        // Evaluate the support that the renderer provides for each track in the group.
        int[] rendererFormatSupport = rendererIndex == rendererCapabilities.length ? new int[group.length] : getFormatSupport(rendererCapabilities[rendererIndex], group);
        // Stash the results.
        int rendererTrackGroupCount = rendererTrackGroupCounts[rendererIndex];
        rendererTrackGroups[rendererIndex][rendererTrackGroupCount] = group;
        rendererFormatSupports[rendererIndex][rendererTrackGroupCount] = rendererFormatSupport;
        rendererTrackGroupCounts[rendererIndex]++;
    }
    // Create a track group array for each renderer, and trim each rendererFormatSupports entry.
    TrackGroupArray[] rendererTrackGroupArrays = new TrackGroupArray[rendererCapabilities.length];
    int[] rendererTrackTypes = new int[rendererCapabilities.length];
    for (int i = 0; i < rendererCapabilities.length; i++) {
        int rendererTrackGroupCount = rendererTrackGroupCounts[i];
        rendererTrackGroupArrays[i] = new TrackGroupArray(Arrays.copyOf(rendererTrackGroups[i], rendererTrackGroupCount));
        rendererFormatSupports[i] = Arrays.copyOf(rendererFormatSupports[i], rendererTrackGroupCount);
        rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
    }
    // Create a track group array for track groups not associated with a renderer.
    int unassociatedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length];
    TrackGroupArray unassociatedTrackGroupArray = new TrackGroupArray(Arrays.copyOf(rendererTrackGroups[rendererCapabilities.length], unassociatedTrackGroupCount));
    TrackSelection[] trackSelections = selectTracks(rendererCapabilities, rendererTrackGroupArrays, rendererFormatSupports);
    // Apply track disabling and overriding.
    for (int i = 0; i < rendererCapabilities.length; i++) {
        if (rendererDisabledFlags.get(i)) {
            trackSelections[i] = null;
        } else {
            TrackGroupArray rendererTrackGroup = rendererTrackGroupArrays[i];
            Map<TrackGroupArray, SelectionOverride> overrides = selectionOverrides.get(i);
            SelectionOverride override = overrides == null ? null : overrides.get(rendererTrackGroup);
            if (override != null) {
                trackSelections[i] = override.createTrackSelection(rendererTrackGroup);
            }
        }
    }
    // Package up the track information and selections.
    MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererTrackTypes, rendererTrackGroupArrays, mixedMimeTypeAdaptationSupport, rendererFormatSupports, unassociatedTrackGroupArray);
    // Initialize the renderer configurations to the default configuration for all renderers with
    // selections, and null otherwise.
    RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCapabilities.length];
    for (int i = 0; i < rendererCapabilities.length; i++) {
        rendererConfigurations[i] = trackSelections[i] != null ? RendererConfiguration.DEFAULT : null;
    }
    // Configure audio and video renderers to use tunneling if appropriate.
    maybeConfigureRenderersForTunneling(rendererCapabilities, rendererTrackGroupArrays, rendererFormatSupports, rendererConfigurations, trackSelections, tunnelingAudioSessionId);
    return new TrackSelectorResult(trackGroups, new TrackSelectionArray(trackSelections), mappedTrackInfo, rendererConfigurations);
}
Also used : TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) RendererConfiguration(com.google.android.exoplayer2.RendererConfiguration)

Example 15 with ExoPlaybackException

use of com.google.android.exoplayer2.ExoPlaybackException in project ExoPlayer by google.

the class MappingTrackSelector method findRenderer.

/**
   * Finds the renderer to which the provided {@link TrackGroup} should be associated.
   * <p>
   * A {@link TrackGroup} is associated to a renderer that reports
   * {@link RendererCapabilities#FORMAT_HANDLED} support for one or more of the tracks in the group,
   * or {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES} if no such renderer exists, or
   * {@link RendererCapabilities#FORMAT_UNSUPPORTED_SUBTYPE} if again no such renderer exists. In
   * the case that two or more renderers report the same level of support, the renderer with the
   * lowest index is associated.
   * <p>
   * If all renderers report {@link RendererCapabilities#FORMAT_UNSUPPORTED_TYPE} for all of the
   * tracks in the group, then {@code renderers.length} is returned to indicate that no association
   * was made.
   *
   * @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
   * @param group The {@link TrackGroup} whose associated renderer is to be found.
   * @return The index of the associated renderer, or {@code renderers.length} if no
   *     association was made.
   * @throws ExoPlaybackException If an error occurs finding a renderer.
   */
private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group) throws ExoPlaybackException {
    int bestRendererIndex = rendererCapabilities.length;
    int bestFormatSupportLevel = RendererCapabilities.FORMAT_UNSUPPORTED_TYPE;
    for (int rendererIndex = 0; rendererIndex < rendererCapabilities.length; rendererIndex++) {
        RendererCapabilities rendererCapability = rendererCapabilities[rendererIndex];
        for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
            int formatSupportLevel = rendererCapability.supportsFormat(group.getFormat(trackIndex)) & RendererCapabilities.FORMAT_SUPPORT_MASK;
            if (formatSupportLevel > bestFormatSupportLevel) {
                bestRendererIndex = rendererIndex;
                bestFormatSupportLevel = formatSupportLevel;
                if (bestFormatSupportLevel == RendererCapabilities.FORMAT_HANDLED) {
                    // We can't do better.
                    return bestRendererIndex;
                }
            }
        }
    }
    return bestRendererIndex;
}
Also used : RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities)

Aggregations

Format (com.google.android.exoplayer2.Format)4 ExoPlaybackException (com.google.android.exoplayer2.ExoPlaybackException)3 TrackSelection (com.google.android.exoplayer2.trackselection.TrackSelection)3 DecoderCounters (com.google.android.exoplayer2.decoder.DecoderCounters)2 ExoMediaCrypto (com.google.android.exoplayer2.drm.ExoMediaCrypto)2 DecoderQueryException (com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException)2 SampleStream (com.google.android.exoplayer2.source.SampleStream)2 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)2 Point (android.graphics.Point)1 CodecException (android.media.MediaCodec.CodecException)1 CryptoException (android.media.MediaCodec.CryptoException)1 MediaCrypto (android.media.MediaCrypto)1 MediaFormat (android.media.MediaFormat)1 ExoPlayerMessage (com.google.android.exoplayer2.ExoPlayer.ExoPlayerMessage)1 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)1 RendererConfiguration (com.google.android.exoplayer2.RendererConfiguration)1 FrameworkMediaCrypto (com.google.android.exoplayer2.drm.FrameworkMediaCrypto)1 UnsupportedDrmException (com.google.android.exoplayer2.drm.UnsupportedDrmException)1 MediaCodecRenderer (com.google.android.exoplayer2.mediacodec.MediaCodecRenderer)1 DecoderInitializationException (com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException)1