20 #include "TtmlSubtecParser.hpp"
26 m_channel = SubtecChannel::SubtecChannelFactory(SubtecChannel::ChannelType::TTML);
27 if (!m_channel->InitComms())
29 AAMPLOG_INFO(
"Init failed - subtitle parsing disabled");
30 throw std::runtime_error(
"PacketSender init failed");
32 m_channel->SendResetAllPacket();
34 int width = 1920, height = 1080;
35 mAamp->GetPlayerVideoSize(width, height);
36 m_channel->SendSelectionPacket(width, height);
37 m_channel->SendMutePacket();
41 bool TtmlSubtecParser::init(
double startPosSeconds,
unsigned long long basePTS)
43 AAMPLOG_INFO(
"startPos %.3fs", startPosSeconds);
44 m_channel->SendTimestampPacket(
static_cast<uint64_t
>(startPosSeconds * 1000.0));
47 m_parsedFirstPacket =
false;
49 m_firstBeginOffset = 0.0;
54 void TtmlSubtecParser::updateTimestamp(
unsigned long long positionMs)
56 m_channel->SendTimestampPacket(positionMs);
59 void TtmlSubtecParser::reset()
61 m_channel->SendResetChannelPacket();
64 static std::int64_t parseFirstBegin(std::stringstream &ss)
66 std::int64_t firstBegin = std::numeric_limits<std::int64_t>::max();
68 static const std::regex beginRegex(R
"(begin="([0-9]+):([0-9][0-9]?):([0-9][0-9]?)\.?([0-9]+)?")");
70 while(std::getline(ss, line))
76 matched = std::regex_search(line, match, beginRegex);
79 std::int64_t hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
81 if (!match.str(1).empty()) AAMPLOG_WARN(
"h:%s", match.str(1).c_str()); hours = std::stol(match.str(1));
82 if (!match.str(2).empty()) AAMPLOG_WARN(
"m:%s", match.str(2).c_str()); minutes = std::stol(match.str(2));
83 if (!match.str(3).empty()) AAMPLOG_WARN(
"s:%s", match.str(3).c_str()); seconds = std::stol(match.str(3));
84 if (!match.str(4).empty()) AAMPLOG_WARN(
"ms:%s", match.str(4).c_str()); milliseconds = std::stol(match.str(4));
86 firstBegin = milliseconds + (1000 * (seconds + (60 * (minutes + (60 * hours)))));
90 catch (
const std::regex_error& e) {
91 AAMPLOG_WARN(
"Regex error %s from line %s", std::to_string(e.code()).c_str(), line.c_str());
98 bool TtmlSubtecParser::processData(
char* buffer,
size_t bufferLen,
double position,
double duration)
102 isobuf.setBuffer(
reinterpret_cast<uint8_t *
>(buffer), bufferLen);
103 isobuf.parseBuffer();
105 if (!isobuf.isInitSegment())
111 isobuf.getMdatBoxSize(mdatLen);
113 mdat = (uint8_t *)malloc(mdatLen);
114 isobuf.parseMdatBox(mdat, mdatLen);
116 std::vector<uint8_t> data(mdatLen);
117 data.assign(mdat, mdat+mdatLen);
122 if (!m_parsedFirstPacket && m_isLinear)
124 m_firstBeginOffset = position;
125 m_parsedFirstPacket =
true;
128 if (!m_sentOffset && m_parsedFirstPacket && m_isLinear)
130 AAMPLOG_TRACE(
"Linear content - parsing first begin as offset - pos %.3f dur %.3f m_firstBeginOffset %.3f",
131 position, duration, m_firstBeginOffset);
132 std::stringstream ss(std::string(data.begin(), data.end()));
133 std::int64_t offset = parseFirstBegin(ss);
135 if (offset != std::numeric_limits<std::int64_t>::max())
137 auto positionDeltaSecs = (position - m_firstBeginOffset);
138 auto timeFromStartMs = mAamp->GetPositionMs() - (mAamp->seek_pos_seconds * 1000.0);
139 std::int64_t totalOffset = offset - (positionDeltaSecs * 1000.0) + timeFromStartMs;
141 std::stringstream output;
142 output <<
"setting totalOffset " << totalOffset <<
" positionDeltaSecs " << positionDeltaSecs <<
143 " timeFromStartMs " << timeFromStartMs;
146 m_channel->SendTimestampPacket(totalOffset);
150 m_channel->SendDataPacket(std::move(data), 0);
153 AAMPLOG_TRACE(
"Sent buffer with size %zu position %.3f", bufferLen, position);
157 AAMPLOG_INFO(
"Init Segment");
162 void TtmlSubtecParser::mute(
bool mute)
165 m_channel->SendMutePacket();
167 m_channel->SendUnmutePacket();
170 void TtmlSubtecParser::pause(
bool pause)
173 m_channel->SendPausePacket();
175 m_channel->SendResumePacket();