Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2024 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include "TextTrackSession.h"
21 : #include "ITextTrackAccessor.h"
22 : #include "RialtoServerLogging.h"
23 : #include <stdexcept>
24 :
25 : namespace firebolt::rialto::server
26 : {
27 0 : ITextTrackSessionFactory &ITextTrackSessionFactory::getFactory()
28 : {
29 0 : static TextTrackSessionFactory factory;
30 0 : return factory;
31 : }
32 :
33 0 : std::unique_ptr<ITextTrackSession> TextTrackSessionFactory::createTextTrackSession(const std::string &display) const
34 : {
35 0 : return std::make_unique<TextTrackSession>(display, ITextTrackAccessorFactory::getFactory());
36 : }
37 :
38 13 : TextTrackSession::TextTrackSession(const std::string &displayName,
39 13 : const ITextTrackAccessorFactory &textTrackAccessorFactory)
40 : {
41 13 : m_textTrackAccessor = textTrackAccessorFactory.getTextTrackAccessor();
42 13 : if (!m_textTrackAccessor)
43 : {
44 1 : RIALTO_SERVER_LOG_ERROR("Failed to get TextTrackAccessor");
45 1 : throw std::runtime_error("Failed to get TextTrackAccessor");
46 : }
47 :
48 12 : std::optional<uint32_t> sessionId = m_textTrackAccessor->openSession(displayName);
49 12 : if (!sessionId)
50 : {
51 1 : RIALTO_SERVER_LOG_ERROR("Failed to create TextTrack session");
52 1 : throw std::runtime_error("Failed to create TextTrack session");
53 : }
54 :
55 11 : m_sessionId = sessionId.value();
56 17 : }
57 :
58 22 : TextTrackSession::~TextTrackSession()
59 : {
60 11 : m_textTrackAccessor->closeSession(m_sessionId);
61 22 : }
62 :
63 1 : bool TextTrackSession::resetSession(bool isMuted)
64 : {
65 : // There is no direct way to clear TextTrack's data. The only option is to reset the session, but that also resets
66 : // the data type and mute values
67 1 : if (!m_textTrackAccessor->resetSession(m_sessionId))
68 : {
69 0 : return false;
70 : }
71 :
72 1 : bool wasDataTypeSelected = false;
73 1 : if (m_dataType == ITextTrackAccessor::DataType::WebVTT)
74 : {
75 0 : wasDataTypeSelected = setSessionWebVTTSelection();
76 : }
77 1 : else if (m_dataType == ITextTrackAccessor::DataType::TTML)
78 : {
79 1 : wasDataTypeSelected = setSessionTTMLSelection();
80 : }
81 0 : else if (m_dataType == ITextTrackAccessor::DataType::CC)
82 : {
83 0 : if (m_ccService.has_value())
84 : {
85 0 : wasDataTypeSelected = setSessionCCSelection(m_ccService.value());
86 0 : if (m_videoDecoderId.has_value())
87 : {
88 0 : wasDataTypeSelected = associateVideoDecoder(m_videoDecoderId.value());
89 : }
90 : }
91 : else
92 : {
93 0 : RIALTO_SERVER_LOG_ERROR("CC service not set");
94 0 : return false;
95 : }
96 : }
97 :
98 1 : if (!wasDataTypeSelected)
99 : {
100 0 : return false;
101 : }
102 :
103 : // changing the data type resets the mute value in TextTrack to its default (false), so we need to set mute
104 : // after selecting the data type
105 1 : return mute(isMuted);
106 : }
107 :
108 1 : bool TextTrackSession::pause()
109 : {
110 1 : return m_textTrackAccessor->pause(m_sessionId);
111 : }
112 :
113 1 : bool TextTrackSession::play()
114 : {
115 1 : return m_textTrackAccessor->play(m_sessionId);
116 : }
117 :
118 2 : bool TextTrackSession::mute(bool mute)
119 : {
120 2 : return m_textTrackAccessor->mute(m_sessionId, mute);
121 : }
122 :
123 1 : bool TextTrackSession::setPosition(uint64_t mediaTimestampMs)
124 : {
125 1 : return m_textTrackAccessor->setPosition(m_sessionId, mediaTimestampMs);
126 : }
127 :
128 3 : bool TextTrackSession::sendData(const std::string &data, int64_t displayOffsetMs)
129 : {
130 3 : return m_textTrackAccessor->sendData(m_sessionId, data, m_dataType, displayOffsetMs);
131 : }
132 :
133 1 : bool TextTrackSession::setSessionWebVTTSelection()
134 : {
135 1 : m_dataType = ITextTrackAccessor::DataType::WebVTT;
136 1 : m_ccService = std::optional<std::string>();
137 1 : return m_textTrackAccessor->setSessionWebVTTSelection(m_sessionId);
138 : }
139 :
140 3 : bool TextTrackSession::setSessionTTMLSelection()
141 : {
142 3 : m_dataType = ITextTrackAccessor::DataType::TTML;
143 3 : m_ccService = std::optional<std::string>();
144 3 : return m_textTrackAccessor->setSessionTTMLSelection(m_sessionId);
145 : }
146 :
147 1 : bool TextTrackSession::setSessionCCSelection(const std::string &service)
148 : {
149 1 : m_dataType = ITextTrackAccessor::DataType::CC;
150 1 : m_ccService = service;
151 1 : return m_textTrackAccessor->setSessionCCSelection(m_sessionId, service);
152 : }
153 :
154 2 : bool TextTrackSession::associateVideoDecoder(uint64_t decoderId)
155 : {
156 2 : m_videoDecoderId = decoderId;
157 2 : std::string decoderIdStr = std::to_string(decoderId);
158 4 : return m_textTrackAccessor->associateVideoDecoder(m_sessionId, decoderIdStr);
159 2 : }
160 :
161 3 : bool TextTrackSession::isClosedCaptions() const
162 : {
163 3 : return m_dataType == ITextTrackAccessor::DataType::CC;
164 : }
165 : } // namespace firebolt::rialto::server
|