Search in sources :

Example 11 with Assertions.checkState

use of com.google.android.exoplayer2.util.Assertions.checkState in project ExoPlayer by google.

the class PlayerView method setPlayer.

/**
 * Sets the {@link Player} to use.
 *
 * <p>To transition a {@link Player} from targeting one view to another, it's recommended to use
 * {@link #switchTargetView(Player, PlayerView, PlayerView)} rather than this method. If you do
 * wish to use this method directly, be sure to attach the player to the new view <em>before</em>
 * calling {@code setPlayer(null)} to detach it from the old one. This ordering is significantly
 * more efficient and may allow for more seamless transitions.
 *
 * @param player The {@link Player} to use, or {@code null} to detach the current player. Only
 *     players which are accessed on the main thread are supported ({@code
 *     player.getApplicationLooper() == Looper.getMainLooper()}).
 */
public void setPlayer(@Nullable Player player) {
    Assertions.checkState(Looper.myLooper() == Looper.getMainLooper());
    Assertions.checkArgument(player == null || player.getApplicationLooper() == Looper.getMainLooper());
    if (this.player == player) {
        return;
    }
    @Nullable Player oldPlayer = this.player;
    if (oldPlayer != null) {
        oldPlayer.removeListener(componentListener);
        if (oldPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
            if (surfaceView instanceof TextureView) {
                oldPlayer.clearVideoTextureView((TextureView) surfaceView);
            } else if (surfaceView instanceof SurfaceView) {
                oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
            }
        }
    }
    if (subtitleView != null) {
        subtitleView.setCues(null);
    }
    this.player = player;
    if (useController()) {
        controller.setPlayer(player);
    }
    updateBuffering();
    updateErrorMessage();
    updateForCurrentTrackSelections(/* isNewPlayer= */
    true);
    if (player != null) {
        if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
            if (surfaceView instanceof TextureView) {
                player.setVideoTextureView((TextureView) surfaceView);
            } else if (surfaceView instanceof SurfaceView) {
                player.setVideoSurfaceView((SurfaceView) surfaceView);
            }
            updateAspectRatio();
        }
        if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) {
            subtitleView.setCues(player.getCurrentCues());
        }
        player.addListener(componentListener);
        maybeShowController(false);
    } else {
        hideController();
    }
}
Also used : Player(com.google.android.exoplayer2.Player) TextureView(android.view.TextureView) Nullable(androidx.annotation.Nullable) SurfaceView(android.view.SurfaceView) GLSurfaceView(android.opengl.GLSurfaceView)

Example 12 with Assertions.checkState

use of com.google.android.exoplayer2.util.Assertions.checkState in project ExoPlayer by google.

the class Mp4Extractor method readAtomHeader.

private boolean readAtomHeader(ExtractorInput input) throws IOException {
    if (atomHeaderBytesRead == 0) {
        // Read the standard length atom header.
        if (!input.readFully(atomHeader.getData(), 0, Atom.HEADER_SIZE, true)) {
            processEndOfStreamReadingAtomHeader();
            return false;
        }
        atomHeaderBytesRead = Atom.HEADER_SIZE;
        atomHeader.setPosition(0);
        atomSize = atomHeader.readUnsignedInt();
        atomType = atomHeader.readInt();
    }
    if (atomSize == Atom.DEFINES_LARGE_SIZE) {
        // Read the large size.
        int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
        input.readFully(atomHeader.getData(), Atom.HEADER_SIZE, headerBytesRemaining);
        atomHeaderBytesRead += headerBytesRemaining;
        atomSize = atomHeader.readUnsignedLongToLong();
    } else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
        // The atom extends to the end of the file. Note that if the atom is within a container we can
        // work out its size even if the input length is unknown.
        long endPosition = input.getLength();
        if (endPosition == C.LENGTH_UNSET) {
            @Nullable ContainerAtom containerAtom = containerAtoms.peek();
            if (containerAtom != null) {
                endPosition = containerAtom.endPosition;
            }
        }
        if (endPosition != C.LENGTH_UNSET) {
            atomSize = endPosition - input.getPosition() + atomHeaderBytesRead;
        }
    }
    if (atomSize < atomHeaderBytesRead) {
        throw ParserException.createForUnsupportedContainerFeature("Atom size less than header length (unsupported).");
    }
    if (shouldParseContainerAtom(atomType)) {
        long endPosition = input.getPosition() + atomSize - atomHeaderBytesRead;
        if (atomSize != atomHeaderBytesRead && atomType == Atom.TYPE_meta) {
            maybeSkipRemainingMetaAtomHeaderBytes(input);
        }
        containerAtoms.push(new ContainerAtom(atomType, endPosition));
        if (atomSize == atomHeaderBytesRead) {
            processAtomEnded(endPosition);
        } else {
            // Start reading the first child atom.
            enterReadingAtomHeaderState();
        }
    } else if (shouldParseLeafAtom(atomType)) {
        // We don't support parsing of leaf atoms that define extended atom sizes, or that have
        // lengths greater than Integer.MAX_VALUE.
        Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
        Assertions.checkState(atomSize <= Integer.MAX_VALUE);
        ParsableByteArray atomData = new ParsableByteArray((int) atomSize);
        System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE);
        this.atomData = atomData;
        parserState = STATE_READING_ATOM_PAYLOAD;
    } else {
        processUnparsedAtom(input.getPosition() - atomHeaderBytesRead);
        atomData = null;
        parserState = STATE_READING_ATOM_PAYLOAD;
    }
    return true;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) ContainerAtom(com.google.android.exoplayer2.extractor.mp4.Atom.ContainerAtom) SeekPoint(com.google.android.exoplayer2.extractor.SeekPoint)

Example 13 with Assertions.checkState

use of com.google.android.exoplayer2.util.Assertions.checkState in project ExoPlayer by google.

the class CacheDataSource method openNextSource.

/**
 * Opens the next source. If the cache contains data spanning the current read position then
 * {@link #cacheReadDataSource} is opened to read from it. Else {@link #upstreamDataSource} is
 * opened to read from the upstream source and write into the cache.
 *
 * <p>There must not be a currently open source when this method is called, except in the case
 * that {@code checkCache} is true. If {@code checkCache} is true then there must be a currently
 * open source, and it must be {@link #upstreamDataSource}. It will be closed and a new source
 * opened if it's possible to switch to reading from or writing to the cache. If a switch isn't
 * possible then the current source is left unchanged.
 *
 * @param requestDataSpec The original {@link DataSpec} to build upon for the next source.
 * @param checkCache If true tries to switch to reading from or writing to cache instead of
 *     reading from {@link #upstreamDataSource}, which is the currently open source.
 */
private void openNextSource(DataSpec requestDataSpec, boolean checkCache) throws IOException {
    @Nullable CacheSpan nextSpan;
    String key = castNonNull(requestDataSpec.key);
    if (currentRequestIgnoresCache) {
        nextSpan = null;
    } else if (blockOnCache) {
        try {
            nextSpan = cache.startReadWrite(key, readPosition, bytesRemaining);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new InterruptedIOException();
        }
    } else {
        nextSpan = cache.startReadWriteNonBlocking(key, readPosition, bytesRemaining);
    }
    DataSpec nextDataSpec;
    DataSource nextDataSource;
    if (nextSpan == null) {
        // The data is locked in the cache, or we're ignoring the cache. Bypass the cache and read
        // from upstream.
        nextDataSource = upstreamDataSource;
        nextDataSpec = requestDataSpec.buildUpon().setPosition(readPosition).setLength(bytesRemaining).build();
    } else if (nextSpan.isCached) {
        // Data is cached in a span file starting at nextSpan.position.
        Uri fileUri = Uri.fromFile(castNonNull(nextSpan.file));
        long filePositionOffset = nextSpan.position;
        long positionInFile = readPosition - filePositionOffset;
        long length = nextSpan.length - positionInFile;
        if (bytesRemaining != C.LENGTH_UNSET) {
            length = min(length, bytesRemaining);
        }
        nextDataSpec = requestDataSpec.buildUpon().setUri(fileUri).setUriPositionOffset(filePositionOffset).setPosition(positionInFile).setLength(length).build();
        nextDataSource = cacheReadDataSource;
    } else {
        // Data is not cached, and data is not locked, read from upstream with cache backing.
        long length;
        if (nextSpan.isOpenEnded()) {
            length = bytesRemaining;
        } else {
            length = nextSpan.length;
            if (bytesRemaining != C.LENGTH_UNSET) {
                length = min(length, bytesRemaining);
            }
        }
        nextDataSpec = requestDataSpec.buildUpon().setPosition(readPosition).setLength(length).build();
        if (cacheWriteDataSource != null) {
            nextDataSource = cacheWriteDataSource;
        } else {
            nextDataSource = upstreamDataSource;
            cache.releaseHoleSpan(nextSpan);
            nextSpan = null;
        }
    }
    checkCachePosition = !currentRequestIgnoresCache && nextDataSource == upstreamDataSource ? readPosition + MIN_READ_BEFORE_CHECKING_CACHE : Long.MAX_VALUE;
    if (checkCache) {
        Assertions.checkState(isBypassingCache());
        if (nextDataSource == upstreamDataSource) {
            // Continue reading from upstream.
            return;
        }
        // We're switching to reading from or writing to the cache.
        try {
            closeCurrentSource();
        } catch (Throwable e) {
            if (castNonNull(nextSpan).isHoleSpan()) {
                // Release the hole span before throwing, else we'll hold it forever.
                cache.releaseHoleSpan(nextSpan);
            }
            throw e;
        }
    }
    if (nextSpan != null && nextSpan.isHoleSpan()) {
        currentHoleSpan = nextSpan;
    }
    currentDataSource = nextDataSource;
    currentDataSpec = nextDataSpec;
    currentDataSourceBytesRead = 0;
    long resolvedLength = nextDataSource.open(nextDataSpec);
    // Update bytesRemaining, actualUri and (if writing to cache) the cache metadata.
    ContentMetadataMutations mutations = new ContentMetadataMutations();
    if (nextDataSpec.length == C.LENGTH_UNSET && resolvedLength != C.LENGTH_UNSET) {
        bytesRemaining = resolvedLength;
        ContentMetadataMutations.setContentLength(mutations, readPosition + bytesRemaining);
    }
    if (isReadingFromUpstream()) {
        actualUri = nextDataSource.getUri();
        boolean isRedirected = !requestDataSpec.uri.equals(actualUri);
        ContentMetadataMutations.setRedirectedUri(mutations, isRedirected ? actualUri : null);
    }
    if (isWritingToCache()) {
        cache.applyContentMetadataMutations(key, mutations);
    }
}
Also used : InterruptedIOException(java.io.InterruptedIOException) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) Uri(android.net.Uri) Nullable(androidx.annotation.Nullable) PriorityDataSource(com.google.android.exoplayer2.upstream.PriorityDataSource) TeeDataSource(com.google.android.exoplayer2.upstream.TeeDataSource) DummyDataSource(com.google.android.exoplayer2.upstream.DummyDataSource) FileDataSource(com.google.android.exoplayer2.upstream.FileDataSource) DataSource(com.google.android.exoplayer2.upstream.DataSource)

Example 14 with Assertions.checkState

use of com.google.android.exoplayer2.util.Assertions.checkState in project ExoPlayer by google.

the class HlsPlaylistParser method parseMultivariantPlaylist.

private static HlsMultivariantPlaylist parseMultivariantPlaylist(LineIterator iterator, String baseUri) throws IOException {
    HashMap<Uri, ArrayList<VariantInfo>> urlToVariantInfos = new HashMap<>();
    HashMap<String, String> variableDefinitions = new HashMap<>();
    ArrayList<Variant> variants = new ArrayList<>();
    ArrayList<Rendition> videos = new ArrayList<>();
    ArrayList<Rendition> audios = new ArrayList<>();
    ArrayList<Rendition> subtitles = new ArrayList<>();
    ArrayList<Rendition> closedCaptions = new ArrayList<>();
    ArrayList<String> mediaTags = new ArrayList<>();
    ArrayList<DrmInitData> sessionKeyDrmInitData = new ArrayList<>();
    ArrayList<String> tags = new ArrayList<>();
    Format muxedAudioFormat = null;
    List<Format> muxedCaptionFormats = null;
    boolean noClosedCaptions = false;
    boolean hasIndependentSegmentsTag = false;
    String line;
    while (iterator.hasNext()) {
        line = iterator.next();
        if (line.startsWith(TAG_PREFIX)) {
            // We expose all tags through the playlist.
            tags.add(line);
        }
        boolean isIFrameOnlyVariant = line.startsWith(TAG_I_FRAME_STREAM_INF);
        if (line.startsWith(TAG_DEFINE)) {
            variableDefinitions.put(/* key= */
            parseStringAttr(line, REGEX_NAME, variableDefinitions), /* value= */
            parseStringAttr(line, REGEX_VALUE, variableDefinitions));
        } else if (line.equals(TAG_INDEPENDENT_SEGMENTS)) {
            hasIndependentSegmentsTag = true;
        } else if (line.startsWith(TAG_MEDIA)) {
            // Media tags are parsed at the end to include codec information from #EXT-X-STREAM-INF
            // tags.
            mediaTags.add(line);
        } else if (line.startsWith(TAG_SESSION_KEY)) {
            String keyFormat = parseOptionalStringAttr(line, REGEX_KEYFORMAT, KEYFORMAT_IDENTITY, variableDefinitions);
            SchemeData schemeData = parseDrmSchemeData(line, keyFormat, variableDefinitions);
            if (schemeData != null) {
                String method = parseStringAttr(line, REGEX_METHOD, variableDefinitions);
                String scheme = parseEncryptionScheme(method);
                sessionKeyDrmInitData.add(new DrmInitData(scheme, schemeData));
            }
        } else if (line.startsWith(TAG_STREAM_INF) || isIFrameOnlyVariant) {
            noClosedCaptions |= line.contains(ATTR_CLOSED_CAPTIONS_NONE);
            int roleFlags = isIFrameOnlyVariant ? C.ROLE_FLAG_TRICK_PLAY : 0;
            int peakBitrate = parseIntAttr(line, REGEX_BANDWIDTH);
            int averageBitrate = parseOptionalIntAttr(line, REGEX_AVERAGE_BANDWIDTH, -1);
            String codecs = parseOptionalStringAttr(line, REGEX_CODECS, variableDefinitions);
            String resolutionString = parseOptionalStringAttr(line, REGEX_RESOLUTION, variableDefinitions);
            int width;
            int height;
            if (resolutionString != null) {
                String[] widthAndHeight = Util.split(resolutionString, "x");
                width = Integer.parseInt(widthAndHeight[0]);
                height = Integer.parseInt(widthAndHeight[1]);
                if (width <= 0 || height <= 0) {
                    // Resolution string is invalid.
                    width = Format.NO_VALUE;
                    height = Format.NO_VALUE;
                }
            } else {
                width = Format.NO_VALUE;
                height = Format.NO_VALUE;
            }
            float frameRate = Format.NO_VALUE;
            String frameRateString = parseOptionalStringAttr(line, REGEX_FRAME_RATE, variableDefinitions);
            if (frameRateString != null) {
                frameRate = Float.parseFloat(frameRateString);
            }
            String videoGroupId = parseOptionalStringAttr(line, REGEX_VIDEO, variableDefinitions);
            String audioGroupId = parseOptionalStringAttr(line, REGEX_AUDIO, variableDefinitions);
            String subtitlesGroupId = parseOptionalStringAttr(line, REGEX_SUBTITLES, variableDefinitions);
            String closedCaptionsGroupId = parseOptionalStringAttr(line, REGEX_CLOSED_CAPTIONS, variableDefinitions);
            Uri uri;
            if (isIFrameOnlyVariant) {
                uri = UriUtil.resolveToUri(baseUri, parseStringAttr(line, REGEX_URI, variableDefinitions));
            } else if (!iterator.hasNext()) {
                throw ParserException.createForMalformedManifest("#EXT-X-STREAM-INF must be followed by another line", /* cause= */
                null);
            } else {
                // The following line contains #EXT-X-STREAM-INF's URI.
                line = replaceVariableReferences(iterator.next(), variableDefinitions);
                uri = UriUtil.resolveToUri(baseUri, line);
            }
            Format format = new Format.Builder().setId(variants.size()).setContainerMimeType(MimeTypes.APPLICATION_M3U8).setCodecs(codecs).setAverageBitrate(averageBitrate).setPeakBitrate(peakBitrate).setWidth(width).setHeight(height).setFrameRate(frameRate).setRoleFlags(roleFlags).build();
            Variant variant = new Variant(uri, format, videoGroupId, audioGroupId, subtitlesGroupId, closedCaptionsGroupId);
            variants.add(variant);
            @Nullable ArrayList<VariantInfo> variantInfosForUrl = urlToVariantInfos.get(uri);
            if (variantInfosForUrl == null) {
                variantInfosForUrl = new ArrayList<>();
                urlToVariantInfos.put(uri, variantInfosForUrl);
            }
            variantInfosForUrl.add(new VariantInfo(averageBitrate, peakBitrate, videoGroupId, audioGroupId, subtitlesGroupId, closedCaptionsGroupId));
        }
    }
    // TODO: Don't deduplicate variants by URL.
    ArrayList<Variant> deduplicatedVariants = new ArrayList<>();
    HashSet<Uri> urlsInDeduplicatedVariants = new HashSet<>();
    for (int i = 0; i < variants.size(); i++) {
        Variant variant = variants.get(i);
        if (urlsInDeduplicatedVariants.add(variant.url)) {
            Assertions.checkState(variant.format.metadata == null);
            HlsTrackMetadataEntry hlsMetadataEntry = new HlsTrackMetadataEntry(/* groupId= */
            null, /* name= */
            null, checkNotNull(urlToVariantInfos.get(variant.url)));
            Metadata metadata = new Metadata(hlsMetadataEntry);
            Format format = variant.format.buildUpon().setMetadata(metadata).build();
            deduplicatedVariants.add(variant.copyWithFormat(format));
        }
    }
    for (int i = 0; i < mediaTags.size(); i++) {
        line = mediaTags.get(i);
        String groupId = parseStringAttr(line, REGEX_GROUP_ID, variableDefinitions);
        String name = parseStringAttr(line, REGEX_NAME, variableDefinitions);
        Format.Builder formatBuilder = new Format.Builder().setId(groupId + ":" + name).setLabel(name).setContainerMimeType(MimeTypes.APPLICATION_M3U8).setSelectionFlags(parseSelectionFlags(line)).setRoleFlags(parseRoleFlags(line, variableDefinitions)).setLanguage(parseOptionalStringAttr(line, REGEX_LANGUAGE, variableDefinitions));
        @Nullable String referenceUri = parseOptionalStringAttr(line, REGEX_URI, variableDefinitions);
        @Nullable Uri uri = referenceUri == null ? null : UriUtil.resolveToUri(baseUri, referenceUri);
        Metadata metadata = new Metadata(new HlsTrackMetadataEntry(groupId, name, Collections.emptyList()));
        switch(parseStringAttr(line, REGEX_TYPE, variableDefinitions)) {
            case TYPE_VIDEO:
                @Nullable Variant variant = getVariantWithVideoGroup(variants, groupId);
                if (variant != null) {
                    Format variantFormat = variant.format;
                    @Nullable String codecs = Util.getCodecsOfType(variantFormat.codecs, C.TRACK_TYPE_VIDEO);
                    formatBuilder.setCodecs(codecs).setSampleMimeType(MimeTypes.getMediaMimeType(codecs)).setWidth(variantFormat.width).setHeight(variantFormat.height).setFrameRate(variantFormat.frameRate);
                }
                if (uri == null) {
                // TODO: Remove this case and add a Rendition with a null uri to videos.
                } else {
                    formatBuilder.setMetadata(metadata);
                    videos.add(new Rendition(uri, formatBuilder.build(), groupId, name));
                }
                break;
            case TYPE_AUDIO:
                @Nullable String sampleMimeType = null;
                variant = getVariantWithAudioGroup(variants, groupId);
                if (variant != null) {
                    @Nullable String codecs = Util.getCodecsOfType(variant.format.codecs, C.TRACK_TYPE_AUDIO);
                    formatBuilder.setCodecs(codecs);
                    sampleMimeType = MimeTypes.getMediaMimeType(codecs);
                }
                @Nullable String channelsString = parseOptionalStringAttr(line, REGEX_CHANNELS, variableDefinitions);
                if (channelsString != null) {
                    int channelCount = Integer.parseInt(Util.splitAtFirst(channelsString, "/")[0]);
                    formatBuilder.setChannelCount(channelCount);
                    if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType) && channelsString.endsWith("/JOC")) {
                        sampleMimeType = MimeTypes.AUDIO_E_AC3_JOC;
                        formatBuilder.setCodecs(MimeTypes.CODEC_E_AC3_JOC);
                    }
                }
                formatBuilder.setSampleMimeType(sampleMimeType);
                if (uri != null) {
                    formatBuilder.setMetadata(metadata);
                    audios.add(new Rendition(uri, formatBuilder.build(), groupId, name));
                } else if (variant != null) {
                    // TODO: Remove muxedAudioFormat and add a Rendition with a null uri to audios.
                    muxedAudioFormat = formatBuilder.build();
                }
                break;
            case TYPE_SUBTITLES:
                sampleMimeType = null;
                variant = getVariantWithSubtitleGroup(variants, groupId);
                if (variant != null) {
                    @Nullable String codecs = Util.getCodecsOfType(variant.format.codecs, C.TRACK_TYPE_TEXT);
                    formatBuilder.setCodecs(codecs);
                    sampleMimeType = MimeTypes.getMediaMimeType(codecs);
                }
                if (sampleMimeType == null) {
                    sampleMimeType = MimeTypes.TEXT_VTT;
                }
                formatBuilder.setSampleMimeType(sampleMimeType).setMetadata(metadata);
                if (uri != null) {
                    subtitles.add(new Rendition(uri, formatBuilder.build(), groupId, name));
                } else {
                    Log.w(LOG_TAG, "EXT-X-MEDIA tag with missing mandatory URI attribute: skipping");
                }
                break;
            case TYPE_CLOSED_CAPTIONS:
                String instreamId = parseStringAttr(line, REGEX_INSTREAM_ID, variableDefinitions);
                int accessibilityChannel;
                if (instreamId.startsWith("CC")) {
                    sampleMimeType = MimeTypes.APPLICATION_CEA608;
                    accessibilityChannel = Integer.parseInt(instreamId.substring(2));
                } else /* starts with SERVICE */
                {
                    sampleMimeType = MimeTypes.APPLICATION_CEA708;
                    accessibilityChannel = Integer.parseInt(instreamId.substring(7));
                }
                if (muxedCaptionFormats == null) {
                    muxedCaptionFormats = new ArrayList<>();
                }
                formatBuilder.setSampleMimeType(sampleMimeType).setAccessibilityChannel(accessibilityChannel);
                muxedCaptionFormats.add(formatBuilder.build());
                // TODO: Remove muxedCaptionFormats and add a Rendition with a null uri to closedCaptions.
                break;
            default:
                // Do nothing.
                break;
        }
    }
    if (noClosedCaptions) {
        muxedCaptionFormats = Collections.emptyList();
    }
    return new HlsMultivariantPlaylist(baseUri, tags, deduplicatedVariants, videos, audios, subtitles, closedCaptions, muxedAudioFormat, muxedCaptionFormats, hasIndependentSegmentsTag, variableDefinitions, sessionKeyDrmInitData);
}
Also used : VariantInfo(com.google.android.exoplayer2.source.hls.HlsTrackMetadataEntry.VariantInfo) HashMap(java.util.HashMap) Rendition(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition) ArrayList(java.util.ArrayList) Metadata(com.google.android.exoplayer2.metadata.Metadata) SchemeData(com.google.android.exoplayer2.drm.DrmInitData.SchemeData) Uri(android.net.Uri) DrmInitData(com.google.android.exoplayer2.drm.DrmInitData) Format(com.google.android.exoplayer2.Format) HashSet(java.util.HashSet) HlsTrackMetadataEntry(com.google.android.exoplayer2.source.hls.HlsTrackMetadataEntry) Variant(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant) Nullable(androidx.annotation.Nullable)

Example 15 with Assertions.checkState

use of com.google.android.exoplayer2.util.Assertions.checkState in project ExoPlayer by google.

the class FakeDataSource method read.

@Override
public final int read(byte[] buffer, int offset, int length) throws IOException {
    Assertions.checkState(sourceOpened);
    while (true) {
        FakeData fakeData = Util.castNonNull(this.fakeData);
        if (currentSegmentIndex == fakeData.getSegments().size() || bytesRemaining == 0) {
            return C.RESULT_END_OF_INPUT;
        }
        Segment current = fakeData.getSegments().get(currentSegmentIndex);
        if (current.isErrorSegment()) {
            if (!current.exceptionCleared) {
                current.exceptionThrown = true;
                throw (IOException) Util.castNonNull(current.exception).fillInStackTrace();
            } else {
                currentSegmentIndex++;
            }
        } else if (current.isActionSegment()) {
            currentSegmentIndex++;
            Util.castNonNull(current.action).run();
        } else {
            // Read at most bytesRemaining.
            length = (int) min(length, bytesRemaining);
            // Do not allow crossing of the segment boundary.
            length = min(length, current.length - current.bytesRead);
            // Perform the read and return.
            Assertions.checkArgument(buffer.length - offset >= length);
            if (current.data != null) {
                System.arraycopy(current.data, current.bytesRead, buffer, offset, length);
            }
            onDataRead(length);
            bytesTransferred(length);
            bytesRemaining -= length;
            current.bytesRead += length;
            if (current.bytesRead == current.length) {
                currentSegmentIndex++;
            }
            return length;
        }
    }
}
Also used : FakeData(com.google.android.exoplayer2.testutil.FakeDataSet.FakeData) IOException(java.io.IOException) Segment(com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment)

Aggregations

Nullable (androidx.annotation.Nullable)12 Format (com.google.android.exoplayer2.Format)4 Player (com.google.android.exoplayer2.Player)4 FormatHolder (com.google.android.exoplayer2.FormatHolder)3 Timeline (com.google.android.exoplayer2.Timeline)3 LoadEventInfo (com.google.android.exoplayer2.source.LoadEventInfo)3 ReadDataResult (com.google.android.exoplayer2.source.SampleStream.ReadDataResult)3 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)3 Segment (com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment)3 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)3 TrackSelection (com.google.android.exoplayer2.trackselection.TrackSelection)3 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)3 SuppressLint (android.annotation.SuppressLint)2 Uri (android.net.Uri)2 GLSurfaceView (android.opengl.GLSurfaceView)2 SurfaceView (android.view.SurfaceView)2 TextureView (android.view.TextureView)2 DecoderException (com.google.android.exoplayer2.decoder.DecoderException)2 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)2 Extractor (com.google.android.exoplayer2.extractor.Extractor)2