本文整理汇总了Java中com.google.android.exoplayer2.extractor.ExtractorInput.resetPeekPosition方法的典型用法代码示例。如果您正苦于以下问题:Java ExtractorInput.resetPeekPosition方法的具体用法?Java ExtractorInput.resetPeekPosition怎么用?Java ExtractorInput.resetPeekPosition使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类com.google.android.exoplayer2.extractor.ExtractorInput
的用法示例。
在下文中一共展示了ExtractorInput.resetPeekPosition方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Java代码示例。
示例1: maybeResyncToNextLevel1Element
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Does a byte by byte search to try and find the next level 1 element. This method is called if
* some invalid data is encountered in the parser.
*
* @param input The {@link ExtractorInput} from which data has to be read.
* @return id of the next level 1 element that has been found.
* @throws EOFException If the end of input was encountered when searching for the next level 1
* element.
* @throws IOException If an error occurs reading from the input.
* @throws InterruptedException If the thread is interrupted.
*/
private long maybeResyncToNextLevel1Element(ExtractorInput input) throws IOException,
InterruptedException {
input.resetPeekPosition();
while (true) {
input.peekFully(scratch, 0, MAX_ID_BYTES);
int varintLength = VarintReader.parseUnsignedVarintLength(scratch[0]);
if (varintLength != C.LENGTH_UNSET && varintLength <= MAX_ID_BYTES) {
int potentialId = (int) VarintReader.assembleVarint(scratch, varintLength, false);
if (output.isLevel1Element(potentialId)) {
input.skipFully(varintLength);
return potentialId;
}
}
input.skipFully(1);
}
}
示例2: skipToData
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Skips to the data in the given WAV input stream and returns its data size. After calling, the
* input stream's position will point to the start of sample data in the WAV.
* <p>
* If an exception is thrown, the input position will be left pointing to a chunk header.
*
* @param input Input stream to skip to the data chunk in. Its peek position must be pointing to
* a valid chunk header.
* @param wavHeader WAV header to populate with data bounds.
* @throws ParserException If an error occurs parsing chunks.
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from input.
*/
public static void skipToData(ExtractorInput input, WavHeader wavHeader)
throws IOException, InterruptedException {
Assertions.checkNotNull(input);
Assertions.checkNotNull(wavHeader);
// Make sure the peek position is set to the read position before we peek the first header.
input.resetPeekPosition();
ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
// Skip all chunks until we hit the data header.
ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
while (chunkHeader.id != Util.getIntegerCodeForString("data")) {
Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
// Override size of RIFF chunk, since it describes its size as the entire file.
if (chunkHeader.id == Util.getIntegerCodeForString("RIFF")) {
bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
}
if (bytesToSkip > Integer.MAX_VALUE) {
throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
}
input.skipFully((int) bytesToSkip);
chunkHeader = ChunkHeader.peek(input, scratch);
}
// Skip past the "data" header.
input.skipFully(ChunkHeader.SIZE_IN_BYTES);
wavHeader.setDataBounds(input.getPosition(), chunkHeader.size);
}
示例3: skipToPageOfGranule
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Skips to the position of the start of the page containing the {@code targetGranule} and
* returns the granule of the page previous to the target page.
*
* @param input the {@link ExtractorInput} to read from.
* @param targetGranule the target granule.
* @param currentGranule the current granule or -1 if it's unknown.
* @return the granule of the prior page or the {@code currentGranule} if there isn't a prior
* page.
* @throws ParserException thrown if populating the page header fails.
* @throws IOException thrown if reading from the input fails.
* @throws InterruptedException thrown if interrupted while reading from the input.
*/
//@VisibleForTesting
long skipToPageOfGranule(ExtractorInput input, long targetGranule, long currentGranule)
throws IOException, InterruptedException {
pageHeader.populate(input, false);
while (pageHeader.granulePosition < targetGranule) {
input.skipFully(pageHeader.headerSize + pageHeader.bodySize);
// Store in a member field to be able to resume after IOExceptions.
currentGranule = pageHeader.granulePosition;
// Peek next header.
pageHeader.populate(input, false);
}
input.resetPeekPosition();
return currentGranule;
}
示例4: sniff
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
@Override
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
// Check if file starts with "FLV" tag
input.peekFully(scratch.data, 0, 3);
scratch.setPosition(0);
if (scratch.readUnsignedInt24() != FLV_TAG) {
return false;
}
// Checking reserved flags are set to 0
input.peekFully(scratch.data, 0, 2);
scratch.setPosition(0);
if ((scratch.readUnsignedShort() & 0xFA) != 0) {
return false;
}
// Read data offset
input.peekFully(scratch.data, 0, 4);
scratch.setPosition(0);
int dataOffset = scratch.readInt();
input.resetPeekPosition();
input.advancePeekPosition(dataOffset);
// Checking first "previous tag size" is set to 0
input.peekFully(scratch.data, 0, 4);
scratch.setPosition(0);
return scratch.readInt() == 0;
}
示例5: readSample
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
private int readSample(ExtractorInput extractorInput) throws IOException, InterruptedException {
if (sampleBytesRemaining == 0) {
extractorInput.resetPeekPosition();
if (!extractorInput.peekFully(scratch.data, 0, 4, true)) {
return RESULT_END_OF_INPUT;
}
scratch.setPosition(0);
int sampleHeaderData = scratch.readInt();
if ((sampleHeaderData & HEADER_MASK) != (synchronizedHeaderData & HEADER_MASK)
|| MpegAudioHeader.getFrameSize(sampleHeaderData) == C.LENGTH_UNSET) {
// We have lost synchronization, so attempt to resynchronize starting at the next byte.
extractorInput.skipFully(1);
synchronizedHeaderData = 0;
return RESULT_CONTINUE;
}
MpegAudioHeader.populateHeader(sampleHeaderData, synchronizedHeader);
if (basisTimeUs == C.TIME_UNSET) {
basisTimeUs = seeker.getTimeUs(extractorInput.getPosition());
if (forcedFirstSampleTimestampUs != C.TIME_UNSET) {
long embeddedFirstSampleTimestampUs = seeker.getTimeUs(0);
basisTimeUs += forcedFirstSampleTimestampUs - embeddedFirstSampleTimestampUs;
}
}
sampleBytesRemaining = synchronizedHeader.frameSize;
}
int bytesAppended = trackOutput.sampleData(extractorInput, sampleBytesRemaining, true);
if (bytesAppended == C.RESULT_END_OF_INPUT) {
return RESULT_END_OF_INPUT;
}
sampleBytesRemaining -= bytesAppended;
if (sampleBytesRemaining > 0) {
return RESULT_CONTINUE;
}
long timeUs = basisTimeUs + (samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate);
trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, synchronizedHeader.frameSize, 0,
null);
samplesRead += synchronizedHeader.samplesPerFrame;
sampleBytesRemaining = 0;
return RESULT_CONTINUE;
}
示例6: peekId3Data
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Peeks ID3 data from the input, including gapless playback information.
*
* @param input The {@link ExtractorInput} from which data should be peeked.
* @throws IOException If an error occurred peeking from the input.
* @throws InterruptedException If the thread was interrupted.
*/
private void peekId3Data(ExtractorInput input) throws IOException, InterruptedException {
int peekedId3Bytes = 0;
while (true) {
input.peekFully(scratch.data, 0, Id3Decoder.ID3_HEADER_LENGTH);
scratch.setPosition(0);
if (scratch.readUnsignedInt24() != Id3Decoder.ID3_TAG) {
// Not an ID3 tag.
break;
}
scratch.skipBytes(3); // Skip major version, minor version and flags.
int framesLength = scratch.readSynchSafeInt();
int tagLength = Id3Decoder.ID3_HEADER_LENGTH + framesLength;
if (metadata == null) {
byte[] id3Data = new byte[tagLength];
System.arraycopy(scratch.data, 0, id3Data, 0, Id3Decoder.ID3_HEADER_LENGTH);
input.peekFully(id3Data, Id3Decoder.ID3_HEADER_LENGTH, framesLength);
// We need to parse enough ID3 metadata to retrieve any gapless playback information even
// if ID3 metadata parsing is disabled.
Id3Decoder.FramePredicate id3FramePredicate = (flags & FLAG_DISABLE_ID3_METADATA) != 0
? GaplessInfoHolder.GAPLESS_INFO_ID3_FRAME_PREDICATE : null;
metadata = new Id3Decoder(id3FramePredicate).decode(id3Data, tagLength);
if (metadata != null) {
gaplessInfoHolder.setFromMetadata(metadata);
}
} else {
input.advancePeekPosition(framesLength);
}
peekedId3Bytes += tagLength;
}
input.resetPeekPosition();
input.advancePeekPosition(peekedId3Bytes);
}
示例7: skipToPageOfGranule
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
private void skipToPageOfGranule(ExtractorInput input, long granule,
long elapsedSamplesExpected) throws IOException, InterruptedException {
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader());
while (true) {
try {
assertEquals(elapsedSamplesExpected, oggSeeker.skipToPageOfGranule(input, granule, -1));
return;
} catch (FakeExtractorInput.SimulatedIOException e) {
input.resetPeekPosition();
}
}
}
示例8: parseId3
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Peeks data from the input and parses ID3 metadata.
*
* @param input The {@link ExtractorInput} from which data should be peeked.
* @param out The {@link GaplessInfoHolder} to populate.
* @throws IOException If an error occurred peeking from the input.
* @throws InterruptedException If the thread was interrupted.
*/
public static void parseId3(ExtractorInput input, GaplessInfoHolder out)
throws IOException, InterruptedException {
ParsableByteArray scratch = new ParsableByteArray(10);
int peekedId3Bytes = 0;
while (true) {
input.peekFully(scratch.data, 0, 10);
scratch.setPosition(0);
if (scratch.readUnsignedInt24() != ID3_TAG) {
break;
}
int majorVersion = scratch.readUnsignedByte();
int minorVersion = scratch.readUnsignedByte();
int flags = scratch.readUnsignedByte();
int length = scratch.readSynchSafeInt();
if (!out.hasGaplessInfo() && canParseMetadata(majorVersion, minorVersion, flags, length)) {
byte[] frame = new byte[length];
input.peekFully(frame, 0, length);
parseGaplessInfo(new ParsableByteArray(frame), majorVersion, flags, out);
} else {
input.advancePeekPosition(length);
}
peekedId3Bytes += 10 + length;
}
input.resetPeekPosition();
input.advancePeekPosition(peekedId3Bytes);
}
示例9: sniff
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
@Override
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
// Skip any ID3 headers.
ParsableByteArray scratch = new ParsableByteArray(10);
ParsableBitArray scratchBits = new ParsableBitArray(scratch.data);
int startPosition = 0;
while (true) {
input.peekFully(scratch.data, 0, 10);
scratch.setPosition(0);
if (scratch.readUnsignedInt24() != ID3_TAG) {
break;
}
scratch.skipBytes(3);
int length = scratch.readSynchSafeInt();
startPosition += 10 + length;
input.advancePeekPosition(length);
}
input.resetPeekPosition();
input.advancePeekPosition(startPosition);
// Try to find four or more consecutive AAC audio frames, exceeding the MPEG TS packet size.
int headerPosition = startPosition;
int validFramesSize = 0;
int validFramesCount = 0;
while (true) {
input.peekFully(scratch.data, 0, 2);
scratch.setPosition(0);
int syncBytes = scratch.readUnsignedShort();
if ((syncBytes & 0xFFF6) != 0xFFF0) {
validFramesCount = 0;
validFramesSize = 0;
input.resetPeekPosition();
if (++headerPosition - startPosition >= MAX_SNIFF_BYTES) {
return false;
}
input.advancePeekPosition(headerPosition);
} else {
if (++validFramesCount >= 4 && validFramesSize > 188) {
return true;
}
// Skip the frame.
input.peekFully(scratch.data, 0, 4);
scratchBits.setPosition(14);
int frameSize = scratchBits.readBits(13);
// Either the stream is malformed OR we're not parsing an ADTS stream.
if (frameSize <= 6) {
return false;
}
input.advancePeekPosition(frameSize - 6);
validFramesSize += frameSize;
}
}
}
示例10: sniff
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
@Override
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
// Skip any ID3 headers.
ParsableByteArray scratch = new ParsableByteArray(10);
int startPosition = 0;
while (true) {
input.peekFully(scratch.data, 0, 10);
scratch.setPosition(0);
if (scratch.readUnsignedInt24() != ID3_TAG) {
break;
}
scratch.skipBytes(3);
int length = scratch.readSynchSafeInt();
startPosition += 10 + length;
input.advancePeekPosition(length);
}
input.resetPeekPosition();
input.advancePeekPosition(startPosition);
int headerPosition = startPosition;
int validFramesCount = 0;
while (true) {
input.peekFully(scratch.data, 0, 5);
scratch.setPosition(0);
int syncBytes = scratch.readUnsignedShort();
if (syncBytes != AC3_SYNC_WORD) {
validFramesCount = 0;
input.resetPeekPosition();
if (++headerPosition - startPosition >= MAX_SNIFF_BYTES) {
return false;
}
input.advancePeekPosition(headerPosition);
} else {
if (++validFramesCount >= 4) {
return true;
}
int frameSize = Ac3Util.parseAc3SyncframeSize(scratch.data);
if (frameSize == C.LENGTH_UNSET) {
return false;
}
input.advancePeekPosition(frameSize - 5);
}
}
}
示例11: getNextSeekPosition
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Returns a position converging to the {@code targetGranule} to which the {@link ExtractorInput}
* has to seek and then be passed for another call until a negative number is returned. If a
* negative number is returned the input is at a position which is before the target page and at
* which it is sensible to just skip pages to the target granule and pre-roll instead of doing
* another seek request.
*
* @param targetGranule the target granule position to seek to.
* @param input the {@link ExtractorInput} to read from.
* @return the position to seek the {@link ExtractorInput} to for a next call or
* -(currentGranule + 2) if it's close enough to skip to the target page.
* @throws IOException thrown if reading from the input fails.
* @throws InterruptedException thrown if interrupted while reading from the input.
*/
//@VisibleForTesting
public long getNextSeekPosition(long targetGranule, ExtractorInput input)
throws IOException, InterruptedException {
if (start == end) {
return -(startGranule + 2);
}
long initialPosition = input.getPosition();
if (!skipToNextPage(input, end)) {
if (start == initialPosition) {
throw new IOException("No ogg page can be found.");
}
return start;
}
pageHeader.populate(input, false);
input.resetPeekPosition();
long granuleDistance = targetGranule - pageHeader.granulePosition;
int pageSize = pageHeader.headerSize + pageHeader.bodySize;
if (granuleDistance < 0 || granuleDistance > MATCH_RANGE) {
if (granuleDistance < 0) {
end = initialPosition;
endGranule = pageHeader.granulePosition;
} else {
start = input.getPosition() + pageSize;
startGranule = pageHeader.granulePosition;
if (end - start + pageSize < MATCH_BYTE_RANGE) {
input.skipFully(pageSize);
return -(startGranule + 2);
}
}
if (end - start < MATCH_BYTE_RANGE) {
end = start;
return start;
}
long offset = pageSize * (granuleDistance <= 0 ? 2 : 1);
long nextPosition = input.getPosition() - offset
+ (granuleDistance * (end - start) / (endGranule - startGranule));
nextPosition = Math.max(nextPosition, start);
nextPosition = Math.min(nextPosition, end - 1);
return nextPosition;
}
// position accepted (before target granule and within MATCH_RANGE)
input.skipFully(pageSize);
return -(pageHeader.granulePosition + 2);
}
示例12: synchronize
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
private boolean synchronize(ExtractorInput input, boolean sniffing)
throws IOException, InterruptedException {
int validFrameCount = 0;
int candidateSynchronizedHeaderData = 0;
int peekedId3Bytes = 0;
int searchedBytes = 0;
int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
input.resetPeekPosition();
if (input.getPosition() == 0) {
peekId3Data(input);
peekedId3Bytes = (int) input.getPeekPosition();
if (!sniffing) {
input.skipFully(peekedId3Bytes);
}
}
while (true) {
if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
// We reached the end of the stream but found at least one valid frame.
break;
}
scratch.setPosition(0);
int headerData = scratch.readInt();
int frameSize;
if ((candidateSynchronizedHeaderData != 0
&& (headerData & HEADER_MASK) != (candidateSynchronizedHeaderData & HEADER_MASK))
|| (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
// The header doesn't match the candidate header or is invalid. Try the next byte offset.
if (searchedBytes++ == searchLimitBytes) {
if (!sniffing) {
throw new ParserException("Searched too many bytes.");
}
return false;
}
validFrameCount = 0;
candidateSynchronizedHeaderData = 0;
if (sniffing) {
input.resetPeekPosition();
input.advancePeekPosition(peekedId3Bytes + searchedBytes);
} else {
input.skipFully(1);
}
} else {
// The header matches the candidate header and/or is valid.
validFrameCount++;
if (validFrameCount == 1) {
MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
candidateSynchronizedHeaderData = headerData;
} else if (validFrameCount == 4) {
break;
}
input.advancePeekPosition(frameSize - 4);
}
}
// Prepare to read the synchronized frame.
if (sniffing) {
input.skipFully(peekedId3Bytes + searchedBytes);
} else {
input.resetPeekPosition();
}
synchronizedHeaderData = candidateSynchronizedHeaderData;
return true;
}
示例13: setupSeeker
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
/**
* Returns a {@link Seeker} to seek using metadata read from {@code input}, which should provide
* data from the start of the first frame in the stream. On returning, the input's position will
* be set to the start of the first frame of audio.
*
* @param input The {@link ExtractorInput} from which to read.
* @throws IOException Thrown if there was an error reading from the stream. Not expected if the
* next two frames were already peeked during synchronization.
* @throws InterruptedException Thrown if reading from the stream was interrupted. Not expected if
* the next two frames were already peeked during synchronization.
* @return a {@link Seeker}.
*/
private Seeker setupSeeker(ExtractorInput input) throws IOException, InterruptedException {
// Read the first frame which may contain a Xing or VBRI header with seeking metadata.
ParsableByteArray frame = new ParsableByteArray(synchronizedHeader.frameSize);
input.peekFully(frame.data, 0, synchronizedHeader.frameSize);
long position = input.getPosition();
long length = input.getLength();
int headerData = 0;
Seeker seeker = null;
// Check if there is a Xing header.
int xingBase = (synchronizedHeader.version & 1) != 0
? (synchronizedHeader.channels != 1 ? 36 : 21) // MPEG 1
: (synchronizedHeader.channels != 1 ? 21 : 13); // MPEG 2 or 2.5
if (frame.limit() >= xingBase + 4) {
frame.setPosition(xingBase);
headerData = frame.readInt();
}
if (headerData == XING_HEADER || headerData == INFO_HEADER) {
seeker = XingSeeker.create(synchronizedHeader, frame, position, length);
if (seeker != null && !gaplessInfoHolder.hasGaplessInfo()) {
// If there is a Xing header, read gapless playback metadata at a fixed offset.
input.resetPeekPosition();
input.advancePeekPosition(xingBase + 141);
input.peekFully(scratch.data, 0, 3);
scratch.setPosition(0);
gaplessInfoHolder.setFromXingHeaderValue(scratch.readUnsignedInt24());
}
input.skipFully(synchronizedHeader.frameSize);
} else if (frame.limit() >= 40) {
// Check if there is a VBRI header.
frame.setPosition(36); // MPEG audio header (4 bytes) + 32 bytes.
headerData = frame.readInt();
if (headerData == VBRI_HEADER) {
seeker = VbriSeeker.create(synchronizedHeader, frame, position, length);
input.skipFully(synchronizedHeader.frameSize);
}
}
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
// would give an invalid CBR bitrate.
input.resetPeekPosition();
input.peekFully(scratch.data, 0, 4);
scratch.setPosition(0);
MpegAudioHeader.populateHeader(scratch.readInt(), synchronizedHeader);
seeker = new ConstantBitrateSeeker(input.getPosition(), synchronizedHeader.bitrate, length);
}
return seeker;
}
示例14: synchronize
import com.google.android.exoplayer2.extractor.ExtractorInput; //导入方法依赖的package包/类
private boolean synchronize(ExtractorInput input, boolean sniffing)
throws IOException, InterruptedException {
int validFrameCount = 0;
int candidateSynchronizedHeaderData = 0;
int peekedId3Bytes = 0;
int searchedBytes = 0;
int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
input.resetPeekPosition();
if (input.getPosition() == 0) {
Id3Util.parseId3(input, gaplessInfoHolder);
peekedId3Bytes = (int) input.getPeekPosition();
if (!sniffing) {
input.skipFully(peekedId3Bytes);
}
}
while (true) {
if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
// We reached the end of the stream but found at least one valid frame.
break;
}
scratch.setPosition(0);
int headerData = scratch.readInt();
int frameSize;
if ((candidateSynchronizedHeaderData != 0
&& (headerData & HEADER_MASK) != (candidateSynchronizedHeaderData & HEADER_MASK))
|| (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
// The header doesn't match the candidate header or is invalid. Try the next byte offset.
if (searchedBytes++ == searchLimitBytes) {
if (!sniffing) {
throw new ParserException("Searched too many bytes.");
}
return false;
}
validFrameCount = 0;
candidateSynchronizedHeaderData = 0;
if (sniffing) {
input.resetPeekPosition();
input.advancePeekPosition(peekedId3Bytes + searchedBytes);
} else {
input.skipFully(1);
}
} else {
// The header matches the candidate header and/or is valid.
validFrameCount++;
if (validFrameCount == 1) {
MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
candidateSynchronizedHeaderData = headerData;
} else if (validFrameCount == 4) {
break;
}
input.advancePeekPosition(frameSize - 4);
}
}
// Prepare to read the synchronized frame.
if (sniffing) {
input.skipFully(peekedId3Bytes + searchedBytes);
} else {
input.resetPeekPosition();
}
synchronizedHeaderData = candidateSynchronizedHeaderData;
return true;
}