mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
Merge #5140: Cea608 - Check parity and valid bits
Imported from GitHub PR https://github.com/google/ExoPlayer/pull/5140
https://github.com/google/ExoPlayer/pull/5086 moved onto the right branch.
Merge 8822e188d24c1d9b3ed101918763b16e46c8debc into 0c385a854d
PiperOrigin-RevId: 222633340
This commit is contained in:
parent
0c385a854d
commit
e2e1c459c8
1 changed files with 65 additions and 6 deletions
|
|
@ -46,7 +46,6 @@ public final class Cea608Decoder extends CeaDecoder {
|
|||
|
||||
private static final int NTSC_CC_FIELD_1 = 0x00;
|
||||
private static final int NTSC_CC_FIELD_2 = 0x01;
|
||||
private static final int CC_VALID_608_ID = 0x04;
|
||||
|
||||
private static final int CC_MODE_UNKNOWN = 0;
|
||||
private static final int CC_MODE_ROLL_UP = 1;
|
||||
|
|
@ -179,6 +178,41 @@ public final class Cea608Decoder extends CeaDecoder {
|
|||
0xC5, 0xE5, 0xD8, 0xF8, 0x250C, 0x2510, 0x2514, 0x2518
|
||||
};
|
||||
|
||||
private static final boolean[] ODD_PARITY_BYTE_TABLE = {
|
||||
false, true, true, false, true, false, false, true, // 0
|
||||
true, false, false, true, false, true, true, false, // 8
|
||||
true, false, false, true, false, true, true, false, // 16
|
||||
false, true, true, false, true, false, false, true, // 24
|
||||
true, false, false, true, false, true, true, false, // 32
|
||||
false, true, true, false, true, false, false, true, // 40
|
||||
false, true, true, false, true, false, false, true, // 48
|
||||
true, false, false, true, false, true, true, false, // 56
|
||||
true, false, false, true, false, true, true, false, // 64
|
||||
false, true, true, false, true, false, false, true, // 72
|
||||
false, true, true, false, true, false, false, true, // 80
|
||||
true, false, false, true, false, true, true, false, // 88
|
||||
false, true, true, false, true, false, false, true, // 96
|
||||
true, false, false, true, false, true, true, false, // 104
|
||||
true, false, false, true, false, true, true, false, // 112
|
||||
false, true, true, false, true, false, false, true, // 120
|
||||
true, false, false, true, false, true, true, false, // 128
|
||||
false, true, true, false, true, false, false, true, // 136
|
||||
false, true, true, false, true, false, false, true, // 144
|
||||
true, false, false, true, false, true, true, false, // 152
|
||||
false, true, true, false, true, false, false, true, // 160
|
||||
true, false, false, true, false, true, true, false, // 168
|
||||
true, false, false, true, false, true, true, false, // 176
|
||||
false, true, true, false, true, false, false, true, // 184
|
||||
false, true, true, false, true, false, false, true, // 192
|
||||
true, false, false, true, false, true, true, false, // 200
|
||||
true, false, false, true, false, true, true, false, // 208
|
||||
false, true, true, false, true, false, false, true, // 216
|
||||
true, false, false, true, false, true, true, false, // 224
|
||||
false, true, true, false, true, false, false, true, // 232
|
||||
false, true, true, false, true, false, false, true, // 240
|
||||
true, false, false, true, false, true, true, false, // 248
|
||||
};
|
||||
|
||||
private final ParsableByteArray ccData;
|
||||
private final int packetLength;
|
||||
private final int selectedField;
|
||||
|
|
@ -191,6 +225,7 @@ public final class Cea608Decoder extends CeaDecoder {
|
|||
private int captionMode;
|
||||
private int captionRowCount;
|
||||
|
||||
private boolean captionValid;
|
||||
private boolean repeatableControlSet;
|
||||
private byte repeatableControlCc1;
|
||||
private byte repeatableControlCc2;
|
||||
|
|
@ -229,6 +264,7 @@ public final class Cea608Decoder extends CeaDecoder {
|
|||
setCaptionMode(CC_MODE_UNKNOWN);
|
||||
setCaptionRowCount(DEFAULT_CAPTIONS_ROW_COUNT);
|
||||
resetCueBuilders();
|
||||
captionValid = false;
|
||||
repeatableControlSet = false;
|
||||
repeatableControlCc1 = 0;
|
||||
repeatableControlCc2 = 0;
|
||||
|
|
@ -259,31 +295,54 @@ public final class Cea608Decoder extends CeaDecoder {
|
|||
while (ccData.bytesLeft() >= packetLength) {
|
||||
byte ccDataHeader = packetLength == 2 ? CC_IMPLICIT_DATA_HEADER
|
||||
: (byte) ccData.readUnsignedByte();
|
||||
byte ccData1 = (byte) (ccData.readUnsignedByte() & 0x7F); // strip the parity bit
|
||||
byte ccData2 = (byte) (ccData.readUnsignedByte() & 0x7F); // strip the parity bit
|
||||
|
||||
// Only examine valid CEA-608 packets
|
||||
// TODO: We're currently ignoring the top 5 marker bits, which should all be 1s according
|
||||
// to the CEA-608 specification. We need to determine if the data should be handled
|
||||
// differently when that is not the case.
|
||||
if ((ccDataHeader & (CC_VALID_FLAG | CC_TYPE_FLAG)) != CC_VALID_608_ID) {
|
||||
|
||||
if ((ccDataHeader & CC_TYPE_FLAG) != 0) {
|
||||
// Do not process anything that is not part of the 608 byte stream.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only examine packets within the selected field
|
||||
if ((selectedField == 1 && (ccDataHeader & CC_FIELD_FLAG) != NTSC_CC_FIELD_1)
|
||||
|| (selectedField == 2 && (ccDataHeader & CC_FIELD_FLAG) != NTSC_CC_FIELD_2)) {
|
||||
// Do not process packets not within the selected field.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore empty captions.
|
||||
int ccByte1 = ccData.readUnsignedByte();
|
||||
int ccByte2 = ccData.readUnsignedByte();
|
||||
|
||||
// Strip the parity bit from each byte to get CC data.
|
||||
byte ccData1 = (byte) (ccByte1 & 0x7F);
|
||||
byte ccData2 = (byte) (ccByte2 & 0x7F);
|
||||
|
||||
if (ccData1 == 0 && ccData2 == 0) {
|
||||
// Ignore empty captions.
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ccDataHeader & CC_VALID_FLAG) != CC_VALID_FLAG) {
|
||||
if (captionValid) {
|
||||
// The encoder has flipped the validity bit to indicate closed captions are being turned.
|
||||
resetCueBuilders();
|
||||
captionValid = false;
|
||||
captionDataProcessed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we've reached this point then there is data to process; flag that work has been done.
|
||||
captionDataProcessed = true;
|
||||
|
||||
if (!ODD_PARITY_BYTE_TABLE[ccByte1] || !ODD_PARITY_BYTE_TABLE[ccByte2]) {
|
||||
// The data is invalid.
|
||||
resetCueBuilders();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Special North American character set.
|
||||
// ccData1 - 0|0|0|1|C|0|0|1
|
||||
// ccData2 - 0|0|1|1|X|X|X|X
|
||||
|
|
|
|||
Loading…
Reference in a new issue