Check for TS synchronization before parsing packet from random position
#minor-release Issue: #9100 PiperOrigin-RevId: 384962258
This commit is contained in:
parent
7157f3c119
commit
99abb4e1e9
@ -109,6 +109,8 @@
|
|||||||
([#7608](https://github.com/google/ExoPlayer/issues/7608)).
|
([#7608](https://github.com/google/ExoPlayer/issues/7608)).
|
||||||
* Add support for MP4 H263 atom type
|
* Add support for MP4 H263 atom type
|
||||||
([#9158](https://github.com/google/ExoPlayer/issues/9158)).
|
([#9158](https://github.com/google/ExoPlayer/issues/9158)).
|
||||||
|
* Fix issue around TS synchronization when reading a file's duration
|
||||||
|
([#9100](https://github.com/google/ExoPlayer/pull/9100)).
|
||||||
* HLS:
|
* HLS:
|
||||||
* Fix issue where playback of a live event could become stuck rather than
|
* Fix issue where playback of a live event could become stuck rather than
|
||||||
transitioning to `STATE_ENDED` when the event ends
|
transitioning to `STATE_ENDED` when the event ends
|
||||||
|
@ -180,10 +180,13 @@ import java.io.IOException;
|
|||||||
private long readLastPcrValueFromBuffer(ParsableByteArray packetBuffer, int pcrPid) {
|
private long readLastPcrValueFromBuffer(ParsableByteArray packetBuffer, int pcrPid) {
|
||||||
int searchStartPosition = packetBuffer.getPosition();
|
int searchStartPosition = packetBuffer.getPosition();
|
||||||
int searchEndPosition = packetBuffer.limit();
|
int searchEndPosition = packetBuffer.limit();
|
||||||
for (int searchPosition = searchEndPosition - 1;
|
// We start searching 'TsExtractor.TS_PACKET_SIZE' bytes from the end to prevent trying to read
|
||||||
|
// from an incomplete TS packet.
|
||||||
|
for (int searchPosition = searchEndPosition - TsExtractor.TS_PACKET_SIZE;
|
||||||
searchPosition >= searchStartPosition;
|
searchPosition >= searchStartPosition;
|
||||||
searchPosition--) {
|
searchPosition--) {
|
||||||
if (packetBuffer.getData()[searchPosition] != TsExtractor.TS_SYNC_BYTE) {
|
if (!TsUtil.isStartOfTsPacket(
|
||||||
|
packetBuffer.getData(), searchStartPosition, searchEndPosition, searchPosition)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
long pcrValue = TsUtil.readPcrFromPacket(packetBuffer, searchPosition, pcrPid);
|
long pcrValue = TsUtil.readPcrFromPacket(packetBuffer, searchPosition, pcrPid);
|
||||||
|
@ -21,6 +21,38 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
|||||||
|
|
||||||
/** Utilities method for extracting MPEG-TS streams. */
|
/** Utilities method for extracting MPEG-TS streams. */
|
||||||
public final class TsUtil {
|
public final class TsUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a TS packet starts at {@code searchPosition} according to the MPEG-TS
|
||||||
|
* synchronization recommendations.
|
||||||
|
*
|
||||||
|
* <p>ISO/IEC 13818-1:2015 Annex G recommends that 5 sync bytes emulating the start of 5
|
||||||
|
* consecutive TS packets should never occur as part of the TS packets' contents. So, this method
|
||||||
|
* returns true when {@code data} contains a sync byte at {@code searchPosition}, and said sync
|
||||||
|
* byte is also one of five consecutive sync bytes separated from each other by the size of a TS
|
||||||
|
* packet.
|
||||||
|
*
|
||||||
|
* @param data The array holding the data to search in.
|
||||||
|
* @param start The first valid position in {@code data} from which a sync byte can be read.
|
||||||
|
* @param limit The first invalid position in {@code data}, after which no data should be read.
|
||||||
|
* @param searchPosition The position to check for a TS packet start.
|
||||||
|
* @return Whether a TS packet starts at {@code searchPosition}.
|
||||||
|
*/
|
||||||
|
public static boolean isStartOfTsPacket(byte[] data, int start, int limit, int searchPosition) {
|
||||||
|
int consecutiveSyncByteCount = 0;
|
||||||
|
for (int i = -4; i <= 4; i++) {
|
||||||
|
int currentPosition = searchPosition + i * TsExtractor.TS_PACKET_SIZE;
|
||||||
|
if (currentPosition < start
|
||||||
|
|| currentPosition >= limit
|
||||||
|
|| data[currentPosition] != TsExtractor.TS_SYNC_BYTE) {
|
||||||
|
consecutiveSyncByteCount = 0;
|
||||||
|
} else if (++consecutiveSyncByteCount == 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the position of the first TS_SYNC_BYTE within the range [startPosition, limitPosition)
|
* Returns the position of the first TS_SYNC_BYTE within the range [startPosition, limitPosition)
|
||||||
* from the provided data array, or returns limitPosition if sync byte could not be found.
|
* from the provided data array, or returns limitPosition if sync byte could not be found.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user