mirror of
https://github.com/androidx/media.git
synced 2025-05-17 04:29:55 +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);
|
output.sampleData(nalStartCode, 4);
|
||||||
// Write the NAL unit type byte.
|
// Write the NAL unit type byte.
|
||||||
output.sampleData(nalPrefix, 1);
|
output.sampleData(nalPrefix, 1);
|
||||||
|
// TODO: Don't try and process the SEI NAL unit if the payload is encrypted.
|
||||||
processSeiNalUnitPayload = cea608TrackOutput != null
|
processSeiNalUnitPayload = cea608TrackOutput != null
|
||||||
&& NalUnitUtil.isNalUnitSei(track.format.sampleMimeType, nalPrefixData[4]);
|
&& NalUnitUtil.isNalUnitSei(track.format.sampleMimeType, nalPrefixData[4]);
|
||||||
sampleBytesWritten += 5;
|
sampleBytesWritten += 5;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.text.cea;
|
package com.google.android.exoplayer2.text.cea;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
@ -24,6 +25,8 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
|||||||
*/
|
*/
|
||||||
public final class CeaUtil {
|
public final class CeaUtil {
|
||||||
|
|
||||||
|
private static final String TAG = "CeaUtil";
|
||||||
|
|
||||||
private static final int PAYLOAD_TYPE_CC = 4;
|
private static final int PAYLOAD_TYPE_CC = 4;
|
||||||
private static final int COUNTRY_CODE = 0xB5;
|
private static final int COUNTRY_CODE = 0xB5;
|
||||||
private static final int PROVIDER_CODE = 0x31;
|
private static final int PROVIDER_CODE = 0x31;
|
||||||
@ -40,22 +43,15 @@ public final class CeaUtil {
|
|||||||
*/
|
*/
|
||||||
public static void consume(long presentationTimeUs, ParsableByteArray seiBuffer,
|
public static void consume(long presentationTimeUs, ParsableByteArray seiBuffer,
|
||||||
TrackOutput output) {
|
TrackOutput output) {
|
||||||
int b;
|
|
||||||
while (seiBuffer.bytesLeft() > 1 /* last byte will be rbsp_trailing_bits */) {
|
while (seiBuffer.bytesLeft() > 1 /* last byte will be rbsp_trailing_bits */) {
|
||||||
// Parse payload type.
|
int payloadType = readNon255TerminatedValue(seiBuffer);
|
||||||
int payloadType = 0;
|
int payloadSize = readNon255TerminatedValue(seiBuffer);
|
||||||
do {
|
|
||||||
b = seiBuffer.readUnsignedByte();
|
|
||||||
payloadType += b;
|
|
||||||
} while (b == 0xFF);
|
|
||||||
// Parse payload size.
|
|
||||||
int payloadSize = 0;
|
|
||||||
do {
|
|
||||||
b = seiBuffer.readUnsignedByte();
|
|
||||||
payloadSize += b;
|
|
||||||
} while (b == 0xFF);
|
|
||||||
// Process the payload.
|
// 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)
|
// Ignore country_code (1) + provider_code (2) + user_identifier (4)
|
||||||
// + user_data_type_code (1).
|
// + user_data_type_code (1).
|
||||||
seiBuffer.skipBytes(8);
|
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.
|
* Inspects an sei message to determine whether it contains CEA-608.
|
||||||
* <p>
|
* <p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user