11#include <QCoreApplication>
24 m_rbuf(new unsigned char[sizeof(
ccsubtitle)+255])
27 for (
uint i = 0; i < 128; i++)
56 auto then = SystemClock::now() - seconds;
57 for (
uint i = 0; i < 4; i++)
61static const std::array<const int,16>
rowdata =
63 11, -1, 1, 2, 3, 4, 12, 13,
64 14, 15, 5, 6, 7, 8, 9, 10
69 QLatin1Char(0xAE), QLatin1Char(0xB0), QLatin1Char(0xBD), QLatin1Char(0xBF),
70 QChar(0x2122), QLatin1Char(0xA2), QLatin1Char(0xA3), QChar(0x266A),
71 QLatin1Char(0xE0), QLatin1Char(
' '), QLatin1Char(0xE8), QLatin1Char(0xE2),
72 QLatin1Char(0xEA), QLatin1Char(0xEE), QLatin1Char(0xF4), QLatin1Char(0xFB)
77 QLatin1Char(0xC1), QLatin1Char(0xC9), QLatin1Char(0xD3), QLatin1Char(0xDA),
78 QLatin1Char(0xDC), QLatin1Char(0xFC), QLatin1Char(
'`'), QLatin1Char(0xA1),
79 QLatin1Char(
'*'), QLatin1Char(
'\''), QChar(0x2014), QLatin1Char(0xA9),
80 QChar(0x2120), QLatin1Char(0xB7), QChar(0x201C), QChar(0x201D),
81 QLatin1Char(0xC0), QLatin1Char(0xC2), QLatin1Char(0xC7), QLatin1Char(0xC8),
82 QLatin1Char(0xCA), QLatin1Char(0xCB), QLatin1Char(0xEB), QLatin1Char(0xCE),
83 QLatin1Char(0xCF), QLatin1Char(0xEF), QLatin1Char(0xD4), QLatin1Char(0xD9),
84 QLatin1Char(0xF9), QLatin1Char(0xDB), QLatin1Char(0xAB), QLatin1Char(0xBB)
89 QLatin1Char(0xC3), QLatin1Char(0xE3), QLatin1Char(0xCD), QLatin1Char(0xCC),
90 QLatin1Char(0xEC), QLatin1Char(0xD2), QLatin1Char(0xF2), QLatin1Char(0xD5),
91 QLatin1Char(0xF5), QLatin1Char(
'{'), QLatin1Char(
'}'), QLatin1Char(
'\\'),
92 QLatin1Char(
'^'), QLatin1Char(
'_'), QLatin1Char(0xA6), QLatin1Char(
'~'),
93 QLatin1Char(0xC4), QLatin1Char(0xE4), QLatin1Char(0xD6), QLatin1Char(0xF6),
94 QLatin1Char(0xDF), QLatin1Char(0xA5), QLatin1Char(0xA4), QLatin1Char(
'|'),
95 QLatin1Char(0xC5), QLatin1Char(0xE5), QLatin1Char(0xD8), QLatin1Char(0xF8),
96 QChar(0x250C), QChar(0x2510), QChar(0x2514), QChar(0x2518)
101 if (mode == std::numeric_limits<std::size_t>::max())
125 int newccmode = (b1 >> 3) & 1;
126 int newtxtmode =
m_txtMode[(field*2) + newccmode];
127 if ((b1 & 0x06) == 0x04)
149 m_txtMode[(field*2) + newccmode] = newtxtmode;
150 size_t mode = (field << 2) | (newtxtmode << 1) |
m_ccMode[field];
153 size_t len =
m_ccBuf[mode].length();
172 LOG(VB_VBI, LOG_INFO,
173 QString(
"cc608 preamble indent, b2=%1")
182 LOG(VB_VBI, LOG_INFO,
183 QString(
"cc608 preamble color change, b2=%1")
196 LOG(VB_VBI, LOG_DEBUG,
197 QString(
"<ATTRIBUTE %1 %2>").arg(b1).arg(b2));
207 LOG(VB_VBI, LOG_INFO,
208 QString(
"cc608 mid-row color change, b2=%1")
213 m_ccBuf[mode] += QChar(0x7000 + (b2 & 0xf));
230 m_ccBuf[mode].remove(len - 1, 1);
243 m_ccBuf[mode].remove(len - 1, 1);
251 LOG(VB_VBI, LOG_DEBUG,
252 QString(
"ccmode %1 cmd %2").arg(
m_ccMode)
253 .arg(b2, 2, 16,
'0'));
263 m_ccBuf[mode].startsWith(
"\b"))
270 m_ccBuf[mode].remove(len - 1, 1);
303 (!newtxtmode ||
m_row[mode] >= 16)))
310 if (
m_row[mode] < 16)
344 if (
m_row[mode] == 0)
435 for (
int x = 0; x < (b2 & 0x03); x++)
455 for (mode = field*4; mode < ((field*4) + 4); mode++)
469 LOG(VB_VBI, LOG_DEBUG,
"Format CC -- Duplicate");
476 int b1 = data & 0x7f;
477 int b2 = (data >> 8) & 0x7f;
479 LOG(VB_VBI, LOG_DEBUG,
480 QString(
"Format CC @%1/%2 = %3 %4, %5/%6 = '%7' '%8'")
481 .arg(tc.count()).arg(field)
482 .arg((data&0xff), 2, 16)
483 .arg((data&0xff00)>>8, 2, 16)
484 .arg(b1, 2, 16, QChar(
'0'))
485 .arg(b2, 2, 16, QChar(
'0'))
486 .arg(QChar((b1 & 0x60) ? b1 :
'_'))
487 .arg(QChar((b2 & 0x60) ? b2 :
'_')));
494 if (mode != std::numeric_limits<std::size_t>::max())
501 mode = std::numeric_limits<std::size_t>::max();
520 else if ((b1 & 0x10) && (b2 > 0x1F))
527 for (
size_t mode2 = field*4; mode2 < ((field*4) + 4); mode2++)
529 size_t len2 =
m_ccBuf[mode2].length();
553 int b1 = data & 0x7f;
554 int b2 = (data >> 8) & 0x7f;
562 ((b1 & 0x70) == 0x10))
574 std::chrono::milliseconds dup_text_fudge = 0ms;
575 std::chrono::milliseconds dup_ctrl_fudge = 0ms;
576 if (
m_badVbi[field] < 100 && b1 != 0 && b2 != 0)
578 std::chrono::milliseconds
d = tc -
m_lastTc[field];
579 if (d < 25ms || d > 42ms)
587 dup_text_fudge = -2ms;
589 dup_ctrl_fudge = 33ms - 4ms;
593 dup_text_fudge = 4ms;
594 dup_ctrl_fudge = 33ms - 4ms;
599 if ((b1 & 0x70) == 0x10)
637 for (
const auto& cp : std::as_const(cc608str))
639 int cpu = cp.unicode();
644 case 0x2120 : ret +=
"(SM)";
break;
645 case 0x2122 : ret +=
"(TM)";
break;
646 case 0x2014 : ret +=
"(--)";
break;
647 case 0x201C : ret +=
"``";
break;
648 case 0x201D : ret +=
"''";
break;
649 case 0x250C : ret +=
"|-";
break;
650 case 0x2510 : ret +=
"-|";
break;
651 case 0x2514 : ret +=
"|_";
break;
652 case 0x2518 : ret +=
"_|";
break;
653 case 0x2588 : ret +=
"[]";
break;
654 case 0x266A : ret +=
"o/~";
break;
655 case '\b' : ret +=
"\\b";
break;
657 if (cpu >= 0x7000 && cpu < 0x7000 + 0x30)
659 if (!suppress_unknown)
660 ret += QString(
"[%1]").arg(cpu, 2, 16);
662 else if (cpu <= 0x80)
664 ret += QString(cp.toLatin1());
666 else if (!suppress_unknown)
668 ret += QString(
"{%1}").arg(cpu, 2, 16);
682 tmpbuf =
m_ccBuf[mode].toUtf8();
683#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
684 len = std::min(tmpbuf.length(), 255);
686 len = std::min(tmpbuf.length(),
static_cast<qsizetype
>(255));
690 unsigned char *bp =
m_rbuf;
691 *(bp++) =
m_row[mode];
716 LOG(VB_VBI, LOG_INFO, QString(
"### %1 %2 %3 %4 %5 %6 %7 - '%8'")
719 .arg(
m_style[mode]).arg(f, 2, 16)
720 .arg(clr).arg(len, 3)
721 .arg(
ToASCII(QString::fromUtf8(tmpbuf.constData(), len),
false)));
729 case CC_CC1: stream = 0;
break;
730 case CC_CC2: stream = 1;
break;
731 case CC_CC3: stream = 2;
break;
732 case CC_CC4: stream = 3;
break;
735 m_lastSeen[stream] = std::chrono::system_clock::now();
763 if (
m_row[mode] == 0)
773 if (
m_row[mode] == 0)
826 for (
int x = 0; x < limit; x++)
848 return ((c) & 0x7F) >= 0x20 && ((c) & 0x7F) <= 0x7E;
857static int OddParity(
unsigned char c)
859 c ^= (c >> 4); c ^= (c >> 2); c ^= (c >> 1);
868static constexpr int PIL_TIME(
int day,
int mon,
int hour,
int min)
869{
return (day << 15) + (mon << 11) + (hour << 6) + min; }
873 int day = (pil >> 15);
874 int mon = (pil >> 11) & 0xF;
875 int hour = (pil >> 6 ) & 0x1F;
876 int min = (pil ) & 0x3F;
879 LOG(VB_VBI, LOG_INFO,
" PDC: Timer-control (no PDC)");
880 else if (pil ==
PIL_TIME(0, 15, 30, 63))
881 LOG(VB_VBI, LOG_INFO,
" PDC: Recording inhibit/terminate");
882 else if (pil ==
PIL_TIME(0, 15, 29, 63))
883 LOG(VB_VBI, LOG_INFO,
" PDC: Interruption");
884 else if (pil ==
PIL_TIME(0, 15, 28, 63))
885 LOG(VB_VBI, LOG_INFO,
" PDC: Continue");
886 else if (pil ==
PIL_TIME(31, 15, 31, 63))
887 LOG(VB_VBI, LOG_INFO,
" PDC: No time");
889 LOG(VB_VBI, LOG_INFO, QString(
" PDC: %1, 200X-%2-%3 %4:%5")
890 .arg(pil).arg(mon).arg(day).arg(hour).arg(min));
908 LOG(VB_VBI, LOG_INFO, QString(
"VPS: 3-10: %1 %2 %3 %4 %5 %6 %7 %8 (\"%9\")")
909 .arg(buf[0]).arg(buf[1]).arg(buf[2]).arg(buf[3]).arg(buf[4])
910 .arg(buf[5]).arg(buf[6]).arg(buf[7]).arg(
m_vpsPrLabel.data()));
912 int pcs = buf[2] >> 6;
913 int cni = + ((buf[10] & 3) << 10)
914 + ((buf[11] & 0xC0) << 2)
915 + ((buf[8] & 0xC0) << 0)
917 int pil = ((buf[8] & 0x3F) << 14) + (buf[9] << 6) + (buf[10] >> 2);
920 LOG(VB_VBI, LOG_INFO, QString(
"CNI: %1 PCS: %2 PTY: %3 ")
921 .arg(cni).arg(pcs).arg(pty));
934 static const std::array<const int,8> kWssBits { 0, 0, 0, 1, 0, 1, 1, 1 };
937 for (
uint i = 0; i < 16; i++)
939 uint b1 = kWssBits[buf[i] & 7];
940 uint b2 = kWssBits[(buf[i] >> 3) & 7];
946 unsigned char parity = wss & 0xf;
947 parity ^= parity >> 2;
948 parity ^= parity >> 1;
950 LOG(VB_VBI, LOG_INFO,
951 QString(
"WSS: %1; %2 mode; %3 color coding;\n\t\t\t"
952 " %4 helper; reserved b7=%5; %6\n\t\t\t"
953 " open subtitles: %7; %scopyright %8; copying %9")
954 .arg(QString::fromStdString(
formats[wss & 7]),
955 (wss & 0x0010) ?
"film" :
"camera",
956 (wss & 0x0020) ?
"MA/CP" :
"standard",
957 (wss & 0x0040) ?
"modulated" :
"no",
958 (wss & 0x0080) ?
"1" :
"0",
959 (wss & 0x0100) ?
"have TTX subtitles; " :
"",
960 QString::fromStdString(
subtitles[(wss >> 9) & 3]),
961 (wss & 0x0800) ?
"surround sound; " :
"",
962 (wss & 0x1000) ?
"asserted" :
"unknown")
964 .arg((wss & 0x2000) ?
"restricted" :
"not restricted"));
977 for (
uint i = start; (i < buf.size()) && (i < end); i++)
979 LOG(VB_VBI, LOG_INFO, QString(
"%1: 0x%2 -> 0x%3 %4")
981 .arg(buf[i],2,16,QChar(
'0'))
988 for (
uint i = start; (i < buf.size()) && (i < end); i++)
995 LOG(VB_VBI, LOG_INFO, QString(
"XDSDecodeString: '%1'").arg(
tmp));
998 return tmp.trimmed();
1001static bool is_better(
const QString &newStr,
const QString &oldStr)
1003 if (!newStr.isEmpty() && newStr != oldStr &&
1004 (newStr != oldStr.left(newStr.length())))
1006 if (oldStr.isEmpty())
1010 return std::all_of(newStr.cbegin(), newStr.cend(),
1011 [](
auto ch){ return ch.toLatin1() >= 0x20; } );
1025 return m_xdsRating[(future) ? 1 : 0][i & 0x3] & 0x7;
1032 const std::array<const QString,4>
prefix {
"MPAA-",
"TV-",
"CE-",
"CF-" };
1033 const std::array<const std::array<const QString,8>,4> mainStr
1035 {
"NR",
"G",
"PG",
"PG-13",
"R",
"NC-17",
"X",
"NR" },
1036 {
"NR",
"Y",
"Y7",
"G",
"PG",
"14",
"MA",
"NR" },
1037 {
"E",
"C",
"C8+",
"G",
"PG",
"14+",
"18+",
"NR" },
1038 {
"E",
"G",
"8+",
"13+",
"16+",
"18+",
"NR",
"NR" },
1045 uint cf = (future) ? 1 : 0;
1073 const std::vector<uint> &program_type =
m_xdsProgramType[(future) ? 1 : 0];
1076 for (
size_t i = 0; i < program_type.size(); i++)
1090 if (key ==
"ratings")
1092 if (key.startsWith(
"has_rating_"))
1094 if (key.startsWith(
"rating_"))
1097 if (key ==
"future_ratings")
1099 if (key.startsWith(
"has_future_rating_"))
1101 if (key.startsWith(
"future_rating_"))
1104 if (key ==
"programname")
1106 if (key ==
"future_programname")
1109 if (key ==
"programtype")
1111 if (key ==
"future_programtype")
1114 if (key ==
"callsign")
1116 if (key ==
"channame")
1142 LOG(VB_VBI, LOG_INFO,
1143 QString(
"XDSDecode: 0x%1 0x%2 '%3%4' xds[%5]=%6 in XDS %7")
1144 .arg(b1,2,16,QChar(
'0')).arg(b2,2,16,QChar(
'0'))
1147 .arg(field).arg(
m_xds[field])
1169 else if ((0x0 < b1) && (b1 < 0x0f))
1193 else if ((0x10 <= b1) && (b1 <= 0x1f))
1196 LOG(VB_VBI, LOG_INFO, QString(
"XDSDecode: Suspending XDS %1 on 0x%2")
1209 bool handled =
false;
1210 int xds_class = xds_buf[0];
1215 if ((xds_class == 0x01) || (xds_class == 0x03))
1217 else if (xds_class == 0x05)
1219 else if ((xds_class == 0x07) ||
1220 (xds_class == 0x09) ||
1221 (xds_class == 0x0b))
1223 else if (xds_class == 0x0d)
1229 LOG(VB_VBI, LOG_INFO, QString(
"XDS: ") +
1230 QString(
"Unhandled packet (0x%1 0x%2) sz(%3) '%4'")
1231 .arg(xds_buf[0],0,16).arg(xds_buf[1],0,16)
1232 .arg(xds_buf.size())
1242 for (
size_t i = 0; i < xds_buf.size() - 1; i++)
1245 if ((((~sum) & 0x7f) + 1) != xds_buf[xds_buf.size() - 1])
1249 LOG(VB_VBI, LOG_ERR, QString(
"XDS: failed CRC %1 of %2")
1260 const std::vector<unsigned char> &xds_buf,
bool future)
1262 bool handled =
true;
1263 int b2 = xds_buf[1];
1264 int cf = (future) ? 1 : 0;
1265 QString loc = (future) ?
"XDS: Future " :
"XDS: Current ";
1267 if ((b2 == 0x01) && (xds_buf.size() >= 6))
1269 uint min = xds_buf[2] & 0x3f;
1270 uint hour = xds_buf[3] & 0x0f;
1271 uint day = xds_buf[4] & 0x1f;
1272 uint month = xds_buf[5] & 0x0f;
1273 month = (month < 1 || month > 12) ? 0 : month;
1275 LOG(VB_VBI, LOG_INFO, loc +
1276 QString(
"Start Time %1/%2 %3:%4%5")
1277 .arg(month).arg(day).arg(hour).arg(min / 10).arg(min % 10));
1279 else if ((b2 == 0x02) && (xds_buf.size() >= 4))
1281 uint length_min = xds_buf[2] & 0x3f;
1282 uint length_hour = xds_buf[3] & 0x3f;
1283 uint length_elapsed_min = 0;
1284 uint length_elapsed_hour = 0;
1285 uint length_elapsed_secs = 0;
1286 if (xds_buf.size() > 6)
1288 length_elapsed_min = xds_buf[4] & 0x3f;
1289 length_elapsed_hour = xds_buf[5] & 0x3f;
1291 if (xds_buf.size() > 8 && xds_buf[7] == 0x40)
1292 length_elapsed_secs = xds_buf[6] & 0x3f;
1294 QString msg = QString(
"Program Length %1:%2%3 "
1295 "Time in Show %4:%5%6.%7%8")
1296 .arg(length_hour).arg(length_min / 10).arg(length_min % 10)
1297 .arg(length_elapsed_hour)
1298 .arg(length_elapsed_min / 10).arg(length_elapsed_min % 10)
1299 .arg(length_elapsed_secs / 10).arg(length_elapsed_secs % 10);
1301 LOG(VB_VBI, LOG_INFO, loc + msg);
1303 else if ((b2 == 0x03) && (xds_buf.size() >= 6))
1309 LOG(VB_VBI, LOG_INFO, loc + QString(
"Program Name: '%1'")
1313 else if ((b2 == 0x04) && (xds_buf.size() >= 6))
1315 std::vector<uint> program_type;
1316 for (
size_t i = 2; i < xds_buf.size() - 2; i++)
1318 int cur = xds_buf[i] - 0x20;
1319 if (cur >= 0 && cur < 96)
1320 program_type.push_back(cur);
1324 for (
uint i = 0; (i < program_type.size()) && unchanged; i++)
1330 LOG(VB_VBI, LOG_INFO, loc + QString(
"Program Type '%1'")
1334 else if ((b2 == 0x05) && (xds_buf.size() >= 4))
1336 uint movie_rating = xds_buf[2] & 0x7;
1337 uint rating_system = (xds_buf[2] >> 3) & 0x7;
1338 uint tv_rating = xds_buf[3] & 0x7;
1339 uint VSL = xds_buf[3] & (0x7 << 3);
1340 uint sel = VSL | rating_system;
1348 LOG(VB_VBI, LOG_INFO, loc + QString(
"VChip %1")
1359 LOG(VB_VBI, LOG_INFO, loc + QString(
"VChip %1")
1363 else if (sel == 0x13 || sel == 0x1f)
1367 else if ((rating_system & 0x3) == 1)
1372 uint f = ((xds_buf[0]<<3) & 0x80) | ((xds_buf[1]<<1) & 0x70);
1375 LOG(VB_VBI, LOG_INFO, loc + QString(
"VChip %1")
1379 else if (rating_system == 0)
1386 LOG(VB_VBI, LOG_INFO, loc + QString(
"VChip %1")
1392 LOG(VB_VBI, LOG_ERR, loc +
1393 QString(
"VChip Unhandled -- rs(%1) rating(%2:%3)")
1394 .arg(rating_system).arg(tv_rating).arg(movie_rating));
1398 else if (b2 == 0x07)
1400 else if (b2 == 0x08)
1402 else if (b2 == 0x09)
1404 else if (b2 == 0x0c)
1406 else if (b2 == 0x10 || b2 == 0x13 || b2 == 0x15 || b2 == 0x16 ||
1407 b2 == 0x91 || b2 == 0x92 || b2 == 0x94 || b2 == 0x97)
1409 else if (b2 == 0x86)
1411 else if (b2 == 0x89)
1413 else if (b2 == 0x8c)
1426 bool handled =
true;
1428 int b2 = xds_buf[1];
1429 if ((b2 == 0x01) && (xds_buf.size() >= 6))
1434 LOG(VB_VBI, LOG_INFO, QString(
"XDS: Network Name '%1'").arg(
tmp));
1438 else if ((b2 == 0x02) && (xds_buf.size() >= 6))
1443 LOG(VB_VBI, LOG_INFO, QString(
"XDS: Network Call '%1'").arg(
tmp));
1447 else if ((b2 == 0x04) && (xds_buf.size() >= 6))
1449 uint tsid = (xds_buf[2] << 24 | xds_buf[3] << 16 |
1450 xds_buf[4] << 8 | xds_buf[5]);
1453 LOG(VB_VBI, LOG_INFO, QString(
"XDS: TSID 0x%1").arg(tsid,0,16));
1467 xds_program_type[0] = QCoreApplication::translate(
"(Categories)",
1469 xds_program_type[1] = QCoreApplication::translate(
"(Categories)",
1471 xds_program_type[2] = QCoreApplication::translate(
"(Categories)",
1473 xds_program_type[3] = QCoreApplication::translate(
"(Categories)",
1475 xds_program_type[4] = QCoreApplication::translate(
"(Categories)",
1477 xds_program_type[5] = QCoreApplication::translate(
"(Categories)",
1479 xds_program_type[6] = QCoreApplication::translate(
"(Categories)",
1481 xds_program_type[7] = QCoreApplication::translate(
"(Categories)",
1483 xds_program_type[8] = QCoreApplication::translate(
"(Categories)",
1485 xds_program_type[9] = QCoreApplication::translate(
"(Categories)",
1487 xds_program_type[10] = QCoreApplication::translate(
"(Categories)",
1489 xds_program_type[11] = QCoreApplication::translate(
"(Categories)",
1491 xds_program_type[12] = QCoreApplication::translate(
"(Categories)",
1493 xds_program_type[13] = QCoreApplication::translate(
"(Categories)",
1495 xds_program_type[14] = QCoreApplication::translate(
"(Categories)",
1497 xds_program_type[15] = QCoreApplication::translate(
"(Categories)",
1499 xds_program_type[16] = QCoreApplication::translate(
"(Categories)",
1501 xds_program_type[17] = QCoreApplication::translate(
"(Categories)",
1503 xds_program_type[18] = QCoreApplication::translate(
"(Categories)",
1505 xds_program_type[19] = QCoreApplication::translate(
"(Categories)",
1507 xds_program_type[20] = QCoreApplication::translate(
"(Categories)",
1509 xds_program_type[21] = QCoreApplication::translate(
"(Categories)",
1511 xds_program_type[22] = QCoreApplication::translate(
"(Categories)",
1513 xds_program_type[23] = QCoreApplication::translate(
"(Categories)",
1515 xds_program_type[24] = QCoreApplication::translate(
"(Categories)",
1517 xds_program_type[25] = QCoreApplication::translate(
"(Categories)",
1519 xds_program_type[26] = QCoreApplication::translate(
"(Categories)",
1521 xds_program_type[27] = QCoreApplication::translate(
"(Categories)",
1523 xds_program_type[28] = QCoreApplication::translate(
"(Categories)",
1525 xds_program_type[29] = QCoreApplication::translate(
"(Categories)",
1527 xds_program_type[30] = QCoreApplication::translate(
"(Categories)",
1529 xds_program_type[31] = QCoreApplication::translate(
"(Categories)",
1531 xds_program_type[32] = QCoreApplication::translate(
"(Categories)",
1533 xds_program_type[33] = QCoreApplication::translate(
"(Categories)",
1535 xds_program_type[34] = QCoreApplication::translate(
"(Categories)",
1537 xds_program_type[35] = QCoreApplication::translate(
"(Categories)",
1539 xds_program_type[36] = QCoreApplication::translate(
"(Categories)",
1541 xds_program_type[37] = QCoreApplication::translate(
"(Categories)",
1543 xds_program_type[38] = QCoreApplication::translate(
"(Categories)",
1545 xds_program_type[39] = QCoreApplication::translate(
"(Categories)",
1547 xds_program_type[40] = QCoreApplication::translate(
"(Categories)",
1549 xds_program_type[41] = QCoreApplication::translate(
"(Categories)",
1551 xds_program_type[42] = QCoreApplication::translate(
"(Categories)",
1553 xds_program_type[43] = QCoreApplication::translate(
"(Categories)",
1555 xds_program_type[44] = QCoreApplication::translate(
"(Categories)",
1557 xds_program_type[45] = QCoreApplication::translate(
"(Categories)",
1559 xds_program_type[46] = QCoreApplication::translate(
"(Categories)",
1561 xds_program_type[47] = QCoreApplication::translate(
"(Categories)",
1563 xds_program_type[48] = QCoreApplication::translate(
"(Categories)",
1565 xds_program_type[49] = QCoreApplication::translate(
"(Categories)",
1567 xds_program_type[50] = QCoreApplication::translate(
"(Categories)",
1569 xds_program_type[51] = QCoreApplication::translate(
"(Categories)",
1571 xds_program_type[52] = QCoreApplication::translate(
"(Categories)",
1573 xds_program_type[53] = QCoreApplication::translate(
"(Categories)",
1575 xds_program_type[54] = QCoreApplication::translate(
"(Categories)",
1577 xds_program_type[55] = QCoreApplication::translate(
"(Categories)",
1579 xds_program_type[56] = QCoreApplication::translate(
"(Categories)",
1581 xds_program_type[57] = QCoreApplication::translate(
"(Categories)",
1583 xds_program_type[58] = QCoreApplication::translate(
"(Categories)",
1585 xds_program_type[59] = QCoreApplication::translate(
"(Categories)",
1587 xds_program_type[60] = QCoreApplication::translate(
"(Categories)",
1589 xds_program_type[61] = QCoreApplication::translate(
"(Categories)",
1591 xds_program_type[62] = QCoreApplication::translate(
"(Categories)",
1593 xds_program_type[63] = QCoreApplication::translate(
"(Categories)",
1595 xds_program_type[64] = QCoreApplication::translate(
"(Categories)",
1597 xds_program_type[65] = QCoreApplication::translate(
"(Categories)",
1599 xds_program_type[66] = QCoreApplication::translate(
"(Categories)",
1601 xds_program_type[67] = QCoreApplication::translate(
"(Categories)",
1603 xds_program_type[68] = QCoreApplication::translate(
"(Categories)",
1605 xds_program_type[69] = QCoreApplication::translate(
"(Categories)",
1607 xds_program_type[70] = QCoreApplication::translate(
"(Categories)",
1609 xds_program_type[71] = QCoreApplication::translate(
"(Categories)",
1611 xds_program_type[72] = QCoreApplication::translate(
"(Categories)",
1613 xds_program_type[73] = QCoreApplication::translate(
"(Categories)",
1615 xds_program_type[74] = QCoreApplication::translate(
"(Categories)",
1617 xds_program_type[75] = QCoreApplication::translate(
"(Categories)",
1619 xds_program_type[76] = QCoreApplication::translate(
"(Categories)",
1621 xds_program_type[77] = QCoreApplication::translate(
"(Categories)",
1623 xds_program_type[78] = QCoreApplication::translate(
"(Categories)",
1625 xds_program_type[79] = QCoreApplication::translate(
"(Categories)",
1627 xds_program_type[80] = QCoreApplication::translate(
"(Categories)",
1629 xds_program_type[81] = QCoreApplication::translate(
"(Categories)",
1631 xds_program_type[82] = QCoreApplication::translate(
"(Categories)",
1633 xds_program_type[83] = QCoreApplication::translate(
"(Categories)",
1635 xds_program_type[84] = QCoreApplication::translate(
"(Categories)",
1637 xds_program_type[85] = QCoreApplication::translate(
"(Categories)",
1639 xds_program_type[86] = QCoreApplication::translate(
"(Categories)",
1641 xds_program_type[87] = QCoreApplication::translate(
"(Categories)",
1643 xds_program_type[88] = QCoreApplication::translate(
"(Categories)",
1645 xds_program_type[89] = QCoreApplication::translate(
"(Categories)",
1647 xds_program_type[90] = QCoreApplication::translate(
"(Categories)",
1649 xds_program_type[91] = QCoreApplication::translate(
"(Categories)",
1651 xds_program_type[92] = QCoreApplication::translate(
"(Categories)",
1653 xds_program_type[93] = QCoreApplication::translate(
"(Categories)",
1655 xds_program_type[94] = QCoreApplication::translate(
"(Categories)",
1657 xds_program_type[95] = QCoreApplication::translate(
"(Categories)",
static std::array< const int, 16 > b1_to_service
static const std::array< const QChar, 32 > extendedchar2
static const std::array< const int, 16 > rowdata
static const std::array< const QChar, 16 > specialchar
static void DumpPIL(int pil)
static bool IsPrintable(char c)
static void init_xds_program_type(CC608ProgramType &xds_program_type)
static char Printable(char c)
static constexpr int PIL_TIME(int day, int mon, int hour, int min)
static const std::array< const QChar, 32 > extendedchar3
static bool is_better(const QString &newStr, const QString &oldStr)
std::array< bool, 4 > CC608Seen
std::array< QString, 96 > CC608ProgramType
static constexpr uint8_t CC_LINE_CONT
static constexpr uint8_t CC_MODE_MASK
CC608PerFieldTc m_lastFormatTc
QString GetRatingString(uint i, bool future) const
void XDSPacketParse(const std::vector< unsigned char > &xds_buf)
QString GetProgramType(bool future) const
bool XDSDecode(int field, int b1, int b2)
static QString ToASCII(const QString &cc608, bool suppress_unknown)
std::array< uint, 2 > m_xdsRatingSystems
QString GetXDS(const QString &key) const
QString XDSDecodeString(const std::vector< unsigned char > &buf, uint start, uint end) const
std::array< QString, 2 > m_xdsProgramName
void DecodeWSS(const unsigned char *buf)
CC608PerField m_lastFormatData
CC608PerMode m_resumeText
std::array< QChar, 128 > m_stdChar
void FormatControlCode(std::chrono::milliseconds tc, size_t field, int b1, int b2)
void FormatTextCode(std::chrono::milliseconds tc, size_t field, size_t mode, size_t len, int b1, int b2)
QRecursiveMutex m_xdsLock
std::array< std::array< uint, 4 >, 2 > m_xdsRating
void FormatCC(std::chrono::milliseconds tc, int code1, int code2)
bool XDSPacketParseChannel(const std::vector< unsigned char > &xds_buf)
bool XDSPacketParseProgram(const std::vector< unsigned char > &xds_buf, bool future)
void DecodeVPS(const unsigned char *buf)
QChar CharCC(int code) const
bool FalseDup(std::chrono::milliseconds tc, int field, int data)
std::array< QString, 8 > m_ccBuf
QString GetProgramName(bool future) const
CC608ProgramType m_xdsProgramTypeString
uint GetRatingSystems(bool future) const
CC608PerFieldTc m_lastCodeTc
void GetServices(std::chrono::seconds seconds, CC608Seen &seen) const
void BufferCC(size_t mode, int len, int clr)
std::array< std::vector< unsigned char >, 7 > m_xdsBuf
void ResetCC(size_t mode)
bool XDSPacketCRC(const std::vector< unsigned char > &xds_buf)
std::array< std::vector< uint >, 2 > m_xdsProgramType
std::array< char, 20 > m_vpsLabel
CC608Decoder(CC608Input *ccr)
std::array< int, 4 > m_txtMode
std::array< SystemTime, 4 > m_lastSeen
uint GetRating(uint i, bool future) const
std::array< char, 20 > m_vpsPrLabel
CC608PerModeTc m_timeCode
int NewRowCC(size_t mode, int len)
void FormatCCField(std::chrono::milliseconds tc, size_t field, int data)
static const iso6937table * d
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
const std::array< const uint8_t, 256 > vbi_bit_reverse
const std::array< const std::string, 4 > subtitles
const std::array< const std::string, 8 > formats