Remove columnLock, columnCount (unimplemented) and rowLock (always true)

Also add a release note and simplify the test by removing the garbage
prefix and suffix.
This commit is contained in:
Ian Baker 2024-01-03 17:43:21 +00:00
parent 04751a1cdb
commit 0b482ef58c
3 changed files with 14 additions and 29 deletions

View File

@ -93,6 +93,10 @@
that contained Binder objects` error when using that contained Binder objects` error when using
`DefaultExtractorsFactory.setTextTrackTranscodingEnabled` `DefaultExtractorsFactory.setTextTrackTranscodingEnabled`
([#836](https://github.com/androidx/media/issues/836)). ([#836](https://github.com/androidx/media/issues/836)).
* CEA-708: Ignore `rowLock` value. The CEA-708-E S-2023 spec states that
`rowLock` and `columnLock` should both be assumed to be true, regardless
of the values present in the stream (`columnLock` support is not
implemented, so it's effectively assumed to always be false).
* Metadata: * Metadata:
* Fix bug where `MediaMetadata` was only populated from Vorbis comments * Fix bug where `MediaMetadata` was only populated from Vorbis comments
with upper-case keys with upper-case keys

View File

@ -784,11 +784,9 @@ public final class Cea708Parser implements SubtitleParser {
captionChannelPacketData.skipBits(2); // null padding captionChannelPacketData.skipBits(2); // null padding
boolean visible = captionChannelPacketData.readBit(); boolean visible = captionChannelPacketData.readBit();
// ANSI/CTA-708-E S-2023 spec (Section 8.4.7) indicates that rowLock and columnLock should be // ANSI/CTA-708-E S-2023 spec (Section 8.4.7) indicates that rowLock and columnLock values in
// ignored and assumed to be lock // the media should be ignored and assumed to be true.
captionChannelPacketData.skipBits(2); captionChannelPacketData.skipBits(2);
boolean rowLock = true;
boolean columnLock = true;
int priority = captionChannelPacketData.readBits(3); int priority = captionChannelPacketData.readBits(3);
// second byte // second byte
@ -801,7 +799,8 @@ public final class Cea708Parser implements SubtitleParser {
int rowCount = captionChannelPacketData.readBits(4); int rowCount = captionChannelPacketData.readBits(4);
// fifth byte // fifth byte
captionChannelPacketData.skipBits(2); // null padding captionChannelPacketData.skipBits(2); // null padding
int columnCount = captionChannelPacketData.readBits(6); // TODO: Add support for column count.
captionChannelPacketData.skipBits(6); // column count
// sixth byte // sixth byte
captionChannelPacketData.skipBits(2); // null padding captionChannelPacketData.skipBits(2); // null padding
int windowStyle = captionChannelPacketData.readBits(3); int windowStyle = captionChannelPacketData.readBits(3);
@ -809,14 +808,11 @@ public final class Cea708Parser implements SubtitleParser {
cueInfoBuilder.defineWindow( cueInfoBuilder.defineWindow(
visible, visible,
rowLock,
columnLock,
priority, priority,
relativePositioning, relativePositioning,
verticalAnchor, verticalAnchor,
horizontalAnchor, horizontalAnchor,
rowCount, rowCount,
columnCount,
anchorId, anchorId,
windowStyle, windowStyle,
penStyle); penStyle);
@ -977,7 +973,6 @@ public final class Cea708Parser implements SubtitleParser {
private int horizontalAnchor; private int horizontalAnchor;
private int anchorId; private int anchorId;
private int rowCount; private int rowCount;
private boolean rowLock;
private int justification; private int justification;
private int windowStyleId; private int windowStyleId;
private int penStyleId; private int penStyleId;
@ -1013,7 +1008,6 @@ public final class Cea708Parser implements SubtitleParser {
horizontalAnchor = 0; horizontalAnchor = 0;
anchorId = 0; anchorId = 0;
rowCount = MAXIMUM_ROW_COUNT; rowCount = MAXIMUM_ROW_COUNT;
rowLock = true;
justification = JUSTIFICATION_LEFT; justification = JUSTIFICATION_LEFT;
windowStyleId = 0; windowStyleId = 0;
penStyleId = 0; penStyleId = 0;
@ -1047,20 +1041,16 @@ public final class Cea708Parser implements SubtitleParser {
public void defineWindow( public void defineWindow(
boolean visible, boolean visible,
boolean rowLock,
boolean columnLock,
int priority, int priority,
boolean relativePositioning, boolean relativePositioning,
int verticalAnchor, int verticalAnchor,
int horizontalAnchor, int horizontalAnchor,
int rowCount, int rowCount,
int columnCount,
int anchorId, int anchorId,
int windowStyleId, int windowStyleId,
int penStyleId) { int penStyleId) {
this.defined = true; this.defined = true;
this.visible = visible; this.visible = visible;
this.rowLock = rowLock;
this.priority = priority; this.priority = priority;
this.relativePositioning = relativePositioning; this.relativePositioning = relativePositioning;
this.verticalAnchor = verticalAnchor; this.verticalAnchor = verticalAnchor;
@ -1072,14 +1062,12 @@ public final class Cea708Parser implements SubtitleParser {
this.rowCount = rowCount + 1; this.rowCount = rowCount + 1;
// Trim any rolled up captions that are no longer valid, if applicable. // Trim any rolled up captions that are no longer valid, if applicable.
while ((rowLock && (rolledUpCaptions.size() >= this.rowCount)) while ((rolledUpCaptions.size() >= this.rowCount)
|| (rolledUpCaptions.size() >= MAXIMUM_ROW_COUNT)) { || (rolledUpCaptions.size() >= MAXIMUM_ROW_COUNT)) {
rolledUpCaptions.remove(0); rolledUpCaptions.remove(0);
} }
} }
// TODO: Add support for column lock and count.
if (windowStyleId != 0 && this.windowStyleId != windowStyleId) { if (windowStyleId != 0 && this.windowStyleId != windowStyleId) {
this.windowStyleId = windowStyleId; this.windowStyleId = windowStyleId;
// windowStyleId is 1-based. // windowStyleId is 1-based.
@ -1241,7 +1229,7 @@ public final class Cea708Parser implements SubtitleParser {
backgroundColorStartPosition = 0; backgroundColorStartPosition = 0;
} }
while ((rowLock && (rolledUpCaptions.size() >= rowCount)) while ((rolledUpCaptions.size() >= rowCount)
|| (rolledUpCaptions.size() >= MAXIMUM_ROW_COUNT)) { || (rolledUpCaptions.size() >= MAXIMUM_ROW_COUNT)) {
rolledUpCaptions.remove(0); rolledUpCaptions.remove(0);
} }

View File

@ -139,20 +139,13 @@ public class Cea708ParserTest {
Bytes.concat( Bytes.concat(
windowDefinition, windowDefinition,
setCurrentWindow, setCurrentWindow,
"row1\r\nrow2\r\nrow3\r\nrow4".getBytes(Charsets.US_ASCII))))); "row1\r\nrow2\r\nrow3\r\nrow4".getBytes(Charsets.UTF_8)))));
byte[] garbagePrefix = TestUtil.buildTestData(subtitleData.length * 2);
byte[] garbageSuffix = TestUtil.buildTestData(10);
byte[] subtitleDataWithGarbagePrefixAndSuffix =
Bytes.concat(garbagePrefix, subtitleData, garbageSuffix);
List<CuesWithTiming> result = new ArrayList<>(); List<CuesWithTiming> result = new ArrayList<>();
cea708Parser.parse( cea708Parser.parse(subtitleData, SubtitleParser.OutputOptions.allCues(), result::add);
subtitleDataWithGarbagePrefixAndSuffix,
garbagePrefix.length,
subtitleData.length,
SubtitleParser.OutputOptions.allCues(),
result::add);
// Row count is 1 (which means 2 rows should be kept). Row lock is disabled in the media,
// but this is ignored and the result is still truncated to only the last two rows.
assertThat(Iterables.getOnlyElement(Iterables.getOnlyElement(result).cues).text.toString()) assertThat(Iterables.getOnlyElement(Iterables.getOnlyElement(result).cues).text.toString())
.isEqualTo("row3\nrow4"); .isEqualTo("row3\nrow4");
} }