shaka-packager/packager/media/formats/mp2t/es_parser_teletext.cc

620 lines
19 KiB
C++
Raw Permalink Normal View History

// Copyright 2020 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include <packager/media/formats/mp2t/es_parser_teletext.h>
#include <packager/media/base/bit_reader.h>
#include <packager/media/base/timestamp.h>
#include <packager/media/formats/mp2t/es_parser_teletext_tables.h>
#include <packager/media/formats/mp2t/mp2t_common.h>
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
#include <iostream>
namespace shaka {
namespace media {
namespace mp2t {
namespace {
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
constexpr const char* kRegionTeletextPrefix = "ttx_";
const uint8_t EBU_TELETEXT_WITH_SUBTITLING = 0x03;
const int kPayloadSize = 40;
const int kNumTriplets = 13;
template <typename T>
constexpr T bit(T value, const size_t bit_pos) {
return (value >> bit_pos) & 0x1;
}
uint8_t ReadHamming(BitReader& reader) {
uint8_t bits;
RCHECK(reader.ReadBits(8, &bits));
return TELETEXT_HAMMING_8_4[bits];
}
bool Hamming_24_18(const uint32_t value, uint32_t& out_result) {
uint32_t result = value;
uint8_t test = 0;
for (uint8_t i = 0; i < 23; i++) {
test ^= ((result >> i) & 0x01) * (i + 0x21);
}
test ^= ((result >> 0x17) & 0x01) * 0x20;
if ((test & 0x1f) != 0x1f) {
if ((test & 0x20) == 0x20) {
return false;
}
result ^= 1 << (0x1e - test);
}
out_result = (result & 0x000004) >> 2 | (result & 0x000070) >> 3 |
(result & 0x007f00) >> 4 | (result & 0x7f0000) >> 5;
return true;
}
bool ParseSubtitlingDescriptor(
const uint8_t* descriptor,
const size_t size,
std::unordered_map<uint16_t, std::string>& result) {
BitReader reader(descriptor, size);
RCHECK(reader.SkipBits(8));
size_t data_size;
RCHECK(reader.ReadBits(8, &data_size));
RCHECK(data_size + 2 <= size);
for (size_t i = 0; i < data_size; i += 8) {
uint32_t lang_code;
RCHECK(reader.ReadBits(24, &lang_code));
uint8_t ignored_teletext_type;
RCHECK(reader.ReadBits(5, &ignored_teletext_type));
uint8_t magazine_number;
RCHECK(reader.ReadBits(3, &magazine_number));
if (magazine_number == 0) {
magazine_number = 8;
}
uint8_t page_number_tens;
RCHECK(reader.ReadBits(4, &page_number_tens));
uint8_t page_number_units;
RCHECK(reader.ReadBits(4, &page_number_units));
const uint8_t page_number = page_number_tens * 10 + page_number_units;
std::string lang(3, '\0');
lang[0] = static_cast<char>((lang_code >> 16) & 0xff);
lang[1] = static_cast<char>((lang_code >> 8) & 0xff);
lang[2] = static_cast<char>((lang_code >> 0) & 0xff);
const uint16_t index = magazine_number * 100 + page_number;
result.emplace(index, std::move(lang));
}
return true;
}
} // namespace
EsParserTeletext::EsParserTeletext(const uint32_t pid,
const NewStreamInfoCB& new_stream_info_cb,
const EmitTextSampleCB& emit_sample_cb,
const uint8_t* descriptor,
const size_t descriptor_length)
: EsParser(pid),
new_stream_info_cb_(new_stream_info_cb),
emit_sample_cb_(emit_sample_cb),
magazine_(0),
page_number_(0),
charset_code_(0),
current_charset_{},
last_pts_(0) {
if (!ParseSubtitlingDescriptor(descriptor, descriptor_length, languages_)) {
LOG(ERROR) << "Unable to parse teletext_descriptor";
}
UpdateCharset();
}
bool EsParserTeletext::Parse(const uint8_t* buf,
int size,
int64_t pts,
int64_t dts) {
if (!sent_info_) {
sent_info_ = true;
auto info = std::make_shared<TextStreamInfo>(pid(), kMpeg2Timescale,
kInfiniteDuration, kCodecText,
"", "", 0, 0, "");
for (const auto& pair : languages_) {
info->AddSubStream(pair.first, {pair.second});
}
new_stream_info_cb_(info);
}
return ParseInternal(buf, size, pts);
}
bool EsParserTeletext::Flush() {
std::vector<uint16_t> keys;
for (const auto& entry : page_state_) {
keys.push_back(entry.first);
}
for (const auto key : keys) {
SendPending(key, last_pts_);
}
return true;
}
void EsParserTeletext::Reset() {
page_state_.clear();
magazine_ = 0;
page_number_ = 0;
sent_info_ = false;
charset_code_ = 0;
UpdateCharset();
}
bool EsParserTeletext::ParseInternal(const uint8_t* data,
const size_t size,
const int64_t pts) {
BitReader reader(data, size);
RCHECK(reader.SkipBits(8));
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
std::vector<TextRow> rows;
while (reader.bits_available()) {
uint8_t data_unit_id;
RCHECK(reader.ReadBits(8, &data_unit_id));
uint8_t data_unit_length;
RCHECK(reader.ReadBits(8, &data_unit_length));
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
if (data_unit_id != EBU_TELETEXT_WITH_SUBTITLING) {
RCHECK(reader.SkipBytes(data_unit_length));
continue;
}
if (data_unit_length != 44) {
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
// Teletext data unit length is always 44 bytes
LOG(ERROR) << "Bad Teletext data length";
break;
}
RCHECK(reader.SkipBits(16));
uint16_t address_bits;
RCHECK(reader.ReadBits(16, &address_bits));
uint8_t magazine = bit(address_bits, 14) + 2 * bit(address_bits, 12) +
4 * bit(address_bits, 10);
if (magazine == 0) {
magazine = 8;
}
const uint8_t packet_nr =
(bit(address_bits, 8) + 2 * bit(address_bits, 6) +
4 * bit(address_bits, 4) + 8 * bit(address_bits, 2) +
16 * bit(address_bits, 0));
const uint8_t* data_block = reader.current_byte_ptr();
RCHECK(reader.SkipBytes(40));
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
TextRow row;
if (ParseDataBlock(pts, data_block, packet_nr, magazine, row)) {
rows.emplace_back(std::move(row));
}
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
if (rows.empty()) {
return true;
}
const uint16_t index = magazine_ * 100 + page_number_;
auto page_state_itr = page_state_.find(index);
if (page_state_itr == page_state_.end()) {
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
page_state_.emplace(index, TextBlock{std::move(rows), {}, last_pts_});
} else {
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
for (auto& row : rows) {
auto& page_state_lines = page_state_itr->second.rows;
page_state_lines.emplace_back(std::move(row));
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
rows.clear();
}
return true;
}
bool EsParserTeletext::ParseDataBlock(const int64_t pts,
const uint8_t* data_block,
const uint8_t packet_nr,
const uint8_t magazine,
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
TextRow& row) {
if (packet_nr == 0) {
last_pts_ = pts;
BitReader reader(data_block, 32);
const uint8_t page_number_units = ReadHamming(reader);
const uint8_t page_number_tens = ReadHamming(reader);
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
if (page_number_units == 0xf || page_number_tens == 0xf) {
RCHECK(reader.SkipBits(40));
return false;
}
const uint8_t page_number = 10 * page_number_tens + page_number_units;
const uint16_t index = magazine * 100 + page_number;
SendPending(index, pts);
page_number_ = page_number;
magazine_ = magazine;
RCHECK(reader.SkipBits(40));
const uint8_t subcode_c11_c14 = ReadHamming(reader);
const uint8_t charset_code = subcode_c11_c14 >> 1;
if (charset_code != charset_code_) {
charset_code_ = charset_code;
UpdateCharset();
}
return false;
} else if (packet_nr == 26) {
ParsePacket26(data_block);
return false;
} else if (packet_nr > 26) {
return false;
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
row = BuildRow(data_block, packet_nr);
return true;
}
void EsParserTeletext::UpdateCharset() {
memcpy(current_charset_, TELETEXT_CHARSET_G0_LATIN, sizeof(TELETEXT_CHARSET_G0_LATIN));
if (charset_code_ > 7) {
return;
}
const auto teletext_national_subset =
static_cast<TELETEXT_NATIONAL_SUBSET>(charset_code_);
switch (teletext_national_subset) {
case TELETEXT_NATIONAL_SUBSET::ENGLISH:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_ENGLISH);
break;
case TELETEXT_NATIONAL_SUBSET::FRENCH:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_FRENCH);
break;
case TELETEXT_NATIONAL_SUBSET::SWEDISH_FINNISH_HUNGARIAN:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_SWEDISH_FINNISH_HUNGARIAN);
break;
case TELETEXT_NATIONAL_SUBSET::CZECH_SLOVAK:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_CZECH_SLOVAK);
break;
case TELETEXT_NATIONAL_SUBSET::GERMAN:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_GERMAN);
break;
case TELETEXT_NATIONAL_SUBSET::PORTUGUESE_SPANISH:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_PORTUGUESE_SPANISH);
break;
case TELETEXT_NATIONAL_SUBSET::ITALIAN:
UpdateNationalSubset(TELETEXT_NATIONAL_SUBSET_ITALIAN);
break;
case TELETEXT_NATIONAL_SUBSET::NONE:
default:
break;
}
}
void EsParserTeletext::SendPending(const uint16_t index, const int64_t pts) {
auto page_state_itr = page_state_.find(index);
if (page_state_itr == page_state_.end() ||
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
page_state_itr->second.rows.empty()) {
return;
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
const auto& pending_rows = page_state_itr->second.rows;
const auto pending_pts = page_state_itr->second.pts;
TextSettings text_settings;
std::shared_ptr<TextSample> text_sample;
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
std::vector<TextFragment> sub_fragments;
if (pending_rows.size() == 1) {
// This is a single line of formatted text.
// Propagate row number/2 and alignment
const float line_nr = float(pending_rows[0].row_number) / 2.0;
text_settings.line = TextNumber(line_nr, TextUnitType::kLines);
text_settings.region = kRegionTeletextPrefix + std::to_string(int(line_nr));
text_settings.text_alignment = pending_rows[0].alignment;
text_sample = std::make_shared<TextSample>(
"", pending_pts, pts, text_settings, pending_rows[0].fragment);
text_sample->set_sub_stream_index(index);
emit_sample_cb_(text_sample);
page_state_.erase(index);
return;
} else {
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
int32_t latest_row_nr = -1;
bool last_double_height = false;
bool new_sample = true;
for (const auto& row : pending_rows) {
int row_nr = row.row_number;
bool double_height = row.double_height;
int row_step = last_double_height ? 2 : 1;
if (latest_row_nr != -1) { // Not the first row
if (row_nr != latest_row_nr + row_step) {
// Send what has been collected since not adjacent
text_sample =
std::make_shared<TextSample>("", pending_pts, pts, text_settings,
TextFragment({}, sub_fragments));
text_sample->set_sub_stream_index(index);
emit_sample_cb_(text_sample);
new_sample = true;
} else {
// Add a newline and the next row to the current sample
sub_fragments.push_back(TextFragment({}, true));
sub_fragments.push_back(row.fragment);
new_sample = false;
}
}
if (new_sample) {
const float line_nr = float(row.row_number) / 2.0;
text_settings.line = TextNumber(line_nr, TextUnitType::kLines);
text_settings.region =
kRegionTeletextPrefix + std::to_string(int(line_nr));
text_settings.text_alignment = row.alignment;
sub_fragments.clear();
sub_fragments.push_back(row.fragment);
}
last_double_height = double_height;
latest_row_nr = row_nr;
}
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
text_sample = std::make_shared<TextSample>(
"", pending_pts, pts, text_settings, TextFragment({}, sub_fragments));
text_sample->set_sub_stream_index(index);
emit_sample_cb_(text_sample);
page_state_.erase(index);
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
// BuildRow builds a row with alignment information.
EsParserTeletext::TextRow EsParserTeletext::BuildRow(const uint8_t* data_block,
const uint8_t row) const {
std::string next_string;
next_string.reserve(kPayloadSize * 2);
const uint16_t index = magazine_ * 100 + page_number_;
const auto page_state_itr = page_state_.find(index);
const std::unordered_map<uint8_t, std::string>* column_replacement_map =
nullptr;
if (page_state_itr != page_state_.cend()) {
const auto row_itr =
page_state_itr->second.packet_26_replacements.find(row);
if (row_itr != page_state_itr->second.packet_26_replacements.cend()) {
column_replacement_map = &(row_itr->second);
}
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
int32_t start_pos = 0;
int32_t end_pos = 0;
bool double_height = false;
TextFragmentStyle text_style = TextFragmentStyle();
text_style.color = "white";
text_style.backgroundColor = "black";
// A typical 40 character line looks like:
// doubleHeight, [color] spaces, Start, Start, text, End End, spaces
for (size_t i = 0; i < kPayloadSize; ++i) {
if (column_replacement_map) {
const auto column_itr = column_replacement_map->find(i);
if (column_itr != column_replacement_map->cend()) {
next_string.append(column_itr->second);
continue;
}
}
char next_char =
static_cast<char>(TELETEXT_BITREVERSE_8[data_block[i]] & 0x7f);
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
if (next_char < 0x20) {
// Here are control characters, which are not printable.
// These include colors, double-height, flashing, etc.
// We only handle one-foreground color and double-height.
switch (next_char) {
case 0x0: // Alpha Black (not included in Level 1.5)
// color = ColorBlack
break;
case 0x1:
text_style.color = "red";
break;
case 0x2:
text_style.color = "green";
break;
case 0x3:
text_style.color = "yellow";
break;
case 0x4:
text_style.color = "blue";
break;
case 0x5:
text_style.color = "magenta";
break;
case 0x6:
text_style.color = "cyan";
break;
case 0x7:
text_style.color = "white";
break;
case 0x08: // Flash (not handled)
break;
case 0x09: // Steady (not handled)
break;
case 0xa: // End Box
end_pos = i - 1;
break;
case 0xb: // Start Box, typically twice due to double height
start_pos = i + 1;
continue; // Do not propagate as a space
break;
case 0xc: // Normal size
break;
case 0xd: // Double height, typically always used
double_height = true;
break;
case 0x1c: // Black background (not handled)
break;
case 0x1d: // Set background color from text color.
text_style.backgroundColor = text_style.color;
text_style.color = "black"; // Avoid having same as background
break;
default:
// Rest of codes below 0x20 are not part of Level 1.5 or related to
// mosaic graphics (non-text)
break;
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
next_char =
0x20; // These characters result in a space if between start and end
}
if (start_pos == 0 || end_pos != 0) { // Not between start and end
continue;
}
switch (next_char) {
case '&':
next_string.append("&amp;");
break;
case '<':
next_string.append("&lt;");
break;
default: {
const std::string replacement(current_charset_[next_char - 0x20]);
next_string.append(replacement);
} break;
}
}
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
if (end_pos == 0) {
end_pos = kPayloadSize - 1;
}
// Using start_pos and end_pos we approximated alignment of text
// depending on the number of spaces to the left and right of the text.
auto left_right_diff = start_pos - (kPayloadSize - 1 - end_pos);
TextAlignment alignment;
if (left_right_diff > 4) {
alignment = TextAlignment::kRight;
} else if (left_right_diff < -4) {
alignment = TextAlignment::kLeft;
} else {
alignment = TextAlignment::kCenter;
}
const auto text_row = TextRow(
{alignment, row, double_height, {TextFragment(text_style, next_string)}});
feat: teletext formatting (#1384) This PR adds parsing of teletext styling, and rendering of the styling in output TTML and WebVTT subtitle tracks. Beyond unit tests, I've used the sample https://drive.google.com/file/d/19ZYsoeUfH85gEilQkaAdLbPhC4CxhDEh/view?usp=sharing which has rather advanced subtitling with two separate rows at the same time, where one is left aligned and another is right aligned. This necessitates two parallel cues to be rendered. It also has some colored text. Solve #1335. ## parse teletext styling and formatting Extend the teletext parser to parse the teletext styling and formatting. This includes translating rows into regions, calculating alignment from start and stop position of the text, and extracting text and background colors. The colors are limited to full lines. Both lines and regions are propagated in the TextSample structures. This is because the number of lines may differ from different sources. For teletext, there are 24 rows, but they are essentially always used with double height, so the number of output lines is 12 from 0 to 11. There are also corresponding regions are denoted "ttx_R", where R is an integer row number. A renderer can use either the line number or the region ID to render the text. ## ttml generation for teletext to EBU-TT-D Add support to render teletext input in EBU-TT-D (IMSC-1) format. This includes appropriate regions ttx_0 to ttx_11 signalled in the TextSamples, alignment and text and background colors. The general TTML output has been changed to always include metadata, layout, and styling nodes, even if they are empty. EBU-TT-D is detected by the presence of "ttx_?" regions in the samples. If detected, extra TTML elements will be added and the EBU-TT-D linePadding used as well. Appropriate styles for background and text colors are generated depending on the color and backgroundColor attributes in the text fragments. ## adapt WebVTT output to teletext TextSample. Teletext input generates both a region with prefix ttx_ and a floating point line number (e.g. 9.5) in the range 0 to 11.5 (due to input 0-23 as double lines). The output is adopted to drop such regions and convert the line number to an integer since the standard only used floats for percent values but not for plain line numbers.
2024-04-29 17:33:03 +00:00
return text_row;
}
void EsParserTeletext::ParsePacket26(const uint8_t* data_block) {
const uint16_t index = magazine_ * 100 + page_number_;
auto page_state_itr = page_state_.find(index);
if (page_state_itr == page_state_.end()) {
page_state_.emplace(index, TextBlock{{}, {}, last_pts_});
}
auto& replacement_map = page_state_[index].packet_26_replacements;
uint8_t row = 0;
std::vector<uint32_t> x26_triplets;
x26_triplets.reserve(kNumTriplets);
for (uint8_t i = 1; i < kPayloadSize; i += 3) {
const uint32_t bytes = (TELETEXT_BITREVERSE_8[data_block[i + 2]] << 16) |
(TELETEXT_BITREVERSE_8[data_block[i + 1]] << 8) |
TELETEXT_BITREVERSE_8[data_block[i]];
uint32_t triplet;
if (Hamming_24_18(bytes, triplet)) {
x26_triplets.emplace_back(triplet);
}
}
for (const auto triplet : x26_triplets) {
const uint8_t mode = (triplet & 0x7c0) >> 6;
const uint8_t address = triplet & 0x3f;
const uint8_t row_address_group = (address >= 0x28) && (address <= 0x3f);
if ((mode == 0x4) && (row_address_group == 0x1)) {
row = address - 0x28;
if (row == 0x0) {
row = 0x18;
}
}
if (mode >= 0x11 && mode <= 0x1f && row_address_group == 0x1) {
break;
}
const uint8_t data = (triplet & 0x3f800) >> 11;
if (mode == 0x0f && row_address_group == 0x0 && data > 0x1f) {
SetPacket26ReplacementString(replacement_map, row, address,
reinterpret_cast<const char*>(
TELETEXT_CHARSET_G2_LATIN[data - 0x20]));
}
if (mode == 0x10 && row_address_group == 0x0 && data == 0x40) {
SetPacket26ReplacementString(replacement_map, row, address, "@");
}
if (mode < 0x11 || mode > 0x1f || row_address_group != 0x0) {
continue;
}
if (data >= 0x41 && data <= 0x5a) {
SetPacket26ReplacementString(
replacement_map, row, address,
reinterpret_cast<const char*>(
TELETEXT_G2_LATIN_ACCENTS[mode - 0x11][data - 0x41]));
} else if (data >= 0x61 && data <= 0x7a) {
SetPacket26ReplacementString(
replacement_map, row, address,
reinterpret_cast<const char*>(
TELETEXT_G2_LATIN_ACCENTS[mode - 0x11][data - 0x47]));
} else if ((data & 0x7f) >= 0x20) {
SetPacket26ReplacementString(
replacement_map, row, address,
reinterpret_cast<const char*>(
TELETEXT_CHARSET_G0_LATIN[(data & 0x7f) - 0x20]));
}
}
}
void EsParserTeletext::UpdateNationalSubset(
const uint8_t national_subset[13][3]) {
for (size_t i = 0; i < 13; ++i) {
const size_t position = TELETEXT_NATIONAL_CHAR_INDEX_G0[i];
memcpy(current_charset_[position], national_subset[i], 3);
}
}
void EsParserTeletext::SetPacket26ReplacementString(
RowColReplacementMap& replacement_map,
const uint8_t row,
const uint8_t column,
std::string&& replacement_string) {
auto replacement_map_itr = replacement_map.find(row);
if (replacement_map_itr == replacement_map.cend()) {
replacement_map.emplace(row, std::unordered_map<uint8_t, std::string>{});
}
auto& column_map = replacement_map[row];
column_map.emplace(column, std::move(replacement_string));
}
} // namespace mp2t
} // namespace media
} // namespace shaka