Commit a4935a9b by cdrolle Committed by Oliver Woodman

Added support for multiple RawCC (CEA-608/CEA-708) tracks in DASH.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=138392065
parent 0354ef24
...@@ -64,8 +64,8 @@ public final class FormatTest extends TestCase { ...@@ -64,8 +64,8 @@ public final class FormatTest extends TestCase {
Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null, Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null,
1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, 6, 44100, 1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, 6, 44100,
C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA, C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.NO_VALUE, Format.OFFSET_SAMPLE_RELATIVE,
drmInitData, metadata); INIT_DATA, drmInitData, metadata);
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
formatToParcel.writeToParcel(parcel, 0); formatToParcel.writeToParcel(parcel, 0);
......
...@@ -17,8 +17,10 @@ package com.google.android.exoplayer2.extractor.rawcc; ...@@ -17,8 +17,10 @@ package com.google.android.exoplayer2.extractor.rawcc;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.MimeTypes;
/** /**
* Tests for {@link RawCcExtractor}. * Tests for {@link RawCcExtractor}.
...@@ -27,10 +29,13 @@ import com.google.android.exoplayer2.testutil.TestUtil; ...@@ -27,10 +29,13 @@ import com.google.android.exoplayer2.testutil.TestUtil;
public final class RawCcExtractorTest extends InstrumentationTestCase { public final class RawCcExtractorTest extends InstrumentationTestCase {
public void testRawCcSample() throws Exception { public void testRawCcSample() throws Exception {
TestUtil.assertOutput(new TestUtil.ExtractorFactory() { TestUtil.assertOutput(
new TestUtil.ExtractorFactory() {
@Override @Override
public Extractor create() { public Extractor create() {
return new RawCcExtractor(); return new RawCcExtractor(
Format.createTextContainerFormat(null, null, MimeTypes.APPLICATION_CEA608,
"cea608", Format.NO_VALUE, 0, null, 1));
} }
}, "rawcc/sample.rawcc", getInstrumentation()); }, "rawcc/sample.rawcc", getInstrumentation());
} }
......
...@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.dash.manifest; ...@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri; import android.net.Uri;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException; import java.io.IOException;
...@@ -68,4 +69,35 @@ public class DashManifestParserTest extends InstrumentationTestCase { ...@@ -68,4 +69,35 @@ public class DashManifestParserTest extends InstrumentationTestCase {
} }
} }
public void testParseCea608AccessibilityChannel() {
assertEquals(1, DashManifestParser.parseCea608AccessibilityChannel("CC1=eng"));
assertEquals(2, DashManifestParser.parseCea608AccessibilityChannel("CC2=eng"));
assertEquals(3, DashManifestParser.parseCea608AccessibilityChannel("CC3=eng"));
assertEquals(4, DashManifestParser.parseCea608AccessibilityChannel("CC4=eng"));
assertEquals(Format.NO_VALUE, DashManifestParser.parseCea608AccessibilityChannel(null));
assertEquals(Format.NO_VALUE, DashManifestParser.parseCea608AccessibilityChannel(""));
assertEquals(Format.NO_VALUE, DashManifestParser.parseCea608AccessibilityChannel("CC0=eng"));
assertEquals(Format.NO_VALUE, DashManifestParser.parseCea608AccessibilityChannel("CC5=eng"));
assertEquals(Format.NO_VALUE,
DashManifestParser.parseCea608AccessibilityChannel("Wrong format"));
}
public void testParseCea708AccessibilityChannel() {
assertEquals(1, DashManifestParser.parseCea708AccessibilityChannel("1=lang:eng"));
assertEquals(2, DashManifestParser.parseCea708AccessibilityChannel("2=lang:eng"));
assertEquals(3, DashManifestParser.parseCea708AccessibilityChannel("3=lang:eng"));
assertEquals(62, DashManifestParser.parseCea708AccessibilityChannel("62=lang:eng"));
assertEquals(63, DashManifestParser.parseCea708AccessibilityChannel("63=lang:eng"));
assertEquals(Format.NO_VALUE, DashManifestParser.parseCea708AccessibilityChannel(null));
assertEquals(Format.NO_VALUE, DashManifestParser.parseCea708AccessibilityChannel(""));
assertEquals(Format.NO_VALUE,
DashManifestParser.parseCea708AccessibilityChannel("0=lang:eng"));
assertEquals(Format.NO_VALUE,
DashManifestParser.parseCea708AccessibilityChannel("64=lang:eng"));
assertEquals(Format.NO_VALUE,
DashManifestParser.parseCea708AccessibilityChannel("Wrong format"));
}
} }
...@@ -24,7 +24,6 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput; ...@@ -24,7 +24,6 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.PositionHolder; import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap; import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
...@@ -45,6 +44,8 @@ public final class RawCcExtractor implements Extractor { ...@@ -45,6 +44,8 @@ public final class RawCcExtractor implements Extractor {
private static final int STATE_READING_TIMESTAMP_AND_COUNT = 1; private static final int STATE_READING_TIMESTAMP_AND_COUNT = 1;
private static final int STATE_READING_SAMPLES = 2; private static final int STATE_READING_SAMPLES = 2;
private final Format format;
private final ParsableByteArray dataScratch; private final ParsableByteArray dataScratch;
private TrackOutput trackOutput; private TrackOutput trackOutput;
...@@ -55,7 +56,8 @@ public final class RawCcExtractor implements Extractor { ...@@ -55,7 +56,8 @@ public final class RawCcExtractor implements Extractor {
private int remainingSampleCount; private int remainingSampleCount;
private int sampleBytesWritten; private int sampleBytesWritten;
public RawCcExtractor() { public RawCcExtractor(Format format) {
this.format = format;
dataScratch = new ParsableByteArray(SCRATCH_SIZE); dataScratch = new ParsableByteArray(SCRATCH_SIZE);
parserState = STATE_READING_HEADER; parserState = STATE_READING_HEADER;
} }
...@@ -65,9 +67,7 @@ public final class RawCcExtractor implements Extractor { ...@@ -65,9 +67,7 @@ public final class RawCcExtractor implements Extractor {
output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET)); output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
trackOutput = output.track(0); trackOutput = output.track(0);
output.endTracks(); output.endTracks();
trackOutput.format(format);
trackOutput.format(Format.createTextSampleFormat(null, MimeTypes.APPLICATION_CEA608,
null, Format.NO_VALUE, 0, null, null));
} }
@Override @Override
......
...@@ -349,7 +349,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -349,7 +349,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
boolean resendFormatOnInit = false; boolean resendFormatOnInit = false;
Extractor extractor; Extractor extractor;
if (MimeTypes.APPLICATION_RAWCC.equals(containerMimeType)) { if (MimeTypes.APPLICATION_RAWCC.equals(containerMimeType)) {
extractor = new RawCcExtractor(); extractor = new RawCcExtractor(representation.format);
resendFormatOnInit = true; resendFormatOnInit = true;
} else if (mimeTypeIsWebm(containerMimeType)) { } else if (mimeTypeIsWebm(containerMimeType)) {
extractor = new MatroskaExtractor(); extractor = new MatroskaExtractor();
......
...@@ -59,6 +59,10 @@ public class DashManifestParser extends DefaultHandler ...@@ -59,6 +59,10 @@ public class DashManifestParser extends DefaultHandler
private static final Pattern FRAME_RATE_PATTERN = Pattern.compile("(\\d+)(?:/(\\d+))?"); private static final Pattern FRAME_RATE_PATTERN = Pattern.compile("(\\d+)(?:/(\\d+))?");
private static final Pattern CEA_608_ACCESSIBILITY_PATTERN = Pattern.compile("CC([1-4])=.*");
private static final Pattern CEA_708_ACCESSIBILITY_PATTERN =
Pattern.compile("([1-9]|[1-5][0-9]|6[0-3])=.*");
private final String contentId; private final String contentId;
private final XmlPullParserFactory xmlParserFactory; private final XmlPullParserFactory xmlParserFactory;
...@@ -235,6 +239,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -235,6 +239,7 @@ public class DashManifestParser extends DefaultHandler
int audioChannels = Format.NO_VALUE; int audioChannels = Format.NO_VALUE;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE); int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE);
String language = xpp.getAttributeValue(null, "lang"); String language = xpp.getAttributeValue(null, "lang");
int accessibilityChannel = Format.NO_VALUE;
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>(); ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
List<RepresentationInfo> representationInfos = new ArrayList<>(); List<RepresentationInfo> representationInfos = new ArrayList<>();
...@@ -256,12 +261,15 @@ public class DashManifestParser extends DefaultHandler ...@@ -256,12 +261,15 @@ public class DashManifestParser extends DefaultHandler
contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp));
} else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) {
RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs,
width, height, frameRate, audioChannels, audioSamplingRate, language, segmentBase); width, height, frameRate, audioChannels, audioSamplingRate, language,
accessibilityChannel, segmentBase);
contentType = checkContentTypeConsistency(contentType, contentType = checkContentTypeConsistency(contentType,
getContentType(representationInfo.format)); getContentType(representationInfo.format));
representationInfos.add(representationInfo); representationInfos.add(representationInfo);
} else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) {
audioChannels = parseAudioChannelConfiguration(xpp); audioChannels = parseAudioChannelConfiguration(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) {
accessibilityChannel = parseAccessibilityValue(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) {
segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase); segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
...@@ -365,7 +373,8 @@ public class DashManifestParser extends DefaultHandler ...@@ -365,7 +373,8 @@ public class DashManifestParser extends DefaultHandler
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl, protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl,
String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth, String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth,
int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels,
int adaptationSetAudioSamplingRate, String adaptationSetLanguage, SegmentBase segmentBase) int adaptationSetAudioSamplingRate, String adaptationSetLanguage,
int adaptationSetAccessibilityChannel, SegmentBase segmentBase)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id"); String id = xpp.getAttributeValue(null, "id");
int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE); int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
...@@ -404,7 +413,8 @@ public class DashManifestParser extends DefaultHandler ...@@ -404,7 +413,8 @@ public class DashManifestParser extends DefaultHandler
} while (!XmlPullParserUtil.isEndTag(xpp, "Representation")); } while (!XmlPullParserUtil.isEndTag(xpp, "Representation"));
Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels,
audioSamplingRate, bandwidth, adaptationSetLanguage, codecs); audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetAccessibilityChannel,
codecs);
segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(baseUrl); segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(baseUrl);
return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas); return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas);
...@@ -412,7 +422,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -412,7 +422,7 @@ public class DashManifestParser extends DefaultHandler
protected Format buildFormat(String id, String containerMimeType, int width, int height, protected Format buildFormat(String id, String containerMimeType, int width, int height,
float frameRate, int audioChannels, int audioSamplingRate, int bitrate, String language, float frameRate, int audioChannels, int audioSamplingRate, int bitrate, String language,
String codecs) { int accessiblityChannel, String codecs) {
String sampleMimeType = getSampleMimeType(containerMimeType, codecs); String sampleMimeType = getSampleMimeType(containerMimeType, codecs);
if (sampleMimeType != null) { if (sampleMimeType != null) {
if (MimeTypes.isVideo(sampleMimeType)) { if (MimeTypes.isVideo(sampleMimeType)) {
...@@ -423,7 +433,10 @@ public class DashManifestParser extends DefaultHandler ...@@ -423,7 +433,10 @@ public class DashManifestParser extends DefaultHandler
bitrate, audioChannels, audioSamplingRate, null, 0, language); bitrate, audioChannels, audioSamplingRate, null, 0, language);
} else if (mimeTypeIsRawText(sampleMimeType)) { } else if (mimeTypeIsRawText(sampleMimeType)) {
return Format.createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs, return Format.createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs,
bitrate, 0, language); bitrate, 0, language, accessiblityChannel);
} else if (containerMimeType.equals(MimeTypes.APPLICATION_RAWCC)) {
return Format.createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs,
bitrate, 0, language, accessiblityChannel);
} else { } else {
return Format.createContainerFormat(id, containerMimeType, codecs, sampleMimeType, bitrate); return Format.createContainerFormat(id, containerMimeType, codecs, sampleMimeType, bitrate);
} }
...@@ -726,6 +739,54 @@ public class DashManifestParser extends DefaultHandler ...@@ -726,6 +739,54 @@ public class DashManifestParser extends DefaultHandler
} }
} }
private static int parseAccessibilityValue(XmlPullParser xpp)
throws IOException, XmlPullParserException {
String schemeIdUri = parseString(xpp, "schemeIdUri", null);
String valueString = parseString(xpp, "value", null);
int accessibilityValue;
if (schemeIdUri == null || valueString == null) {
accessibilityValue = Format.NO_VALUE;
} else if ("urn:scte:dash:cc:cea-608:2015".equals(schemeIdUri)) {
accessibilityValue = parseCea608AccessibilityChannel(valueString);
} else if ("urn:scte:dash:cc:cea-708:2015".equals(schemeIdUri)) {
accessibilityValue = parseCea708AccessibilityChannel(valueString);
} else {
accessibilityValue = Format.NO_VALUE;
}
do {
xpp.next();
} while (!XmlPullParserUtil.isEndTag(xpp, "Accessibility"));
return accessibilityValue;
}
static int parseCea608AccessibilityChannel(String accessibilityValueString) {
if (accessibilityValueString == null) {
return Format.NO_VALUE;
}
Matcher accessibilityValueMatcher =
CEA_608_ACCESSIBILITY_PATTERN.matcher(accessibilityValueString);
if (accessibilityValueMatcher.matches()) {
return Integer.parseInt(accessibilityValueMatcher.group(1));
} else {
Log.w(TAG, "Unable to parse channel number from " + accessibilityValueString);
return Format.NO_VALUE;
}
}
static int parseCea708AccessibilityChannel(String accessibilityValueString) {
if (accessibilityValueString == null) {
return Format.NO_VALUE;
}
Matcher accessibilityValueMatcher =
CEA_708_ACCESSIBILITY_PATTERN.matcher(accessibilityValueString);
if (accessibilityValueMatcher.matches()) {
return Integer.parseInt(accessibilityValueMatcher.group(1));
} else {
Log.w(TAG, "Unable to parse service block number from " + accessibilityValueString);
return Format.NO_VALUE;
}
}
protected static float parseFrameRate(XmlPullParser xpp, float defaultValue) { protected static float parseFrameRate(XmlPullParser xpp, float defaultValue) {
float frameRate = defaultValue; float frameRate = defaultValue;
String frameRateAttribute = xpp.getAttributeValue(null, "frameRate"); String frameRateAttribute = xpp.getAttributeValue(null, "frameRate");
......
...@@ -74,7 +74,12 @@ public interface SubtitleDecoderFactory { ...@@ -74,7 +74,12 @@ public interface SubtitleDecoderFactory {
if (clazz == null) { if (clazz == null) {
throw new IllegalArgumentException("Attempted to create decoder for unsupported format"); throw new IllegalArgumentException("Attempted to create decoder for unsupported format");
} }
if (clazz == Cea608Decoder.class) {
return clazz.asSubclass(SubtitleDecoder.class)
.getConstructor(Integer.TYPE).newInstance(format.accessibilityChannel);
} else {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor().newInstance(); return clazz.asSubclass(SubtitleDecoder.class).getConstructor().newInstance();
}
} catch (Exception e) { } catch (Exception e) {
throw new IllegalStateException("Unexpected error instantiating decoder", e); throw new IllegalStateException("Unexpected error instantiating decoder", e);
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.text.cea; package com.google.android.exoplayer2.text.cea;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.Subtitle; import com.google.android.exoplayer2.text.Subtitle;
import com.google.android.exoplayer2.text.SubtitleDecoder; import com.google.android.exoplayer2.text.SubtitleDecoder;
...@@ -27,9 +28,15 @@ import com.google.android.exoplayer2.util.ParsableByteArray; ...@@ -27,9 +28,15 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
*/ */
public final class Cea608Decoder extends CeaDecoder { public final class Cea608Decoder extends CeaDecoder {
private static final int NTSC_CC_FIELD_1 = 0x00; private static final String TAG = "Cea608Decoder";
private static final int CC_TYPE_MASK = 0x03;
private static final int CC_VALID_FLAG = 0x04; private static final int CC_VALID_FLAG = 0x04;
private static final int CC_TYPE_FLAG = 0x02;
private static final int CC_FIELD_FLAG = 0x01;
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 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;
...@@ -160,6 +167,8 @@ public final class Cea608Decoder extends CeaDecoder { ...@@ -160,6 +167,8 @@ public final class Cea608Decoder extends CeaDecoder {
private final StringBuilder captionStringBuilder; private final StringBuilder captionStringBuilder;
private final int selectedField;
private int captionMode; private int captionMode;
private int captionRowCount; private int captionRowCount;
private String captionString; private String captionString;
...@@ -170,10 +179,21 @@ public final class Cea608Decoder extends CeaDecoder { ...@@ -170,10 +179,21 @@ public final class Cea608Decoder extends CeaDecoder {
private byte repeatableControlCc1; private byte repeatableControlCc1;
private byte repeatableControlCc2; private byte repeatableControlCc2;
public Cea608Decoder() { public Cea608Decoder(int accessibilityChannel) {
ccData = new ParsableByteArray(); ccData = new ParsableByteArray();
captionStringBuilder = new StringBuilder(); captionStringBuilder = new StringBuilder();
switch (accessibilityChannel) {
case 3:
case 4:
selectedField = 2;
break;
case 1:
case 2:
case Format.NO_VALUE:
default:
selectedField = 1;
}
setCaptionMode(CC_MODE_UNKNOWN); setCaptionMode(CC_MODE_UNKNOWN);
captionRowCount = DEFAULT_CAPTIONS_ROW_COUNT; captionRowCount = DEFAULT_CAPTIONS_ROW_COUNT;
...@@ -219,14 +239,18 @@ public final class Cea608Decoder extends CeaDecoder { ...@@ -219,14 +239,18 @@ public final class Cea608Decoder extends CeaDecoder {
boolean captionDataProcessed = false; boolean captionDataProcessed = false;
boolean isRepeatableControl = false; boolean isRepeatableControl = false;
while (ccData.bytesLeft() > 0) { while (ccData.bytesLeft() > 0) {
byte ccTypeAndValid = (byte) (ccData.readUnsignedByte() & 0x07); byte ccDataHeader = (byte) ccData.readUnsignedByte();
byte ccData1 = (byte) (ccData.readUnsignedByte() & 0x7F); byte ccData1 = (byte) (ccData.readUnsignedByte() & 0x7F);
byte ccData2 = (byte) (ccData.readUnsignedByte() & 0x7F); byte ccData2 = (byte) (ccData.readUnsignedByte() & 0x7F);
// Only examine valid NTSC_CC_FIELD_1 packets // Only examine valid CEA-608 packets
if ((ccTypeAndValid & CC_VALID_FLAG) == 0 if ((ccDataHeader & (CC_VALID_FLAG | CC_TYPE_FLAG)) != CC_VALID_608_ID) {
|| (ccTypeAndValid & CC_TYPE_MASK) != NTSC_CC_FIELD_1) { continue;
// TODO: Add support for NTSC_CC_FIELD_2 packets }
// 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; continue;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment