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