LCOV - code coverage report
Current view: top level - source - GStreamerMSEMediaPlayerClient.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 4 4
Test Date: 2025-08-11 12:19:57 Functions: 100.0 % 3 3

            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              : #pragma once
      20              : 
      21              : #include <atomic>
      22              : #include <condition_variable>
      23              : #include <functional>
      24              : #include <memory>
      25              : #include <mutex>
      26              : #include <thread>
      27              : #include <unordered_map>
      28              : #include <unordered_set>
      29              : #include <vector>
      30              : 
      31              : #include <gst/gst.h>
      32              : #include <sys/syscall.h>
      33              : #include <sys/types.h>
      34              : #include <unistd.h>
      35              : 
      36              : #include "BufferParser.h"
      37              : #include "Constants.h"
      38              : #include "IMediaPipeline.h"
      39              : #include "IMessageQueue.h"
      40              : #include "IPullModePlaybackDelegate.h"
      41              : #include "MediaCommon.h"
      42              : #include "MediaPlayerClientBackendInterface.h"
      43              : #include "RialtoGStreamerMSEBaseSink.h"
      44              : 
      45              : #define DEFAULT_MAX_VIDEO_WIDTH 3840
      46              : #define DEFAULT_MAX_VIDEO_HEIGHT 2160
      47              : 
      48              : class GStreamerMSEMediaPlayerClient;
      49              : 
      50              : enum class ClientState
      51              : {
      52              :     IDLE,
      53              :     READY,
      54              :     AWAITING_PAUSED,
      55              :     PAUSED,
      56              :     AWAITING_PLAYING,
      57              :     PLAYING
      58              : };
      59              : 
      60              : class BufferPuller
      61              : {
      62              : public:
      63              :     BufferPuller(const std::shared_ptr<IMessageQueueFactory> &messageQueueFactory, GstElement *rialtoSink,
      64              :                  const std::shared_ptr<BufferParser> &bufferParser,
      65              :                  const std::shared_ptr<IPullModePlaybackDelegate> &delegate);
      66              : 
      67              :     void start();
      68              :     void stop();
      69              :     bool requestPullBuffer(int sourceId, size_t frameCount, unsigned int needDataRequestId,
      70              :                            GStreamerMSEMediaPlayerClient *player);
      71              : 
      72              : private:
      73              :     std::unique_ptr<IMessageQueue> m_queue;
      74              :     GstElement *m_rialtoSink;
      75              :     std::shared_ptr<BufferParser> m_bufferParser;
      76              :     std::shared_ptr<IPullModePlaybackDelegate> m_delegate;
      77              : };
      78              : 
      79              : class AttachedSource
      80              : {
      81              :     friend class GStreamerMSEMediaPlayerClient;
      82              : 
      83              : public:
      84          197 :     AttachedSource(RialtoMSEBaseSink *rialtoSink, std::shared_ptr<BufferPuller> puller,
      85              :                    const std::shared_ptr<IPullModePlaybackDelegate> &delegate, firebolt::rialto::MediaSourceType type,
      86              :                    ClientState state = ClientState::READY)
      87          197 :         : m_rialtoSink(rialtoSink), m_bufferPuller(puller), m_delegate{delegate}, m_type(type), m_state(state)
      88              :     {
      89              :     }
      90              : 
      91          394 :     firebolt::rialto::MediaSourceType getType() const { return m_type; }
      92            1 :     void setPosition(int64_t position) { m_position = position; }
      93              : 
      94              : private:
      95              :     RialtoMSEBaseSink *m_rialtoSink;
      96              :     std::shared_ptr<BufferPuller> m_bufferPuller;
      97              :     std::shared_ptr<IPullModePlaybackDelegate> m_delegate;
      98              :     std::unordered_set<uint32_t> m_ongoingNeedDataRequests;
      99              :     firebolt::rialto::MediaSourceType m_type = firebolt::rialto::MediaSourceType::UNKNOWN;
     100              :     int64_t m_position = 0;
     101              :     bool m_isFlushing = false;
     102              :     ClientState m_state = ClientState::READY;
     103              : };
     104              : 
     105              : class HaveDataMessage : public Message
     106              : {
     107              : public:
     108              :     HaveDataMessage(firebolt::rialto::MediaSourceStatus status, int sourceId, unsigned int needDataRequestId,
     109              :                     GStreamerMSEMediaPlayerClient *player);
     110              :     void handle() override;
     111              : 
     112              : private:
     113              :     firebolt::rialto::MediaSourceStatus m_status;
     114              :     int m_sourceId;
     115              :     unsigned int m_needDataRequestId;
     116              :     GStreamerMSEMediaPlayerClient *m_player;
     117              : };
     118              : 
     119              : class PullBufferMessage : public Message
     120              : {
     121              : public:
     122              :     PullBufferMessage(int sourceId, size_t frameCount, unsigned int needDataRequestId, GstElement *rialtoSink,
     123              :                       const std::shared_ptr<BufferParser> &bufferParser, IMessageQueue &pullerQueue,
     124              :                       GStreamerMSEMediaPlayerClient *player, const std::shared_ptr<IPullModePlaybackDelegate> &delegate);
     125              :     void handle() override;
     126              : 
     127              : private:
     128              :     int m_sourceId;
     129              :     size_t m_frameCount;
     130              :     unsigned int m_needDataRequestId;
     131              :     GstElement *m_rialtoSink;
     132              :     std::shared_ptr<BufferParser> m_bufferParser;
     133              :     IMessageQueue &m_pullerQueue;
     134              :     GStreamerMSEMediaPlayerClient *m_player;
     135              :     std::shared_ptr<IPullModePlaybackDelegate> m_delegate;
     136              : };
     137              : 
     138              : class NeedDataMessage : public Message
     139              : {
     140              : public:
     141              :     NeedDataMessage(int sourceId, size_t frameCount, unsigned int needDataRequestId,
     142              :                     GStreamerMSEMediaPlayerClient *player);
     143              :     void handle() override;
     144              : 
     145              : private:
     146              :     int m_sourceId;
     147              :     size_t m_frameCount;
     148              :     unsigned int m_needDataRequestId;
     149              :     GStreamerMSEMediaPlayerClient *m_player;
     150              : };
     151              : 
     152              : class PlaybackStateMessage : public Message
     153              : {
     154              : public:
     155              :     PlaybackStateMessage(firebolt::rialto::PlaybackState state, GStreamerMSEMediaPlayerClient *player);
     156              :     void handle() override;
     157              : 
     158              : private:
     159              :     firebolt::rialto::PlaybackState m_state;
     160              :     GStreamerMSEMediaPlayerClient *m_player;
     161              : };
     162              : 
     163              : class QosMessage : public Message
     164              : {
     165              : public:
     166              :     QosMessage(int sourceId, firebolt::rialto::QosInfo qosInfo, GStreamerMSEMediaPlayerClient *player);
     167              :     void handle() override;
     168              : 
     169              : private:
     170              :     int m_sourceId;
     171              :     firebolt::rialto::QosInfo m_qosInfo;
     172              :     GStreamerMSEMediaPlayerClient *m_player;
     173              : };
     174              : 
     175              : class BufferUnderflowMessage : public Message
     176              : {
     177              : public:
     178              :     BufferUnderflowMessage(int sourceId, GStreamerMSEMediaPlayerClient *player);
     179              :     void handle() override;
     180              : 
     181              : private:
     182              :     int m_sourceId;
     183              :     GStreamerMSEMediaPlayerClient *m_player;
     184              : };
     185              : 
     186              : class PlaybackErrorMessage : public Message
     187              : {
     188              : public:
     189              :     PlaybackErrorMessage(int sourceId, firebolt::rialto::PlaybackError error, GStreamerMSEMediaPlayerClient *player);
     190              :     void handle() override;
     191              : 
     192              : private:
     193              :     int m_sourceId;
     194              :     firebolt::rialto::PlaybackError m_error;
     195              :     GStreamerMSEMediaPlayerClient *m_player;
     196              : };
     197              : 
     198              : class SetPositionMessage : public Message
     199              : {
     200              : public:
     201              :     SetPositionMessage(int64_t newPosition, std::unordered_map<int32_t, AttachedSource> &attachedSources);
     202              :     void handle() override;
     203              : 
     204              : private:
     205              :     int64_t m_newPosition;
     206              :     std::unordered_map<int32_t, AttachedSource> &m_attachedSources;
     207              : };
     208              : 
     209              : class SetDurationMessage : public Message
     210              : {
     211              : public:
     212              :     SetDurationMessage(int64_t newDuration, int64_t &targetDuration);
     213              :     void handle() override;
     214              : 
     215              : private:
     216              :     int64_t m_newDuration;
     217              :     int64_t &m_targetDuration;
     218              : };
     219              : 
     220              : class SourceFlushedMessage : public Message
     221              : {
     222              : public:
     223              :     SourceFlushedMessage(int32_t sourceId, GStreamerMSEMediaPlayerClient *player);
     224              :     void handle() override;
     225              : 
     226              : private:
     227              :     int32_t m_sourceId;
     228              :     GStreamerMSEMediaPlayerClient *m_player;
     229              : };
     230              : 
     231              : enum class StateChangeResult
     232              : {
     233              :     SUCCESS_ASYNC,
     234              :     SUCCESS_SYNC,
     235              :     NOT_ATTACHED
     236              : };
     237              : 
     238              : class GStreamerMSEMediaPlayerClient : public firebolt::rialto::IMediaPipelineClient,
     239              :                                       public std::enable_shared_from_this<GStreamerMSEMediaPlayerClient>
     240              : {
     241              :     friend class NeedDataMessage;
     242              :     friend class PullBufferMessage;
     243              :     friend class HaveDataMessage;
     244              :     friend class QosMessage;
     245              : 
     246              : public:
     247              :     GStreamerMSEMediaPlayerClient(
     248              :         const std::shared_ptr<IMessageQueueFactory> &messageQueueFactory,
     249              :         const std::shared_ptr<firebolt::rialto::client::MediaPlayerClientBackendInterface> &MediaPlayerClientBackend,
     250              :         const uint32_t maxVideoWidth, const uint32_t maxVideoHeight);
     251              :     virtual ~GStreamerMSEMediaPlayerClient();
     252              : 
     253              :     void notifyDuration(int64_t duration) override;
     254              :     void notifyPosition(int64_t position) override;
     255              :     void notifyNativeSize(uint32_t width, uint32_t height, double aspect) override;
     256              :     void notifyNetworkState(firebolt::rialto::NetworkState state) override;
     257              :     void notifyPlaybackState(firebolt::rialto::PlaybackState state) override;
     258              :     void notifyVideoData(bool hasData) override;
     259              :     void notifyAudioData(bool hasData) override;
     260              :     void notifyNeedMediaData(int32_t sourceId, size_t frameCount, uint32_t needDataRequestId,
     261              :                              const std::shared_ptr<firebolt::rialto::MediaPlayerShmInfo> &shmInfo) override;
     262              :     void notifyCancelNeedMediaData(int32_t sourceId) override;
     263              :     void notifyQos(int32_t sourceId, const firebolt::rialto::QosInfo &qosInfo) override;
     264              :     void notifyBufferUnderflow(int32_t sourceId) override;
     265              :     void notifyPlaybackError(int32_t sourceId, firebolt::rialto::PlaybackError error) override;
     266              :     void notifySourceFlushed(int32_t sourceId) override;
     267              : 
     268              :     void getPositionDo(int64_t *position, int32_t sourceId);
     269              :     int64_t getPosition(int32_t sourceId);
     270              :     bool setImmediateOutput(int32_t sourceId, bool immediateOutput);
     271              :     bool getImmediateOutput(int32_t sourceId, bool &immediateOutput);
     272              :     bool getStats(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames);
     273              : 
     274              :     firebolt::rialto::AddSegmentStatus
     275              :     addSegment(unsigned int needDataRequestId,
     276              :                const std::unique_ptr<firebolt::rialto::IMediaPipeline::MediaSegment> &mediaSegment);
     277              : 
     278              :     bool createBackend();
     279              :     StateChangeResult play(int32_t sourceId);
     280              :     StateChangeResult pause(int32_t sourceId);
     281              :     void stop();
     282              :     void setPlaybackRate(double rate);
     283              :     void flush(int32_t sourceId, bool resetTime);
     284              :     void setSourcePosition(int32_t sourceId, int64_t position, bool resetTime, double appliedRate = 1.0,
     285              :                            uint64_t stopPosition = GST_CLOCK_TIME_NONE);
     286              :     void processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac);
     287              : 
     288              :     bool attachSource(std::unique_ptr<firebolt::rialto::IMediaPipeline::MediaSource> &source,
     289              :                       RialtoMSEBaseSink *rialtoSink, const std::shared_ptr<IPullModePlaybackDelegate> &delegate);
     290              :     void removeSource(int32_t sourceId);
     291              :     void handlePlaybackStateChange(firebolt::rialto::PlaybackState state);
     292              :     void handleSourceFlushed(int32_t sourceId);
     293              :     void sendAllSourcesAttachedIfPossible();
     294              : 
     295              :     void setVideoRectangle(const std::string &rectangleString);
     296              :     std::string getVideoRectangle();
     297              : 
     298              :     bool requestPullBuffer(int streamId, size_t frameCount, unsigned int needDataRequestId);
     299              :     bool handleQos(int sourceId, firebolt::rialto::QosInfo qosInfo);
     300              :     bool handleBufferUnderflow(int sourceId);
     301              :     bool handlePlaybackError(int sourceId, firebolt::rialto::PlaybackError error);
     302              :     void stopStreaming();
     303              :     void destroyClientBackend();
     304              :     bool renderFrame(int32_t sourceId);
     305              :     void setVolume(double targetVolume, uint32_t volumeDuration, firebolt::rialto::EaseType easeType);
     306              :     bool getVolume(double &volume);
     307              :     void setMute(bool mute, int32_t sourceId);
     308              :     bool getMute(int sourceId);
     309              :     void setTextTrackIdentifier(const std::string &textTrackIdentifier);
     310              :     std::string getTextTrackIdentifier();
     311              :     bool setLowLatency(bool lowLatency);
     312              :     bool setSync(bool sync);
     313              :     bool getSync(bool &sync);
     314              :     bool setSyncOff(bool syncOff);
     315              :     bool setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode);
     316              :     bool getStreamSyncMode(int32_t &streamSyncMode);
     317              :     ClientState getClientState();
     318              :     void handleStreamCollection(int32_t audioStreams, int32_t videoStreams, int32_t subtitleStreams);
     319              :     void setBufferingLimit(uint32_t limitBufferingMs);
     320              :     uint32_t getBufferingLimit();
     321              :     void setUseBuffering(bool useBuffering);
     322              :     bool getUseBuffering();
     323              :     bool switchSource(const std::unique_ptr<firebolt::rialto::IMediaPipeline::MediaSource> &source);
     324              : 
     325              : private:
     326              :     bool areAllStreamsAttached();
     327              :     void sendAllSourcesAttachedIfPossibleInternal();
     328              :     bool checkIfAllAttachedSourcesInStates(const std::vector<ClientState> &states);
     329              : 
     330              :     std::unique_ptr<IMessageQueue> m_backendQueue;
     331              :     std::shared_ptr<IMessageQueueFactory> m_messageQueueFactory;
     332              :     std::shared_ptr<firebolt::rialto::client::MediaPlayerClientBackendInterface> m_clientBackend;
     333              :     int64_t m_position;
     334              :     int64_t m_duration;
     335              :     std::mutex m_playerMutex;
     336              :     std::unordered_map<int32_t, AttachedSource> m_attachedSources;
     337              :     bool m_wasAllSourcesAttachedSent = false;
     338              :     int32_t m_audioStreams;
     339              :     int32_t m_videoStreams;
     340              :     int32_t m_subtitleStreams;
     341              : 
     342              :     struct Rectangle
     343              :     {
     344              :         unsigned int x, y, width, height;
     345              :     } m_videoRectangle;
     346              : 
     347              :     firebolt::rialto::PlaybackState m_serverPlaybackState = firebolt::rialto::PlaybackState::IDLE;
     348              :     ClientState m_clientState = ClientState::IDLE;
     349              :     // To check if the backend message queue and pulling of data to serve backend is stopped or not
     350              :     bool m_streamingStopped;
     351              : 
     352              :     const uint32_t m_maxWidth;
     353              :     const uint32_t m_maxHeight;
     354              : };
        

Generated by: LCOV version 2.0-1