com.google.android.exoplayer2.text.SubtitleInputBuffer Java Examples
The following examples show how to use
com.google.android.exoplayer2.text.SubtitleInputBuffer.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CeaDecoder.java From MediaSDK with Apache License 2.0 | 5 votes |
@Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow // for decoding to begin mid-stream. releaseInputBuffer(dequeuedInputBuffer); } else { dequeuedInputBuffer.queuedInputBufferCount = queuedInputBufferCount++; queuedInputBuffers.add(dequeuedInputBuffer); } dequeuedInputBuffer = null; }
Example #2
Source File: CeaDecoder.java From Telegram with GNU General Public License v2.0 | 5 votes |
@Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow // for decoding to begin mid-stream. releaseInputBuffer(dequeuedInputBuffer); } else { dequeuedInputBuffer.queuedInputBufferCount = queuedInputBufferCount++; queuedInputBuffers.add(dequeuedInputBuffer); } dequeuedInputBuffer = null; }
Example #3
Source File: CeaDecoder.java From Telegram with GNU General Public License v2.0 | 5 votes |
@Override public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; } dequeuedInputBuffer = availableInputBuffers.pollFirst(); return dequeuedInputBuffer; }
Example #4
Source File: CeaDecoder.java From Telegram-FOSS with GNU General Public License v2.0 | 5 votes |
@Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow // for decoding to begin mid-stream. releaseInputBuffer(dequeuedInputBuffer); } else { dequeuedInputBuffer.queuedInputBufferCount = queuedInputBufferCount++; queuedInputBuffers.add(dequeuedInputBuffer); } dequeuedInputBuffer = null; }
Example #5
Source File: CeaDecoder.java From Telegram-FOSS with GNU General Public License v2.0 | 5 votes |
@Override public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; } dequeuedInputBuffer = availableInputBuffers.pollFirst(); return dequeuedInputBuffer; }
Example #6
Source File: CeaDecoder.java From K-Sonic with MIT License | 5 votes |
@Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer != null); Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow // for decoding to begin mid-stream. releaseInputBuffer(inputBuffer); } else { queuedInputBuffers.add(inputBuffer); } dequeuedInputBuffer = null; }
Example #7
Source File: CeaDecoder.java From K-Sonic with MIT License | 5 votes |
@Override public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; } dequeuedInputBuffer = availableInputBuffers.pollFirst(); return dequeuedInputBuffer; }
Example #8
Source File: CeaDecoder.java From K-Sonic with MIT License | 5 votes |
public CeaDecoder() { availableInputBuffers = new LinkedList<>(); for (int i = 0; i < NUM_INPUT_BUFFERS; i++) { availableInputBuffers.add(new SubtitleInputBuffer()); } availableOutputBuffers = new LinkedList<>(); for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) { availableOutputBuffers.add(new CeaOutputBuffer(this)); } queuedInputBuffers = new TreeSet<>(); }
Example #9
Source File: CeaDecoder.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
@Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow // for decoding to begin mid-stream. releaseInputBuffer(dequeuedInputBuffer); } else { dequeuedInputBuffer.queuedInputBufferCount = queuedInputBufferCount++; queuedInputBuffers.add(dequeuedInputBuffer); } dequeuedInputBuffer = null; }
Example #10
Source File: CeaDecoder.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
@Override public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; } dequeuedInputBuffer = availableInputBuffers.pollFirst(); return dequeuedInputBuffer; }
Example #11
Source File: CeaDecoder.java From MediaSDK with Apache License 2.0 | 5 votes |
@Override public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; } dequeuedInputBuffer = availableInputBuffers.pollFirst(); return dequeuedInputBuffer; }
Example #12
Source File: CeaDecoder.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
@Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow // for decoding to begin mid-stream. releaseInputBuffer(dequeuedInputBuffer); } else { dequeuedInputBuffer.queuedInputBufferCount = queuedInputBufferCount++; queuedInputBuffers.add(dequeuedInputBuffer); } dequeuedInputBuffer = null; }
Example #13
Source File: CeaDecoder.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
@Override public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; } dequeuedInputBuffer = availableInputBuffers.pollFirst(); return dequeuedInputBuffer; }
Example #14
Source File: Cea608Decoder.java From K-Sonic with MIT License | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); boolean captionDataProcessed = false; boolean isRepeatableControl = false; 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) { 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)) { continue; } // Ignore empty captions. if (ccData1 == 0 && ccData2 == 0) { continue; } // If we've reached this point then there is data to process; flag that work has been done. captionDataProcessed = true; // Special North American character set. // ccData1 - 0|0|0|1|C|0|0|1 // ccData2 - 0|0|1|1|X|X|X|X if (((ccData1 & 0xF7) == 0x11) && ((ccData2 & 0xF0) == 0x30)) { // TODO: Make use of the channel toggle currentCueBuilder.append(getSpecialChar(ccData2)); continue; } // Extended Western European character set. // ccData1 - 0|0|0|1|C|0|1|S // ccData2 - 0|0|1|X|X|X|X|X if (((ccData1 & 0xF6) == 0x12) && (ccData2 & 0xE0) == 0x20) { // TODO: Make use of the channel toggle // Remove standard equivalent of the special extended char before appending new one currentCueBuilder.backspace(); if ((ccData1 & 0x01) == 0x00) { // Extended Spanish/Miscellaneous and French character set (S = 0). currentCueBuilder.append(getExtendedEsFrChar(ccData2)); } else { // Extended Portuguese and German/Danish character set (S = 1). currentCueBuilder.append(getExtendedPtDeChar(ccData2)); } continue; } // Control character. // ccData1 - 0|0|0|X|X|X|X|X if ((ccData1 & 0xE0) == 0x00) { isRepeatableControl = handleCtrl(ccData1, ccData2); continue; } // Basic North American character set. currentCueBuilder.append(getChar(ccData1)); if ((ccData2 & 0xE0) != 0x00) { currentCueBuilder.append(getChar(ccData2)); } } if (captionDataProcessed) { if (!isRepeatableControl) { repeatableControlSet = false; } if (captionMode == CC_MODE_ROLL_UP || captionMode == CC_MODE_PAINT_ON) { cues = getDisplayCues(); } } }
Example #15
Source File: Cea608Decoder.java From Telegram with GNU General Public License v2.0 | 4 votes |
@SuppressWarnings("ByteBufferBackingArray") @Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); boolean captionDataProcessed = false; while (ccData.bytesLeft() >= packetLength) { byte ccHeader = packetLength == 2 ? CC_IMPLICIT_DATA_HEADER : (byte) ccData.readUnsignedByte(); int ccByte1 = ccData.readUnsignedByte(); int ccByte2 = ccData.readUnsignedByte(); // 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 ((ccHeader & CC_TYPE_FLAG) != 0) { // Do not process anything that is not part of the 608 byte stream. continue; } if ((ccHeader & CC_FIELD_FLAG) != selectedField) { // Do not process packets not within the selected field. continue; } // 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; } boolean previousIsCaptionValid = isCaptionValid; isCaptionValid = (ccHeader & CC_VALID_FLAG) == CC_VALID_FLAG && ODD_PARITY_BYTE_TABLE[ccByte1] && ODD_PARITY_BYTE_TABLE[ccByte2]; if (isRepeatedCommand(isCaptionValid, ccData1, ccData2)) { // Ignore repeated valid commands. continue; } if (!isCaptionValid) { if (previousIsCaptionValid) { // The encoder has flipped the validity bit to indicate captions are being turned off. resetCueBuilders(); captionDataProcessed = true; } continue; } maybeUpdateIsInCaptionService(ccData1, ccData2); if (!isInCaptionService) { // Only the Captioning service is supported. Drop all other bytes. continue; } if (!updateAndVerifyCurrentChannel(ccData1)) { // Wrong channel. continue; } if (isCtrlCode(ccData1)) { if (isSpecialNorthAmericanChar(ccData1, ccData2)) { currentCueBuilder.append(getSpecialNorthAmericanChar(ccData2)); } else if (isExtendedWestEuropeanChar(ccData1, ccData2)) { // Remove standard equivalent of the special extended char before appending new one. currentCueBuilder.backspace(); currentCueBuilder.append(getExtendedWestEuropeanChar(ccData1, ccData2)); } else if (isMidrowCtrlCode(ccData1, ccData2)) { handleMidrowCtrl(ccData2); } else if (isPreambleAddressCode(ccData1, ccData2)) { handlePreambleAddressCode(ccData1, ccData2); } else if (isTabCtrlCode(ccData1, ccData2)) { currentCueBuilder.tabOffset = ccData2 - 0x20; } else if (isMiscCode(ccData1, ccData2)) { handleMiscCode(ccData2); } } else { // Basic North American character set. currentCueBuilder.append(getBasicChar(ccData1)); if ((ccData2 & 0xE0) != 0x00) { currentCueBuilder.append(getBasicChar(ccData2)); } } captionDataProcessed = true; } if (captionDataProcessed) { if (captionMode == CC_MODE_ROLL_UP || captionMode == CC_MODE_PAINT_ON) { cues = getDisplayCues(); } } }
Example #16
Source File: Cea708Decoder.java From Telegram with GNU General Public License v2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { // Subtitle input buffers are non-direct and the position is zero, so calling array() is safe. @SuppressWarnings("ByteBufferBackingArray") byte[] inputBufferData = inputBuffer.data.array(); ccData.reset(inputBufferData, inputBuffer.data.limit()); while (ccData.bytesLeft() >= 3) { int ccTypeAndValid = (ccData.readUnsignedByte() & 0x07); int ccType = ccTypeAndValid & (DTVCC_PACKET_DATA | DTVCC_PACKET_START); boolean ccValid = (ccTypeAndValid & CC_VALID_FLAG) == CC_VALID_FLAG; byte ccData1 = (byte) ccData.readUnsignedByte(); byte ccData2 = (byte) ccData.readUnsignedByte(); // Ignore any non-CEA-708 data if (ccType != DTVCC_PACKET_DATA && ccType != DTVCC_PACKET_START) { continue; } if (!ccValid) { // This byte-pair isn't valid, ignore it and continue. continue; } if (ccType == DTVCC_PACKET_START) { finalizeCurrentPacket(); int sequenceNumber = (ccData1 & 0xC0) >> 6; // first 2 bits int packetSize = ccData1 & 0x3F; // last 6 bits if (packetSize == 0) { packetSize = 64; } currentDtvCcPacket = new DtvCcPacket(sequenceNumber, packetSize); currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } else { // The only remaining valid packet type is DTVCC_PACKET_DATA Assertions.checkArgument(ccType == DTVCC_PACKET_DATA); if (currentDtvCcPacket == null) { Log.e(TAG, "Encountered DTVCC_PACKET_DATA before DTVCC_PACKET_START"); continue; } currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData1; currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } if (currentDtvCcPacket.currentIndex == (currentDtvCcPacket.packetSize * 2 - 1)) { finalizeCurrentPacket(); } } }
Example #17
Source File: Cea608Decoder.java From Telegram-FOSS with GNU General Public License v2.0 | 4 votes |
@SuppressWarnings("ByteBufferBackingArray") @Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); boolean captionDataProcessed = false; while (ccData.bytesLeft() >= packetLength) { byte ccHeader = packetLength == 2 ? CC_IMPLICIT_DATA_HEADER : (byte) ccData.readUnsignedByte(); int ccByte1 = ccData.readUnsignedByte(); int ccByte2 = ccData.readUnsignedByte(); // 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 ((ccHeader & CC_TYPE_FLAG) != 0) { // Do not process anything that is not part of the 608 byte stream. continue; } if ((ccHeader & CC_FIELD_FLAG) != selectedField) { // Do not process packets not within the selected field. continue; } // 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; } boolean previousIsCaptionValid = isCaptionValid; isCaptionValid = (ccHeader & CC_VALID_FLAG) == CC_VALID_FLAG && ODD_PARITY_BYTE_TABLE[ccByte1] && ODD_PARITY_BYTE_TABLE[ccByte2]; if (isRepeatedCommand(isCaptionValid, ccData1, ccData2)) { // Ignore repeated valid commands. continue; } if (!isCaptionValid) { if (previousIsCaptionValid) { // The encoder has flipped the validity bit to indicate captions are being turned off. resetCueBuilders(); captionDataProcessed = true; } continue; } maybeUpdateIsInCaptionService(ccData1, ccData2); if (!isInCaptionService) { // Only the Captioning service is supported. Drop all other bytes. continue; } if (!updateAndVerifyCurrentChannel(ccData1)) { // Wrong channel. continue; } if (isCtrlCode(ccData1)) { if (isSpecialNorthAmericanChar(ccData1, ccData2)) { currentCueBuilder.append(getSpecialNorthAmericanChar(ccData2)); } else if (isExtendedWestEuropeanChar(ccData1, ccData2)) { // Remove standard equivalent of the special extended char before appending new one. currentCueBuilder.backspace(); currentCueBuilder.append(getExtendedWestEuropeanChar(ccData1, ccData2)); } else if (isMidrowCtrlCode(ccData1, ccData2)) { handleMidrowCtrl(ccData2); } else if (isPreambleAddressCode(ccData1, ccData2)) { handlePreambleAddressCode(ccData1, ccData2); } else if (isTabCtrlCode(ccData1, ccData2)) { currentCueBuilder.tabOffset = ccData2 - 0x20; } else if (isMiscCode(ccData1, ccData2)) { handleMiscCode(ccData2); } } else { // Basic North American character set. currentCueBuilder.append(getBasicChar(ccData1)); if ((ccData2 & 0xE0) != 0x00) { currentCueBuilder.append(getBasicChar(ccData2)); } } captionDataProcessed = true; } if (captionDataProcessed) { if (captionMode == CC_MODE_ROLL_UP || captionMode == CC_MODE_PAINT_ON) { cues = getDisplayCues(); } } }
Example #18
Source File: Cea708Decoder.java From Telegram-FOSS with GNU General Public License v2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { // Subtitle input buffers are non-direct and the position is zero, so calling array() is safe. @SuppressWarnings("ByteBufferBackingArray") byte[] inputBufferData = inputBuffer.data.array(); ccData.reset(inputBufferData, inputBuffer.data.limit()); while (ccData.bytesLeft() >= 3) { int ccTypeAndValid = (ccData.readUnsignedByte() & 0x07); int ccType = ccTypeAndValid & (DTVCC_PACKET_DATA | DTVCC_PACKET_START); boolean ccValid = (ccTypeAndValid & CC_VALID_FLAG) == CC_VALID_FLAG; byte ccData1 = (byte) ccData.readUnsignedByte(); byte ccData2 = (byte) ccData.readUnsignedByte(); // Ignore any non-CEA-708 data if (ccType != DTVCC_PACKET_DATA && ccType != DTVCC_PACKET_START) { continue; } if (!ccValid) { // This byte-pair isn't valid, ignore it and continue. continue; } if (ccType == DTVCC_PACKET_START) { finalizeCurrentPacket(); int sequenceNumber = (ccData1 & 0xC0) >> 6; // first 2 bits int packetSize = ccData1 & 0x3F; // last 6 bits if (packetSize == 0) { packetSize = 64; } currentDtvCcPacket = new DtvCcPacket(sequenceNumber, packetSize); currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } else { // The only remaining valid packet type is DTVCC_PACKET_DATA Assertions.checkArgument(ccType == DTVCC_PACKET_DATA); if (currentDtvCcPacket == null) { Log.e(TAG, "Encountered DTVCC_PACKET_DATA before DTVCC_PACKET_START"); continue; } currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData1; currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } if (currentDtvCcPacket.currentIndex == (currentDtvCcPacket.packetSize * 2 - 1)) { finalizeCurrentPacket(); } } }
Example #19
Source File: Cea708Decoder.java From MediaSDK with Apache License 2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { // Subtitle input buffers are non-direct and the position is zero, so calling array() is safe. @SuppressWarnings("ByteBufferBackingArray") byte[] inputBufferData = inputBuffer.data.array(); ccData.reset(inputBufferData, inputBuffer.data.limit()); while (ccData.bytesLeft() >= 3) { int ccTypeAndValid = (ccData.readUnsignedByte() & 0x07); int ccType = ccTypeAndValid & (DTVCC_PACKET_DATA | DTVCC_PACKET_START); boolean ccValid = (ccTypeAndValid & CC_VALID_FLAG) == CC_VALID_FLAG; byte ccData1 = (byte) ccData.readUnsignedByte(); byte ccData2 = (byte) ccData.readUnsignedByte(); // Ignore any non-CEA-708 data if (ccType != DTVCC_PACKET_DATA && ccType != DTVCC_PACKET_START) { continue; } if (!ccValid) { // This byte-pair isn't valid, ignore it and continue. continue; } if (ccType == DTVCC_PACKET_START) { finalizeCurrentPacket(); int sequenceNumber = (ccData1 & 0xC0) >> 6; // first 2 bits int packetSize = ccData1 & 0x3F; // last 6 bits if (packetSize == 0) { packetSize = 64; } currentDtvCcPacket = new DtvCcPacket(sequenceNumber, packetSize); currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } else { // The only remaining valid packet type is DTVCC_PACKET_DATA Assertions.checkArgument(ccType == DTVCC_PACKET_DATA); if (currentDtvCcPacket == null) { Log.e(TAG, "Encountered DTVCC_PACKET_DATA before DTVCC_PACKET_START"); continue; } currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData1; currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } if (currentDtvCcPacket.currentIndex == (currentDtvCcPacket.packetSize * 2 - 1)) { finalizeCurrentPacket(); } } }
Example #20
Source File: Cea608Decoder.java From MediaSDK with Apache License 2.0 | 4 votes |
@SuppressWarnings("ByteBufferBackingArray") @Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); boolean captionDataProcessed = false; while (ccData.bytesLeft() >= packetLength) { byte ccHeader = packetLength == 2 ? CC_IMPLICIT_DATA_HEADER : (byte) ccData.readUnsignedByte(); int ccByte1 = ccData.readUnsignedByte(); int ccByte2 = ccData.readUnsignedByte(); // 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 ((ccHeader & CC_TYPE_FLAG) != 0) { // Do not process anything that is not part of the 608 byte stream. continue; } if ((ccHeader & CC_FIELD_FLAG) != selectedField) { // Do not process packets not within the selected field. continue; } // 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; } boolean previousIsCaptionValid = isCaptionValid; isCaptionValid = (ccHeader & CC_VALID_FLAG) == CC_VALID_FLAG && ODD_PARITY_BYTE_TABLE[ccByte1] && ODD_PARITY_BYTE_TABLE[ccByte2]; if (isRepeatedCommand(isCaptionValid, ccData1, ccData2)) { // Ignore repeated valid commands. continue; } if (!isCaptionValid) { if (previousIsCaptionValid) { // The encoder has flipped the validity bit to indicate captions are being turned off. resetCueBuilders(); captionDataProcessed = true; } continue; } maybeUpdateIsInCaptionService(ccData1, ccData2); if (!isInCaptionService) { // Only the Captioning service is supported. Drop all other bytes. continue; } if (!updateAndVerifyCurrentChannel(ccData1)) { // Wrong channel. continue; } if (isCtrlCode(ccData1)) { if (isSpecialNorthAmericanChar(ccData1, ccData2)) { currentCueBuilder.append(getSpecialNorthAmericanChar(ccData2)); } else if (isExtendedWestEuropeanChar(ccData1, ccData2)) { // Remove standard equivalent of the special extended char before appending new one. currentCueBuilder.backspace(); currentCueBuilder.append(getExtendedWestEuropeanChar(ccData1, ccData2)); } else if (isMidrowCtrlCode(ccData1, ccData2)) { handleMidrowCtrl(ccData2); } else if (isPreambleAddressCode(ccData1, ccData2)) { handlePreambleAddressCode(ccData1, ccData2); } else if (isTabCtrlCode(ccData1, ccData2)) { currentCueBuilder.tabOffset = ccData2 - 0x20; } else if (isMiscCode(ccData1, ccData2)) { handleMiscCode(ccData2); } } else { // Basic North American character set. currentCueBuilder.append(getBasicChar(ccData1)); if ((ccData2 & 0xE0) != 0x00) { currentCueBuilder.append(getBasicChar(ccData2)); } } captionDataProcessed = true; } if (captionDataProcessed) { if (captionMode == CC_MODE_ROLL_UP || captionMode == CC_MODE_PAINT_ON) { cues = getDisplayCues(); } } }
Example #21
Source File: Cea608Decoder.java From TelePlus-Android with GNU General Public License v2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); boolean captionDataProcessed = false; boolean isRepeatableControl = false; 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) { 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)) { continue; } // Ignore empty captions. if (ccData1 == 0 && ccData2 == 0) { continue; } // If we've reached this point then there is data to process; flag that work has been done. captionDataProcessed = true; // Special North American character set. // ccData1 - 0|0|0|1|C|0|0|1 // ccData2 - 0|0|1|1|X|X|X|X if (((ccData1 & 0xF7) == 0x11) && ((ccData2 & 0xF0) == 0x30)) { // TODO: Make use of the channel toggle currentCueBuilder.append(getSpecialChar(ccData2)); continue; } // Extended Western European character set. // ccData1 - 0|0|0|1|C|0|1|S // ccData2 - 0|0|1|X|X|X|X|X if (((ccData1 & 0xF6) == 0x12) && (ccData2 & 0xE0) == 0x20) { // TODO: Make use of the channel toggle // Remove standard equivalent of the special extended char before appending new one currentCueBuilder.backspace(); if ((ccData1 & 0x01) == 0x00) { // Extended Spanish/Miscellaneous and French character set (S = 0). currentCueBuilder.append(getExtendedEsFrChar(ccData2)); } else { // Extended Portuguese and German/Danish character set (S = 1). currentCueBuilder.append(getExtendedPtDeChar(ccData2)); } continue; } // Control character. // ccData1 - 0|0|0|X|X|X|X|X if ((ccData1 & 0xE0) == 0x00) { isRepeatableControl = handleCtrl(ccData1, ccData2); continue; } // Basic North American character set. currentCueBuilder.append(getChar(ccData1)); if ((ccData2 & 0xE0) != 0x00) { currentCueBuilder.append(getChar(ccData2)); } } if (captionDataProcessed) { if (!isRepeatableControl) { repeatableControlSet = false; } if (captionMode == CC_MODE_ROLL_UP || captionMode == CC_MODE_PAINT_ON) { cues = getDisplayCues(); } } }
Example #22
Source File: Cea708Decoder.java From K-Sonic with MIT License | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); while (ccData.bytesLeft() >= 3) { int ccTypeAndValid = (ccData.readUnsignedByte() & 0x07); int ccType = ccTypeAndValid & (DTVCC_PACKET_DATA | DTVCC_PACKET_START); boolean ccValid = (ccTypeAndValid & CC_VALID_FLAG) == CC_VALID_FLAG; byte ccData1 = (byte) ccData.readUnsignedByte(); byte ccData2 = (byte) ccData.readUnsignedByte(); // Ignore any non-CEA-708 data if (ccType != DTVCC_PACKET_DATA && ccType != DTVCC_PACKET_START) { continue; } if (!ccValid) { // This byte-pair isn't valid, ignore it and continue. continue; } if (ccType == DTVCC_PACKET_START) { finalizeCurrentPacket(); int sequenceNumber = (ccData1 & 0xC0) >> 6; // first 2 bits int packetSize = ccData1 & 0x3F; // last 6 bits if (packetSize == 0) { packetSize = 64; } currentDtvCcPacket = new DtvCcPacket(sequenceNumber, packetSize); currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } else { // The only remaining valid packet type is DTVCC_PACKET_DATA Assertions.checkArgument(ccType == DTVCC_PACKET_DATA); if (currentDtvCcPacket == null) { Log.e(TAG, "Encountered DTVCC_PACKET_DATA before DTVCC_PACKET_START"); continue; } currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData1; currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } if (currentDtvCcPacket.currentIndex == (currentDtvCcPacket.packetSize * 2 - 1)) { finalizeCurrentPacket(); } } }
Example #23
Source File: CeaDecoder.java From K-Sonic with MIT License | 4 votes |
private void releaseInputBuffer(SubtitleInputBuffer inputBuffer) { inputBuffer.clear(); availableInputBuffers.add(inputBuffer); }
Example #24
Source File: Cea608Decoder.java From TelePlus-Android with GNU General Public License v2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { ccData.reset(inputBuffer.data.array(), inputBuffer.data.limit()); boolean captionDataProcessed = false; boolean isRepeatableControl = false; 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) { 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)) { continue; } // Ignore empty captions. if (ccData1 == 0 && ccData2 == 0) { continue; } // If we've reached this point then there is data to process; flag that work has been done. captionDataProcessed = true; // Special North American character set. // ccData1 - 0|0|0|1|C|0|0|1 // ccData2 - 0|0|1|1|X|X|X|X if (((ccData1 & 0xF7) == 0x11) && ((ccData2 & 0xF0) == 0x30)) { // TODO: Make use of the channel toggle currentCueBuilder.append(getSpecialChar(ccData2)); continue; } // Extended Western European character set. // ccData1 - 0|0|0|1|C|0|1|S // ccData2 - 0|0|1|X|X|X|X|X if (((ccData1 & 0xF6) == 0x12) && (ccData2 & 0xE0) == 0x20) { // TODO: Make use of the channel toggle // Remove standard equivalent of the special extended char before appending new one currentCueBuilder.backspace(); if ((ccData1 & 0x01) == 0x00) { // Extended Spanish/Miscellaneous and French character set (S = 0). currentCueBuilder.append(getExtendedEsFrChar(ccData2)); } else { // Extended Portuguese and German/Danish character set (S = 1). currentCueBuilder.append(getExtendedPtDeChar(ccData2)); } continue; } // Control character. // ccData1 - 0|0|0|X|X|X|X|X if ((ccData1 & 0xE0) == 0x00) { isRepeatableControl = handleCtrl(ccData1, ccData2); continue; } // Basic North American character set. currentCueBuilder.append(getChar(ccData1)); if ((ccData2 & 0xE0) != 0x00) { currentCueBuilder.append(getChar(ccData2)); } } if (captionDataProcessed) { if (!isRepeatableControl) { repeatableControlSet = false; } if (captionMode == CC_MODE_ROLL_UP || captionMode == CC_MODE_PAINT_ON) { cues = getDisplayCues(); } } }
Example #25
Source File: Cea708Decoder.java From TelePlus-Android with GNU General Public License v2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { // Subtitle input buffers are non-direct and the position is zero, so calling array() is safe. @SuppressWarnings("ByteBufferBackingArray") byte[] inputBufferData = inputBuffer.data.array(); ccData.reset(inputBufferData, inputBuffer.data.limit()); while (ccData.bytesLeft() >= 3) { int ccTypeAndValid = (ccData.readUnsignedByte() & 0x07); int ccType = ccTypeAndValid & (DTVCC_PACKET_DATA | DTVCC_PACKET_START); boolean ccValid = (ccTypeAndValid & CC_VALID_FLAG) == CC_VALID_FLAG; byte ccData1 = (byte) ccData.readUnsignedByte(); byte ccData2 = (byte) ccData.readUnsignedByte(); // Ignore any non-CEA-708 data if (ccType != DTVCC_PACKET_DATA && ccType != DTVCC_PACKET_START) { continue; } if (!ccValid) { // This byte-pair isn't valid, ignore it and continue. continue; } if (ccType == DTVCC_PACKET_START) { finalizeCurrentPacket(); int sequenceNumber = (ccData1 & 0xC0) >> 6; // first 2 bits int packetSize = ccData1 & 0x3F; // last 6 bits if (packetSize == 0) { packetSize = 64; } currentDtvCcPacket = new DtvCcPacket(sequenceNumber, packetSize); currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } else { // The only remaining valid packet type is DTVCC_PACKET_DATA Assertions.checkArgument(ccType == DTVCC_PACKET_DATA); if (currentDtvCcPacket == null) { Log.e(TAG, "Encountered DTVCC_PACKET_DATA before DTVCC_PACKET_START"); continue; } currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData1; currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } if (currentDtvCcPacket.currentIndex == (currentDtvCcPacket.packetSize * 2 - 1)) { finalizeCurrentPacket(); } } }
Example #26
Source File: Cea708Decoder.java From TelePlus-Android with GNU General Public License v2.0 | 4 votes |
@Override protected void decode(SubtitleInputBuffer inputBuffer) { // Subtitle input buffers are non-direct and the position is zero, so calling array() is safe. @SuppressWarnings("ByteBufferBackingArray") byte[] inputBufferData = inputBuffer.data.array(); ccData.reset(inputBufferData, inputBuffer.data.limit()); while (ccData.bytesLeft() >= 3) { int ccTypeAndValid = (ccData.readUnsignedByte() & 0x07); int ccType = ccTypeAndValid & (DTVCC_PACKET_DATA | DTVCC_PACKET_START); boolean ccValid = (ccTypeAndValid & CC_VALID_FLAG) == CC_VALID_FLAG; byte ccData1 = (byte) ccData.readUnsignedByte(); byte ccData2 = (byte) ccData.readUnsignedByte(); // Ignore any non-CEA-708 data if (ccType != DTVCC_PACKET_DATA && ccType != DTVCC_PACKET_START) { continue; } if (!ccValid) { // This byte-pair isn't valid, ignore it and continue. continue; } if (ccType == DTVCC_PACKET_START) { finalizeCurrentPacket(); int sequenceNumber = (ccData1 & 0xC0) >> 6; // first 2 bits int packetSize = ccData1 & 0x3F; // last 6 bits if (packetSize == 0) { packetSize = 64; } currentDtvCcPacket = new DtvCcPacket(sequenceNumber, packetSize); currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } else { // The only remaining valid packet type is DTVCC_PACKET_DATA Assertions.checkArgument(ccType == DTVCC_PACKET_DATA); if (currentDtvCcPacket == null) { Log.e(TAG, "Encountered DTVCC_PACKET_DATA before DTVCC_PACKET_START"); continue; } currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData1; currentDtvCcPacket.packetData[currentDtvCcPacket.currentIndex++] = ccData2; } if (currentDtvCcPacket.currentIndex == (currentDtvCcPacket.packetSize * 2 - 1)) { finalizeCurrentPacket(); } } }
Example #27
Source File: CeaDecoder.java From K-Sonic with MIT License | 2 votes |
/** * Filters and processes the raw data, providing {@link Subtitle}s via {@link #createSubtitle()} * when sufficient data has been processed. */ protected abstract void decode(SubtitleInputBuffer inputBuffer);
Example #28
Source File: CeaDecoder.java From Telegram-FOSS with GNU General Public License v2.0 | 2 votes |
/** * Filters and processes the raw data, providing {@link Subtitle}s via {@link #createSubtitle()} * when sufficient data has been processed. */ protected abstract void decode(SubtitleInputBuffer inputBuffer);
Example #29
Source File: CeaDecoder.java From TelePlus-Android with GNU General Public License v2.0 | 2 votes |
/** * Filters and processes the raw data, providing {@link Subtitle}s via {@link #createSubtitle()} * when sufficient data has been processed. */ protected abstract void decode(SubtitleInputBuffer inputBuffer);
Example #30
Source File: CeaDecoder.java From MediaSDK with Apache License 2.0 | 2 votes |
/** * Filters and processes the raw data, providing {@link Subtitle}s via {@link #createSubtitle()} * when sufficient data has been processed. */ protected abstract void decode(SubtitleInputBuffer inputBuffer);