/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer.chunk;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.parser.mp4.FragmentedMp4Extractor;
import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer.upstream.DataSpec;
import com.google.android.exoplayer.upstream.NonBlockingInputStream;
import com.google.android.exoplayer.util.Assertions;
import java.util.Map;
import java.util.UUID;
/**
* An Mp4 {@link MediaChunk}.
*/
public final class Mp4MediaChunk extends MediaChunk {
private final FragmentedMp4Extractor extractor;
private final long sampleOffsetUs;
/**
* @param dataSource A {@link DataSource} for loading the data.
* @param dataSpec Defines the data to be loaded.
* @param format The format of the stream to which this chunk belongs.
* @param extractor The extractor that will be used to extract the samples.
* @param trigger The reason for this chunk being selected.
* @param startTimeUs The start time of the media contained by the chunk, in microseconds.
* @param endTimeUs The end time of the media contained by the chunk, in microseconds.
* @param sampleOffsetUs An offset to subtract from the sample timestamps parsed by the extractor.
* @param nextChunkIndex The index of the next chunk, or -1 if this is the last chunk.
*/
public Mp4MediaChunk(DataSource dataSource, DataSpec dataSpec, Format format,
int trigger, FragmentedMp4Extractor extractor, long startTimeUs, long endTimeUs,
long sampleOffsetUs, int nextChunkIndex) {
super(dataSource, dataSpec, format, trigger, startTimeUs, endTimeUs, nextChunkIndex);
this.extractor = extractor;
this.sampleOffsetUs = sampleOffsetUs;
}
@Override
public boolean seekTo(long positionUs, boolean allowNoop) {
long seekTimeUs = positionUs + sampleOffsetUs;
boolean isDiscontinuous = extractor.seekTo(seekTimeUs, allowNoop);
if (isDiscontinuous) {
resetReadPosition();
}
return isDiscontinuous;
}
@Override
public boolean read(SampleHolder holder) throws ParserException {
NonBlockingInputStream inputStream = getNonBlockingInputStream();
Assertions.checkState(inputStream != null);
int result = extractor.read(inputStream, holder);
boolean sampleRead = (result & FragmentedMp4Extractor.RESULT_READ_SAMPLE_FULL) != 0;
if (sampleRead) {
holder.timeUs -= sampleOffsetUs;
}
return sampleRead;
}
@Override
public MediaFormat getMediaFormat() {
return extractor.getFormat();
}
@Override
public Map<UUID, byte[]> getPsshInfo() {
return extractor.getPsshInfo();
}
}