summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
Diffstat (limited to 'libhb')
-rw-r--r--libhb/colormap.c721
-rw-r--r--libhb/colormap.h20
-rw-r--r--libhb/common.c5
-rw-r--r--libhb/deccc608sub.c745
-rw-r--r--libhb/deccc608sub.h3
-rw-r--r--libhb/rendersub.c317
-rw-r--r--libhb/stream.c9
-rw-r--r--libhb/sync.c19
-rw-r--r--libhb/work.c3
9 files changed, 1307 insertions, 535 deletions
diff --git a/libhb/colormap.c b/libhb/colormap.c
new file mode 100644
index 000000000..059166463
--- /dev/null
+++ b/libhb/colormap.c
@@ -0,0 +1,721 @@
+/* colormap.c
+ *
+ * Copyright (c) 2003-2014 HandBrake Team
+ * This file is part of the HandBrake source code
+ * Homepage: <http://handbrake.fr/>.
+ * It may be used under the terms of the GNU General Public License v2.
+ * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <strings.h>
+#include "colormap.h"
+
+typedef struct
+{
+ char *name;
+ uint32_t rgb;
+} hb_colormap_t;
+
+static hb_colormap_t colormap[] =
+{
+ { "none", 0xFFFFFF },
+ { "black", 0x000000 },
+ { "white", 0xFFFFFF },
+ { "red", 0xFF0000 },
+ { "green", 0x00FF00 },
+ { "blue", 0x0000FF },
+ { "aliceblue", 0xF0F8FF },
+ { "antiquewhite", 0xFAEBD7 },
+ { "antiquewhite1", 0xFFEFDB },
+ { "antiquewhite2", 0xEEDFCC },
+ { "antiquewhite3", 0xCDC0B0 },
+ { "antiquewhite4", 0x8B8378 },
+ { "aqua", 0x00FFFF },
+ { "aquamarine", 0x7FFFD4 },
+ { "aquamarine1", 0x7FFFD4 },
+ { "aquamarine2", 0x76EEC6 },
+ { "aquamarine3", 0x66CDAA },
+ { "aquamarine4", 0x458B74 },
+ { "azure", 0xF0FFFF },
+ { "azure1", 0xF0FFFF },
+ { "azure2", 0xE0EEEE },
+ { "azure3", 0xC1CDCD },
+ { "azure4", 0x838B8B },
+ { "beige", 0xF5F5DC },
+ { "bisque", 0xFFE4C4 },
+ { "bisque1", 0xFFE4C4 },
+ { "bisque2", 0xEED5B7 },
+ { "bisque3", 0xCDB79E },
+ { "bisque4", 0x8B7D6B },
+ { "black", 0x000000 },
+ { "blanchedalmond", 0xFFEBCD },
+ { "blue", 0x0000FF },
+ { "blue1", 0x0000FF },
+ { "blue2", 0x0000EE },
+ { "blue3", 0x0000CD },
+ { "blue4", 0x00008B },
+ { "blueviolet", 0x8A2BE2 },
+ { "brown", 0xA52A2A },
+ { "brown1", 0xFF4040 },
+ { "brown2", 0xEE3B3B },
+ { "brown3", 0xCD3333 },
+ { "brown4", 0x8B2323 },
+ { "burlywood", 0xDEB887 },
+ { "burlywood1", 0xFFD39B },
+ { "burlywood2", 0xEEC591 },
+ { "burlywood3", 0xCDAA7D },
+ { "burlywood4", 0x8B7355 },
+ { "cadetblue", 0x5F9EA0 },
+ { "cadetblue", 0x5F9EA0 },
+ { "cadetblue1", 0x98F5FF },
+ { "cadetblue2", 0x8EE5EE },
+ { "cadetblue3", 0x7AC5CD },
+ { "cadetblue4", 0x53868B },
+ { "chartreuse", 0x7FFF00 },
+ { "chartreuse1", 0x7FFF00 },
+ { "chartreuse2", 0x76EE00 },
+ { "chartreuse3", 0x66CD00 },
+ { "chartreuse4", 0x458B00 },
+ { "chocolate", 0xD2691E },
+ { "chocolate1", 0xFF7F24 },
+ { "chocolate2", 0xEE7621 },
+ { "chocolate3", 0xCD661D },
+ { "chocolate4", 0x8B4513 },
+ { "coral", 0xFF7F50 },
+ { "coral1", 0xFF7256 },
+ { "coral2", 0xEE6A50 },
+ { "coral3", 0xCD5B45 },
+ { "coral4", 0x8B3E2F },
+ { "cornflowerblue", 0x6495ED },
+ { "cornsilk", 0xFFF8DC },
+ { "cornsilk1", 0xFFF8DC },
+ { "cornsilk2", 0xEEE8CD },
+ { "cornsilk3", 0xCDC8B1 },
+ { "cornsilk4", 0x8B8878 },
+ { "crimson", 0xDC143C },
+ { "cyan", 0x00FFFF },
+ { "cyan1", 0x00FFFF },
+ { "cyan2", 0x00EEEE },
+ { "cyan3", 0x00CDCD },
+ { "cyan4", 0x008B8B },
+ { "darkblue", 0x00008B },
+ { "darkcyan", 0x008B8B },
+ { "darkgoldenrod", 0xB8860B },
+ { "darkgoldenrod1", 0xFFB90F },
+ { "darkgoldenrod2", 0xEEAD0E },
+ { "darkgoldenrod3", 0xCD950C },
+ { "darkgoldenrod4", 0x8B6508 },
+ { "darkgray", 0xA9A9A9 },
+ { "darkgreen", 0x006400 },
+ { "darkgrey", 0xA9A9A9 },
+ { "darkkhaki", 0xBDB76B },
+ { "darkmagenta", 0x8B008B },
+ { "darkolivegreen", 0x556B2F },
+ { "darkolivegreen1", 0xCAFF70 },
+ { "darkolivegreen2", 0xBCEE68 },
+ { "darkolivegreen3", 0xA2CD5A },
+ { "darkolivegreen4", 0x6E8B3D },
+ { "darkorange", 0xFF8C00 },
+ { "darkorange1", 0xFF7F00 },
+ { "darkorange2", 0xEE7600 },
+ { "darkorange3", 0xCD6600 },
+ { "darkorange4", 0x8B4500 },
+ { "darkorchid", 0x9932CC },
+ { "darkorchid1", 0xBF3EFF },
+ { "darkorchid2", 0xB23AEE },
+ { "darkorchid3", 0x9A32CD },
+ { "darkorchid4", 0x68228B },
+ { "darkred", 0x8B0000 },
+ { "darksalmon", 0xE9967A },
+ { "darkseagreen", 0x8FBC8F },
+ { "darkseagreen1", 0xC1FFC1 },
+ { "darkseagreen2", 0xB4EEB4 },
+ { "darkseagreen3", 0x9BCD9B },
+ { "darkseagreen4", 0x698B69 },
+ { "darkslateblue", 0x483D8B },
+ { "darkslategray", 0x2F4F4F },
+ { "darkslategray1", 0x97FFFF },
+ { "darkslategray2", 0x8DEEEE },
+ { "darkslategray3", 0x79CDCD },
+ { "darkslategray4", 0x528B8B },
+ { "darkslategrey", 0x2F4F4F },
+ { "darkturquoise", 0x00CED1 },
+ { "darkviolet", 0x9400D3 },
+ { "darkviolet", 0x9400D3 },
+ { "deeppink", 0xFF1493 },
+ { "deeppink1", 0xFF1493 },
+ { "deeppink2", 0xEE1289 },
+ { "deeppink3", 0xCD1076 },
+ { "deeppink4", 0x8B0A50 },
+ { "deepskyblue", 0x00BFFF },
+ { "deepskyblue1", 0x00BFFF },
+ { "deepskyblue2", 0x00B2EE },
+ { "deepskyblue3", 0x009ACD },
+ { "deepskyblue4", 0x00688B },
+ { "dimgray", 0x696969 },
+ { "dimgrey", 0x696969 },
+ { "dodgerblue", 0x1E90FF },
+ { "dodgerblue1", 0x1E90FF },
+ { "dodgerblue2", 0x1C86EE },
+ { "dodgerblue3", 0x1874CD },
+ { "dodgerblue4", 0x104E8B },
+ { "firebrick", 0xB22222 },
+ { "firebrick1", 0xFF3030 },
+ { "firebrick2", 0xEE2C2C },
+ { "firebrick3", 0xCD2626 },
+ { "firebrick4", 0x8B1A1A },
+ { "floralwhite", 0xFFFAF0 },
+ { "forestgreen", 0x228B22 },
+ { "fractal", 0x808080 },
+ { "fuchsia", 0xFF00FF },
+ { "gainsboro", 0xDCDCDC },
+ { "ghostwhite", 0xF8F8FF },
+ { "gold", 0xFFD700 },
+ { "gold1", 0xFFD700 },
+ { "gold2", 0xEEC900 },
+ { "gold3", 0xCDAD00 },
+ { "gold4", 0x8B7500 },
+ { "goldenrod", 0xDAA520 },
+ { "goldenrod1", 0xFFC125 },
+ { "goldenrod2", 0xEEB422 },
+ { "goldenrod3", 0xCD9B1D },
+ { "goldenrod4", 0x8B6914 },
+ { "gray", 0x7E7E7E },
+ { "gray", 0xBEBEBE },
+ { "gray0", 0x000000 },
+ { "gray1", 0x030303 },
+ { "gray10", 0x1A1A1A },
+ { "gray100", 0xFFFFFF },
+ { "gray11", 0x1C1C1C },
+ { "gray12", 0x1F1F1F },
+ { "gray13", 0x212121 },
+ { "gray14", 0x242424 },
+ { "gray15", 0x262626 },
+ { "gray16", 0x292929 },
+ { "gray17", 0x2B2B2B },
+ { "gray18", 0x2E2E2E },
+ { "gray19", 0x303030 },
+ { "gray2", 0x050505 },
+ { "gray20", 0x333333 },
+ { "gray21", 0x363636 },
+ { "gray22", 0x383838 },
+ { "gray23", 0x3B3B3B },
+ { "gray24", 0x3D3D3D },
+ { "gray25", 0x404040 },
+ { "gray26", 0x424242 },
+ { "gray27", 0x454545 },
+ { "gray28", 0x474747 },
+ { "gray29", 0x4A4A4A },
+ { "gray3", 0x080808 },
+ { "gray30", 0x4D4D4D },
+ { "gray31", 0x4F4F4F },
+ { "gray32", 0x525252 },
+ { "gray33", 0x545454 },
+ { "gray34", 0x575757 },
+ { "gray35", 0x595959 },
+ { "gray36", 0x5C5C5C },
+ { "gray37", 0x5E5E5E },
+ { "gray38", 0x616161 },
+ { "gray39", 0x636363 },
+ { "gray4", 0x0A0A0A },
+ { "gray40", 0x666666 },
+ { "gray41", 0x696969 },
+ { "gray42", 0x6B6B6B },
+ { "gray43", 0x6E6E6E },
+ { "gray44", 0x707070 },
+ { "gray45", 0x737373 },
+ { "gray46", 0x757575 },
+ { "gray47", 0x787878 },
+ { "gray48", 0x7A7A7A },
+ { "gray49", 0x7D7D7D },
+ { "gray5", 0x0D0D0D },
+ { "gray50", 0x7F7F7F },
+ { "gray51", 0x828282 },
+ { "gray52", 0x858585 },
+ { "gray53", 0x878787 },
+ { "gray54", 0x8A8A8A },
+ { "gray55", 0x8C8C8C },
+ { "gray56", 0x8F8F8F },
+ { "gray57", 0x919191 },
+ { "gray58", 0x949494 },
+ { "gray59", 0x969696 },
+ { "gray6", 0x0F0F0F },
+ { "gray60", 0x999999 },
+ { "gray61", 0x9C9C9C },
+ { "gray62", 0x9E9E9E },
+ { "gray63", 0xA1A1A1 },
+ { "gray64", 0xA3A3A3 },
+ { "gray65", 0xA6A6A6 },
+ { "gray66", 0xA8A8A8 },
+ { "gray67", 0xABABAB },
+ { "gray68", 0xADADAD },
+ { "gray69", 0xB0B0B0 },
+ { "gray7", 0x121212 },
+ { "gray70", 0xB3B3B3 },
+ { "gray71", 0xB5B5B5 },
+ { "gray72", 0xB8B8B8 },
+ { "gray73", 0xBABABA },
+ { "gray74", 0xBDBDBD },
+ { "gray75", 0xBFBFBF },
+ { "gray76", 0xC2C2C2 },
+ { "gray77", 0xC4C4C4 },
+ { "gray78", 0xC7C7C7 },
+ { "gray79", 0xC9C9C9 },
+ { "gray8", 0x141414 },
+ { "gray80", 0xCCCCCC },
+ { "gray81", 0xCFCFCF },
+ { "gray82", 0xD1D1D1 },
+ { "gray83", 0xD4D4D4 },
+ { "gray84", 0xD6D6D6 },
+ { "gray85", 0xD9D9D9 },
+ { "gray86", 0xDBDBDB },
+ { "gray87", 0xDEDEDE },
+ { "gray88", 0xE0E0E0 },
+ { "gray89", 0xE3E3E3 },
+ { "gray9", 0x171717 },
+ { "gray90", 0xE5E5E5 },
+ { "gray91", 0xE8E8E8 },
+ { "gray92", 0xEBEBEB },
+ { "gray93", 0xEDEDED },
+ { "gray94", 0xF0F0F0 },
+ { "gray95", 0xF2F2F2 },
+ { "gray96", 0xF5F5F5 },
+ { "gray97", 0xF7F7F7 },
+ { "gray98", 0xFAFAFA },
+ { "gray99", 0xFCFCFC },
+ { "green", 0x008000 },
+ { "green", 0x00FF00 },
+ { "green1", 0x00FF00 },
+ { "green2", 0x00EE00 },
+ { "green3", 0x00CD00 },
+ { "green4", 0x008B00 },
+ { "greenyellow", 0xADFF2F },
+ { "grey", 0xBEBEBE },
+ { "grey0", 0x000000 },
+ { "grey1", 0x030303 },
+ { "grey10", 0x1A1A1A },
+ { "grey100", 0xFFFFFF },
+ { "grey11", 0x1C1C1C },
+ { "grey12", 0x1F1F1F },
+ { "grey13", 0x212121 },
+ { "grey14", 0x242424 },
+ { "grey15", 0x262626 },
+ { "grey16", 0x292929 },
+ { "grey17", 0x2B2B2B },
+ { "grey18", 0x2E2E2E },
+ { "grey19", 0x303030 },
+ { "grey2", 0x050505 },
+ { "grey20", 0x333333 },
+ { "grey21", 0x363636 },
+ { "grey22", 0x383838 },
+ { "grey23", 0x3B3B3B },
+ { "grey24", 0x3D3D3D },
+ { "grey25", 0x404040 },
+ { "grey26", 0x424242 },
+ { "grey27", 0x454545 },
+ { "grey28", 0x474747 },
+ { "grey29", 0x4A4A4A },
+ { "grey3", 0x080808 },
+ { "grey30", 0x4D4D4D },
+ { "grey31", 0x4F4F4F },
+ { "grey32", 0x525252 },
+ { "grey33", 0x545454 },
+ { "grey34", 0x575757 },
+ { "grey35", 0x595959 },
+ { "grey36", 0x5C5C5C },
+ { "grey37", 0x5E5E5E },
+ { "grey38", 0x616161 },
+ { "grey39", 0x636363 },
+ { "grey4", 0x0A0A0A },
+ { "grey40", 0x666666 },
+ { "grey41", 0x696969 },
+ { "grey42", 0x6B6B6B },
+ { "grey43", 0x6E6E6E },
+ { "grey44", 0x707070 },
+ { "grey45", 0x737373 },
+ { "grey46", 0x757575 },
+ { "grey47", 0x787878 },
+ { "grey48", 0x7A7A7A },
+ { "grey49", 0x7D7D7D },
+ { "grey5", 0x0D0D0D },
+ { "grey50", 0x7F7F7F },
+ { "grey51", 0x828282 },
+ { "grey52", 0x858585 },
+ { "grey53", 0x878787 },
+ { "grey54", 0x8A8A8A },
+ { "grey55", 0x8C8C8C },
+ { "grey56", 0x8F8F8F },
+ { "grey57", 0x919191 },
+ { "grey58", 0x949494 },
+ { "grey59", 0x969696 },
+ { "grey6", 0x0F0F0F },
+ { "grey60", 0x999999 },
+ { "grey61", 0x9C9C9C },
+ { "grey62", 0x9E9E9E },
+ { "grey63", 0xA1A1A1 },
+ { "grey64", 0xA3A3A3 },
+ { "grey65", 0xA6A6A6 },
+ { "grey66", 0xA8A8A8 },
+ { "grey67", 0xABABAB },
+ { "grey68", 0xADADAD },
+ { "grey69", 0xB0B0B0 },
+ { "grey7", 0x121212 },
+ { "grey70", 0xB3B3B3 },
+ { "grey71", 0xB5B5B5 },
+ { "grey72", 0xB8B8B8 },
+ { "grey73", 0xBABABA },
+ { "grey74", 0xBDBDBD },
+ { "grey75", 0xBFBFBF },
+ { "grey76", 0xC2C2C2 },
+ { "grey77", 0xC4C4C4 },
+ { "grey78", 0xC7C7C7 },
+ { "grey79", 0xC9C9C9 },
+ { "grey8", 0x141414 },
+ { "grey80", 0xCCCCCC },
+ { "grey81", 0xCFCFCF },
+ { "grey82", 0xD1D1D1 },
+ { "grey83", 0xD4D4D4 },
+ { "grey84", 0xD6D6D6 },
+ { "grey85", 0xD9D9D9 },
+ { "grey86", 0xDBDBDB },
+ { "grey87", 0xDEDEDE },
+ { "grey88", 0xE0E0E0 },
+ { "grey89", 0xE3E3E3 },
+ { "grey9", 0x171717 },
+ { "grey90", 0xE5E5E5 },
+ { "grey91", 0xE8E8E8 },
+ { "grey92", 0xEBEBEB },
+ { "grey93", 0xEDEDED },
+ { "grey94", 0xF0F0F0 },
+ { "grey95", 0xF2F2F2 },
+ { "grey96", 0xF5F5F5 },
+ { "grey97", 0xF7F7F7 },
+ { "grey98", 0xFAFAFA },
+ { "grey99", 0xFCFCFC },
+ { "honeydew", 0xF0FFF0 },
+ { "honeydew1", 0xF0FFF0 },
+ { "honeydew2", 0xE0EEE0 },
+ { "honeydew3", 0xC1CDC1 },
+ { "honeydew4", 0x838B83 },
+ { "hotpink", 0xFF69B4 },
+ { "hotpink1", 0xFF6EB4 },
+ { "hotpink2", 0xEE6AA7 },
+ { "hotpink3", 0xCD6090 },
+ { "hotpink4", 0x8B3A62 },
+ { "indianred", 0xCD5C5C },
+ { "indianred1", 0xFF6A6A },
+ { "indianred2", 0xEE6363 },
+ { "indianred3", 0xCD5555 },
+ { "indianred4", 0x8B3A3A },
+ { "indigo", 0x4B0082 },
+ { "ivory", 0xFFFFF0 },
+ { "ivory1", 0xFFFFF0 },
+ { "ivory2", 0xEEEEE0 },
+ { "ivory3", 0xCDCDC1 },
+ { "ivory4", 0x8B8B83 },
+ { "khaki", 0xF0E68C },
+ { "khaki1", 0xFFF68F },
+ { "khaki2", 0xEEE685 },
+ { "khaki3", 0xCDC673 },
+ { "khaki4", 0x8B864E },
+ { "lavender", 0xE6E6FA },
+ { "lavenderblush", 0xFFF0F5 },
+ { "lavenderblush1", 0xFFF0F5 },
+ { "lavenderblush2", 0xEEE0E5 },
+ { "lavenderblush3", 0xCDC1C5 },
+ { "lavenderblush4", 0x8B8386 },
+ { "lawngreen", 0x7CFC00 },
+ { "lemonchiffon", 0xFFFACD },
+ { "lemonchiffon1", 0xFFFACD },
+ { "lemonchiffon2", 0xEEE9BF },
+ { "lemonchiffon3", 0xCDC9A5 },
+ { "lemonchiffon4", 0x8B8970 },
+ { "lightblue", 0xADD8E6 },
+ { "lightblue1", 0xBFEFFF },
+ { "lightblue2", 0xB2DFEE },
+ { "lightblue3", 0x9AC0CD },
+ { "lightblue4", 0x68838B },
+ { "lightcoral", 0xF08080 },
+ { "lightcyan", 0xE0FFFF },
+ { "lightcyan1", 0xE0FFFF },
+ { "lightcyan2", 0xD1EEEE },
+ { "lightcyan3", 0xB4CDCD },
+ { "lightcyan4", 0x7A8B8B },
+ { "lightgoldenrod", 0xEEDD82 },
+ { "lightgoldenrod1", 0xFFEC8B },
+ { "lightgoldenrod2", 0xEEDC82 },
+ { "lightgoldenrod3", 0xCDBE70 },
+ { "lightgoldenrod4", 0x8B814C },
+ { "lightgoldenrodyellow", 0xFAFAD2 },
+ { "lightgray", 0xD3D3D3 },
+ { "lightgreen", 0x90EE90 },
+ { "lightgrey", 0xD3D3D3 },
+ { "lightpink", 0xFFB6C1 },
+ { "lightpink1", 0xFFAEB9 },
+ { "lightpink2", 0xEEA2AD },
+ { "lightpink3", 0xCD8C95 },
+ { "lightpink4", 0x8B5F65 },
+ { "lightsalmon", 0xFFA07A },
+ { "lightsalmon1", 0xFFA07A },
+ { "lightsalmon2", 0xEE9572 },
+ { "lightsalmon3", 0xCD8162 },
+ { "lightsalmon4", 0x8B5742 },
+ { "lightseagreen", 0x20B2AA },
+ { "lightskyblue", 0x87CEFA },
+ { "lightskyblue1", 0xB0E2FF },
+ { "lightskyblue2", 0xA4D3EE },
+ { "lightskyblue3", 0x8DB6CD },
+ { "lightskyblue4", 0x607B8B },
+ { "lightslateblue", 0x8470FF },
+ { "lightslategray", 0x778899 },
+ { "lightslategrey", 0x778899 },
+ { "lightsteelblue", 0xB0C4DE },
+ { "lightsteelblue1", 0xCAE1FF },
+ { "lightsteelblue2", 0xBCD2EE },
+ { "lightsteelblue3", 0xA2B5CD },
+ { "lightsteelblue4", 0x6E7B8B },
+ { "lightyellow", 0xFFFFE0 },
+ { "lightyellow1", 0xFFFFE0 },
+ { "lightyellow2", 0xEEEED1 },
+ { "lightyellow3", 0xCDCDB4 },
+ { "lightyellow4", 0x8B8B7A },
+ { "lime", 0x00FF00 },
+ { "limegreen", 0x32CD32 },
+ { "linen", 0xFAF0E6 },
+ { "magenta", 0xFF00FF },
+ { "magenta1", 0xFF00FF },
+ { "magenta2", 0xEE00EE },
+ { "magenta3", 0xCD00CD },
+ { "magenta4", 0x8B008B },
+ { "maroon", 0x800000 },
+ { "maroon", 0xB03060 },
+ { "maroon1", 0xFF34B3 },
+ { "maroon2", 0xEE30A7 },
+ { "maroon3", 0xCD2990 },
+ { "maroon4", 0x8B1C62 },
+ { "mediumaquamarine", 0x66CDAA },
+ { "mediumblue", 0x0000CD },
+ { "mediumforestgreen", 0x32814B },
+ { "mediumgoldenrod", 0xD1C166 },
+ { "mediumorchid", 0xBA55D3 },
+ { "mediumorchid1", 0xE066FF },
+ { "mediumorchid2", 0xD15FEE },
+ { "mediumorchid3", 0xB452CD },
+ { "mediumorchid4", 0x7A378B },
+ { "mediumpurple", 0x9370DB },
+ { "mediumpurple1", 0xAB82FF },
+ { "mediumpurple2", 0x9F79EE },
+ { "mediumpurple3", 0x8968CD },
+ { "mediumpurple4", 0x5D478B },
+ { "mediumseagreen", 0x3CB371 },
+ { "mediumslateblue", 0x7B68EE },
+ { "mediumspringgreen", 0x00FA9A },
+ { "mediumturquoise", 0x48D1CC },
+ { "mediumvioletred", 0xC71585 },
+ { "midnightblue", 0x191970 },
+ { "mintcream", 0xF5FFFA },
+ { "mistyrose", 0xFFE4E1 },
+ { "mistyrose1", 0xFFE4E1 },
+ { "mistyrose2", 0xEED5D2 },
+ { "mistyrose3", 0xCDB7B5 },
+ { "mistyrose4", 0x8B7D7B },
+ { "moccasin", 0xFFE4B5 },
+ { "navajowhite", 0xFFDEAD },
+ { "navajowhite1", 0xFFDEAD },
+ { "navajowhite2", 0xEECFA1 },
+ { "navajowhite3", 0xCDB38B },
+ { "navajowhite4", 0x8B795E },
+ { "navy", 0x000080 },
+ { "navyblue", 0x000080 },
+ { "none", 0x0000FF },
+ { "oldlace", 0xFDF5E6 },
+ { "olive", 0x808000 },
+ { "olivedrab", 0x6B8E23 },
+ { "olivedrab1", 0xC0FF3E },
+ { "olivedrab2", 0xB3EE3A },
+ { "olivedrab3", 0x9ACD32 },
+ { "olivedrab4", 0x698B22 },
+ { "opaque", 0x000000 },
+ { "orange", 0xFFA500 },
+ { "orange1", 0xFFA500 },
+ { "orange2", 0xEE9A00 },
+ { "orange3", 0xCD8500 },
+ { "orange4", 0x8B5A00 },
+ { "orangered", 0xFF4500 },
+ { "orangered1", 0xFF4500 },
+ { "orangered2", 0xEE4000 },
+ { "orangered3", 0xCD3700 },
+ { "orangered4", 0x8B2500 },
+ { "orchid", 0xDA70D6 },
+ { "orchid1", 0xFF83FA },
+ { "orchid2", 0xEE7AE9 },
+ { "orchid3", 0xCD69C9 },
+ { "orchid4", 0x8B4789 },
+ { "palegoldenrod", 0xEEE8AA },
+ { "palegreen", 0x98FB98 },
+ { "palegreen1", 0x9AFF9A },
+ { "palegreen2", 0x90EE90 },
+ { "palegreen3", 0x7CCD7C },
+ { "palegreen4", 0x548B54 },
+ { "paleturquoise", 0xAFEEEE },
+ { "paleturquoise1", 0xBBFFFF },
+ { "paleturquoise2", 0xAEEEEE },
+ { "paleturquoise3", 0x96CDCD },
+ { "paleturquoise4", 0x668B8B },
+ { "palevioletred", 0xDB7093 },
+ { "palevioletred1", 0xFF82AB },
+ { "palevioletred2", 0xEE799F },
+ { "palevioletred3", 0xCD6889 },
+ { "palevioletred4", 0x8B475D },
+ { "papayawhip", 0xFFEFD5 },
+ { "peachpuff", 0xFFDAB9 },
+ { "peachpuff1", 0xFFDAB9 },
+ { "peachpuff2", 0xEECBAD },
+ { "peachpuff3", 0xCDAF95 },
+ { "peachpuff4", 0x8B7765 },
+ { "peru", 0xCD853F },
+ { "pink", 0xFFC0CB },
+ { "pink1", 0xFFB5C5 },
+ { "pink2", 0xEEA9B8 },
+ { "pink3", 0xCD919E },
+ { "pink4", 0x8B636C },
+ { "plum", 0xDDA0DD },
+ { "plum1", 0xFFBBFF },
+ { "plum2", 0xEEAEEE },
+ { "plum3", 0xCD96CD },
+ { "plum4", 0x8B668B },
+ { "powderblue", 0xB0E0E6 },
+ { "purple", 0x800080 },
+ { "purple", 0xA020F0 },
+ { "purple1", 0x9B30FF },
+ { "purple2", 0x912CEE },
+ { "purple3", 0x7D26CD },
+ { "purple4", 0x551A8B },
+ { "red", 0xFF0000 },
+ { "red1", 0xFF0000 },
+ { "red2", 0xEE0000 },
+ { "red3", 0xCD0000 },
+ { "red4", 0x8B0000 },
+ { "rosybrown", 0xBC8F8F },
+ { "rosybrown1", 0xFFC1C1 },
+ { "rosybrown2", 0xEEB4B4 },
+ { "rosybrown3", 0xCD9B9B },
+ { "rosybrown4", 0x8B6969 },
+ { "royalblue", 0x4169E1 },
+ { "royalblue1", 0x4876FF },
+ { "royalblue2", 0x436EEE },
+ { "royalblue3", 0x3A5FCD },
+ { "royalblue4", 0x27408B },
+ { "saddlebrown", 0x8B4513 },
+ { "salmon", 0xFA8072 },
+ { "salmon1", 0xFF8C69 },
+ { "salmon2", 0xEE8262 },
+ { "salmon3", 0xCD7054 },
+ { "salmon4", 0x8B4C39 },
+ { "sandybrown", 0xF4A460 },
+ { "seagreen", 0x2E8B57 },
+ { "seagreen1", 0x54FF9F },
+ { "seagreen2", 0x4EEE94 },
+ { "seagreen3", 0x43CD80 },
+ { "seagreen4", 0x2E8B57 },
+ { "seashell", 0xFFF5EE },
+ { "seashell1", 0xFFF5EE },
+ { "seashell2", 0xEEE5DE },
+ { "seashell3", 0xCDC5BF },
+ { "seashell4", 0x8B8682 },
+ { "sienna", 0xA0522D },
+ { "sienna1", 0xFF8247 },
+ { "sienna2", 0xEE7942 },
+ { "sienna3", 0xCD6839 },
+ { "sienna4", 0x8B4726 },
+ { "silver", 0xC0C0C0 },
+ { "skyblue", 0x87CEEB },
+ { "skyblue1", 0x87CEFF },
+ { "skyblue2", 0x7EC0EE },
+ { "skyblue3", 0x6CA6CD },
+ { "skyblue4", 0x4A708B },
+ { "slateblue", 0x6A5ACD },
+ { "slateblue1", 0x836FFF },
+ { "slateblue2", 0x7A67EE },
+ { "slateblue3", 0x6959CD },
+ { "slateblue4", 0x473C8B },
+ { "slategray", 0x708090 },
+ { "slategray1", 0xC6E2FF },
+ { "slategray2", 0xB9D3EE },
+ { "slategray3", 0x9FB6CD },
+ { "slategray4", 0x6C7B8B },
+ { "slategrey", 0x708090 },
+ { "snow", 0xFFFAFA },
+ { "snow1", 0xFFFAFA },
+ { "snow2", 0xEEE9E9 },
+ { "snow3", 0xCDC9C9 },
+ { "snow4", 0x8B8989 },
+ { "springgreen", 0x00FF7F },
+ { "springgreen1", 0x00FF7F },
+ { "springgreen2", 0x00EE76 },
+ { "springgreen3", 0x00CD66 },
+ { "springgreen4", 0x008B45 },
+ { "steelblue", 0x4682B4 },
+ { "steelblue1", 0x63B8FF },
+ { "steelblue2", 0x5CACEE },
+ { "steelblue3", 0x4F94CD },
+ { "steelblue4", 0x36648B },
+ { "tan", 0xD2B48C },
+ { "tan1", 0xFFA54F },
+ { "tan2", 0xEE9A49 },
+ { "tan3", 0xCD853F },
+ { "tan4", 0x8B5A2B },
+ { "teal", 0x008080 },
+ { "thistle", 0xD8BFD8 },
+ { "thistle1", 0xFFE1FF },
+ { "thistle2", 0xEED2EE },
+ { "thistle3", 0xCDB5CD },
+ { "thistle4", 0x8B7B8B },
+ { "tomato", 0xFF6347 },
+ { "tomato1", 0xFF6347 },
+ { "tomato2", 0xEE5C42 },
+ { "tomato3", 0xCD4F39 },
+ { "tomato4", 0x8B3626 },
+ { "transparent", 0x0000FF },
+ { "turquoise", 0x40E0D0 },
+ { "turquoise1", 0x00F5FF },
+ { "turquoise2", 0x00E5EE },
+ { "turquoise3", 0x00C5CD },
+ { "turquoise4", 0x00868B },
+ { "violet", 0xEE82EE },
+ { "violetred", 0xD02090 },
+ { "violetred1", 0xFF3E96 },
+ { "violetred2", 0xEE3A8C },
+ { "violetred3", 0xCD3278 },
+ { "violetred4", 0x8B2252 },
+ { "wheat", 0xF5DEB3 },
+ { "wheat1", 0xFFE7BA },
+ { "wheat2", 0xEED8AE },
+ { "wheat3", 0xCDBA96 },
+ { "wheat4", 0x8B7E66 },
+ { "white", 0xFFFFFF },
+ { "whitesmoke", 0xF5F5F5 },
+ { "yellow", 0xFFFF00 },
+ { "yellow1", 0xFFFF00 },
+ { "yellow2", 0xEEEE00 },
+ { "yellow3", 0xCDCD00 },
+ { "yellow4", 0x8B8B00 },
+ { "yellowgreen", 0x9ACD32 },
+ { NULL, 0x000000 }
+};
+
+uint32_t hb_rgb_lookup_by_name(const char *color)
+{
+ int ii = 0;
+
+ while (colormap[ii].name != NULL)
+ {
+ if (!strcasecmp(color, colormap[ii].name))
+ return colormap[ii].rgb;
+ ii++;
+ }
+ return 0;
+}
+
diff --git a/libhb/colormap.h b/libhb/colormap.h
new file mode 100644
index 000000000..ab049aa0b
--- /dev/null
+++ b/libhb/colormap.h
@@ -0,0 +1,20 @@
+/* colormap.h
+ *
+ * Copyright (c) 2003-2014 HandBrake Team
+ * This file is part of the HandBrake source code
+ * Homepage: <http://handbrake.fr/>.
+ * It may be used under the terms of the GNU General Public License v2.
+ * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+#ifndef HB_COLORMAP_H
+#define HB_COLORMAP_H
+
+#define HB_RGB_TO_BGR(c) (((c & 0xff0000) >> 16) | \
+ ((c & 0x00ff00) ) | \
+ ((c & 0x0000ff) << 16))
+#define HB_BGR_TO_RGB(c) HB_RGB_TO_BGR(c)
+
+uint32_t hb_rgb_lookup_by_name(const char *color);
+
+#endif // HB_COLORMAP_H
diff --git a/libhb/common.c b/libhb/common.c
index 8f206c69f..b689facd4 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -3728,7 +3728,6 @@ int hb_srt_add( const hb_job_t * job,
strncpy( subtitle->iso639_2, lang, 4 );
subtitle->config = *subtitlecfg;
- subtitle->config.dest = PASSTHRUSUB;
hb_list_add(job->list_subtitle, subtitle);
retval = 1;
@@ -3743,7 +3742,9 @@ int hb_subtitle_can_force( int source )
int hb_subtitle_can_burn( int source )
{
- return source == VOBSUB || source == PGSSUB || source == SSASUB;
+ return source == VOBSUB || source == PGSSUB || source == SSASUB ||
+ source == SRTSUB || source == CC608SUB || source == UTF8SUB ||
+ source == TX3GSUB;
}
int hb_subtitle_can_pass( int source, int mux )
diff --git a/libhb/deccc608sub.c b/libhb/deccc608sub.c
index c18fa76b8..d732ae21e 100644
--- a/libhb/deccc608sub.c
+++ b/libhb/deccc608sub.c
@@ -1,5 +1,5 @@
/*
- * From ccextractor, leave this file as intact and close to the original as possible so that
+ * From ccextractor, leave this file as intact and close to the original as possible so that
* it is easy to patch in fixes - even though this file contains code that we don't need.
*
* Note that the SRT sub generation from CC could be useful for mkv subs.
@@ -15,13 +15,9 @@ static int trim_subs = 1;
static int nofontcolor = 0;
static enum encoding_type encoding = ENC_UTF_8;
static int cc_channel = 1;
-static enum output_format write_format = OF_SRT;
static int sentence_cap = 0;
static int subs_delay = 0;
-static int64_t screens_to_process = -1;
-static int processed_enough = 0;
-static int gui_mode_reports = 0;
-static int norollup = 1;
+static int norollup = 0;
static int direct_rollup = 0;
/*
@@ -33,14 +29,13 @@ static int64_t get_fts(struct s_write *wb)
}
#define fatal(N, ...) // N
-#define XMLRPC_APPEND(N, ...) // N
int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10};
// Relationship between the first PAC byte and the row number
// The following enc_buffer is not used at the moment, if it does get used
// we need to bring it into the swrite struct. Same for "str".
-#define INITIAL_ENC_BUFFER_CAPACITY 2048
+#define INITIAL_ENC_BUFFER_CAPACITY 2048
unsigned char str[2048]; // Another generic general purpose buffer
@@ -51,7 +46,7 @@ unsigned char str[2048]; // Another generic general purpose buffer
const unsigned char pac2_attribs[][3]= // Color, font, ident
{
- {COL_WHITE, FONT_REGULAR, 0}, // 0x40 || 0x60
+ {COL_WHITE, FONT_REGULAR, 0}, // 0x40 || 0x60
{COL_WHITE, FONT_UNDERLINED, 0}, // 0x41 || 0x61
{COL_GREEN, FONT_REGULAR, 0}, // 0x42 || 0x62
{COL_GREEN, FONT_UNDERLINED, 0}, // 0x43 || 0x63
@@ -86,7 +81,7 @@ const unsigned char pac2_attribs[][3]= // Color, font, ident
};
// Preencoded strings
-unsigned char encoded_crlf[16];
+unsigned char encoded_crlf[16];
unsigned int encoded_crlf_length;
unsigned char encoded_br[16];
unsigned int encoded_br_length;
@@ -95,19 +90,6 @@ unsigned int encoded_br_length;
unsigned char usercolor_rgb[8]="";
enum color_code default_color=COL_WHITE;
-const char *sami_header= // TODO: Revise the <!-- comments
-"<SAMI>\n\
-<HEAD>\n\
-<STYLE TYPE=\"text/css\">\n\
-<!--\n\
-P {margin-left: 16pt; margin-right: 16pt; margin-bottom: 16pt; margin-top: 16pt;\n\
-text-align: center; font-size: 18pt; font-family: arial; font-weight: bold; color: #f0f0f0;}\n\
-.UNKNOWNCC {Name:Unknown; lang:en-US; SAMIType:CC;}\n\
--->\n\
-</STYLE>\n\
-</HEAD>\n\n\
-<BODY>\n";
-
const char *command_type[] =
{
"Unknown",
@@ -155,7 +137,7 @@ int general_608_init (struct s_write *wb)
{
if( !wb->enc_buffer )
{
- wb->enc_buffer=(unsigned char *) malloc (INITIAL_ENC_BUFFER_CAPACITY);
+ wb->enc_buffer=(unsigned char *) malloc (INITIAL_ENC_BUFFER_CAPACITY);
if (wb->enc_buffer==NULL)
return -1;
wb->enc_buffer_capacity=INITIAL_ENC_BUFFER_CAPACITY;
@@ -163,7 +145,7 @@ int general_608_init (struct s_write *wb)
if( !wb->subline) {
wb->subline = malloc(2048);
-
+
if (!wb->subline)
{
return -1;
@@ -207,8 +189,8 @@ void general_608_close (struct s_write *wb)
void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
{
unsigned char c1='?';
- if (c<0x80)
- {
+ if (c<0x80)
+ {
// Regular line-21 character set, mostly ASCII except these exceptions
switch (c)
{
@@ -220,7 +202,7 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
break;
case 0x5e: // lowercase i, acute accent
c1=0xed;
- break;
+ break;
case 0x5f: // lowercase o, acute accent
c1=0xf3;
break;
@@ -249,25 +231,25 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
switch (c)
{
// THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
+ // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
case 0x80: // Registered symbol (R)
c1=0xae;
- break;
+ break;
case 0x81: // degree sign
c1=0xb0;
break;
- case 0x82: // 1/2 symbol
+ case 0x82: // 1/2 symbol
c1=0xbd;
break;
- case 0x83: // Inverted (open) question mark
+ case 0x83: // Inverted (open) question mark
c1=0xbf;
break;
case 0x84: // Trademark symbol (TM) - Does not exist in Latin 1
- break;
- case 0x85: // Cents symbol
+ break;
+ case 0x85: // Cents symbol
c1=0xa2;
break;
- case 0x86: // Pounds sterling
+ case 0x86: // Pounds sterling
c1=0xa3;
break;
case 0x87: // Music note - Not in latin 1, so we use 'pilcrow'
@@ -277,7 +259,7 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
c1=0xe0;
break;
case 0x89: // transparent space, we make it regular
- c1=0x20;
+ c1=0x20;
break;
case 0x8a: // lowercase e, grave accent
c1=0xe8;
@@ -286,7 +268,7 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
c1=0xe2;
break;
case 0x8c: // lowercase e, circumflex accent
- c1=0xea;
+ c1=0xea;
break;
case 0x8d: // lowercase i, circumflex accent
c1=0xee;
@@ -318,19 +300,19 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
c1=0xfc;
break;
case 0x96: // apostrophe
- c1=0x27;
+ c1=0x27;
break;
- case 0x97: // inverted exclamation mark
+ case 0x97: // inverted exclamation mark
c1=0xa1;
break;
case 0x98: // asterisk
- c1=0x2a;
+ c1=0x2a;
break;
case 0x99: // apostrophe (yes, duped). See CCADI source code.
- c1=0x27;
+ c1=0x27;
break;
case 0x9a: // hyphen-minus
- c1=0x2d;
+ c1=0x2d;
break;
case 0x9b: // copyright sign
c1=0xa9;
@@ -341,17 +323,17 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
c1=0x2e;
break;
case 0x9e: // Quoatation mark
- c1=0x22;
+ c1=0x22;
break;
case 0x9f: // Quoatation mark
- c1=0x22;
+ c1=0x22;
break;
case 0xa0: // uppercase A, grave accent
c1=0xc0;
break;
case 0xa1: // uppercase A, circumflex
c1=0xc2;
- break;
+ break;
case 0xa2: // uppercase C with cedilla
c1=0xc7;
break;
@@ -427,7 +409,7 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
c1=0x7b;
break;
case 0xba: // Closing curly brace
- c1=0x7d;
+ c1=0x7d;
break;
case 0xbb: // Backslash
c1=0x5c;
@@ -438,17 +420,17 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
case 0xbd: // Underscore
c1=0x5f;
break;
- case 0xbe: // Pipe (broken bar)
+ case 0xbe: // Pipe (broken bar)
c1=0xa6;
break;
case 0xbf: // Tilde
- c1=0x7e;
+ c1=0x7e;
break;
- case 0xc0: // Uppercase A, umlaut
+ case 0xc0: // Uppercase A, umlaut
c1=0xc4;
break;
case 0xc1: // Lowercase A, umlaut
- c1=0xe3;
+ c1=0xe3;
break;
case 0xc2: // Uppercase O, umlaut
c1=0xd6;
@@ -464,10 +446,10 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
break;
case 0xc6: // Currency symbol
c1=0xa4;
- break;
+ break;
case 0xc7: // Vertical bar
c1=0x7c;
- break;
+ break;
case 0xc8: // Uppercase A, ring
c1=0xc5;
break;
@@ -488,7 +470,7 @@ void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
*buffer='?'; // I'll do it eventually, I promise
break; // This are weird chars anyway
}
- *buffer=c1;
+ *buffer=c1;
}
void get_char_in_unicode (unsigned char *buffer, unsigned char c)
@@ -496,7 +478,7 @@ void get_char_in_unicode (unsigned char *buffer, unsigned char c)
unsigned char c1,c2;
switch (c)
{
- case 0x84: // Trademark symbol (TM)
+ case 0x84: // Trademark symbol (TM)
c2=0x21;
c1=0x22;
break;
@@ -511,7 +493,7 @@ void get_char_in_unicode (unsigned char *buffer, unsigned char c)
case 0xcc: // Upper left corner
c2=0x23;
c1=0x1c;
- break;
+ break;
case 0xcd: // Upper right corner
c2=0x23;
c1=0x1d;
@@ -524,7 +506,7 @@ void get_char_in_unicode (unsigned char *buffer, unsigned char c)
c2=0x23;
c1=0x1f;
break;
- default: // Everything else, same as latin-1 followed by 00
+ default: // Everything else, same as latin-1 followed by 00
get_char_in_latin_1 (&c1,c);
c2=0;
break;
@@ -585,10 +567,10 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
switch (c)
{
// THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
+ // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
case 0x80: // Registered symbol (R)
*buffer=0xc2;
- *(buffer+1)=0xae;
+ *(buffer+1)=0xae;
return 2;
case 0x81: // degree sign
*buffer=0xc2;
@@ -615,7 +597,7 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*buffer=0xc2;
*(buffer+1)=0xa3;
return 2;
- case 0x87: // Music note
+ case 0x87: // Music note
*buffer=0xe2;
*(buffer+1)=0x99;
*(buffer+2)=0xaa;
@@ -625,7 +607,7 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*(buffer+1)=0xa0;
return 2;
case 0x89: // transparent space, we make it regular
- *buffer=0x20;
+ *buffer=0x20;
return 1;
case 0x8a: // lowercase e, grave accent
*buffer=0xc3;
@@ -678,38 +660,38 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*(buffer+1)=0xbc;
return 2;
case 0x96: // apostrophe
- *buffer=0x27;
+ *buffer=0x27;
return 1;
case 0x97: // inverted exclamation mark
*buffer=0xc2;
*(buffer+1)=0xa1;
return 2;
case 0x98: // asterisk
- *buffer=0x2a;
+ *buffer=0x2a;
return 1;
case 0x99: // apostrophe (yes, duped). See CCADI source code.
- *buffer=0x27;
+ *buffer=0x27;
return 1;
case 0x9a: // hyphen-minus
- *buffer=0x2d;
+ *buffer=0x2d;
return 1;
case 0x9b: // copyright sign
*buffer=0xc2;
*(buffer+1)=0xa9;
return 2;
- case 0x9c: // Service mark
- *buffer=0xe2;
+ case 0x9c: // Service mark
+ *buffer=0xe2;
*(buffer+1)=0x84;
*(buffer+2)=0xa0;
return 3;
case 0x9d: // Full stop (.)
- *buffer=0x2e;
+ *buffer=0x2e;
return 1;
case 0x9e: // Quoatation mark
- *buffer=0x22;
+ *buffer=0x22;
return 1;
case 0x9f: // Quoatation mark
- *buffer=0x22;
+ *buffer=0x22;
return 1;
case 0xa0: // uppercase A, grave accent
*buffer=0xc3;
@@ -817,7 +799,7 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*buffer=0x7b;
return 1;
case 0xba: // Closing curly brace
- *buffer=0x7d;
+ *buffer=0x7d;
return 1;
case 0xbb: // Backslash
*buffer=0x5c;
@@ -829,26 +811,26 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*buffer=0x5f;
return 1;
case 0xbe: // Pipe (broken bar)
- *buffer=0xc2;
+ *buffer=0xc2;
*(buffer+1)=0xa6;
return 1;
case 0xbf: // Tilde
*buffer=0x7e; // Not sure
return 1;
case 0xc0: // Uppercase A, umlaut
- *buffer=0xc3;
+ *buffer=0xc3;
*(buffer+1)=0x84;
return 2;
case 0xc1: // Lowercase A, umlaut
- *buffer=0xc3;
+ *buffer=0xc3;
*(buffer+1)=0xa4;
return 2;
case 0xc2: // Uppercase O, umlaut
- *buffer=0xc3;
+ *buffer=0xc3;
*(buffer+1)=0x96;
return 2;
case 0xc3: // Lowercase o, umlaut
- *buffer=0xc3;
+ *buffer=0xc3;
*(buffer+1)=0xb6;
return 2;
case 0xc4: // Esszett (sharp S)
@@ -864,7 +846,7 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*(buffer+1)=0xa4;
return 2;
case 0xc7: // Vertical bar
- *buffer=0x7c;
+ *buffer=0x7c;
return 1;
case 0xc8: // Uppercase A, ring
*buffer=0xc3;
@@ -902,7 +884,7 @@ int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number
*(buffer+1)=0x8c;
*(buffer+2)=0x9f;
return 3;
- default: //
+ default: //
*buffer='?'; // I'll do it eventually, I promise
return 1; // This are weird chars anyway
}
@@ -919,35 +901,35 @@ unsigned char cctolower (unsigned char c)
case 0x90: // capital letter A with acute
return 0x2a;
case 0x91: // capital letter E with acute
- return 0x5c;
+ return 0x5c;
case 0x92: // capital letter O with acute
- return 0x5f;
+ return 0x5f;
case 0x93: // capital letter U with acute
- return 0x60;
+ return 0x60;
case 0xa2: // uppercase C with cedilla
- return 0x7b;
+ return 0x7b;
case 0xa0: // uppercase A, grave accent
- return 0x88;
+ return 0x88;
case 0xa3: // uppercase E, grave accent
- return 0x8a;
+ return 0x8a;
case 0xa1: // uppercase A, circumflex
- return 0x8b;
+ return 0x8b;
case 0xa4: // uppercase E, circumflex
- return 0x8c;
+ return 0x8c;
case 0xa7: // uppercase I, circumflex
- return 0x8d;
+ return 0x8d;
case 0xaa: // uppercase O, circumflex
- return 0x8e;
+ return 0x8e;
case 0xad: // uppercase U, circumflex
- return 0x8f;
+ return 0x8f;
case 0x94: // capital letter U with diaresis
- return 0x95;
+ return 0x95;
case 0xa5: // capital letter E with diaresis
- return 0xa6;
+ return 0xa6;
case 0xa8: // uppercase I, with diaresis
- return 0xa9;
+ return 0xa9;
case 0xab: // uppercase U, grave accent
- return 0xac;
+ return 0xac;
case 0xb0: // Uppercase A, tilde
return 0xb1;
case 0xb2: // Uppercase I, acute accent
@@ -1013,21 +995,21 @@ unsigned char cctoupper (unsigned char c)
case 0xac: // lowercase u, grave accent
return 0xab;
case 0xb1: // Lowercase a, tilde
- return 0xb0;
+ return 0xb0;
case 0xb4: // Lowercase i, grave accent
return 0xb3;
case 0xb6: // Lowercase o, grave accent
- return 0xb5;
- case 0xb8: // Lowercase o, tilde
+ return 0xb5;
+ case 0xb8: // Lowercase o, tilde
return 0xb7;
- case 0xc1: // Lowercase A, umlaut
- return 0xc0;
+ case 0xc1: // Lowercase A, umlaut
+ return 0xc0;
case 0xc3: // Lowercase o, umlaut
return 0xc2;
case 0xc9: // Lowercase A, ring
- return 0xc8;
+ return 0xc8;
case 0xcb: // Lowercase o, slash
- return 0xca;
+ return 0xca;
}
return c;
}
@@ -1035,12 +1017,12 @@ unsigned char cctoupper (unsigned char c)
// Encodes a generic string. Note that since we use the encoders for closed caption
// data, text would have to be encoded as CCs... so using special characters here
-// it's a bad idea.
+// it's a bad idea.
unsigned encode_line (unsigned char *buffer, unsigned char *text)
-{
+{
unsigned bytes=0;
while (*text)
- {
+ {
switch (encoding)
{
case ENC_UTF_8:
@@ -1049,13 +1031,13 @@ unsigned encode_line (unsigned char *buffer, unsigned char *text)
bytes++;
buffer++;
break;
- case ENC_UNICODE:
- *buffer=*text;
+ case ENC_UNICODE:
+ *buffer=*text;
*(buffer+1)=0;
- bytes+=2;
+ bytes+=2;
buffer+=2;
break;
- }
+ }
text++;
}
return bytes;
@@ -1086,7 +1068,7 @@ void correct_case (int line_num, struct eia608_screen *data)
/* if (c-(char *) data->characters[line_num]+len==CC608_SCREEN_WIDTH) // End of line... */
/* next=' '; // ... pretend we have a blank later */
/* else */
-/* next=*(c+len); */
+/* next=*(c+len); */
/* if ( ISSEPARATOR(prev) && ISSEPARATOR(next)) */
/* { */
/* memcpy (c,spell_correct[i],len); */
@@ -1105,10 +1087,10 @@ void capitalize (int line_num, struct eia608_screen *data, int *new_sentence)
{
switch (data->characters[line_num][i])
{
- case ' ':
+ case ' ':
case 0x89: // This is a transparent space
case '-':
- break;
+ break;
case '.': // Fallthrough
case '?': // Fallthrough
case '!':
@@ -1116,7 +1098,7 @@ void capitalize (int line_num, struct eia608_screen *data, int *new_sentence)
*new_sentence=1;
break;
default:
- if (*new_sentence)
+ if (*new_sentence)
data->characters[line_num][i]=cctoupper (data->characters[line_num][i]);
else
data->characters[line_num][i]=cctolower (data->characters[line_num][i]);
@@ -1174,7 +1156,7 @@ unsigned get_decoder_line_basic (unsigned char *buffer, int line_num, struct eia
break;
case ENC_UNICODE:
get_char_in_unicode (buffer,c);
- bytes=2;
+ bytes=2;
break;
}
buffer+=bytes;
@@ -1183,38 +1165,20 @@ unsigned get_decoder_line_basic (unsigned char *buffer, int line_num, struct eia
return (unsigned) (buffer-orig); // Return length
}
-unsigned get_decoder_line_encoded_for_gui (unsigned char *buffer, int line_num, struct eia608_screen *data)
-{
- unsigned char *line = data->characters[line_num];
- unsigned char *orig=buffer; // Keep for debugging
- int first=0, last=31;
- int i;
-
- find_limit_characters(line,&first,&last);
- for (i=first;i<=last;i++)
- {
- get_char_in_latin_1 (buffer,line[i]);
- buffer++;
- }
- *buffer=0;
- return (unsigned) (buffer-orig); // Return length
-
-}
-
unsigned get_decoder_line_encoded (unsigned char *buffer, int line_num, struct eia608_screen *data)
{
int col = COL_WHITE;
int underlined = 0;
- int italics = 0;
+ int italics = 0;
int i;
- unsigned char *line = data->characters[line_num];
+ unsigned char *line = data->characters[line_num];
unsigned char *orig=buffer; // Keep for debugging
int first=0, last=31;
if (trim_subs)
find_limit_characters(line,&first,&last);
for (i=first;i<=last;i++)
- {
+ {
// Handle color
int its_col = data->colors[line_num][i];
if (its_col != col && !nofontcolor)
@@ -1227,11 +1191,11 @@ unsigned get_decoder_line_encoded (unsigned char *buffer, int line_num, struct e
buffer+=encode_line (buffer, (unsigned char*) color_text[its_col][1]);
if (its_col==COL_USERDEFINED)
{
- // The previous sentence doesn't copy the whole
+ // The previous sentence doesn't copy the whole
// <font> tag, just up to the quote before the color
buffer+=encode_line (buffer, (unsigned char*) usercolor_rgb);
buffer+=encode_line (buffer, (unsigned char*) "\">");
- }
+ }
col = its_col;
}
@@ -1244,10 +1208,10 @@ unsigned get_decoder_line_encoded (unsigned char *buffer, int line_num, struct e
if (is_underlined==0 && underlined) // Close underline
{
buffer+=encode_line (buffer, (unsigned char *) "</u>");
- }
+ }
underlined=is_underlined;
// Handle italics
- int has_ita = data->fonts[line_num][i] & FONT_ITALICS;
+ int has_ita = data->fonts[line_num][i] & FONT_ITALICS;
if (has_ita && italics==0) // Open italics
{
buffer+=encode_line (buffer, (unsigned char *) "<i>");
@@ -1255,7 +1219,7 @@ unsigned get_decoder_line_encoded (unsigned char *buffer, int line_num, struct e
if (has_ita==0 && italics) // Close italics
{
buffer+=encode_line (buffer, (unsigned char *) "</i>");
- }
+ }
italics=has_ita;
int bytes=0;
switch (encoding)
@@ -1269,10 +1233,10 @@ unsigned get_decoder_line_encoded (unsigned char *buffer, int line_num, struct e
break;
case ENC_UNICODE:
get_char_in_unicode (buffer,line[i]);
- bytes=2;
+ bytes=2;
break;
}
- buffer+=bytes;
+ buffer+=bytes;
}
if (italics)
{
@@ -1299,10 +1263,10 @@ void delete_all_lines_but_current (struct eia608_screen *data, int row)
if (i!=row)
{
memset(data->characters[i],' ',CC608_SCREEN_WIDTH);
- data->characters[i][CC608_SCREEN_WIDTH]=0;
- memset (data->colors[i],default_color,CC608_SCREEN_WIDTH+1);
- memset (data->fonts[i],FONT_REGULAR,CC608_SCREEN_WIDTH+1);
- data->row_used[i]=0;
+ data->characters[i][CC608_SCREEN_WIDTH]=0;
+ memset (data->colors[i],default_color,CC608_SCREEN_WIDTH+1);
+ memset (data->fonts[i],FONT_REGULAR,CC608_SCREEN_WIDTH+1);
+ data->row_used[i]=0;
}
}
}
@@ -1314,10 +1278,10 @@ void clear_eia608_cc_buffer (struct eia608_screen *data)
for (i=0;i<15;i++)
{
memset(data->characters[i],' ',CC608_SCREEN_WIDTH);
- data->characters[i][CC608_SCREEN_WIDTH]=0;
- memset (data->colors[i],default_color,CC608_SCREEN_WIDTH+1);
- memset (data->fonts[i],FONT_REGULAR,CC608_SCREEN_WIDTH+1);
- data->row_used[i]=0;
+ data->characters[i][CC608_SCREEN_WIDTH]=0;
+ memset (data->colors[i],default_color,CC608_SCREEN_WIDTH+1);
+ memset (data->fonts[i],FONT_REGULAR,CC608_SCREEN_WIDTH+1);
+ data->row_used[i]=0;
}
data->empty=1;
}
@@ -1336,33 +1300,52 @@ void init_eia608 (struct eia608 *data)
data->current_visible_start_ms=0;
data->srt_counter=0;
data->screenfuls_counter=0;
- data->channel=1;
+ data->channel=1;
data->color=default_color;
data->font=FONT_REGULAR;
data->rollup_base_row=14;
}
+struct eia608_screen *get_current_hidden_buffer(struct s_write *wb)
+{
+ struct eia608_screen *data;
+ if (wb->data608->visible_buffer == 1)
+ data = &wb->data608->buffer2;
+ else
+ data = &wb->data608->buffer1;
+ return data;
+}
+
+struct eia608_screen *get_current_visible_buffer(struct s_write *wb)
+{
+ struct eia608_screen *data;
+ if (wb->data608->visible_buffer == 1)
+ data = &wb->data608->buffer1;
+ else
+ data = &wb->data608->buffer2;
+ return data;
+}
+
+static void swap_visible_buffer(struct s_write *wb)
+{
+ wb->data608->visible_buffer = (wb->data608->visible_buffer == 1) ? 2 : 1;
+}
+
struct eia608_screen *get_writing_buffer (struct s_write *wb)
{
struct eia608_screen *use_buffer=NULL;
switch (wb->data608->mode)
{
case MODE_POPUP: // Write on the non-visible buffer
- if (wb->data608->visible_buffer==1)
- use_buffer = &wb->data608->buffer2;
- else
- use_buffer = &wb->data608->buffer1;
+ use_buffer = get_current_hidden_buffer(wb);
break;
case MODE_ROLLUP_2: // Write directly to screen
case MODE_ROLLUP_3:
case MODE_ROLLUP_4:
- if (wb->data608->visible_buffer==1)
- use_buffer = &wb->data608->buffer1;
- else
- use_buffer = &wb->data608->buffer2;
+ use_buffer = get_current_visible_buffer(wb);
break;
default:
- fatal (EXIT_BUG_BUG, "Caption mode has an illegal value at get_writing_buffer(), this is a bug.\n");
+ fatal (EXIT_BUG_BUG, "Caption mode has an illegal value at get_writing_buffer(), this is a bug.\n");
}
return use_buffer;
}
@@ -1377,7 +1360,7 @@ void write_char (const unsigned char c, struct s_write *wb)
wb->data608->cursor_row,wb->data608->cursor_column); */
use_buffer->characters[wb->data608->cursor_row][wb->data608->cursor_column]=c;
use_buffer->colors[wb->data608->cursor_row][wb->data608->cursor_column]=wb->data608->color;
- use_buffer->fonts[wb->data608->cursor_row][wb->data608->cursor_column]=wb->data608->font;
+ use_buffer->fonts[wb->data608->cursor_row][wb->data608->cursor_column]=wb->data608->font;
use_buffer->row_used[wb->data608->cursor_row]=1;
use_buffer->empty=0;
if (wb->data608->cursor_column<31)
@@ -1427,25 +1410,6 @@ void mstotime (int64_t milli, unsigned *hours, unsigned *minutes,
*hours=(int) milli;
}
-void write_subtitle_file_footer (struct s_write *wb)
-{
- switch (write_format)
- {
- case OF_SAMI:
- sprintf ((char *) str,"</BODY></SAMI>\n");
- if (debug_608 && encoding!=ENC_UNICODE)
- {
- hb_log ("\r%s\n", str);
- }
- wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str);
- //fwrite (enc_buffer,enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
- break;
- default: // Nothing to do. Only SAMI has a footer
- break;
- }
-}
-
void fhb_log_encoded (FILE *fh, const char *string)
{
//GUARANTEE(wb, strlen (string)*3);
@@ -1453,135 +1417,7 @@ void fhb_log_encoded (FILE *fh, const char *string)
//fwrite (wb->enc_buffer,wb->enc_buffer_used,1,fh);
}
-void write_subtitle_file_header (struct s_write *wb)
-{
- switch (write_format)
- {
- case OF_SRT: // Subrip subtitles have no header
- break;
- case OF_SAMI: // This header brought to you by McPoodle's CCASDI
- //fhb_log_encoded (wb->fh, sami_header);
- GUARANTEE(wb, strlen (sami_header)*3);
- wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) sami_header);
- //fwrite (enc_buffer,enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
- break;
- case OF_RCWT: // Write header
- //fwrite (rcwt_header, sizeof(rcwt_header),1,wb->fh);
- break;
- case OF_TRANSCRIPT: // No header. Fall thru
- default:
- break;
- }
-}
-
-void write_cc_line_as_transcript (struct eia608_screen *data, struct s_write *wb, int line_number)
-{
- hb_buffer_t *buffer;
-
- if (sentence_cap)
- {
- capitalize(line_number,data, &wb->new_sentence);
- correct_case(line_number,data);
- }
- int length = get_decoder_line_basic (wb->subline, line_number, data);
- if (debug_608 && encoding!=ENC_UNICODE)
- {
- hb_log ("\r");
- hb_log ("%s\n",wb->subline);
- }
- if (length>0)
- {
- //fwrite (wb->subline, 1, length, wb->fh);
- /*
- * Put this subtitle in a hb_buffer_t and shove it into the subtitle fifo
- */
- buffer = hb_buffer_init( length + 1 );
- buffer->s.frametype = HB_FRAME_SUBTITLE;
- buffer->s.start = wb->data608->current_visible_start_ms;
- buffer->s.stop = get_fts(wb);
- memcpy( buffer->data, wb->subline, length + 1 );
- //hb_log("CC %"PRId64": %s", buffer->s.stop, wb->subline);
-
- if (wb->hb_last_buffer) {
- wb->hb_last_buffer->next = buffer;
- } else {
- wb->hb_buffer = buffer;
- }
- wb->hb_last_buffer = buffer;
-
- XMLRPC_APPEND(wb->subline,length);
- //fwrite (encoded_crlf, 1, encoded_crlf_length,wb->fh);
- XMLRPC_APPEND(encoded_crlf,encoded_crlf_length);
- }
- // fhb_log (wb->fh,encoded_crlf);
-}
-
-int write_cc_buffer_as_transcript (struct eia608_screen *data, struct s_write *wb)
-{
- int i;
-
- int wrote_something = 0;
- if (debug_608)
- {
- hb_log ("\n- - - TRANSCRIPT caption - - -\n");
- }
- for (i=0;i<15;i++)
- {
- if (data->row_used[i])
- {
- write_cc_line_as_transcript (data,wb, i);
- }
- wrote_something=1;
- }
- if (debug_608)
- {
- hb_log ("- - - - - - - - - - - -\r\n");
- }
- return wrote_something;
-}
-
-void write_cc_buffer_to_gui (struct eia608_screen *data, struct s_write *wb)
-{
- unsigned h1,m1,s1,ms1;
- unsigned h2,m2,s2,ms2;
- int i;
-
- int64_t ms_start= wb->data608->current_visible_start_ms;
-
- ms_start+=subs_delay;
- if (ms_start<0) // Drop screens that because of subs_delay start too early
- return;
- int time_reported=0;
- for (i=0;i<15;i++)
- {
- if (data->row_used[i])
- {
- hb_log ("###SUBTITLE#");
- if (!time_reported)
- {
- int64_t ms_end = get_fts(wb)+subs_delay;
- mstotime (ms_start,&h1,&m1,&s1,&ms1);
- mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
- // Note, only MM:SS here as we need to save space in the preview window
- hb_log ("%02u:%02u#%02u:%02u#",
- h1*60+m1,s1, h2*60+m2,s2);
- time_reported=1;
- }
- else
- hb_log ("##");
-
- // We don't capitalize here because whatever function that was used
- // before to write to file already took care of it.
- int length = get_decoder_line_encoded_for_gui (wb->subline, i, data);
- fwrite (wb->subline, 1, length, stderr);
- fwrite ("\n",1,1,stderr);
- }
- }
- fflush (stderr);
-}
-
-int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb)
+int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_write *wb)
{
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
@@ -1593,36 +1429,30 @@ int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb)
if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;
- int64_t ms_end = get_fts(wb)+subs_delay;
+ int64_t ms_end = get_fts(wb)+subs_delay;
mstotime (ms_start,&h1,&m1,&s1,&ms1);
mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
- char timeline[128];
+ char timeline[128];
wb->data608->srt_counter++;
sprintf (timeline,"%u\r\n",wb->data608->srt_counter);
- //wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) timeline);
- //fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
- //sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n",
- // h1,m1,s1,ms1, h2,m2,s2,ms2);
- //wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) timeline);
+
if (debug_608)
{
hb_log ("\n- - - SRT caption - - -\n");
hb_log ("%s", timeline);
}
- //fwrite (enc_buffer,enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
-
+
/*
* Write all the lines into enc_buffer, and then write that out at the end
* ensure that we only have two lines, insert a newline after the first one,
* and have a big bottom line (strip spaces from any joined lines).
*/
+ wb->enc_buffer_used = 0;
int line = 1;
for (i=0;i<15;i++)
{
if (data->row_used[i])
- {
+ {
if (sentence_cap)
{
capitalize(i,data, &wb->new_sentence);
@@ -1633,18 +1463,18 @@ int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb)
* here just in case..
*/
if (line == 1) {
- wb->enc_buffer_used = get_decoder_line_encoded (wb->enc_buffer, i, data);
+ wb->enc_buffer_used = get_decoder_line_encoded(wb->enc_buffer, i, data);
line = 2;
} else {
if (line == 2) {
- wb->enc_buffer_used += encode_line (wb->enc_buffer+wb->enc_buffer_used,
- (unsigned char *) "\n");
+ wb->enc_buffer_used += encode_line(wb->enc_buffer+wb->enc_buffer_used,
+ (unsigned char *) "\n");
line = 3;
} else {
- wb->enc_buffer_used += encode_line (wb->enc_buffer+wb->enc_buffer_used,
- (unsigned char *) " ");
+ wb->enc_buffer_used += encode_line(wb->enc_buffer+wb->enc_buffer_used,
+ (unsigned char *) " ");
}
- wb->enc_buffer_used += get_decoder_line_encoded (wb->enc_buffer+wb->enc_buffer_used, i, data);
+ wb->enc_buffer_used += get_decoder_line_encoded(wb->enc_buffer+wb->enc_buffer_used, i, data);
}
}
}
@@ -1661,126 +1491,40 @@ int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb)
wb->hb_buffer = buffer;
}
wb->hb_last_buffer = buffer;
-
- wrote_something=1;
- }
- if (debug_608)
- {
- hb_log ("- - - - - - - - - - - -\r\n");
- }
- // fhb_log (wb->fh, encoded_crlf);
- //fwrite (encoded_crlf, 1, encoded_crlf_length,wb->fh);
- XMLRPC_APPEND(encoded_crlf,encoded_crlf_length);
- return wrote_something;
-}
-int write_cc_buffer_as_sami (struct eia608_screen *data, struct s_write *wb)
-{
- int wrote_something=0;
- int64_t startms = wb->data608->current_visible_start_ms;
- int i;
-
- startms+=subs_delay;
- if (startms<0) // Drop screens that because of subs_delay start too early
- return 0;
-
- int64_t endms = get_fts(wb)+subs_delay;
- endms--; // To prevent overlapping with next line.
- sprintf ((char *) str,"<SYNC start=\"%"PRId64"\"><P class=\"UNKNOWNCC\">\r\n",startms);
- if (debug_608 && encoding!=ENC_UNICODE)
- {
- hb_log ("\r%s\n", str);
+ wrote_something=1;
+ wb->clear_sub_needed = 1;
}
- wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str);
- fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
- for (i=0;i<15;i++)
+ else if (wb->clear_sub_needed)
{
- if (data->row_used[i])
- {
- int length = get_decoder_line_encoded (wb->subline, i, data);
- if (debug_608 && encoding!=ENC_UNICODE)
- {
- hb_log ("\r");
- hb_log ("%s\n",wb->subline);
- }
- fwrite (wb->subline, 1, length, wb->fh);
- XMLRPC_APPEND(wb->subline,length);
- wrote_something=1;
- if (i!=14)
- {
- fwrite (encoded_br, 1, encoded_br_length,wb->fh);
- XMLRPC_APPEND(encoded_br, encoded_br_length);
- }
- fwrite (encoded_crlf, 1, encoded_crlf_length,wb->fh);
- XMLRPC_APPEND(encoded_crlf, encoded_crlf_length);
+ hb_buffer_t *buffer = hb_buffer_init( 1 );
+ buffer->s.frametype = HB_FRAME_SUBTITLE;
+ buffer->s.start = ms_start;
+ buffer->s.stop = ms_start;
+ buffer->data[0] = 0;
+ if (wb->hb_last_buffer != NULL) {
+ wb->hb_last_buffer->next = buffer;
+ } else {
+ wb->hb_buffer = buffer;
}
+ wb->hb_last_buffer = buffer;
+ wb->clear_sub_needed = 0;
}
- sprintf ((char *) str,"</P></SYNC>\r\n");
- if (debug_608 && encoding!=ENC_UNICODE)
- {
- hb_log ("\r%s\n", str);
- }
- wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str);
- fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
- sprintf ((char *) str,"<SYNC start=\"%"PRId64"\"><P class=\"UNKNOWNCC\">&nbsp;</P></SYNC>\r\n\r\n",endms);
- if (debug_608 && encoding!=ENC_UNICODE)
+ if (debug_608)
{
- hb_log ("\r%s\n", str);
+ hb_log ("- - - - - - - - - - - -\r\n");
}
- wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) str);
- fwrite (wb->enc_buffer,wb->enc_buffer_used,1,wb->fh);
- XMLRPC_APPEND(wb->enc_buffer,wb->enc_buffer_used);
return wrote_something;
}
-struct eia608_screen *get_current_visible_buffer (struct s_write *wb)
-{
- struct eia608_screen *data;
- if (wb->data608->visible_buffer==1)
- data = &wb->data608->buffer1;
- else
- data = &wb->data608->buffer2;
- return data;
-}
-
-
-int write_cc_buffer (struct s_write *wb)
+int write_cc_buffer(struct s_write *wb)
{
struct eia608_screen *data;
int wrote_something=0;
- if (screens_to_process!=-1 && wb->data608->screenfuls_counter>=screens_to_process)
- {
- // We are done.
- processed_enough=1;
- return 0;
- }
- if (wb->data608->visible_buffer==1)
- data = &wb->data608->buffer1;
- else
- data = &wb->data608->buffer2;
- if (!data->empty)
- {
- wb->new_sentence=1;
- switch (write_format)
- {
- case OF_SRT:
- wrote_something = write_cc_buffer_as_srt (data, wb);
- break;
- case OF_SAMI:
- wrote_something = write_cc_buffer_as_sami (data,wb);
- break;
- case OF_TRANSCRIPT:
- wrote_something = write_cc_buffer_as_transcript (data,wb);
- break;
- default:
- break;
- }
- if (wrote_something && gui_mode_reports)
- write_cc_buffer_to_gui (data,wb);
- }
+ data = get_current_visible_buffer(wb);
+ wb->new_sentence=1;
+ wrote_something = write_cc_buffer_as_srt (data, wb);
return wrote_something;
}
@@ -1789,10 +1533,7 @@ void roll_up(struct s_write *wb)
struct eia608_screen *use_buffer;
int i, j;
- if (wb->data608->visible_buffer==1)
- use_buffer = &wb->data608->buffer1;
- else
- use_buffer = &wb->data608->buffer2;
+ use_buffer = get_current_visible_buffer(wb);
int keep_lines;
switch (wb->data608->mode)
{
@@ -1822,7 +1563,7 @@ void roll_up(struct s_write *wb)
lastrow=i;
}
}
-
+
if (debug_608)
hb_log ("\rIn roll-up: %d lines used, first: %d, last: %d\n", rows_now, firstrow, lastrow);
@@ -1841,7 +1582,7 @@ void roll_up(struct s_write *wb)
}
for (j=0;j<(1+wb->data608->cursor_row-keep_lines);j++)
{
- memset(use_buffer->characters[j],' ',CC608_SCREEN_WIDTH);
+ memset(use_buffer->characters[j],' ',CC608_SCREEN_WIDTH);
memset(use_buffer->colors[j],COL_WHITE,CC608_SCREEN_WIDTH);
memset(use_buffer->fonts[j],FONT_REGULAR,CC608_SCREEN_WIDTH);
use_buffer->characters[j][CC608_SCREEN_WIDTH]=0;
@@ -1853,7 +1594,7 @@ void roll_up(struct s_write *wb)
use_buffer->characters[lastrow][CC608_SCREEN_WIDTH]=0;
use_buffer->row_used[lastrow]=0;
-
+
// Sanity check
rows_now=0;
for (i=0;i<15;i++)
@@ -1869,17 +1610,11 @@ void erase_memory (struct s_write *wb, int displayed)
struct eia608_screen *buf;
if (displayed)
{
- if (wb->data608->visible_buffer==1)
- buf=&wb->data608->buffer1;
- else
- buf=&wb->data608->buffer2;
+ buf = get_current_visible_buffer(wb);
}
else
{
- if (wb->data608->visible_buffer==1)
- buf=&wb->data608->buffer2;
- else
- buf=&wb->data608->buffer1;
+ buf = get_current_hidden_buffer(wb);
}
clear_eia608_cc_buffer (buf);
}
@@ -1889,10 +1624,7 @@ int is_current_row_empty (struct s_write *wb)
struct eia608_screen *use_buffer;
int i;
- if (wb->data608->visible_buffer==1)
- use_buffer = &wb->data608->buffer1;
- else
- use_buffer = &wb->data608->buffer2;
+ use_buffer = get_current_visible_buffer(wb);
for (i=0;i<CC608_SCREEN_WIDTH;i++)
{
if (use_buffer->characters[wb->data608->rollup_base_row][i]!=' ')
@@ -1967,23 +1699,27 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
break;
case COM_RESUMECAPTIONLOADING:
wb->data608->mode=MODE_POPUP;
+ wb->data608->current_visible_start_ms = get_fts(wb);
break;
case COM_RESUMETEXTDISPLAY:
wb->data608->mode=MODE_TEXT;
+ wb->data608->current_visible_start_ms = get_fts(wb);
break;
- case COM_ROLLUP2:
+ case COM_ROLLUP2:
if (wb->data608->mode==MODE_POPUP)
{
- if (write_cc_buffer (wb))
+ swap_visible_buffer(wb);
+ if (write_cc_buffer(wb))
wb->data608->screenfuls_counter++;
- erase_memory (wb, 1);
+ erase_memory (wb, 1);
}
+ wb->data608->current_visible_start_ms = get_fts(wb);
if (wb->data608->mode==MODE_ROLLUP_2 && !is_current_row_empty(wb))
{
if (debug_608)
hb_log ("Two RU2, current line not empty. Simulating a CR\n");
handle_command(0x14, 0x2D, wb);
- }
+ }
wb->data608->mode=MODE_ROLLUP_2;
erase_memory (wb, 0);
wb->data608->cursor_column=0;
@@ -1992,10 +1728,11 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
case COM_ROLLUP3:
if (wb->data608->mode==MODE_POPUP)
{
- if (write_cc_buffer (wb))
+ if (write_cc_buffer(wb))
wb->data608->screenfuls_counter++;
erase_memory (wb, 1);
}
+ wb->data608->current_visible_start_ms = get_fts(wb);
if (wb->data608->mode==MODE_ROLLUP_3 && !is_current_row_empty(wb))
{
if (debug_608)
@@ -2010,17 +1747,18 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
case COM_ROLLUP4:
if (wb->data608->mode==MODE_POPUP)
{
- if (write_cc_buffer (wb))
+ if (write_cc_buffer(wb))
wb->data608->screenfuls_counter++;
- erase_memory (wb, 1);
+ erase_memory (wb, 1);
}
+ wb->data608->current_visible_start_ms = get_fts(wb);
if (wb->data608->mode==MODE_ROLLUP_4 && !is_current_row_empty(wb))
{
if (debug_608)
hb_log ("Two RU4, current line not empty. Simulating a CR\n");
handle_command(0x14, 0x2D, wb);
}
-
+
wb->data608->mode=MODE_ROLLUP_4;
wb->data608->cursor_column=0;
wb->data608->cursor_row=wb->data608->rollup_base_row;
@@ -2029,19 +1767,11 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
case COM_CARRIAGERETURN:
// In transcript mode, CR doesn't write the whole screen, to avoid
// repeated lines.
- if (write_format==OF_TRANSCRIPT)
- {
- write_cc_line_as_transcript(get_current_visible_buffer (wb), wb, wb->data608->cursor_row);
- }
- else
- {
- if (norollup)
- delete_all_lines_but_current (get_current_visible_buffer (wb), wb->data608->cursor_row);
- if (write_cc_buffer(wb))
- wb->data608->screenfuls_counter++;
- }
- roll_up(wb);
- wb->data608->current_visible_start_ms=get_fts(wb);
+ if (norollup)
+ delete_all_lines_but_current(get_current_visible_buffer(wb), wb->data608->cursor_row);
+ if (write_cc_buffer(wb))
+ wb->data608->screenfuls_counter++;
+ roll_up(wb);
wb->data608->cursor_column=0;
break;
case COM_ERASENONDISPLAYEDMEMORY:
@@ -2050,30 +1780,30 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
case COM_ERASEDISPLAYEDMEMORY:
// Write it to disk before doing this, and make a note of the new
// time it became clear.
- if (write_format==OF_TRANSCRIPT &&
- (wb->data608->mode==MODE_ROLLUP_2 || wb->data608->mode==MODE_ROLLUP_3 ||
- wb->data608->mode==MODE_ROLLUP_4))
- {
- // In transcript mode we just write the cursor line. The previous lines
- // should have been written already, so writing everything produces
- // duplicate lines.
- write_cc_line_as_transcript(get_current_visible_buffer (wb), wb, wb->data608->cursor_row);
- }
- else
- {
- if (write_cc_buffer (wb))
- wb->data608->screenfuls_counter++;
- }
erase_memory (wb,1);
- wb->data608->current_visible_start_ms=get_fts(wb);
+ // Write "clear" subtitle if necessary
+ write_cc_buffer(wb);
break;
case COM_ENDOFCAPTION: // Switch buffers
// The currently *visible* buffer is leaving, so now we know it's ending
// time. Time to actually write it to file.
- if (write_cc_buffer (wb))
+ if (wb->data608->mode == MODE_POPUP)
+ {
+ swap_visible_buffer(wb);
+ wb->data608->current_visible_start_ms = get_fts(wb);
+ }
+ if (write_cc_buffer(wb))
wb->data608->screenfuls_counter++;
- wb->data608->visible_buffer = (wb->data608->visible_buffer==1) ? 2 : 1;
- wb->data608->current_visible_start_ms=get_fts(wb);
+
+ if (wb->data608->mode != MODE_POPUP)
+ swap_visible_buffer(wb);
+ else if (wb->hb_last_buffer != NULL)
+ {
+ // POPUPs are displayed when ENDOFCAPTION is received.
+ // We do not know their stop time. That is determined by
+ // ERASEDISPLAYEDMEMORY
+ wb->hb_last_buffer->s.stop = AV_NOPTS_VALUE;
+ }
wb->data608->cursor_column=0;
wb->data608->cursor_row=0;
wb->data608->color=default_color;
@@ -2089,9 +1819,9 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
}
void handle_end_of_data (struct s_write *wb)
-{
+{
// We issue a EraseDisplayedMemory here so if there's any captions pending
- // they get written to file.
+ // they get written to file.
handle_command (0x14, 0x2c, wb); // EDM
}
@@ -2113,7 +1843,7 @@ void handle_double (const unsigned char c1, const unsigned char c2, struct s_wri
unsigned char handle_extended (unsigned char hi, unsigned char lo, struct s_write *wb)
{
// Handle channel change
- if (wb->new_channel > 2)
+ if (wb->new_channel > 2)
{
wb->new_channel -= 2;
if (debug_608)
@@ -2139,11 +1869,11 @@ unsigned char handle_extended (unsigned char hi, unsigned char lo, struct s_writ
c=lo+0x90; // So if c>=0xb0 && c<=0xcf it comes from here
break;
}
- // This column change is because extended characters replace
+ // This column change is because extended characters replace
// the previous character (which is sent for basic decoders
// to show something similar to the real char)
- if (wb->data608->cursor_column>0)
- wb->data608->cursor_column--;
+ if (wb->data608->cursor_column>0)
+ wb->data608->cursor_column--;
write_char (c,wb);
}
@@ -2154,7 +1884,7 @@ unsigned char handle_extended (unsigned char hi, unsigned char lo, struct s_writ
void handle_pac (unsigned char c1, unsigned char c2, struct s_write *wb)
{
// Handle channel change
- if (wb->new_channel > 2)
+ if (wb->new_channel > 2)
{
wb->new_channel -= 2;
if (debug_608)
@@ -2199,12 +1929,12 @@ void handle_pac (unsigned char c1, unsigned char c2, struct s_write *wb)
wb->data608->cursor_row=row-1 ; // Since the array is 0 based
}
wb->data608->rollup_base_row=row-1;
- wb->data608->cursor_column=indent;
+ wb->data608->cursor_column=indent;
}
void handle_single (const unsigned char c1, struct s_write *wb)
-{
+{
if (c1<0x20 || wb->data608->channel!=cc_channel)
return; // We don't allow special stuff here
if (debug_608)
@@ -2217,25 +1947,25 @@ void handle_single (const unsigned char c1, struct s_write *wb)
int check_channel (unsigned char c1, struct s_write *wb)
{
- if (c1==0x14)
+ if (c1==0x14)
{
if (debug_608 && wb->data608->channel!=1)
hb_log ("\nChannel change, now 1\n");
return 1;
}
- if (c1==0x1c)
+ if (c1==0x1c)
{
if (debug_608 && wb->data608->channel!=2)
hb_log ("\nChannel change, now 2\n");
return 2;
}
- if (c1==0x15)
+ if (c1==0x15)
{
if (debug_608 && wb->data608->channel!=3)
hb_log ("\nChannel change, now 3\n");
return 3;
}
- if (c1==0x1d)
+ if (c1==0x1d)
{
if (debug_608 && wb->data608->channel!=4)
hb_log ("\nChannel change, now 4\n");
@@ -2325,14 +2055,12 @@ void process608 (const unsigned char *data, int length, struct s_write *wb)
for (i=0;i<length;i=i+2)
{
unsigned char hi, lo;
- int wrote_to_screen=0;
+ int wrote_to_screen=0;
hi = data[i] & 0x7F; // Get rid of parity bit
lo = data[i+1] & 0x7F; // Get rid of parity bit
if (hi==0 && lo==0) // Just padding
continue;
- // hb_log ("\r[%02X:%02X]\n",hi,lo);
-
if (hi>=0x01 && hi<=0x0E)
{
// XDS crap - mode. Would be nice to support it eventually
@@ -2401,8 +2129,8 @@ void process608 (const unsigned char *data, int length, struct s_write *wb)
wb->data608->mode==MODE_ROLLUP_4))
{
// We don't increase screenfuls_counter here.
- write_cc_buffer (wb);
- wb->data608->current_visible_start_ms=get_fts(wb);
+ write_cc_buffer(wb);
+ wb->data608->current_visible_start_ms = get_fts(wb);
}
}
}
@@ -2474,6 +2202,7 @@ int decccInit( hb_work_object_t * w, hb_job_t * job )
{
retval = 1;
}
+ init_eia608(pv->cc608->data608);
}
}
}
@@ -2507,17 +2236,17 @@ int decccWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
}
pv->cc608->last_pts = in->s.start;
-
process608(in->data, in->size, pv->cc608);
/*
* If there is one waiting then pass it on
*/
*buf_out = pv->cc608->hb_buffer;
+
pv->cc608->hb_buffer = NULL;
pv->cc608->hb_last_buffer = NULL;
- return HB_WORK_OK;
+ return HB_WORK_OK;
}
void decccClose( hb_work_object_t * w )
diff --git a/libhb/deccc608sub.h b/libhb/deccc608sub.h
index c142c2aec..b281bedbd 100644
--- a/libhb/deccc608sub.h
+++ b/libhb/deccc608sub.h
@@ -94,6 +94,9 @@ struct s_write {
unsigned char *enc_buffer; // Generic general purpose buffer
unsigned enc_buffer_used;
unsigned enc_buffer_capacity;
+
+ int clear_sub_needed; // Indicates that we need to send a null
+ // subtitle to clear the current subtitle
};
enum command_code
diff --git a/libhb/rendersub.c b/libhb/rendersub.c
index 403131453..680b5f9ed 100644
--- a/libhb/rendersub.c
+++ b/libhb/rendersub.c
@@ -6,9 +6,10 @@
It may be used under the terms of the GNU General Public License v2.
For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
*/
-
+
#include "hb.h"
#include "hbffmpeg.h"
+#include "colormap.h"
#include <ass/ass.h>
struct hb_filter_private_s
@@ -24,8 +25,15 @@ struct hb_filter_private_s
ASS_Library * ssa;
ASS_Renderer * renderer;
ASS_Track * ssaTrack;
+
+ // SRT
+ int line;
+ hb_buffer_t * current_sub;
};
+static char* srt_markup_to_ssa(char *srt, int *len);
+static void srt_to_ssa(hb_buffer_t *srt_sub);
+
// VOBSUB
static int vobsub_init( hb_filter_object_t * filter, hb_filter_init_t * init );
@@ -46,6 +54,16 @@ static int ssa_work( hb_filter_object_t * filter,
static void ssa_close( hb_filter_object_t * filter );
+// SRT
+static int textsub_init( hb_filter_object_t * filter, hb_filter_init_t * init );
+
+static int textsub_work( hb_filter_object_t * filter,
+ hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out );
+
+static void textsub_close( hb_filter_object_t * filter );
+
+
// PGS
static int pgssub_init ( hb_filter_object_t * filter, hb_filter_init_t * init );
@@ -119,7 +137,7 @@ static void blend( hb_buffer_t *dst, hb_buffer_t *src, int left, int top )
/*
* Merge the luminance and alpha with the picture
*/
- y_out[left + xx] =
+ y_out[left + xx] =
( (uint16_t)y_out[left + xx] * ( 255 - alpha ) +
(uint16_t)y_in[xx] * alpha ) >> 8;
}
@@ -335,7 +353,7 @@ static int vobsub_work( hb_filter_object_t * filter,
ApplyVOBSubs( pv, in );
*buf_in = NULL;
*buf_out = in;
-
+
return HB_FILTER_OK;
}
@@ -361,7 +379,7 @@ static hb_buffer_t * RenderSSAFrame( hb_filter_private_t * pv, ASS_Image * frame
unsigned b = ( frame->color >> 8 ) & 0xff;
int yuv = hb_rgb2yuv((r << 16) | (g << 8) | b );
-
+
unsigned frameY = (yuv >> 16) & 0xff;
unsigned frameV = (yuv >> 8 ) & 0xff;
unsigned frameU = (yuv >> 0 ) & 0xff;
@@ -408,6 +426,7 @@ static void ApplySSASubs( hb_filter_private_t * pv, hb_buffer_t * buf )
{
ASS_Image *frameList;
hb_buffer_t *sub;
+
frameList = ass_render_frame( pv->renderer, pv->ssaTrack,
buf->s.start / 90, NULL );
if ( !frameList )
@@ -442,17 +461,17 @@ static int ssa_init( hb_filter_object_t * filter,
hb_error( "decssasub: libass initialization failed\n" );
return 1;
}
-
+
// Redirect libass output to hb_log
ass_set_message_cb( pv->ssa, ssa_log, NULL );
-
+
// Load embedded fonts
hb_list_t * list_attachment = init->job->list_attachment;
int i;
for ( i = 0; i < hb_list_count(list_attachment); i++ )
{
hb_attachment_t * attachment = hb_list_item( list_attachment, i );
-
+
if ( attachment->type == FONT_TTF_ATTACH )
{
ass_add_font(
@@ -462,41 +481,41 @@ static int ssa_init( hb_filter_object_t * filter,
attachment->size );
}
}
-
+
ass_set_extract_fonts( pv->ssa, 1 );
ass_set_style_overrides( pv->ssa, NULL );
-
+
pv->renderer = ass_renderer_init( pv->ssa );
if ( !pv->renderer ) {
hb_log( "decssasub: renderer initialization failed\n" );
return 1;
}
-
+
ass_set_use_margins( pv->renderer, 0 );
ass_set_hinting( pv->renderer, ASS_HINTING_LIGHT ); // VLC 1.0.4 uses this
ass_set_font_scale( pv->renderer, 1.0 );
ass_set_line_spacing( pv->renderer, 1.0 );
-
+
// Setup default font family
- //
+ //
// SSA v4.00 requires that "Arial" be the default font
const char *font = NULL;
const char *family = "Arial";
// NOTE: This can sometimes block for several *seconds*.
// It seems that process_fontdata() for some embedded fonts is slow.
ass_set_fonts( pv->renderer, font, family, /*haveFontConfig=*/1, NULL, 1 );
-
+
// Setup track state
pv->ssaTrack = ass_new_track( pv->ssa );
if ( !pv->ssaTrack ) {
hb_log( "decssasub: ssa track initialization failed\n" );
return 1;
}
-
+
// NOTE: The codec extradata is expected to be in MKV format
ass_process_codec_private( pv->ssaTrack,
(char *)filter->subtitle->extradata, filter->subtitle->extradata_size );
-
+
int width = init->width - ( pv->crop[2] + pv->crop[3] );
int height = init->height - ( pv->crop[0] + pv->crop[1] );
ass_set_frame_size( pv->renderer, width, height);
@@ -552,12 +571,144 @@ static int ssa_work( hb_filter_object_t * filter,
ass_process_chunk( pv->ssaTrack, (char*)sub->data, sub->size,
sub->s.start / 90,
(sub->s.stop - sub->s.start) / 90 );
+ hb_buffer_close(&sub);
}
ApplySSASubs( pv, in );
*buf_in = NULL;
*buf_out = in;
-
+
+ return HB_FILTER_OK;
+}
+
+static int textsub_init( hb_filter_object_t * filter,
+ hb_filter_init_t * init )
+{
+ const char * ssa_header =
+ "[Script Info]\r\n"
+ "ScriptType: v4.00+\r\n"
+ "Collisions: Normal\r\n"
+ "PlayResX: 1920\r\n"
+ "PlayResY: 1080\r\n"
+ "Timer: 100.0\r\n"
+ "WrapStyle: 0\r\n"
+ "\r\n"
+ "[V4+ Styles]\r\n"
+ "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r\n"
+ "Style: Default,Arial,72,&H00FFFFFF,&H00FFFFFF,&H000F0F0F,&H000F0F0F,0,0,0,0,100,100,0,0.00,1,2,3,2,20,20,20,0\r\n";
+
+ filter->subtitle->extradata = (uint8_t*)ssa_header;
+ filter->subtitle->extradata_size = strlen(ssa_header);
+
+ int result = ssa_init(filter, init);
+
+ filter->subtitle->extradata = NULL;
+ filter->subtitle->extradata_size = 0;
+
+ return result;
+}
+
+static void textsub_close( hb_filter_object_t * filter )
+{
+ return ssa_close(filter);
+}
+
+static void process_sub(hb_filter_private_t *pv, hb_buffer_t *sub)
+{
+ char *ssa;
+ int len;
+ int64_t start, duration;
+
+ // Create SSA entry
+ ssa = hb_strdup_printf("%d,,Default,,0,0,0,,%s", ++pv->line, sub->data);
+ len = strlen(ssa);
+
+ // Parse MKV-SSA packet
+ // SSA subtitles always have an explicit stop time, so we
+ // do not need to do special processing for stop == AV_NOPTS_VALUE
+ start = sub->s.start / 90;
+ duration = (sub->s.stop - sub->s.start) / 90;
+ ass_process_chunk( pv->ssaTrack, ssa, len, start, duration);
+ free(ssa);
+}
+
+static int textsub_work(hb_filter_object_t * filter,
+ hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out)
+{
+ hb_filter_private_t * pv = filter->private_data;
+ hb_buffer_t * in = *buf_in;
+ hb_buffer_t * sub;
+
+ if (in->size <= 0)
+ {
+ *buf_in = NULL;
+ *buf_out = in;
+ return HB_FILTER_DONE;
+ }
+
+ // Get any pending subtitles and add them to the active
+ // subtitle list
+ while ((sub = hb_fifo_get(filter->subtitle->fifo_out)))
+ {
+ switch (pv->type)
+ {
+ case SRTSUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ srt_to_ssa(sub);
+ break;
+ default:
+ break;
+ }
+ // Subtitle formats such as CC can have stop times
+ // that are not known until an "erase display" command
+ // is encountered in the stream. For these formats
+ // current_sub is the currently active subtitle for which
+ // we do not yet know the stop time. We do not currently
+ // support overlapping subtitles of this type.
+ if (pv->current_sub != NULL)
+ {
+ // Next sub start time tells us the stop time of the
+ // current sub when it is not known in advance.
+ pv->current_sub->s.stop = sub->s.start;
+ process_sub(pv, pv->current_sub);
+ hb_buffer_close(&pv->current_sub);
+ }
+ if (sub->s.start == sub->s.stop)
+ {
+ // Zero duration sub used to "clear" previous sub that had
+ // an unknown duration
+ hb_buffer_close(&sub);
+ }
+ else if (sub->s.stop == AV_NOPTS_VALUE)
+ {
+ // We don't know the duration of this sub. So we will
+ // apply it to every video frame until we see a "clear" sub.
+ pv->current_sub = sub;
+ }
+ else
+ {
+ // Duration of this subtitle is known, so we can just
+ // process it normally.
+ process_sub(pv, sub);
+ hb_buffer_close(&sub);
+ }
+ }
+ if (pv->current_sub != NULL && pv->current_sub->s.start < in->s.start)
+ {
+ // We don't know the duration of this subtitle, but we know
+ // that it started before the current video frame and that
+ // it is still active. So render it on this video frame.
+ pv->current_sub->s.start = in->s.start;
+ pv->current_sub->s.stop = in->s.start + 90;
+ process_sub(pv, pv->current_sub);
+ }
+
+ ApplySSASubs(pv, in);
+ *buf_in = NULL;
+ *buf_out = in;
+
return HB_FILTER_OK;
}
@@ -715,6 +866,14 @@ static int hb_rendersub_init( hb_filter_object_t * filter,
return ssa_init( filter, init );
} break;
+ case SRTSUB:
+ case CC608SUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ {
+ return textsub_init( filter, init );
+ } break;
+
case PGSSUB:
{
return pgssub_init( filter, init );
@@ -745,6 +904,14 @@ static int hb_rendersub_work( hb_filter_object_t * filter,
return ssa_work( filter, buf_in, buf_out );
} break;
+ case SRTSUB:
+ case CC608SUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ {
+ return textsub_work( filter, buf_in, buf_out );
+ } break;
+
case PGSSUB:
{
return pgssub_work( filter, buf_in, buf_out );
@@ -773,6 +940,14 @@ static void hb_rendersub_close( hb_filter_object_t * filter )
ssa_close( filter );
} break;
+ case SRTSUB:
+ case CC608SUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ {
+ textsub_close( filter );
+ } break;
+
case PGSSUB:
{
pgssub_close( filter );
@@ -785,3 +960,113 @@ static void hb_rendersub_close( hb_filter_object_t * filter )
}
}
+static char* srt_markup_to_ssa(char *srt, int *len)
+{
+ char terminator;
+ char color[40];
+ uint32_t rgb;
+
+ *len = 0;
+ if (srt[0] != '<' && srt[0] != '{')
+ return NULL;
+
+ if (srt[0] == '<')
+ terminator = '>';
+ else
+ terminator = '}';
+
+ if (srt[1] == 'i' && srt[2] == terminator)
+ {
+ *len = 3;
+ return hb_strdup_printf("{\\i1}");
+ }
+ else if (srt[1] == 'b' && srt[2] == terminator)
+ {
+ *len = 3;
+ return hb_strdup_printf("{\\b1}");
+ }
+ else if (srt[1] == 'u' && srt[2] == terminator)
+ {
+ *len = 3;
+ return hb_strdup_printf("{\\u1}");
+ }
+ else if (srt[1] == '/' && srt[2] == 'i' && srt[3] == terminator)
+ {
+ *len = 4;
+ return hb_strdup_printf("{\\i0}");
+ }
+ else if (srt[1] == '/' && srt[2] == 'b' && srt[3] == terminator)
+ {
+ *len = 4;
+ return hb_strdup_printf("{\\b0}");
+ }
+ else if (srt[1] == '/' && srt[2] == 'u' && srt[3] == terminator)
+ {
+ *len = 4;
+ return hb_strdup_printf("{\\u0}");
+ }
+ else if (srt[0] == '<' && !strncmp(srt + 1, "font", 4))
+ {
+ int match;
+ match = sscanf(srt + 1, "font color=\"%39[^\"]\">", color);
+ if (match != 1)
+ {
+ return NULL;
+ }
+ while (srt[*len] != '>') (*len)++;
+ (*len)++;
+ if (color[0] == '#')
+ rgb = strtol(color + 1, NULL, 16);
+ else
+ rgb = hb_rgb_lookup_by_name(color);
+ return hb_strdup_printf("{\\1c&H%X&}", HB_RGB_TO_BGR(rgb));
+ }
+ else if (srt[0] == '<' && srt[1] == '/' && !strncmp(srt + 2, "font", 4) &&
+ srt[6] == '>')
+ {
+ *len = 7;
+ return hb_strdup_printf("{\\1c&HFFFFFF&}");
+ }
+
+ return NULL;
+}
+
+static void srt_to_ssa(hb_buffer_t *sub_in)
+{
+ char * srt = (char*)sub_in->data;
+ // SSA markup expands a little over SRT, so allocate a bit of extra
+ // space. More will be realloc'd if needed.
+ hb_buffer_t * sub = hb_buffer_init(sub_in->size + 20);
+ char * ssa, *ssa_markup;
+ int skip, len, pos, ii;
+
+ // Exchange data between input sub and new ssa_sub
+ // After this, sub_in contains ssa data
+ hb_buffer_swap_copy(sub_in, sub);
+ pos = 0;
+ ii = 0;
+ while (srt[ii] != '\0')
+ {
+ if ((ssa_markup = srt_markup_to_ssa(srt + ii, &skip)) != NULL)
+ {
+ len = strlen(ssa_markup);
+ hb_buffer_realloc(sub_in, pos + len + 1);
+ // After realloc, sub_in->data may change
+ ssa = (char*)sub_in->data;
+ snprintf(ssa + pos, len + 1, "%s", ssa_markup);
+ free(ssa_markup);
+ pos += len;
+ ii += skip;
+ }
+ else
+ {
+ hb_buffer_realloc(sub_in, pos + 2);
+ // After realloc, sub_in->data may change
+ ssa = (char*)sub_in->data;
+ ssa[pos++] = srt[ii++];
+ }
+ }
+ ssa[pos] = '\0';
+ hb_buffer_close(&sub);
+}
+
diff --git a/libhb/stream.c b/libhb/stream.c
index a48d339f1..b133dda78 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -5228,9 +5228,12 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id
strncpy( subtitle->iso639_2, language->iso639_2, 4 );
// Copy the extradata for the subtitle track
- subtitle->extradata = malloc( codec->extradata_size );
- memcpy( subtitle->extradata, codec->extradata, codec->extradata_size );
- subtitle->extradata_size = codec->extradata_size;
+ if (codec->extradata != NULL)
+ {
+ subtitle->extradata = malloc( codec->extradata_size );
+ memcpy( subtitle->extradata, codec->extradata, codec->extradata_size );
+ subtitle->extradata_size = codec->extradata_size;
+ }
subtitle->track = id;
hb_list_add(title->list_subtitle, subtitle);
diff --git a/libhb/sync.c b/libhb/sync.c
index 80ee15836..84eb1eac5 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -427,14 +427,23 @@ static hb_buffer_t * sanitizeSubtitle(
sanitizer->last->s.stop = sub->s.start;
}
- if (sanitizer->last == NULL)
+ if (sub->s.start == sub->s.stop)
{
- sanitizer->list_current = sanitizer->last = sub;
+ // Used to indicate "clear" subtitles when the duration
+ // of subtitles is not encoded in the stream
+ hb_buffer_close(&sub);
}
- else
+ if (sub != NULL)
{
- sanitizer->last->next = sub;
- sanitizer->last = sub;
+ if (sanitizer->last == NULL)
+ {
+ sanitizer->list_current = sanitizer->last = sub;
+ }
+ else
+ {
+ sanitizer->last->next = sub;
+ sanitizer->last = sub;
+ }
}
return mergeSubtitles(sanitizer, 0);
}
diff --git a/libhb/work.c b/libhb/work.c
index d0a0f6cd3..92e8692d0 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -413,8 +413,9 @@ void hb_display_job_info(hb_job_t *job)
else if( subtitle->source == SRTSUB )
{
/* For SRT, print offset and charset too */
- hb_log( " * subtitle track %d, %s (track %d, id 0x%x) Text [SRT] -> Passthrough%s, offset: %"PRId64", charset: %s",
+ hb_log( " * subtitle track %d, %s (track %d, id 0x%x) Text [SRT] -> %s%s, offset: %"PRId64", charset: %s",
subtitle->out_track, subtitle->lang, subtitle->track, subtitle->id,
+ subtitle->config.dest == RENDERSUB ? "Render/Burn-in" : "Passthrough",
subtitle->config.default_track ? ", Default" : "",
subtitle->config.offset, subtitle->config.src_codeset );
}