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 2022 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 "WebAudioPlayerService.h"
21 : #include "IGstWebAudioPlayer.h"
22 : #include "IMainThread.h"
23 : #include "ITimer.h"
24 : #include "IWebAudioPlayer.h"
25 : #include "IWebAudioPlayerServerInternal.h"
26 : #include "RialtoServerLogging.h"
27 : #include "WebAudioPlayerMetricsClient.h"
28 : #include <exception>
29 : #include <future>
30 : #include <string>
31 : #include <utility>
32 : #include <vector>
33 :
34 : namespace firebolt::rialto::server::service
35 : {
36 43 : WebAudioPlayerService::WebAudioPlayerService(IPlaybackService &playbackService,
37 : std::shared_ptr<IWebAudioPlayerServerInternalFactory> &&webAudioPlayerFactory,
38 43 : IPrivateMetricsService &metricsService)
39 43 : : m_playbackService{playbackService}, m_webAudioPlayerFactory{std::move(webAudioPlayerFactory)},
40 86 : m_metricsService{metricsService}
41 : {
42 43 : RIALTO_SERVER_LOG_DEBUG("WebAudioPlayerService is constructed");
43 : }
44 :
45 86 : WebAudioPlayerService::~WebAudioPlayerService()
46 : {
47 43 : RIALTO_SERVER_LOG_DEBUG("WebAudioPlayerService is destructed");
48 86 : }
49 :
50 1 : void WebAudioPlayerService::clearWebAudioPlayers()
51 : {
52 1 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
53 1 : m_webAudioPlayers.clear();
54 : }
55 :
56 27 : bool WebAudioPlayerService::createWebAudioPlayer(int handle,
57 : const std::shared_ptr<IWebAudioPlayerClient> &webAudioPlayerClient,
58 : const std::string &audioMimeType, const uint32_t priority,
59 : std::weak_ptr<const WebAudioConfig> config)
60 : {
61 27 : RIALTO_SERVER_LOG_DEBUG("WebAudioPlayerService requested to create new WebAudioPlayer with id: %d", handle);
62 27 : if (!m_playbackService.isActive())
63 : {
64 1 : RIALTO_SERVER_LOG_ERROR("Skip create WebAudioPlayer with id: %d - Session Server in Inactive state", handle);
65 1 : return false;
66 : }
67 :
68 : {
69 26 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
70 26 : if (m_webAudioPlayers.size() == static_cast<size_t>(m_playbackService.getMaxWebAudioPlayers()))
71 : {
72 1 : RIALTO_SERVER_LOG_ERROR("Unable to create WebAudioPlayer with id: %d. Max instance number reached.", handle);
73 1 : return false;
74 : }
75 25 : if (m_webAudioPlayers.find(handle) != m_webAudioPlayers.end())
76 : {
77 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d already exists", handle);
78 1 : return false;
79 : }
80 24 : auto shmBuffer = m_playbackService.getShmBuffer();
81 :
82 24 : m_webAudioPlayers.emplace(
83 48 : std::make_pair(handle,
84 24 : m_webAudioPlayerFactory
85 120 : ->createWebAudioPlayerServerInternal(std::make_shared<
86 48 : WebAudioPlayerMetricsClient>(handle,
87 : webAudioPlayerClient,
88 : m_metricsService),
89 : audioMimeType, priority, config, shmBuffer, handle,
90 48 : IMainThreadFactory::createFactory(),
91 48 : IGstWebAudioPlayerFactory::getFactory(),
92 48 : common::ITimerFactory::getFactory())));
93 24 : if (!m_webAudioPlayers.at(handle))
94 : {
95 1 : RIALTO_SERVER_LOG_ERROR("Could not create WebAudioPlayer for handle: %d", handle);
96 1 : m_webAudioPlayers.erase(handle);
97 1 : return false;
98 : }
99 27 : }
100 :
101 23 : RIALTO_SERVER_LOG_INFO("New WebAudioPlayer: %d created", handle);
102 23 : return true;
103 : }
104 :
105 3 : bool WebAudioPlayerService::destroyWebAudioPlayer(int handle)
106 : {
107 3 : RIALTO_SERVER_LOG_DEBUG("WebAudioPlayerService requested to destroy WebAudioPlayer with handle: %d", handle);
108 : {
109 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
110 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
111 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
112 : {
113 2 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
114 2 : return false;
115 : }
116 1 : m_webAudioPlayers.erase(webAudioPlayerIter);
117 3 : }
118 1 : RIALTO_SERVER_LOG_INFO("WebAudioPlayer: %d destroyed", handle);
119 1 : return true;
120 : }
121 :
122 3 : bool WebAudioPlayerService::play(int handle)
123 : {
124 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to play WebAudioPlayer with handle: %d", handle);
125 :
126 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
127 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
128 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
129 : {
130 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
131 1 : return false;
132 : }
133 2 : return webAudioPlayerIter->second->play();
134 3 : }
135 :
136 3 : bool WebAudioPlayerService::pause(int handle)
137 : {
138 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to pause WebAudioPlayer with handle: %d", handle);
139 :
140 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
141 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
142 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
143 : {
144 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
145 1 : return false;
146 : }
147 2 : return webAudioPlayerIter->second->pause();
148 3 : }
149 :
150 3 : bool WebAudioPlayerService::setEos(int handle)
151 : {
152 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to setEos WebAudioPlayer with handle: %d", handle);
153 :
154 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
155 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
156 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
157 : {
158 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
159 1 : return false;
160 : }
161 2 : return webAudioPlayerIter->second->setEos();
162 3 : }
163 :
164 3 : bool WebAudioPlayerService::getBufferAvailable(int handle, uint32_t &availableFrames,
165 : std::shared_ptr<WebAudioShmInfo> &webAudioShmInfo)
166 : {
167 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to getBufferAvailable WebAudioPlayer with handle: %d",
168 : handle);
169 :
170 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
171 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
172 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
173 : {
174 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
175 1 : return false;
176 : }
177 2 : return webAudioPlayerIter->second->getBufferAvailable(availableFrames, webAudioShmInfo);
178 3 : }
179 :
180 3 : bool WebAudioPlayerService::getBufferDelay(int handle, uint32_t &delayFrames)
181 : {
182 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to getBufferDelay WebAudioPlayer with handle: %d", handle);
183 :
184 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
185 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
186 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
187 : {
188 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
189 1 : return false;
190 : }
191 2 : return webAudioPlayerIter->second->getBufferDelay(delayFrames);
192 3 : }
193 :
194 3 : bool WebAudioPlayerService::writeBuffer(int handle, const uint32_t numberOfFrames, void *data)
195 : {
196 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to writeBuffer WebAudioPlayer with handle: %d", handle);
197 :
198 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
199 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
200 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
201 : {
202 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
203 1 : return false;
204 : }
205 2 : return webAudioPlayerIter->second->writeBuffer(numberOfFrames, data);
206 3 : }
207 :
208 3 : bool WebAudioPlayerService::getDeviceInfo(int handle, uint32_t &preferredFrames, uint32_t &maximumFrames,
209 : bool &supportDeferredPlay)
210 : {
211 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to getDeviceInfo WebAudioPlayer with handle: %d", handle);
212 :
213 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
214 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
215 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
216 : {
217 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
218 1 : return false;
219 : }
220 2 : return webAudioPlayerIter->second->getDeviceInfo(preferredFrames, maximumFrames, supportDeferredPlay);
221 3 : }
222 :
223 3 : bool WebAudioPlayerService::setVolume(int handle, double volume)
224 : {
225 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to setVolume WebAudioPlayer with handle: %d", handle);
226 :
227 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
228 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
229 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
230 : {
231 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
232 1 : return false;
233 : }
234 2 : return webAudioPlayerIter->second->setVolume(volume);
235 3 : }
236 :
237 3 : bool WebAudioPlayerService::getVolume(int handle, double &volume)
238 : {
239 3 : RIALTO_SERVER_LOG_INFO("WebAudioPlayerService requested to getVolume WebAudioPlayer with handle: %d", handle);
240 :
241 3 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
242 3 : auto webAudioPlayerIter = m_webAudioPlayers.find(handle);
243 3 : if (webAudioPlayerIter == m_webAudioPlayers.end())
244 : {
245 1 : RIALTO_SERVER_LOG_ERROR("WebAudioPlayer with handle: %d does not exists", handle);
246 1 : return false;
247 : }
248 2 : return webAudioPlayerIter->second->getVolume(volume);
249 3 : }
250 :
251 2 : void WebAudioPlayerService::ping(const std::shared_ptr<IHeartbeatProcedure> &heartbeatProcedure)
252 : {
253 2 : RIALTO_SERVER_LOG_DEBUG("Ping requested");
254 2 : std::lock_guard<std::mutex> lock{m_webAudioPlayerMutex};
255 3 : for (const auto &webAudioPlayersPair : m_webAudioPlayers)
256 : {
257 1 : auto &webAudioPlayer = webAudioPlayersPair.second;
258 1 : webAudioPlayer->ping(heartbeatProcedure->createHandler());
259 : }
260 2 : }
261 : } // namespace firebolt::rialto::server::service
|