Merge pull request #5201 from zsmatyas:dev-v2

PiperOrigin-RevId: 228341073
This commit is contained in:
Oliver Woodman 2019-01-08 17:17:59 +00:00
commit e0c6f538af

View File

@ -542,13 +542,34 @@ public final class Cea608Decoder extends CeaDecoder {
} }
private List<Cue> getDisplayCues() { private List<Cue> getDisplayCues() {
List<Cue> displayCues = new ArrayList<>(); // CEA-608 does not define middle and end alignment, however content providers artificially
for (int i = 0; i < cueBuilders.size(); i++) { // introduce them using whitespace. When each cue is built, we try and infer the alignment based
Cue cue = cueBuilders.get(i).build(); // on the amount of whitespace either side of the text. To avoid consecutive cues being aligned
// differently, we force all cues to have the same alignment, with start alignment given
// preference, then middle alignment, then end alignment.
@Cue.AnchorType int positionAnchor = Cue.ANCHOR_TYPE_END;
int cueBuilderCount = cueBuilders.size();
List<Cue> cueBuilderCues = new ArrayList<>(cueBuilderCount);
for (int i = 0; i < cueBuilderCount; i++) {
Cue cue = cueBuilders.get(i).build(/* forcedPositionAnchor= */ Cue.TYPE_UNSET);
cueBuilderCues.add(cue);
if (cue != null) { if (cue != null) {
positionAnchor = Math.min(positionAnchor, cue.positionAnchor);
}
}
// Skip null cues and rebuild any that don't have the preferred alignment.
List<Cue> displayCues = new ArrayList<>(cueBuilderCount);
for (int i = 0; i < cueBuilderCount; i++) {
Cue cue = cueBuilderCues.get(i);
if (cue != null) {
if (cue.positionAnchor != positionAnchor) {
cue = cueBuilders.get(i).build(positionAnchor);
}
displayCues.add(cue); displayCues.add(cue);
} }
} }
return displayCues; return displayCues;
} }
@ -721,7 +742,7 @@ public final class Cea608Decoder extends CeaDecoder {
} }
} }
public Cue build() { public Cue build(@Cue.AnchorType int forcedPositionAnchor) {
SpannableStringBuilder cueString = new SpannableStringBuilder(); SpannableStringBuilder cueString = new SpannableStringBuilder();
// Add any rolled up captions, separated by new lines. // Add any rolled up captions, separated by new lines.
for (int i = 0; i < rolledUpCaptions.size(); i++) { for (int i = 0; i < rolledUpCaptions.size(); i++) {
@ -736,33 +757,46 @@ public final class Cea608Decoder extends CeaDecoder {
return null; return null;
} }
float position;
int positionAnchor; int positionAnchor;
// The number of empty columns before the start of the text, in the range [0-31]. // The number of empty columns before the start of the text, in the range [0-31].
int startPadding = indent + tabOffset; int startPadding = indent + tabOffset;
// The number of empty columns after the end of the text, in the same range. // The number of empty columns after the end of the text, in the same range.
int endPadding = SCREEN_CHARWIDTH - startPadding - cueString.length(); int endPadding = SCREEN_CHARWIDTH - startPadding - cueString.length();
int startEndPaddingDelta = startPadding - endPadding; int startEndPaddingDelta = startPadding - endPadding;
if (captionMode == CC_MODE_POP_ON && (Math.abs(startEndPaddingDelta) < 3 || endPadding < 0)) { if (forcedPositionAnchor != Cue.TYPE_UNSET) {
positionAnchor = forcedPositionAnchor;
} else if (captionMode == CC_MODE_POP_ON
&& (Math.abs(startEndPaddingDelta) < 3 || endPadding < 0)) {
// Treat approximately centered pop-on captions as middle aligned. We also treat captions // Treat approximately centered pop-on captions as middle aligned. We also treat captions
// that are wider than they should be in this way. See // that are wider than they should be in this way. See
// https://github.com/google/ExoPlayer/issues/3534. // https://github.com/google/ExoPlayer/issues/3534.
position = 0.5f;
positionAnchor = Cue.ANCHOR_TYPE_MIDDLE; positionAnchor = Cue.ANCHOR_TYPE_MIDDLE;
} else if (captionMode == CC_MODE_POP_ON && startEndPaddingDelta > 0) { } else if (captionMode == CC_MODE_POP_ON && startEndPaddingDelta > 0) {
// Treat pop-on captions with less padding at the end than the start as end aligned. // Treat pop-on captions with less padding at the end than the start as end aligned.
position = (float) (SCREEN_CHARWIDTH - endPadding) / SCREEN_CHARWIDTH;
// Adjust the position to fit within the safe area.
position = position * 0.8f + 0.1f;
positionAnchor = Cue.ANCHOR_TYPE_END; positionAnchor = Cue.ANCHOR_TYPE_END;
} else { } else {
// For all other cases assume start aligned. // For all other cases assume start aligned.
position = (float) startPadding / SCREEN_CHARWIDTH;
// Adjust the position to fit within the safe area.
position = position * 0.8f + 0.1f;
positionAnchor = Cue.ANCHOR_TYPE_START; positionAnchor = Cue.ANCHOR_TYPE_START;
} }
float position;
switch (positionAnchor) {
case Cue.ANCHOR_TYPE_MIDDLE:
position = 0.5f;
break;
case Cue.ANCHOR_TYPE_END:
position = (float) (SCREEN_CHARWIDTH - endPadding) / SCREEN_CHARWIDTH;
// Adjust the position to fit within the safe area.
position = position * 0.8f + 0.1f;
break;
case Cue.ANCHOR_TYPE_START:
default:
position = (float) startPadding / SCREEN_CHARWIDTH;
// Adjust the position to fit within the safe area.
position = position * 0.8f + 0.1f;
break;
}
int lineAnchor; int lineAnchor;
int line; int line;
// Note: Row indices are in the range [1-15]. // Note: Row indices are in the range [1-15].