LCOV - code coverage report
Current view: top level - media/server/main/source - WebAudioPlayerServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.4 % 251 242
Test Date: 2025-02-18 13:13:53 Functions: 97.4 % 38 37

            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 <limits.h>
      21              : #include <stdexcept>
      22              : 
      23              : #include "RialtoServerLogging.h"
      24              : #include "WebAudioPlayerServerInternal.h"
      25              : 
      26              : namespace
      27              : {
      28              : constexpr uint32_t kPreferredFrames{640};
      29              : constexpr std::chrono::milliseconds kWriteDataTimeMs{100};
      30              : } // namespace
      31              : 
      32              : namespace firebolt::rialto
      33              : {
      34            1 : std::shared_ptr<IWebAudioPlayerFactory> IWebAudioPlayerFactory::createFactory()
      35              : {
      36            1 :     return server::IWebAudioPlayerServerInternalFactory::createFactory();
      37              : }
      38              : }; // namespace firebolt::rialto
      39              : 
      40              : namespace firebolt::rialto::server
      41              : {
      42            2 : std::shared_ptr<IWebAudioPlayerServerInternalFactory> IWebAudioPlayerServerInternalFactory::createFactory()
      43              : {
      44            2 :     std::shared_ptr<IWebAudioPlayerServerInternalFactory> factory;
      45              : 
      46              :     try
      47              :     {
      48            2 :         factory = std::make_shared<server::WebAudioPlayerServerInternalFactory>();
      49              :     }
      50            0 :     catch (const std::exception &e)
      51              :     {
      52            0 :         RIALTO_SERVER_LOG_ERROR("Failed to create the web audio player factory, reason: %s", e.what());
      53              :     }
      54              : 
      55            2 :     return factory;
      56              : }
      57              : 
      58              : std::unique_ptr<IWebAudioPlayer>
      59            1 : WebAudioPlayerServerInternalFactory::createWebAudioPlayer(std::weak_ptr<IWebAudioPlayerClient> client,
      60              :                                                           const std::string &audioMimeType, const uint32_t priority,
      61              :                                                           std::weak_ptr<const WebAudioConfig> config) const
      62              : {
      63            1 :     RIALTO_SERVER_LOG_ERROR(
      64              :         "This function can't be used by rialto server. Please use createWebAudioPlayerServerInternal");
      65            1 :     return nullptr;
      66              : }
      67              : 
      68            1 : std::unique_ptr<IWebAudioPlayerServerInternal> WebAudioPlayerServerInternalFactory::createWebAudioPlayerServerInternal(
      69              :     std::weak_ptr<IWebAudioPlayerClient> client, const std::string &audioMimeType, const uint32_t priority,
      70              :     std::weak_ptr<const WebAudioConfig> config, const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, int handle,
      71              :     const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
      72              :     const std::shared_ptr<IGstWebAudioPlayerFactory> &gstPlayerFactory,
      73              :     std::weak_ptr<common::ITimerFactory> timerFactory) const
      74              : {
      75            1 :     std::unique_ptr<IWebAudioPlayerServerInternal> webAudioPlayer;
      76              :     try
      77              :     {
      78            2 :         webAudioPlayer = std::make_unique<server::WebAudioPlayerServerInternal>(client, audioMimeType, priority, config,
      79              :                                                                                 shmBuffer, handle, mainThreadFactory,
      80            1 :                                                                                 gstPlayerFactory, timerFactory);
      81              :     }
      82            0 :     catch (const std::exception &e)
      83              :     {
      84            0 :         RIALTO_SERVER_LOG_ERROR("Failed to create the web audio player, reason: %s", e.what());
      85              :     }
      86              : 
      87            1 :     return webAudioPlayer;
      88              : }
      89              : 
      90           39 : WebAudioPlayerServerInternal::WebAudioPlayerServerInternal(
      91              :     std::weak_ptr<IWebAudioPlayerClient> client, const std::string &audioMimeType, const uint32_t priority,
      92              :     std::weak_ptr<const WebAudioConfig> webAudioConfig, const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer,
      93              :     int handle, const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
      94           39 :     const std::shared_ptr<IGstWebAudioPlayerFactory> &gstPlayerFactory, std::weak_ptr<common::ITimerFactory> timerFactory)
      95           39 :     : m_webAudioPlayerClient(client), m_shmBuffer{shmBuffer}, m_priority{priority}, m_shmId{handle}, m_shmPtr{nullptr},
      96           39 :       m_partitionOffset{0}, m_maxDataLength{0}, m_availableBuffer{}, m_expectWriteBuffer{false},
      97           78 :       m_timerFactory{timerFactory}, m_bytesPerFrame{0}, m_isEosRequested{false}
      98              : {
      99           39 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     100              : 
     101           39 :     if (audioMimeType == "audio/x-raw")
     102              :     {
     103           38 :         std::shared_ptr<const WebAudioConfig> kConfig = webAudioConfig.lock();
     104           38 :         if (kConfig == nullptr)
     105              :         {
     106            1 :             throw std::runtime_error("Config is null for 'audio/x-raw'");
     107              :         }
     108           37 :         m_bytesPerFrame = kConfig->pcm.channels * (kConfig->pcm.sampleSize / CHAR_BIT);
     109           37 :         if (m_bytesPerFrame == 0)
     110              :         {
     111            3 :             throw std::runtime_error("Bytes per frame cannot be 0, channels " + std::to_string(kConfig->pcm.channels) +
     112            4 :                                      ", sampleSize " + std::to_string(kConfig->pcm.sampleSize));
     113              :         }
     114           38 :     }
     115              :     else
     116              :     {
     117            1 :         throw std::runtime_error("Mimetype '" + audioMimeType + "' not supported");
     118              :     }
     119              : 
     120           36 :     m_mainThread = mainThreadFactory->getMainThread();
     121           36 :     if (!m_mainThread)
     122              :     {
     123            1 :         throw std::runtime_error("Failed to get the main thread");
     124              :     }
     125           35 :     m_mainThreadClientId = m_mainThread->registerClient();
     126              : 
     127           35 :     bool result = false;
     128           35 :     auto task = [&]() { result = initWebAudioPlayerInternal(audioMimeType, webAudioConfig, gstPlayerFactory); };
     129              : 
     130           35 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     131           35 :     if (!result)
     132              :     {
     133            5 :         throw std::runtime_error("WebAudioPlayerServerInternal construction failed");
     134              :     }
     135          102 : }
     136              : 
     137           35 : bool WebAudioPlayerServerInternal::initWebAudioPlayerInternal(
     138              :     const std::string &audioMimeType, std::weak_ptr<const WebAudioConfig> config,
     139              :     const std::shared_ptr<IGstWebAudioPlayerFactory> &gstPlayerFactory)
     140              : {
     141           35 :     if (!m_shmBuffer->mapPartition(ISharedMemoryBuffer::MediaPlaybackType::WEB_AUDIO, m_shmId))
     142              :     {
     143            1 :         RIALTO_SERVER_LOG_ERROR("Unable to map shm partition");
     144            1 :         return false;
     145              :     }
     146              : 
     147           34 :     if (!(m_shmPtr = m_shmBuffer->getBuffer()))
     148              :     {
     149            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get the data pointer for the shared memory");
     150            1 :         return false;
     151              :     }
     152              : 
     153              :     try
     154              :     {
     155           33 :         m_partitionOffset = m_shmBuffer->getDataOffset(ISharedMemoryBuffer::MediaPlaybackType::WEB_AUDIO, m_shmId,
     156           33 :                                                        MediaSourceType::AUDIO);
     157              :     }
     158            1 :     catch (const std::exception &e)
     159              :     {
     160            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get the data pointer of the partition");
     161            1 :         return false;
     162              :     }
     163              : 
     164           32 :     if (!(m_maxDataLength = m_shmBuffer->getMaxDataLen(ISharedMemoryBuffer::MediaPlaybackType::WEB_AUDIO, m_shmId,
     165           32 :                                                        MediaSourceType::AUDIO)))
     166              :     {
     167            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get the length of the partition");
     168            1 :         return false;
     169              :     }
     170              : 
     171           31 :     if (!initGstWebAudioPlayer(audioMimeType, config, gstPlayerFactory))
     172              :     {
     173            1 :         RIALTO_SERVER_LOG_ERROR("Failed to initalise the GstPlayer");
     174            1 :         return false;
     175              :     }
     176              : 
     177              :     // Set the available bytes
     178           30 :     m_availableBuffer.lengthMain = m_maxDataLength;
     179           30 :     m_availableBuffer.offsetMain = m_partitionOffset;
     180           30 :     m_availableBuffer.offsetWrap = m_partitionOffset;
     181              : 
     182           30 :     return true;
     183              : }
     184              : 
     185           60 : WebAudioPlayerServerInternal::~WebAudioPlayerServerInternal()
     186              : {
     187           30 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     188              : 
     189           30 :     auto task = [&]()
     190              :     {
     191           30 :         if (m_writeDataTimer && (m_writeDataTimer->isActive()))
     192              :         {
     193            4 :             m_writeDataTimer->cancel();
     194              :         }
     195              : 
     196           30 :         if (!m_shmBuffer->unmapPartition(ISharedMemoryBuffer::MediaPlaybackType::WEB_AUDIO, m_shmId))
     197              :         {
     198            0 :             RIALTO_SERVER_LOG_ERROR("Unable to unmap shm partition");
     199              :         }
     200              : 
     201           30 :         m_shmBuffer.reset();
     202           30 :         m_mainThread->unregisterClient(m_mainThreadClientId);
     203           60 :     };
     204           30 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     205           60 : }
     206              : 
     207            1 : bool WebAudioPlayerServerInternal::play()
     208              : {
     209            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     210              : 
     211            1 :     auto task = [&]() { m_gstPlayer->play(); };
     212              : 
     213            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
     214              : 
     215            1 :     return true;
     216              : }
     217              : 
     218            1 : bool WebAudioPlayerServerInternal::pause()
     219              : {
     220            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     221              : 
     222            1 :     auto task = [&]() { m_gstPlayer->pause(); };
     223              : 
     224            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
     225              : 
     226            1 :     return true;
     227              : }
     228              : 
     229            2 : bool WebAudioPlayerServerInternal::setEos()
     230              : {
     231            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     232              : 
     233            2 :     auto task = [&]()
     234              :     {
     235            2 :         if (0 != getQueuedFramesInShm())
     236              :         {
     237            1 :             m_isEosRequested = true;
     238              :         }
     239              :         else
     240              :         {
     241            1 :             m_gstPlayer->setEos();
     242              :         }
     243            4 :     };
     244              : 
     245            2 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
     246              : 
     247            2 :     return true;
     248              : }
     249              : 
     250           31 : bool WebAudioPlayerServerInternal::getBufferAvailable(uint32_t &availableFrames,
     251              :                                                       std::shared_ptr<WebAudioShmInfo> &webAudioShmInfo)
     252              : {
     253           31 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     254              : 
     255           31 :     if (!webAudioShmInfo)
     256              :     {
     257            0 :         RIALTO_SERVER_LOG_ERROR("WebAudioShmInfo is null");
     258            0 :         return false;
     259              :     }
     260              : 
     261           31 :     auto task = [&]()
     262              :     {
     263           31 :         *webAudioShmInfo = m_availableBuffer;
     264           31 :         availableFrames = (m_availableBuffer.lengthMain + m_availableBuffer.lengthWrap) / m_bytesPerFrame;
     265              : 
     266              :         // A new getBufferAvailable shall overwrite the previous if writeBuffer is not called inbetween
     267           31 :         m_expectWriteBuffer = true;
     268           62 :     };
     269              : 
     270           31 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     271              : 
     272           31 :     return true;
     273              : }
     274              : 
     275            3 : bool WebAudioPlayerServerInternal::getBufferDelay(uint32_t &delayFrames)
     276              : {
     277            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     278              : 
     279            3 :     bool status = false;
     280            3 :     auto task = [&]()
     281              :     {
     282              :         // Gstreamer returns a uint64, so check the value first
     283            3 :         uint64_t queuedFrames = (m_gstPlayer->getQueuedBytes() / m_bytesPerFrame) + getQueuedFramesInShm();
     284            3 :         if (queuedFrames > std::numeric_limits<uint32_t>::max())
     285              :         {
     286            1 :             RIALTO_SERVER_LOG_ERROR("Queued frames are larger than the max uint32_t");
     287              :         }
     288              :         else
     289              :         {
     290            2 :             delayFrames = static_cast<uint32_t>(queuedFrames);
     291            2 :             status = true;
     292              :         }
     293            6 :     };
     294              : 
     295            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     296            3 :     return status;
     297              : }
     298              : 
     299           24 : bool WebAudioPlayerServerInternal::writeBuffer(const uint32_t numberOfFrames, void *data)
     300              : {
     301           24 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     302              : 
     303           24 :     bool result = false;
     304           24 :     auto task = [&]()
     305              :     {
     306              :         // data can be ignored, the frames should be written to the shared memory
     307           24 :         result = writeBufferInternal(numberOfFrames);
     308           48 :     };
     309              : 
     310           24 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     311              : 
     312           24 :     return result;
     313              : }
     314              : 
     315           24 : bool WebAudioPlayerServerInternal::writeBufferInternal(const uint32_t numberOfFrames)
     316              : {
     317           24 :     if (!m_expectWriteBuffer)
     318              :     {
     319            4 :         RIALTO_SERVER_LOG_ERROR("No getBufferAvailable to match with this writeBuffer call");
     320            4 :         return false;
     321              :     }
     322           20 :     m_expectWriteBuffer = false;
     323              : 
     324              :     // Cancel timer
     325           20 :     if (m_writeDataTimer && (m_writeDataTimer->isActive()))
     326              :     {
     327            7 :         m_writeDataTimer->cancel();
     328            7 :         m_writeDataTimer = nullptr;
     329              :     }
     330              : 
     331              :     // Write stored frames first
     332           20 :     uint32_t numberOfBytesToWrite = numberOfFrames * m_bytesPerFrame;
     333           20 :     if (!writeStoredBuffers())
     334              :     {
     335              :         // Update the available buffer with the new data that will not be written to gst
     336            2 :         updateAvailableBuffer(numberOfBytesToWrite, 0);
     337              :         m_writeDataTimer =
     338            6 :             m_timerFactory->createTimer(kWriteDataTimeMs,
     339            4 :                                         std::bind(&WebAudioPlayerServerInternal::handleWriteDataTimer, this));
     340            2 :         return true;
     341              :     }
     342              : 
     343           18 :     if (0 == numberOfFrames)
     344              :     {
     345              :         // No frames to write to gst
     346            2 :         return true;
     347              :     }
     348              : 
     349              :     // Write new frames
     350           16 :     uint8_t *mainPtr = m_shmPtr + m_availableBuffer.offsetMain;
     351           16 :     uint8_t *wrapPtr = m_shmPtr + m_availableBuffer.offsetWrap;
     352           16 :     uint32_t mainLength = 0;
     353           16 :     uint32_t wrapLength = 0;
     354           16 :     if (numberOfBytesToWrite <= m_availableBuffer.lengthMain)
     355              :     {
     356           14 :         mainLength = numberOfBytesToWrite;
     357              :     }
     358              :     else
     359              :     {
     360            2 :         mainLength = m_availableBuffer.lengthMain;
     361            2 :         wrapLength = numberOfBytesToWrite - mainLength;
     362              :     }
     363              : 
     364           16 :     uint32_t newBytesWritten = m_gstPlayer->writeBuffer(mainPtr, mainLength, wrapPtr, wrapLength);
     365           16 :     updateAvailableBuffer(numberOfBytesToWrite, newBytesWritten);
     366           16 :     if (newBytesWritten != numberOfBytesToWrite)
     367              :     {
     368              :         m_writeDataTimer =
     369           30 :             m_timerFactory->createTimer(kWriteDataTimeMs,
     370           30 :                                         std::bind(&WebAudioPlayerServerInternal::handleWriteDataTimer, this));
     371              :     }
     372              : 
     373           16 :     return true;
     374              : }
     375              : 
     376           22 : bool WebAudioPlayerServerInternal::writeStoredBuffers()
     377              : {
     378           22 :     uint8_t *mainPtr = nullptr;
     379           22 :     uint32_t mainLength = 0;
     380           22 :     uint8_t *wrapPtr = nullptr;
     381           22 :     uint32_t wrapLength = 0;
     382              : 
     383           22 :     if (m_availableBuffer.lengthWrap + m_availableBuffer.lengthMain == m_maxDataLength)
     384              :     {
     385              :         // No data stored
     386           13 :         return true;
     387              :     }
     388            9 :     else if (m_availableBuffer.lengthWrap != 0)
     389              :     {
     390              :         // Data stored in the shared memory has not wrapped, data only stored in the middle of the shared memory region
     391            5 :         uint32_t startOfDataOffset = m_availableBuffer.offsetWrap + m_availableBuffer.lengthWrap;
     392            5 :         mainPtr = m_shmPtr + startOfDataOffset;
     393            5 :         mainLength = m_availableBuffer.offsetMain - startOfDataOffset;
     394              :     }
     395              :     else
     396              :     {
     397              :         // Data stored in the shared memory has wrapped, data stored at the end and start of the shared memory region
     398            4 :         uint32_t startOfDataOffset = m_availableBuffer.offsetMain + m_availableBuffer.lengthMain;
     399            4 :         mainPtr = m_shmPtr + startOfDataOffset;
     400            4 :         mainLength = m_maxDataLength - (startOfDataOffset - m_partitionOffset);
     401              :         // Wrapped data stored at the start of the shared memory region up to where the availableBuffer starts
     402            4 :         wrapPtr = m_shmPtr + m_partitionOffset;
     403            4 :         wrapLength = m_availableBuffer.offsetMain - m_partitionOffset;
     404              :     }
     405              : 
     406            9 :     uint32_t storedBytesWritten = m_gstPlayer->writeBuffer(mainPtr, mainLength, wrapPtr, wrapLength);
     407              : 
     408              :     // Update available buffer with the bytes written to gst.
     409              :     // Bytes written to shm is 0 becuase they have already been handled.
     410            9 :     updateAvailableBuffer(0, storedBytesWritten);
     411              : 
     412            9 :     if (storedBytesWritten == mainLength + wrapLength)
     413              :     {
     414              :         // All data written to gstreamer
     415            6 :         if (m_isEosRequested)
     416              :         {
     417            1 :             m_gstPlayer->setEos();
     418            1 :             m_isEosRequested = false;
     419              :         }
     420            6 :         return true;
     421              :     }
     422              : 
     423            3 :     return false;
     424              : }
     425              : 
     426           27 : void WebAudioPlayerServerInternal::updateAvailableBuffer(uint32_t bytesWrittenToShm, uint32_t bytesWrittenToGst)
     427              : {
     428           27 :     if (bytesWrittenToShm <= m_availableBuffer.lengthMain)
     429              :     {
     430              :         // Data written to the shared memory has not wrapped
     431           24 :         uint32_t offetRelativeToPartition = m_availableBuffer.offsetMain - m_partitionOffset;
     432           24 :         uint32_t storedDataLengthAtEndOfShm = m_maxDataLength - (offetRelativeToPartition + m_availableBuffer.lengthMain);
     433              : 
     434           24 :         m_availableBuffer.offsetMain = m_availableBuffer.offsetMain + bytesWrittenToShm;
     435           24 :         if (bytesWrittenToGst <= storedDataLengthAtEndOfShm)
     436              :         {
     437              :             // Data written to gst has not wrapped, data written is taken from the main buffer only
     438            7 :             m_availableBuffer.lengthMain = m_availableBuffer.lengthMain - bytesWrittenToShm + bytesWrittenToGst;
     439              :         }
     440              :         else
     441              :         {
     442              :             // Data written to gst has wrapped, data written is taken from the main buffer and wrapped buffer
     443           17 :             m_availableBuffer.lengthMain = m_availableBuffer.lengthMain - bytesWrittenToShm + storedDataLengthAtEndOfShm;
     444           17 :             m_availableBuffer.lengthWrap = m_availableBuffer.lengthWrap +
     445           17 :                                            (bytesWrittenToGst - storedDataLengthAtEndOfShm);
     446              :         }
     447              :     }
     448              :     else
     449              :     {
     450              :         // Data written to the shared memory has wrapped, available buffer should now point to where the wrapped buffer was
     451            3 :         uint32_t newDataLengthAtEndOfShm = m_availableBuffer.lengthMain;
     452              : 
     453            3 :         m_availableBuffer.offsetMain = m_availableBuffer.offsetWrap + (bytesWrittenToShm - m_availableBuffer.lengthMain);
     454            3 :         uint32_t newOffetRelativeToPartition = m_availableBuffer.offsetMain - m_partitionOffset;
     455            3 :         if (bytesWrittenToGst <= m_availableBuffer.lengthMain)
     456              :         {
     457              :             // Data written to gstreamer has not wrapped, data written is taken from the main buffer only
     458            1 :             m_availableBuffer.lengthMain = (m_availableBuffer.lengthWrap - newOffetRelativeToPartition) +
     459              :                                            bytesWrittenToGst;
     460            1 :             m_availableBuffer.lengthWrap = 0;
     461              :         }
     462              :         else
     463              :         {
     464              :             // Data written to gstreamer has wrapped, data written is taken from the main buffer and wrapped buffer
     465            2 :             m_availableBuffer.lengthMain = m_maxDataLength - newOffetRelativeToPartition;
     466            2 :             m_availableBuffer.lengthWrap = bytesWrittenToGst - newDataLengthAtEndOfShm;
     467              :         }
     468              :     }
     469           27 : }
     470              : 
     471            2 : bool WebAudioPlayerServerInternal::getDeviceInfo(uint32_t &preferredFrames, uint32_t &maximumFrames,
     472              :                                                  bool &supportDeferredPlay)
     473              : {
     474            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     475              : 
     476              :     // Can be called from any thread
     477            2 :     maximumFrames = m_maxDataLength / m_bytesPerFrame;
     478            2 :     preferredFrames = std::min(kPreferredFrames, maximumFrames);
     479            2 :     supportDeferredPlay = true;
     480              : 
     481            2 :     return true;
     482              : }
     483              : 
     484            1 : bool WebAudioPlayerServerInternal::setVolume(double volume)
     485              : {
     486            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     487              : 
     488            1 :     auto task = [&, volume]() { m_gstPlayer->setVolume(volume); };
     489              : 
     490            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
     491              : 
     492            1 :     return true;
     493              : }
     494              : 
     495            2 : bool WebAudioPlayerServerInternal::getVolume(double &volume)
     496              : {
     497            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     498              : 
     499            2 :     bool result = false;
     500            2 :     auto task = [&]() { result = m_gstPlayer->getVolume(volume); };
     501              : 
     502            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     503              : 
     504            2 :     return result;
     505              : }
     506              : 
     507            0 : std::weak_ptr<IWebAudioPlayerClient> WebAudioPlayerServerInternal::getClient()
     508              : {
     509            0 :     return m_webAudioPlayerClient;
     510              : }
     511              : 
     512            1 : void WebAudioPlayerServerInternal::notifyState(WebAudioPlayerState state)
     513              : {
     514            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     515              : 
     516            2 :     auto task = [&, state]()
     517              :     {
     518            1 :         if (m_webAudioPlayerClient)
     519              :         {
     520            1 :             m_webAudioPlayerClient->notifyState(state);
     521              :         }
     522            2 :     };
     523              : 
     524            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
     525              : }
     526              : 
     527           31 : bool WebAudioPlayerServerInternal::initGstWebAudioPlayer(const std::string &audioMimeType,
     528              :                                                          std::weak_ptr<const WebAudioConfig> config,
     529              :                                                          const std::shared_ptr<IGstWebAudioPlayerFactory> &gstPlayerFactory)
     530              : {
     531           31 :     m_gstPlayer = gstPlayerFactory->createGstWebAudioPlayer(this, m_priority);
     532           31 :     if (!m_gstPlayer)
     533              :     {
     534            1 :         RIALTO_SERVER_LOG_ERROR("Failed to load gstreamer player");
     535            1 :         return false;
     536              :     }
     537              : 
     538           30 :     m_gstPlayer->setCaps(audioMimeType, config);
     539              : 
     540           30 :     return true;
     541              : }
     542              : 
     543            2 : void WebAudioPlayerServerInternal::handleWriteDataTimer()
     544              : {
     545            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     546              : 
     547            2 :     auto task = [&]()
     548              :     {
     549            2 :         if (!writeStoredBuffers())
     550              :         {
     551              :             // Not all data was written to gstreamer, restart the timer
     552              :             m_writeDataTimer =
     553            3 :                 m_timerFactory->createTimer(kWriteDataTimeMs,
     554            3 :                                             std::bind(&WebAudioPlayerServerInternal::handleWriteDataTimer, this));
     555              :         }
     556              :         else
     557              :         {
     558            1 :             m_writeDataTimer = nullptr;
     559              :         }
     560            2 :     };
     561              : 
     562            2 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
     563              : }
     564              : 
     565            5 : uint32_t WebAudioPlayerServerInternal::getQueuedFramesInShm()
     566              : {
     567            5 :     return (m_maxDataLength - (m_availableBuffer.lengthMain + m_availableBuffer.lengthWrap)) / m_bytesPerFrame;
     568              : }
     569              : 
     570            1 : void WebAudioPlayerServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
     571              : {
     572            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     573              : 
     574            1 :     auto task = [&]() { m_gstPlayer->ping(std::move(heartbeatHandler)); };
     575            1 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     576              : }
     577              : }; // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1