/** * Skips the current sample. */ public void skipSample() { long nextOffset = infoQueue.moveToNextSample(); dropDownstreamTo(nextOffset); }
/** * Attempts to skip to the keyframe before the specified time, if it's present in the buffer. * * @param timeUs The seek time. * @return True if the skip was successful. False otherwise. */ public boolean skipToKeyframeBefore(long timeUs) { long nextOffset = infoQueue.skipToKeyframeBefore(timeUs); if (nextOffset == -1) { return false; } dropDownstreamTo(nextOffset); return true; }
/** * Reads data from the front of the rolling buffer. * * @param absolutePosition The absolute position from which data should be read. * @param target The buffer into which data should be written. * @param length The number of bytes to read. */ private void readData(long absolutePosition, ByteBuffer target, int length) { int remaining = length; while (remaining > 0) { dropDownstreamTo(absolutePosition); int positionInAllocation = (int) (absolutePosition - totalBytesDropped); int toCopy = Math.min(remaining, allocationLength - positionInAllocation); Allocation allocation = dataQueue.peek(); target.put(allocation.data, allocation.translateOffset(positionInAllocation), toCopy); absolutePosition += toCopy; remaining -= toCopy; } }
/** * Reads data from the front of the rolling buffer. * * @param absolutePosition The absolute position from which data should be read. * @param target The array into which data should be written. * @param length The number of bytes to read. */ // TODO: Consider reducing duplication of this method and the one above. private void readData(long absolutePosition, byte[] target, int length) { int bytesRead = 0; while (bytesRead < length) { dropDownstreamTo(absolutePosition); int positionInAllocation = (int) (absolutePosition - totalBytesDropped); int toCopy = Math.min(length - bytesRead, allocationLength - positionInAllocation); Allocation allocation = dataQueue.peek(); System.arraycopy(allocation.data, allocation.translateOffset(positionInAllocation), target, bytesRead, toCopy); absolutePosition += toCopy; bytesRead += toCopy; } }
/** * Reads the current sample, advancing the read index to the next sample. * * @param sampleHolder The holder into which the current sample should be written. * @return True if a sample was read. False if there is no current sample. */ public boolean readSample(SampleHolder sampleHolder) { // Write the sample information into the holder and extrasHolder. boolean haveSample = infoQueue.peekSample(sampleHolder, extrasHolder); if (!haveSample) { return false; } // Read encryption data if the sample is encrypted. if (sampleHolder.isEncrypted()) { readEncryptionData(sampleHolder, extrasHolder); } // Write the sample data into the holder. if (sampleHolder.data == null || sampleHolder.data.capacity() < sampleHolder.size) { sampleHolder.replaceBuffer(sampleHolder.size); } if (sampleHolder.data != null) { readData(extrasHolder.offset, sampleHolder.data, sampleHolder.size); } // Advance the read head. long nextOffset = infoQueue.moveToNextSample(); dropDownstreamTo(nextOffset); return true; }