Call init() on the extractor only once for each chunk.

On retrying loading a chunk, the state of the extractor was reset due to a call
to seek(). Prevent this call by only calling init() if no bytes were loaded.

Also make the DefaultExtractorInput use the loading position not the original
stream position so that its getPosition() method returns offsets relative to
the start of the stream, which fixes a bug where the chunk index offsets would
be relative to the wrong position if there was a retry while loading the chunk.
This commit is contained in:
Oliver Woodman 2015-04-22 16:14:46 +01:00
parent 21e69f3154
commit a7e2b719c5
3 changed files with 16 additions and 19 deletions

View File

@ -19,7 +19,6 @@ import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.chunk.ChunkExtractorWrapper.SingleTrackOutput;
import com.google.android.exoplayer.drm.DrmInitData;
import com.google.android.exoplayer.extractor.DefaultExtractorInput;
import com.google.android.exoplayer.extractor.DefaultTrackOutput;
import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.SeekMap;
@ -83,12 +82,6 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
return bytesLoaded;
}
@Override
public void init(DefaultTrackOutput output) {
super.init(output);
extractorWrapper.init(this);
}
@Override
public MediaFormat getMediaFormat() {
return mediaFormat;
@ -149,10 +142,12 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded);
try {
// Create and open the input.
ExtractorInput input = new DefaultExtractorInput(dataSource, dataSpec.absoluteStreamPosition,
dataSource.open(loadDataSpec));
// Set the target to ourselves.
extractorWrapper.init(this);
ExtractorInput input = new DefaultExtractorInput(dataSource,
loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
if (bytesLoaded == 0) {
// Set the target to ourselves.
extractorWrapper.init(this);
}
// Load and parse the initialization data.
try {
int result = Extractor.RESULT_CONTINUE;
@ -160,7 +155,7 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
result = extractorWrapper.read(input);
}
} finally {
bytesLoaded += (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
}
} finally {
dataSource.close();

View File

@ -170,10 +170,12 @@ public final class InitializationChunk extends Chunk implements SingleTrackOutpu
DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded);
try {
// Create and open the input.
ExtractorInput input = new DefaultExtractorInput(dataSource, dataSpec.absoluteStreamPosition,
dataSource.open(loadDataSpec));
// Set the target to ourselves.
extractorWrapper.init(this);
ExtractorInput input = new DefaultExtractorInput(dataSource,
loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
if (bytesLoaded == 0) {
// Set the target to ourselves.
extractorWrapper.init(this);
}
// Load and parse the initialization data.
try {
int result = Extractor.RESULT_CONTINUE;
@ -181,7 +183,7 @@ public final class InitializationChunk extends Chunk implements SingleTrackOutpu
result = extractorWrapper.read(input);
}
} finally {
bytesLoaded += (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
}
} finally {
dataSource.close();

View File

@ -99,8 +99,8 @@ public final class TsChunk extends MediaChunk {
}
try {
ExtractorInput input = new DefaultExtractorInput(dataSource, dataSpec.absoluteStreamPosition,
dataSource.open(loadDataSpec));
ExtractorInput input = new DefaultExtractorInput(dataSource,
loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
if (skipLoadedBytes) {
input.skipFully(bytesLoaded);
}