Skip to content

Commit

Permalink
Workaround for TS seeking
Browse files Browse the repository at this point in the history
- Increase the search window size to fix TS seeking for problematic
  media we've had provided to us.
- As per my comments on the issue, we should look at doing more here
  to better fix the problem. This will solve the worst of the
  immediate problem, however.
- The memory usage is non-trivial, particularly with the increased
  search window size. I've made the allocations only live whilst
  determining duration and seeking to address this. I've done the same
  for PS just for consistency.

Issue: #5097

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=221449988
  • Loading branch information
ojw28 committed Nov 27, 2018
1 parent 84fc244 commit c08edc5
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 34 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### 2.9.2 ###

* Support seeking for a wider range of MPEG-TS streams
([#5097](https://github.com/google/ExoPlayer/issues/5097)).
* DASH: Fix detecting the end of live events
([#4780](https://github.com/google/ExoPlayer/issues/4780)).
* Include channel count in audio capabilities check
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ protected interface TimestampSeeker {
TimestampSearchResult searchForTimestamp(
ExtractorInput input, long targetTimestamp, OutputFrameHolder outputFrameHolder)
throws IOException, InterruptedException;

/** Called when a seek operation finishes. */
default void onSeekFinished() {}
}

/**
Expand Down Expand Up @@ -255,6 +258,7 @@ protected SeekOperationParams createSeekParamsForTargetTimeUs(long timeUs) {

protected final void markSeekOperationFinished(boolean foundTargetFrame, long resultPosition) {
seekOperationParams = null;
timestampSeeker.onSeekFinished();
onSeekOperationFinished(foundTargetFrame, resultPosition);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;

/**
Expand Down Expand Up @@ -64,7 +65,7 @@ private static final class PsScrSeeker implements TimestampSeeker {

private PsScrSeeker(TimestampAdjuster scrTimestampAdjuster) {
this.scrTimestampAdjuster = scrTimestampAdjuster;
packetBuffer = new ParsableByteArray(TIMESTAMP_SEARCH_BYTES);
packetBuffer = new ParsableByteArray();
}

@Override
Expand All @@ -74,12 +75,17 @@ public TimestampSearchResult searchForTimestamp(
long inputPosition = input.getPosition();
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);

input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);

return searchForScrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
}

@Override
public void onSeekFinished() {
packetBuffer.reset(Util.EMPTY_BYTE_ARRAY);
}

private TimestampSearchResult searchForScrValueInBuffer(
ParsableByteArray packetBuffer, long targetScrTimeUs, long bufferStartOffset) {
int startOfLastPacketPosition = C.POSITION_UNSET;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;

/**
Expand Down Expand Up @@ -56,7 +57,7 @@
firstScrValue = C.TIME_UNSET;
lastScrValue = C.TIME_UNSET;
durationUs = C.TIME_UNSET;
packetBuffer = new ParsableByteArray(TIMESTAMP_SEARCH_BYTES);
packetBuffer = new ParsableByteArray();
}

/** Returns true if a PS duration has been read. */
Expand Down Expand Up @@ -129,6 +130,7 @@ public static long readScrValueFromPack(ParsableByteArray packetBuffer) {
}

private int finishReadDuration(ExtractorInput input) {
packetBuffer.reset(Util.EMPTY_BYTE_ARRAY);
isDurationRead = true;
input.resetPeekPosition();
return Extractor.RESULT_CONTINUE;
Expand All @@ -143,9 +145,9 @@ private int readFirstScrValue(ExtractorInput input, PositionHolder seekPositionH
return Extractor.RESULT_SEEK;
}

packetBuffer.reset(bytesToSearch);
input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

firstScrValue = readFirstScrValueFromBuffer(packetBuffer);
isFirstScrValueRead = true;
Expand Down Expand Up @@ -180,9 +182,9 @@ private int readLastScrValue(ExtractorInput input, PositionHolder seekPositionHo
return Extractor.RESULT_SEEK;
}

packetBuffer.reset(bytesToSearch);
input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

lastScrValue = readLastScrValueFromBuffer(packetBuffer);
isLastScrValueRead = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;

/**
Expand All @@ -34,7 +35,7 @@

private static final long SEEK_TOLERANCE_US = 100_000;
private static final int MINIMUM_SEARCH_RANGE_BYTES = 5 * TsExtractor.TS_PACKET_SIZE;
private static final int TIMESTAMP_SEARCH_BYTES = 200 * TsExtractor.TS_PACKET_SIZE;
private static final int TIMESTAMP_SEARCH_BYTES = 600 * TsExtractor.TS_PACKET_SIZE;

public TsBinarySearchSeeker(
TimestampAdjuster pcrTimestampAdjuster, long streamDurationUs, long inputLength, int pcrPid) {
Expand Down Expand Up @@ -68,7 +69,7 @@ private static final class TsPcrSeeker implements TimestampSeeker {
public TsPcrSeeker(int pcrPid, TimestampAdjuster pcrTimestampAdjuster) {
this.pcrPid = pcrPid;
this.pcrTimestampAdjuster = pcrTimestampAdjuster;
packetBuffer = new ParsableByteArray(TIMESTAMP_SEARCH_BYTES);
packetBuffer = new ParsableByteArray();
}

@Override
Expand All @@ -78,8 +79,8 @@ public TimestampSearchResult searchForTimestamp(
long inputPosition = input.getPosition();
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);

input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);

return searchForPcrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
}
Expand Down Expand Up @@ -131,5 +132,10 @@ private TimestampSearchResult searchForPcrValueInBuffer(
return TimestampSearchResult.NO_TIMESTAMP_IN_RANGE_RESULT;
}
}

@Override
public void onSeekFinished() {
packetBuffer.reset(Util.EMPTY_BYTE_ARRAY);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;

/**
Expand All @@ -35,7 +36,7 @@
*/
/* package */ final class TsDurationReader {

private static final int TIMESTAMP_SEARCH_BYTES = 200 * TsExtractor.TS_PACKET_SIZE;
private static final int TIMESTAMP_SEARCH_BYTES = 600 * TsExtractor.TS_PACKET_SIZE;

private final TimestampAdjuster pcrTimestampAdjuster;
private final ParsableByteArray packetBuffer;
Expand All @@ -53,7 +54,7 @@
firstPcrValue = C.TIME_UNSET;
lastPcrValue = C.TIME_UNSET;
durationUs = C.TIME_UNSET;
packetBuffer = new ParsableByteArray(TIMESTAMP_SEARCH_BYTES);
packetBuffer = new ParsableByteArray();
}

/** Returns true if a TS duration has been read. */
Expand Down Expand Up @@ -116,6 +117,7 @@ public TimestampAdjuster getPcrTimestampAdjuster() {
}

private int finishReadDuration(ExtractorInput input) {
packetBuffer.reset(Util.EMPTY_BYTE_ARRAY);
isDurationRead = true;
input.resetPeekPosition();
return Extractor.RESULT_CONTINUE;
Expand All @@ -130,9 +132,9 @@ private int readFirstPcrValue(ExtractorInput input, PositionHolder seekPositionH
return Extractor.RESULT_SEEK;
}

packetBuffer.reset(bytesToSearch);
input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

firstPcrValue = readFirstPcrValueFromBuffer(packetBuffer, pcrPid);
isFirstPcrValueRead = true;
Expand Down Expand Up @@ -166,9 +168,9 @@ private int readLastPcrValue(ExtractorInput input, PositionHolder seekPositionHo
return Extractor.RESULT_SEEK;
}

packetBuffer.reset(bytesToSearch);
input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

lastPcrValue = readLastPcrValueFromBuffer(packetBuffer, pcrPid);
isLastPcrValueRead = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ public ParsableByteArray(byte[] data, int limit) {
this.limit = limit;
}

/** Sets the position and limit to zero. */
public void reset() {
position = 0;
limit = 0;
}

/**
* Resets the position to zero and the limit to the specified value. If the limit exceeds the
* capacity, {@code data} is replaced with a new array of sufficient size.
Expand All @@ -77,6 +83,16 @@ public void reset(int limit) {
reset(capacity() < limit ? new byte[limit] : data, limit);
}

/**
* Updates the instance to wrap {@code data}, and resets the position to zero and the limit to
* {@code data.length}.
*
* @param data The array to wrap.
*/
public void reset(byte[] data) {
reset(data, data.length);
}

/**
* Updates the instance to wrap {@code data}, and resets the position to zero.
*
Expand All @@ -89,14 +105,6 @@ public void reset(byte[] data, int limit) {
position = 0;
}

/**
* Sets the position and limit to zero.
*/
public void reset() {
position = 0;
limit = 0;
}

/**
* Returns the number of bytes yet to be read.
*/
Expand Down
18 changes: 11 additions & 7 deletions library/core/src/test/assets/ts/sample.ts.1.dump
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ track 256:
drmInitData = -
initializationData:
data = length 22, hash CE183139
total output bytes = 24315
sample count = 1
total output bytes = 45026
sample count = 2
sample 0:
time = 55611
time = 55610
flags = 1
data = length 20711, hash 34341E8
sample 1:
time = 88977
flags = 0
data = length 18112, hash EC44B35B
track 257:
Expand Down Expand Up @@ -57,19 +61,19 @@ track 257:
total output bytes = 5015
sample count = 4
sample 0:
time = 11333
time = 44699
flags = 1
data = length 1253, hash 727FD1C6
sample 1:
time = 37455
time = 70821
flags = 1
data = length 1254, hash 73FB07B8
sample 2:
time = 63578
time = 96944
flags = 1
data = length 1254, hash 73FB07B8
sample 3:
time = 89700
time = 123066
flags = 1
data = length 1254, hash 73FB07B8
track 8448:
Expand Down
18 changes: 11 additions & 7 deletions library/core/src/test/assets/ts/sample.ts.2.dump
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ track 256:
drmInitData = -
initializationData:
data = length 22, hash CE183139
total output bytes = 24315
sample count = 1
total output bytes = 45026
sample count = 2
sample 0:
time = 77855
time = 77854
flags = 1
data = length 20711, hash 34341E8
sample 1:
time = 111221
flags = 0
data = length 18112, hash EC44B35B
track 257:
Expand Down Expand Up @@ -57,19 +61,19 @@ track 257:
total output bytes = 5015
sample count = 4
sample 0:
time = 33577
time = 66943
flags = 1
data = length 1253, hash 727FD1C6
sample 1:
time = 59699
time = 93065
flags = 1
data = length 1254, hash 73FB07B8
sample 2:
time = 85822
time = 119188
flags = 1
data = length 1254, hash 73FB07B8
sample 3:
time = 111944
time = 145310
flags = 1
data = length 1254, hash 73FB07B8
track 8448:
Expand Down

0 comments on commit c08edc5

Please sign in to comment.