Commit e9399f86 by Daniel Santiago Committed by Daniel Santiago-Rivera

Added flags to the mp3 extractor to control behavior of the extractor. Added…

Added flags to the mp3 extractor to control behavior of the extractor. Added FLAG_ENABLE_CONSTANT_BITRATE_SEEKING to let the extractor know that the CBR seeker is desired in the case where the seeker has determine the track is not seekable For example, in the case where the track has a Xing Header but no content table.
parent c3d7eecd
...@@ -31,8 +31,13 @@ import com.google.android.exoplayer2.metadata.Metadata; ...@@ -31,8 +31,13 @@ import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.id3.Id3Decoder; import com.google.android.exoplayer2.metadata.id3.Id3Decoder;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import android.support.annotation.IntDef;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Extracts data from an MP3 file. * Extracts data from an MP3 file.
...@@ -52,6 +57,19 @@ public final class Mp3Extractor implements Extractor { ...@@ -52,6 +57,19 @@ public final class Mp3Extractor implements Extractor {
}; };
/** /**
* Flags controlling the behavior of the extractor.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {FLAG_ENABLE_CONSTANT_BITRATE_SEEKING})
public @interface Flags {}
/**
* Flag to force enable seeking using a constant bitrate assumption in cases where seeking would
* otherwise not be possible.
*/
public static final int FLAG_ENABLE_CONSTANT_BITRATE_SEEKING = 1;
/**
* The maximum number of bytes to search when synchronizing, before giving up. * The maximum number of bytes to search when synchronizing, before giving up.
*/ */
private static final int MAX_SYNC_BYTES = 128 * 1024; private static final int MAX_SYNC_BYTES = 128 * 1024;
...@@ -72,6 +90,9 @@ public final class Mp3Extractor implements Extractor { ...@@ -72,6 +90,9 @@ public final class Mp3Extractor implements Extractor {
private static final int INFO_HEADER = Util.getIntegerCodeForString("Info"); private static final int INFO_HEADER = Util.getIntegerCodeForString("Info");
private static final int VBRI_HEADER = Util.getIntegerCodeForString("VBRI"); private static final int VBRI_HEADER = Util.getIntegerCodeForString("VBRI");
@Flags
private final int flags;
private final long forcedFirstSampleTimestampUs; private final long forcedFirstSampleTimestampUs;
private final ParsableByteArray scratch; private final ParsableByteArray scratch;
private final MpegAudioHeader synchronizedHeader; private final MpegAudioHeader synchronizedHeader;
...@@ -93,16 +114,27 @@ public final class Mp3Extractor implements Extractor { ...@@ -93,16 +114,27 @@ public final class Mp3Extractor implements Extractor {
* Constructs a new {@link Mp3Extractor}. * Constructs a new {@link Mp3Extractor}.
*/ */
public Mp3Extractor() { public Mp3Extractor() {
this(C.TIME_UNSET); this(0);
}
/**
* Constructs a new {@link Mp3Extractor}.
*
* @param flags Flags that control the extractor's behavior.
*/
public Mp3Extractor(@Flags int flags) {
this(flags, C.TIME_UNSET);
} }
/** /**
* Constructs a new {@link Mp3Extractor}. * Constructs a new {@link Mp3Extractor}.
* *
* @param flags Flags that control the extractor's behavior.
* @param forcedFirstSampleTimestampUs A timestamp to force for the first sample, or * @param forcedFirstSampleTimestampUs A timestamp to force for the first sample, or
* {@link C#TIME_UNSET} if forcing is not required. * {@link C#TIME_UNSET} if forcing is not required.
*/ */
public Mp3Extractor(long forcedFirstSampleTimestampUs) { public Mp3Extractor(@Flags int flags, long forcedFirstSampleTimestampUs) {
this.flags = flags;
this.forcedFirstSampleTimestampUs = forcedFirstSampleTimestampUs; this.forcedFirstSampleTimestampUs = forcedFirstSampleTimestampUs;
scratch = new ParsableByteArray(SCRATCH_LENGTH); scratch = new ParsableByteArray(SCRATCH_LENGTH);
synchronizedHeader = new MpegAudioHeader(); synchronizedHeader = new MpegAudioHeader();
...@@ -350,7 +382,8 @@ public final class Mp3Extractor implements Extractor { ...@@ -350,7 +382,8 @@ public final class Mp3Extractor implements Extractor {
} }
} }
if (seeker == null) { if (seeker == null || (!seeker.isSeekable()
&& (flags & FLAG_ENABLE_CONSTANT_BITRATE_SEEKING) != 0)) {
// Repopulate the synchronized header in case we had to skip an invalid seeking header, which // Repopulate the synchronized header in case we had to skip an invalid seeking header, which
// would give an invalid CBR bitrate. // would give an invalid CBR bitrate.
input.resetPeekPosition(); input.resetPeekPosition();
......
...@@ -379,7 +379,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -379,7 +379,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|| lastPathSegment.endsWith(EC3_FILE_EXTENSION)) { || lastPathSegment.endsWith(EC3_FILE_EXTENSION)) {
extractor = new Ac3Extractor(startTimeUs); extractor = new Ac3Extractor(startTimeUs);
} else if (lastPathSegment.endsWith(MP3_FILE_EXTENSION)) { } else if (lastPathSegment.endsWith(MP3_FILE_EXTENSION)) {
extractor = new Mp3Extractor(startTimeUs); extractor = new Mp3Extractor(0, startTimeUs);
} else { } else {
throw new IllegalArgumentException("Unkown extension for audio file: " + lastPathSegment); throw new IllegalArgumentException("Unkown extension for audio file: " + lastPathSegment);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment