Search in sources :

Example 1 with TrueHdSampleRechunker

use of com.google.android.exoplayer2.extractor.TrueHdSampleRechunker in project ExoPlayer by google.

the class Mp4Extractor method readSample.

/**
 * Attempts to extract the next sample in the current mdat atom for the specified track.
 *
 * <p>Returns {@link #RESULT_SEEK} if the source should be reloaded from the position in {@code
 * positionHolder}.
 *
 * <p>Returns {@link #RESULT_END_OF_INPUT} if no samples are left. Otherwise, returns {@link
 * #RESULT_CONTINUE}.
 *
 * @param input The {@link ExtractorInput} from which to read data.
 * @param positionHolder If {@link #RESULT_SEEK} is returned, this holder is updated to hold the
 *     position of the required data.
 * @return One of the {@code RESULT_*} flags in {@link Extractor}.
 * @throws IOException If an error occurs reading from the input.
 */
private int readSample(ExtractorInput input, PositionHolder positionHolder) throws IOException {
    long inputPosition = input.getPosition();
    if (sampleTrackIndex == C.INDEX_UNSET) {
        sampleTrackIndex = getTrackIndexOfNextReadSample(inputPosition);
        if (sampleTrackIndex == C.INDEX_UNSET) {
            return RESULT_END_OF_INPUT;
        }
    }
    Mp4Track track = castNonNull(tracks)[sampleTrackIndex];
    TrackOutput trackOutput = track.trackOutput;
    int sampleIndex = track.sampleIndex;
    long position = track.sampleTable.offsets[sampleIndex];
    int sampleSize = track.sampleTable.sizes[sampleIndex];
    @Nullable TrueHdSampleRechunker trueHdSampleRechunker = track.trueHdSampleRechunker;
    long skipAmount = position - inputPosition + sampleBytesRead;
    if (skipAmount < 0 || skipAmount >= RELOAD_MINIMUM_SEEK_DISTANCE) {
        positionHolder.position = position;
        return RESULT_SEEK;
    }
    if (track.track.sampleTransformation == Track.TRANSFORMATION_CEA608_CDAT) {
        // The sample information is contained in a cdat atom. The header must be discarded for
        // committing.
        skipAmount += Atom.HEADER_SIZE;
        sampleSize -= Atom.HEADER_SIZE;
    }
    input.skipFully((int) skipAmount);
    if (track.track.nalUnitLengthFieldLength != 0) {
        // Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
        // they're only 1 or 2 bytes long.
        byte[] nalLengthData = nalLength.getData();
        nalLengthData[0] = 0;
        nalLengthData[1] = 0;
        nalLengthData[2] = 0;
        int nalUnitLengthFieldLength = track.track.nalUnitLengthFieldLength;
        int nalUnitLengthFieldLengthDiff = 4 - track.track.nalUnitLengthFieldLength;
        // start codes as we encounter them.
        while (sampleBytesWritten < sampleSize) {
            if (sampleCurrentNalBytesRemaining == 0) {
                // Read the NAL length so that we know where we find the next one.
                input.readFully(nalLengthData, nalUnitLengthFieldLengthDiff, nalUnitLengthFieldLength);
                sampleBytesRead += nalUnitLengthFieldLength;
                nalLength.setPosition(0);
                int nalLengthInt = nalLength.readInt();
                if (nalLengthInt < 0) {
                    throw ParserException.createForMalformedContainer("Invalid NAL length", /* cause= */
                    null);
                }
                sampleCurrentNalBytesRemaining = nalLengthInt;
                // Write a start code for the current NAL unit.
                nalStartCode.setPosition(0);
                trackOutput.sampleData(nalStartCode, 4);
                sampleBytesWritten += 4;
                sampleSize += nalUnitLengthFieldLengthDiff;
            } else {
                // Write the payload of the NAL unit.
                int writtenBytes = trackOutput.sampleData(input, sampleCurrentNalBytesRemaining, false);
                sampleBytesRead += writtenBytes;
                sampleBytesWritten += writtenBytes;
                sampleCurrentNalBytesRemaining -= writtenBytes;
            }
        }
    } else {
        if (MimeTypes.AUDIO_AC4.equals(track.track.format.sampleMimeType)) {
            if (sampleBytesWritten == 0) {
                Ac4Util.getAc4SampleHeader(sampleSize, scratch);
                trackOutput.sampleData(scratch, Ac4Util.SAMPLE_HEADER_SIZE);
                sampleBytesWritten += Ac4Util.SAMPLE_HEADER_SIZE;
            }
            sampleSize += Ac4Util.SAMPLE_HEADER_SIZE;
        } else if (trueHdSampleRechunker != null) {
            trueHdSampleRechunker.startSample(input);
        }
        while (sampleBytesWritten < sampleSize) {
            int writtenBytes = trackOutput.sampleData(input, sampleSize - sampleBytesWritten, false);
            sampleBytesRead += writtenBytes;
            sampleBytesWritten += writtenBytes;
            sampleCurrentNalBytesRemaining -= writtenBytes;
        }
    }
    long timeUs = track.sampleTable.timestampsUs[sampleIndex];
    @C.BufferFlags int flags = track.sampleTable.flags[sampleIndex];
    if (trueHdSampleRechunker != null) {
        trueHdSampleRechunker.sampleMetadata(trackOutput, timeUs, flags, sampleSize, /* offset= */
        0, /* cryptoData= */
        null);
        if (sampleIndex + 1 == track.sampleTable.sampleCount) {
            trueHdSampleRechunker.outputPendingSampleMetadata(trackOutput, /* cryptoData= */
            null);
        }
    } else {
        trackOutput.sampleMetadata(timeUs, flags, sampleSize, /* offset= */
        0, /* cryptoData= */
        null);
    }
    track.sampleIndex++;
    sampleTrackIndex = C.INDEX_UNSET;
    sampleBytesRead = 0;
    sampleBytesWritten = 0;
    sampleCurrentNalBytesRemaining = 0;
    return RESULT_CONTINUE;
}
Also used : TrueHdSampleRechunker(com.google.android.exoplayer2.extractor.TrueHdSampleRechunker) TrackOutput(com.google.android.exoplayer2.extractor.TrackOutput) SeekPoint(com.google.android.exoplayer2.extractor.SeekPoint) Nullable(androidx.annotation.Nullable)

Aggregations

Nullable (androidx.annotation.Nullable)1 SeekPoint (com.google.android.exoplayer2.extractor.SeekPoint)1 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)1 TrueHdSampleRechunker (com.google.android.exoplayer2.extractor.TrueHdSampleRechunker)1