From eec6458b435027da1609da4d9468edfeb691e22f Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Tue, 10 Mar 2015 19:37:47 +0000 Subject: [PATCH] Add handling of Extended Western European character set for CEA-608. --- .../text/eia608/ClosedCaptionCtrl.java | 2 + .../exoplayer/text/eia608/Eia608Parser.java | 80 ++++++++++++++++--- .../text/eia608/Eia608TrackRenderer.java | 5 ++ 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/text/eia608/ClosedCaptionCtrl.java b/library/src/main/java/com/google/android/exoplayer/text/eia608/ClosedCaptionCtrl.java index c784f50cd9..0fd1b1fcb6 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/eia608/ClosedCaptionCtrl.java +++ b/library/src/main/java/com/google/android/exoplayer/text/eia608/ClosedCaptionCtrl.java @@ -57,6 +57,8 @@ package com.google.android.exoplayer.text.eia608; public static final byte CARRIAGE_RETURN = 0x2D; public static final byte ERASE_NON_DISPLAYED_MEMORY = 0x2E; + public static final byte BACKSPACE = 0x21; + public static final byte MID_ROW_CHAN_1 = 0x11; public static final byte MID_ROW_CHAN_2 = 0x19; diff --git a/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608Parser.java b/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608Parser.java index b5b8c39eff..ddc29dbd59 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608Parser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608Parser.java @@ -82,6 +82,26 @@ public class Eia608Parser { 0xFB // 3F: 251 'รป' "Latin small letter U with circumflex" }; + // Extended Spanish/Miscellaneous and French char set. + private static final int[] SPECIAL_ES_FR_CHARACTER_SET = new int[] { + // Spanish and misc. + 0xC1, 0xC9, 0xD3, 0xDA, 0xDC, 0xFC, 0x2018, 0xA1, + 0x2A, 0x27, 0x2014, 0xA9, 0x2120, 0x2022, 0x201C, 0x201D, + // French. + 0xC0, 0xC2, 0xC7, 0xC8, 0xCA, 0xCB, 0xEB, 0xCE, + 0xCF, 0xEF, 0xD4, 0xD9, 0xF9, 0xDB, 0xAB, 0xBB + }; + + //Extended Portuguese and German/Danish char set. + private static final int[] SPECIAL_PT_DE_CHARACTER_SET = new int[] { + // Portuguese. + 0xC3, 0xE3, 0xCD, 0xCC, 0xEC, 0xD2, 0xF2, 0xD5, + 0xF5, 0x7B, 0x7D, 0x5C, 0x5E, 0x5F, 0x7C, 0x7E, + // German/Danish. + 0xC4, 0xE4, 0xD6, 0xF6, 0xDF, 0xA5, 0xA4, 0x2502, + 0xC5, 0xE5, 0xD8, 0xF8, 0x250C, 0x2510, 0x2514, 0x2518 + }; + private final ParsableBitArray seiBuffer; private final StringBuilder stringBuilder; private final ArrayList captions; @@ -134,31 +154,45 @@ public class Eia608Parser { } // Special North American character set. - if ((ccData1 == 0x11) && ((ccData2 & 0x70) == 0x30)) { + // ccData2 - P|0|1|1|X|X|X|X + if ((ccData1 == 0x11 || ccData1 == 0x19) + && ((ccData2 & 0x70) == 0x30)) { stringBuilder.append(getSpecialChar(ccData2)); continue; } + // Extended Spanish/Miscellaneous and French character set. + // ccData2 - P|0|1|X|X|X|X|X + if ((ccData1 == 0x12 || ccData1 == 0x1A) + && ((ccData2 & 0x60) == 0x20)) { + backspace(); // Remove standard equivalent of the special extended char. + stringBuilder.append(getExtendedEsFrChar(ccData2)); + continue; + } + + // Extended Portuguese and German/Danish character set. + // ccData2 - P|0|1|X|X|X|X|X + if ((ccData1 == 0x13 || ccData1 == 0x1B) + && ((ccData2 & 0x60) == 0x20)) { + backspace(); // Remove standard equivalent of the special extended char. + stringBuilder.append(getExtendedPtDeChar(ccData2)); + continue; + } + // Control character. if (ccData1 < 0x20) { - if (stringBuilder.length() > 0) { - captions.add(new ClosedCaptionText(stringBuilder.toString())); - stringBuilder.setLength(0); - } - captions.add(new ClosedCaptionCtrl(ccData1, ccData2)); + addCtrl(ccData1, ccData2); continue; } // Basic North American character set. stringBuilder.append(getChar(ccData1)); - if (ccData2 != 0) { + if (ccData2 >= 0x20) { stringBuilder.append(getChar(ccData2)); } } - if (stringBuilder.length() > 0) { - captions.add(new ClosedCaptionText(stringBuilder.toString())); - } + addBufferedText(); if (captions.isEmpty()) { return null; @@ -179,6 +213,32 @@ public class Eia608Parser { return (char) SPECIAL_CHARACTER_SET[index]; } + private static char getExtendedEsFrChar(byte ccData) { + int index = ccData & 0x1F; + return (char) SPECIAL_ES_FR_CHARACTER_SET[index]; + } + + private static char getExtendedPtDeChar(byte ccData) { + int index = ccData & 0x1F; + return (char) SPECIAL_PT_DE_CHARACTER_SET[index]; + } + + private void addBufferedText() { + if (stringBuilder.length() > 0) { + captions.add(new ClosedCaptionText(stringBuilder.toString())); + stringBuilder.setLength(0); + } + } + + private void addCtrl(byte ccData1, byte ccData2) { + addBufferedText(); + captions.add(new ClosedCaptionCtrl(ccData1, ccData2)); + } + + private void backspace() { + addCtrl((byte) 0x14, ClosedCaptionCtrl.BACKSPACE); + } + /** * Inspects an sei message to determine whether it contains EIA-608. *

diff --git a/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608TrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608TrackRenderer.java index 8e855bf730..664b549cf9 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608TrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608TrackRenderer.java @@ -317,6 +317,11 @@ public class Eia608TrackRenderer extends TrackRenderer implements Callback { case ClosedCaptionCtrl.CARRIAGE_RETURN: maybeAppendNewline(); return; + case ClosedCaptionCtrl.BACKSPACE: + if (captionStringBuilder.length() > 0) { + captionStringBuilder.setLength(captionStringBuilder.length() - 1); + } + return; } }