Line data Source code
1 : /*
2 : * Copyright (C) 2022 Sky UK
3 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Lesser General Public
6 : * License as published by the Free Software Foundation;
7 : * version 2.1 of the License.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Lesser General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public
15 : * License along with this library; if not, write to the Free Software
16 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 : */
18 :
19 : #include "MediaPlayerManager.h"
20 : #include "GstreamerCatLog.h"
21 : #include "IMessageQueue.h"
22 : #include "MediaPlayerClientBackend.h"
23 :
24 : std::mutex MediaPlayerManager::m_mediaPlayerClientsMutex;
25 : std::map<const GstObject *, MediaPlayerManager::MediaPlayerClientInfo> MediaPlayerManager::m_mediaPlayerClientsInfo;
26 : #define GST_CAT_DEFAULT rialtoGStreamerCat
27 278 : MediaPlayerManager::MediaPlayerManager() : m_currentGstBinParent(nullptr) {}
28 :
29 278 : MediaPlayerManager::~MediaPlayerManager()
30 : {
31 278 : releaseMediaPlayerClient();
32 : }
33 :
34 150 : bool MediaPlayerManager::attachMediaPlayerClient(const GstObject *gstBinParent, const uint32_t maxVideoWidth,
35 : const uint32_t maxVideoHeight)
36 : {
37 150 : if (!m_client.lock())
38 : {
39 149 : createMediaPlayerClient(gstBinParent, maxVideoWidth, maxVideoHeight);
40 : }
41 1 : else if (gstBinParent != m_currentGstBinParent)
42 : {
43 : // New parent gst bin, release old client and create new
44 1 : releaseMediaPlayerClient();
45 1 : createMediaPlayerClient(gstBinParent, maxVideoWidth, maxVideoHeight);
46 : }
47 :
48 150 : if (!m_client.lock())
49 : {
50 4 : GST_ERROR("Failed to attach the media player client");
51 4 : return false;
52 : }
53 : else
54 : {
55 146 : return true;
56 : }
57 : }
58 :
59 1139 : std::shared_ptr<GStreamerMSEMediaPlayerClient> MediaPlayerManager::getMediaPlayerClient()
60 : {
61 1139 : return m_client.lock();
62 : }
63 :
64 8 : bool MediaPlayerManager::hasControl()
65 : {
66 8 : if (m_client.lock())
67 : {
68 7 : std::lock_guard<std::mutex> guard(m_mediaPlayerClientsMutex);
69 :
70 7 : auto it = m_mediaPlayerClientsInfo.find(m_currentGstBinParent);
71 7 : if (it != m_mediaPlayerClientsInfo.end())
72 : {
73 7 : if (it->second.controller == this)
74 : {
75 5 : return true;
76 : }
77 : else
78 : { // in case there's no controller anymore
79 2 : return acquireControl(it->second);
80 : }
81 : }
82 : else
83 : {
84 0 : GST_WARNING("Could not find the attached media player client");
85 : }
86 7 : }
87 : else
88 : {
89 1 : GST_WARNING("No media player client attached");
90 : }
91 :
92 1 : return false;
93 : }
94 :
95 433 : void MediaPlayerManager::releaseMediaPlayerClient()
96 : {
97 433 : if (m_client.lock())
98 : {
99 146 : std::lock_guard<std::mutex> guard(m_mediaPlayerClientsMutex);
100 :
101 146 : auto it = m_mediaPlayerClientsInfo.find(m_currentGstBinParent);
102 146 : if (it != m_mediaPlayerClientsInfo.end())
103 : {
104 146 : it->second.refCount--;
105 146 : if (it->second.refCount == 0)
106 : {
107 142 : it->second.client->stop();
108 142 : it->second.client->stopStreaming();
109 142 : it->second.client->destroyClientBackend();
110 142 : m_mediaPlayerClientsInfo.erase(it);
111 : }
112 : else
113 : {
114 4 : if (it->second.controller == this)
115 4 : it->second.controller = nullptr;
116 : }
117 146 : m_client.reset();
118 146 : m_currentGstBinParent = nullptr;
119 : }
120 : else
121 : {
122 0 : GST_ERROR("Could not find the attached media player client");
123 : }
124 146 : }
125 433 : }
126 :
127 2 : bool MediaPlayerManager::acquireControl(MediaPlayerClientInfo &mediaPlayerClientInfo)
128 : {
129 2 : if (mediaPlayerClientInfo.controller == nullptr)
130 : {
131 1 : mediaPlayerClientInfo.controller = this;
132 1 : return true;
133 : }
134 :
135 1 : return false;
136 : }
137 :
138 150 : void MediaPlayerManager::createMediaPlayerClient(const GstObject *gstBinParent, const uint32_t maxVideoWidth,
139 : const uint32_t maxVideoHeight)
140 : {
141 150 : std::lock_guard<std::mutex> guard(m_mediaPlayerClientsMutex);
142 :
143 150 : auto it = m_mediaPlayerClientsInfo.find(gstBinParent);
144 150 : if (it != m_mediaPlayerClientsInfo.end())
145 : {
146 4 : it->second.refCount++;
147 4 : m_client = it->second.client;
148 4 : m_currentGstBinParent = gstBinParent;
149 : }
150 : else
151 : {
152 : std::shared_ptr<firebolt::rialto::client::MediaPlayerClientBackendInterface> clientBackend =
153 146 : std::make_shared<firebolt::rialto::client::MediaPlayerClientBackend>();
154 : std::shared_ptr<GStreamerMSEMediaPlayerClient> client =
155 292 : std::make_shared<GStreamerMSEMediaPlayerClient>(IMessageQueueFactory::createFactory(), clientBackend,
156 146 : maxVideoWidth, maxVideoHeight);
157 :
158 146 : if (client->createBackend())
159 : {
160 : // Store the new client in global map
161 142 : MediaPlayerClientInfo newClientInfo;
162 142 : newClientInfo.client = client;
163 142 : newClientInfo.controller = this;
164 142 : newClientInfo.refCount = 1;
165 142 : m_mediaPlayerClientsInfo.insert(
166 284 : std::pair<const GstObject *, MediaPlayerClientInfo>(gstBinParent, newClientInfo));
167 :
168 : // Store client info in object
169 142 : m_client = client;
170 142 : m_currentGstBinParent = gstBinParent;
171 : }
172 : else
173 : {
174 4 : GST_ERROR("Failed to create the media player client backend");
175 4 : return;
176 : }
177 150 : }
178 : }
|