mirror of
https://github.com/androidx/media.git
synced 2025-05-16 20:19:57 +08:00
Make CeaUtil robust against malformed SEI data
I've also added a TODO to not even bother trying to parse CEA from SEI NAL units if they're fully or partially encrypted, which it's possible to determine in the FMP4 extractor. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=147613979
This commit is contained in:
parent
ec98bd9ea1
commit
65d4b1cf5c
@ -1086,6 +1086,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
output.sampleData(nalStartCode, 4);
|
||||
// Write the NAL unit type byte.
|
||||
output.sampleData(nalPrefix, 1);
|
||||
// TODO: Don't try and process the SEI NAL unit if the payload is encrypted.
|
||||
processSeiNalUnitPayload = cea608TrackOutput != null
|
||||
&& NalUnitUtil.isNalUnitSei(track.format.sampleMimeType, nalPrefixData[4]);
|
||||
sampleBytesWritten += 5;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.text.cea;
|
||||
|
||||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
@ -24,6 +25,8 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
*/
|
||||
public final class CeaUtil {
|
||||
|
||||
private static final String TAG = "CeaUtil";
|
||||
|
||||
private static final int PAYLOAD_TYPE_CC = 4;
|
||||
private static final int COUNTRY_CODE = 0xB5;
|
||||
private static final int PROVIDER_CODE = 0x31;
|
||||
@ -40,22 +43,15 @@ public final class CeaUtil {
|
||||
*/
|
||||
public static void consume(long presentationTimeUs, ParsableByteArray seiBuffer,
|
||||
TrackOutput output) {
|
||||
int b;
|
||||
while (seiBuffer.bytesLeft() > 1 /* last byte will be rbsp_trailing_bits */) {
|
||||
// Parse payload type.
|
||||
int payloadType = 0;
|
||||
do {
|
||||
b = seiBuffer.readUnsignedByte();
|
||||
payloadType += b;
|
||||
} while (b == 0xFF);
|
||||
// Parse payload size.
|
||||
int payloadSize = 0;
|
||||
do {
|
||||
b = seiBuffer.readUnsignedByte();
|
||||
payloadSize += b;
|
||||
} while (b == 0xFF);
|
||||
int payloadType = readNon255TerminatedValue(seiBuffer);
|
||||
int payloadSize = readNon255TerminatedValue(seiBuffer);
|
||||
// Process the payload.
|
||||
if (isSeiMessageCea608(payloadType, payloadSize, seiBuffer)) {
|
||||
if (payloadSize == -1 || payloadSize > seiBuffer.bytesLeft()) {
|
||||
// This might occur if we're trying to read an encrypted SEI NAL unit.
|
||||
Log.w(TAG, "Skipping remainder of malformed SEI NAL unit.");
|
||||
seiBuffer.setPosition(seiBuffer.limit());
|
||||
} else if (isSeiMessageCea608(payloadType, payloadSize, seiBuffer)) {
|
||||
// Ignore country_code (1) + provider_code (2) + user_identifier (4)
|
||||
// + user_data_type_code (1).
|
||||
seiBuffer.skipBytes(8);
|
||||
@ -76,6 +72,27 @@ public final class CeaUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a value from the provided buffer consisting of zero or more 0xFF bytes followed by a
|
||||
* terminating byte not equal to 0xFF. The returned value is ((0xFF * N) + T), where N is the
|
||||
* number of 0xFF bytes and T is the value of the terminating byte.
|
||||
*
|
||||
* @param buffer The buffer from which to read the value.
|
||||
* @returns The read value, or -1 if the end of the buffer is reached before a value is read.
|
||||
*/
|
||||
private static int readNon255TerminatedValue(ParsableByteArray buffer) {
|
||||
int b;
|
||||
int value = 0;
|
||||
do {
|
||||
if (buffer.bytesLeft() == 0) {
|
||||
return -1;
|
||||
}
|
||||
b = buffer.readUnsignedByte();
|
||||
value += b;
|
||||
} while (b == 0xFF);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects an sei message to determine whether it contains CEA-608.
|
||||
* <p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user