Search in sources :

Example 26 with C

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

the class DefaultTrackSelectorTest method selectTracksSelectPreferredAudioLanguageOverSelectionFlag.

/**
 * Tests that track selector will prefer selecting audio track with language that match preferred
 * language given by {@link Parameters} over track with {@link C#SELECTION_FLAG_DEFAULT}.
 */
@Test
public void selectTracksSelectPreferredAudioLanguageOverSelectionFlag() throws Exception {
    Format.Builder formatBuilder = AUDIO_FORMAT.buildUpon();
    Format frDefaultFormat = formatBuilder.setLanguage("fra").setSelectionFlags(C.SELECTION_FLAG_DEFAULT).build();
    Format enNonDefaultFormat = formatBuilder.setLanguage("eng").setSelectionFlags(0).build();
    TrackGroupArray trackGroups = wrapFormats(frDefaultFormat, enNonDefaultFormat);
    trackSelector.setParameters(defaultParameters.buildUpon().setPreferredAudioLanguage("eng"));
    TrackSelectorResult result = trackSelector.selectTracks(new RendererCapabilities[] { ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES }, trackGroups, periodId, TIMELINE);
    assertFixedSelection(result.selections[0], trackGroups, enNonDefaultFormat);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) Test(org.junit.Test)

Example 27 with C

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

the class CacheWriter method readBlockToCache.

/**
 * Reads the specified block of data, writing it into the cache.
 *
 * @param position The starting position of the block.
 * @param length The length of the block, or {@link C#LENGTH_UNSET} if unbounded.
 * @return The number of bytes read.
 * @throws IOException If an error occurs reading the data or writing it to the cache.
 */
private long readBlockToCache(long position, long length) throws IOException {
    boolean isLastBlock = position + length == endPosition || length == C.LENGTH_UNSET;
    long resolvedLength = C.LENGTH_UNSET;
    boolean isDataSourceOpen = false;
    if (length != C.LENGTH_UNSET) {
        // If the length is specified, try to open the data source with a bounded request to avoid
        // the underlying network stack requesting more data than required.
        DataSpec boundedDataSpec = dataSpec.buildUpon().setPosition(position).setLength(length).build();
        try {
            resolvedLength = dataSource.open(boundedDataSpec);
            isDataSourceOpen = true;
        } catch (IOException e) {
            DataSourceUtil.closeQuietly(dataSource);
        }
    }
    if (!isDataSourceOpen) {
        // Either the length was unspecified, or we allow short content and our attempt to open the
        // DataSource with the specified length failed.
        throwIfCanceled();
        DataSpec unboundedDataSpec = dataSpec.buildUpon().setPosition(position).setLength(C.LENGTH_UNSET).build();
        try {
            resolvedLength = dataSource.open(unboundedDataSpec);
        } catch (IOException e) {
            DataSourceUtil.closeQuietly(dataSource);
            throw e;
        }
    }
    int totalBytesRead = 0;
    try {
        if (isLastBlock && resolvedLength != C.LENGTH_UNSET) {
            onRequestEndPosition(position + resolvedLength);
        }
        int bytesRead = 0;
        while (bytesRead != C.RESULT_END_OF_INPUT) {
            throwIfCanceled();
            bytesRead = dataSource.read(temporaryBuffer, /* offset= */
            0, temporaryBuffer.length);
            if (bytesRead != C.RESULT_END_OF_INPUT) {
                onNewBytesCached(bytesRead);
                totalBytesRead += bytesRead;
            }
        }
        if (isLastBlock) {
            onRequestEndPosition(position + totalBytesRead);
        }
    } catch (IOException e) {
        DataSourceUtil.closeQuietly(dataSource);
        throw e;
    }
    // Util.closeQuietly(dataSource) is not used here because it's important that an exception is
    // thrown if DataSource.close fails. This is because there's no way of knowing whether the block
    // was successfully cached in this case.
    dataSource.close();
    return totalBytesRead;
}
Also used : DataSpec(com.google.android.exoplayer2.upstream.DataSpec) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException)

Example 28 with C

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

the class DefaultHttpDataSource method maybeTerminateInputStream.

/**
 * On platform API levels 19 and 20, okhttp's implementation of {@link InputStream#close} can
 * block for a long time if the stream has a lot of data remaining. Call this method before
 * closing the input stream to make a best effort to cause the input stream to encounter an
 * unexpected end of input, working around this issue. On other platform API levels, the method
 * does nothing.
 *
 * @param connection The connection whose {@link InputStream} should be terminated.
 * @param bytesRemaining The number of bytes remaining to be read from the input stream if its
 *     length is known. {@link C#LENGTH_UNSET} otherwise.
 */
private static void maybeTerminateInputStream(@Nullable HttpURLConnection connection, long bytesRemaining) {
    if (connection == null || Util.SDK_INT < 19 || Util.SDK_INT > 20) {
        return;
    }
    try {
        InputStream inputStream = connection.getInputStream();
        if (bytesRemaining == C.LENGTH_UNSET) {
            // If the input stream has already ended, do nothing. The socket may be re-used.
            if (inputStream.read() == -1) {
                return;
            }
        } else if (bytesRemaining <= MAX_BYTES_TO_DRAIN) {
            // re-used.
            return;
        }
        String className = inputStream.getClass().getName();
        if ("com.android.okhttp.internal.http.HttpTransport$ChunkedInputStream".equals(className) || "com.android.okhttp.internal.http.HttpTransport$FixedLengthInputStream".equals(className)) {
            Class<?> superclass = inputStream.getClass().getSuperclass();
            Method unexpectedEndOfInput = checkNotNull(superclass).getDeclaredMethod("unexpectedEndOfInput");
            unexpectedEndOfInput.setAccessible(true);
            unexpectedEndOfInput.invoke(inputStream);
        }
    } catch (Exception e) {
    // If an IOException then the connection didn't ever have an input stream, or it was closed
    // already. If another type of exception then something went wrong, most likely the device
    // isn't using okhttp.
    }
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) HttpMethod(com.google.android.exoplayer2.upstream.DataSpec.HttpMethod) Method(java.lang.reflect.Method) InterruptedIOException(java.io.InterruptedIOException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) PlaybackException(com.google.android.exoplayer2.PlaybackException) NoRouteToHostException(java.net.NoRouteToHostException)

Example 29 with C

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

the class AdaptiveTrackSelection method determineIdealSelectedIndex.

/**
 * Computes the ideal selected index ignoring buffer health.
 *
 * @param nowMs The current time in the timebase of {@link Clock#elapsedRealtime()}, or {@link
 *     Long#MIN_VALUE} to ignore track exclusion.
 * @param chunkDurationUs The duration of a media chunk in microseconds, or {@link C#TIME_UNSET}
 *     if unknown.
 */
private int determineIdealSelectedIndex(long nowMs, long chunkDurationUs) {
    long effectiveBitrate = getAllocatedBandwidth(chunkDurationUs);
    int lowestBitrateAllowedIndex = 0;
    for (int i = 0; i < length; i++) {
        if (nowMs == Long.MIN_VALUE || !isBlacklisted(i, nowMs)) {
            Format format = getFormat(i);
            if (canSelectFormat(format, format.bitrate, effectiveBitrate)) {
                return i;
            } else {
                lowestBitrateAllowedIndex = i;
            }
        }
    }
    return lowestBitrateAllowedIndex;
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 30 with C

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

the class MappingTrackSelector method findRenderer.

/**
 * Finds the renderer to which the provided {@link TrackGroup} should be mapped.
 *
 * <p>A {@link TrackGroup} is mapped to the renderer that reports the highest of (listed in
 * decreasing order of support) {@link C#FORMAT_HANDLED}, {@link C#FORMAT_EXCEEDS_CAPABILITIES},
 * {@link C#FORMAT_UNSUPPORTED_DRM} and {@link C#FORMAT_UNSUPPORTED_SUBTYPE}.
 *
 * <p>In the case that two or more renderers report the same level of support, the assignment
 * depends on {@code preferUnassociatedRenderer}.
 *
 * <ul>
 *   <li>If {@code preferUnassociatedRenderer} is false, the renderer with the lowest index is
 *       chosen regardless of how many other track groups are already mapped to this renderer.
 *   <li>If {@code preferUnassociatedRenderer} is true, the renderer with the lowest index and no
 *       other mapped track group is chosen, or the renderer with the lowest index if all
 *       available renderers have already mapped track groups.
 * </ul>
 *
 * <p>If all renderers report {@link C#FORMAT_UNSUPPORTED_TYPE} for all of the tracks in the
 * group, then {@code renderers.length} is returned to indicate that the group was not mapped to
 * any renderer.
 *
 * @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
 * @param group The track group to map to a renderer.
 * @param rendererTrackGroupCounts The number of already mapped track groups for each renderer.
 * @param preferUnassociatedRenderer Whether renderers unassociated to any track group should be
 *     preferred.
 * @return The index of the renderer to which the track group was mapped, or {@code
 *     renderers.length} if it was not mapped to any renderer.
 * @throws ExoPlaybackException If an error occurs finding a renderer.
 */
private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group, int[] rendererTrackGroupCounts, boolean preferUnassociatedRenderer) throws ExoPlaybackException {
    int bestRendererIndex = rendererCapabilities.length;
    @FormatSupport int bestFormatSupportLevel = C.FORMAT_UNSUPPORTED_TYPE;
    boolean bestRendererIsUnassociated = true;
    for (int rendererIndex = 0; rendererIndex < rendererCapabilities.length; rendererIndex++) {
        RendererCapabilities rendererCapability = rendererCapabilities[rendererIndex];
        @FormatSupport int formatSupportLevel = C.FORMAT_UNSUPPORTED_TYPE;
        for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
            @FormatSupport int trackFormatSupportLevel = RendererCapabilities.getFormatSupport(rendererCapability.supportsFormat(group.getFormat(trackIndex)));
            formatSupportLevel = max(formatSupportLevel, trackFormatSupportLevel);
        }
        boolean rendererIsUnassociated = rendererTrackGroupCounts[rendererIndex] == 0;
        if (formatSupportLevel > bestFormatSupportLevel || (formatSupportLevel == bestFormatSupportLevel && preferUnassociatedRenderer && !bestRendererIsUnassociated && rendererIsUnassociated)) {
            bestRendererIndex = rendererIndex;
            bestFormatSupportLevel = formatSupportLevel;
            bestRendererIsUnassociated = rendererIsUnassociated;
        }
    }
    return bestRendererIndex;
}
Also used : FormatSupport(com.google.android.exoplayer2.C.FormatSupport) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities)

Aggregations

Test (org.junit.Test)14 BaseUrl (com.google.android.exoplayer2.source.dash.manifest.BaseUrl)6 Format (com.google.android.exoplayer2.Format)5 SeekPoint (com.google.android.exoplayer2.extractor.SeekPoint)5 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)4 IOException (java.io.IOException)4 Nullable (androidx.annotation.Nullable)3 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)3 HashMap (java.util.HashMap)3 Metadata (com.google.android.exoplayer2.metadata.Metadata)2 EventStream (com.google.android.exoplayer2.source.dash.manifest.EventStream)2 InterruptedIOException (java.io.InterruptedIOException)2 TargetApi (android.annotation.TargetApi)1 Activity (android.app.Activity)1 ActivityManager (android.app.ActivityManager)1 Application (android.app.Application)1 UiModeManager (android.app.UiModeManager)1 Context (android.content.Context)1 Intent (android.content.Intent)1 SharedPreferences (android.content.SharedPreferences)1