Skip to content

Commit

Permalink
Change playback rate with GST_SEEK_FLAG_INSTANT_RATE_CHANGE in rialto…
Browse files Browse the repository at this point in the history
… server (#300)

Summary: Change playback rate with GST_SEEK_FLAG_INSTANT_RATE_CHANGE in
rialto server
Type: Feature
Test Plan: UT
Jira: RIALTO-564
  • Loading branch information
skywojciechowskim committed May 14, 2024
1 parent 4bf3a9b commit 9a10024
Show file tree
Hide file tree
Showing 69 changed files with 397 additions and 131 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,14 @@ if (NOT NUM_OF_PINGS_BEFORE_RECOVERY)
set( NUM_OF_PINGS_BEFORE_RECOVERY 3 )
endif()

if (NOT ENABLE_INSTANT_RATE_CHANGE_SEEK)
if( NATIVE_BUILD )
set( ENABLE_INSTANT_RATE_CHANGE_SEEK "true" )
else()
set( ENABLE_INSTANT_RATE_CHANGE_SEEK "false" )
endif()
endif()

if( NATIVE_BUILD )
add_subdirectory( stubs/rdk_gstreamer_utils )
add_subdirectory( stubs/opencdm )
Expand Down
2 changes: 2 additions & 0 deletions common/public/include/SessionServerCommon.in
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ struct ServerManagerConfig
SocketPermissions sessionManagementSocketPermissions{}; /* Defines permissions of session management socket */
unsigned numOfFailedPingsBeforeRecovery{@NUM_OF_PINGS_BEFORE_RECOVERY@};
/* Defines how many pings have to fail before recovery action will be taken */
bool enableInstantRateChangeSeek{@ENABLE_INSTANT_RATE_CHANGE_SEEK@};
/* Defines if new rate change method can be used */
};

} // namespace firebolt::rialto::common
Expand Down
9 changes: 4 additions & 5 deletions media/server/gstplayer/include/GstGenericPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,15 @@ constexpr uint32_t kMinPrimaryVideoHeight{1080};
class GstGenericPlayerFactory : public IGstGenericPlayerFactory
{
public:
/**
* @brief Weak pointer to the singleton factory object.
*/
static std::weak_ptr<IGstGenericPlayerFactory> m_factory;

explicit GstGenericPlayerFactory(bool enableInstantRateChangeSeek);
std::unique_ptr<IGstGenericPlayer>
createGstGenericPlayer(IGstGenericPlayerClient *client, IDecryptionService &decryptionService, MediaType type,
const VideoRequirements &videoRequirements,
const std::shared_ptr<firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapperFactory>
&rdkGstreamerUtilsWrapperFactory) override;

private:
const bool m_kEnableInstantRateChangeSeek;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class GenericPlayerTaskFactory : public IGenericPlayerTaskFactory
GenericPlayerTaskFactory(
IGstGenericPlayerClient *client, const std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> &gstWrapper,
const std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> &glibWrapper,
const std::shared_ptr<firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapper> &rdkGstreamerUtilsWrapper);
const std::shared_ptr<firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapper> &rdkGstreamerUtilsWrapper,
bool enableInstantRateChangeSeek);
~GenericPlayerTaskFactory() override = default;

std::unique_ptr<IPlayerTask> createAttachSamples(GenericPlayerContext &context, IGstGenericPlayerPrivate &player,
Expand Down Expand Up @@ -98,6 +99,7 @@ class GenericPlayerTaskFactory : public IGenericPlayerTaskFactory
std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> m_gstWrapper;
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> m_glibWrapper;
std::shared_ptr<firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapper> m_rdkGstreamerUtilsWrapper;
const bool m_kEnableInstantRateChangeSeek;
};
} // namespace firebolt::rialto::server

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class SetPlaybackRate : public IPlayerTask
{
public:
SetPlaybackRate(GenericPlayerContext &context, std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate);
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate,
bool enableInstantRateChangeSeek);
~SetPlaybackRate() override;
void execute() const override;

Expand All @@ -41,6 +42,7 @@ class SetPlaybackRate : public IPlayerTask
std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> m_gstWrapper;
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> m_glibWrapper;
double m_rate;
bool m_enableInstantRateChangeSeek;
};
} // namespace firebolt::rialto::server::tasks::generic

Expand Down
6 changes: 4 additions & 2 deletions media/server/gstplayer/interface/IGstGenericPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ class IGstGenericPlayerFactory
virtual ~IGstGenericPlayerFactory() = default;

/**
* @brief Gets the IGstGenericPlayerFactory instance.
* @brief Creates the IGstGenericPlayerFactory instance.
*
* @param[in] enableInstantRateChangeSeek : Defines if new rate change method can be used
*
* @retval the factory instance or null on error.
*/
static std::shared_ptr<IGstGenericPlayerFactory> getFactory();
static std::shared_ptr<IGstGenericPlayerFactory> createFactory(bool enableInstantRateChangeSeek);

/**
* @brief Creates a IGstGenericPlayer object.
Expand Down
28 changes: 8 additions & 20 deletions media/server/gstplayer/source/GstGenericPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,14 @@ constexpr std::chrono::milliseconds kPositionReportTimerMs{250};

namespace firebolt::rialto::server
{
std::weak_ptr<IGstGenericPlayerFactory> GstGenericPlayerFactory::m_factory;

std::shared_ptr<IGstGenericPlayerFactory> IGstGenericPlayerFactory::getFactory()
std::shared_ptr<IGstGenericPlayerFactory> IGstGenericPlayerFactory::createFactory(bool enableInstantRateChangeSeek)
{
std::shared_ptr<IGstGenericPlayerFactory> factory = GstGenericPlayerFactory::m_factory.lock();

if (!factory)
{
try
{
factory = std::make_shared<GstGenericPlayerFactory>();
}
catch (const std::exception &e)
{
RIALTO_SERVER_LOG_ERROR("Failed to create the gstreamer player factory, reason: %s", e.what());
}

GstGenericPlayerFactory::m_factory = factory;
}
return std::make_shared<GstGenericPlayerFactory>(enableInstantRateChangeSeek);
}

return factory;
GstGenericPlayerFactory::GstGenericPlayerFactory(bool enableInstantRateChangeSeek)
: m_kEnableInstantRateChangeSeek{enableInstantRateChangeSeek}
{
}

std::unique_ptr<IGstGenericPlayer> GstGenericPlayerFactory::createGstGenericPlayer(
Expand Down Expand Up @@ -96,7 +83,8 @@ std::unique_ptr<IGstGenericPlayer> GstGenericPlayerFactory::createGstGenericPlay
glibWrapper, IGstSrcFactory::getFactory(),
common::ITimerFactory::getFactory(),
std::make_unique<GenericPlayerTaskFactory>(client, gstWrapper, glibWrapper,
rdkGstreamerUtilsWrapper),
rdkGstreamerUtilsWrapper,
m_kEnableInstantRateChangeSeek),
std::make_unique<WorkerThreadFactory>(),
std::make_unique<GstDispatcherThreadFactory>(),
IGstProtectionMetadataHelperFactory::createFactory());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ namespace firebolt::rialto::server
GenericPlayerTaskFactory::GenericPlayerTaskFactory(
IGstGenericPlayerClient *client, const std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> &gstWrapper,
const std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> &glibWrapper,
const std::shared_ptr<firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapper> &rdkGstreamerUtilsWrapper)
: m_client{client}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rdkGstreamerUtilsWrapper{
rdkGstreamerUtilsWrapper}
const std::shared_ptr<firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapper> &rdkGstreamerUtilsWrapper,
bool enableInstantRateChangeSeek)
: m_client{client}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper},
m_rdkGstreamerUtilsWrapper{rdkGstreamerUtilsWrapper}, m_kEnableInstantRateChangeSeek{enableInstantRateChangeSeek}
{
}

Expand Down Expand Up @@ -152,7 +153,8 @@ std::unique_ptr<IPlayerTask> GenericPlayerTaskFactory::createCheckAudioUnderflow
std::unique_ptr<IPlayerTask> GenericPlayerTaskFactory::createSetPlaybackRate(GenericPlayerContext &context,
double rate) const
{
return std::make_unique<tasks::generic::SetPlaybackRate>(context, m_gstWrapper, m_glibWrapper, rate);
return std::make_unique<tasks::generic::SetPlaybackRate>(context, m_gstWrapper, m_glibWrapper, rate,
m_kEnableInstantRateChangeSeek);
}

std::unique_ptr<IPlayerTask> GenericPlayerTaskFactory::createSetPosition(GenericPlayerContext &context,
Expand Down
21 changes: 19 additions & 2 deletions media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ namespace firebolt::rialto::server::tasks::generic
{
SetPlaybackRate::SetPlaybackRate(GenericPlayerContext &context,
std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate)
: m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate}
std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, double rate,
bool enableInstantRateChangeSeek)
: m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper}, m_rate{rate},
m_enableInstantRateChangeSeek{enableInstantRateChangeSeek}
{
RIALTO_SERVER_LOG_DEBUG("Constructing SetPlaybackRate");
}
Expand Down Expand Up @@ -81,8 +83,23 @@ void SetPlaybackRate::execute() const
RIALTO_SERVER_LOG_DEBUG("Sent new segment, success = %s", success ? "true" : "false");
m_gstWrapper->gstSegmentFree(segment);
}
#if GST_CHECK_VERSION(1, 18, 0)
else if (m_enableInstantRateChangeSeek)
{
success = m_gstWrapper->gstElementSeek(m_context.pipeline, m_rate, GST_FORMAT_TIME,
static_cast<GstSeekFlags>(GST_SEEK_FLAG_INSTANT_RATE_CHANGE),
GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0);
RIALTO_SERVER_LOG_DEBUG("Rate changed using gst_element_seek, success = %s", success ? "true" : "false");
}
#endif
else
{
#if !GST_CHECK_VERSION(1, 18, 0)
if (m_enableInstantRateChangeSeek)
{
RIALTO_SERVER_LOG_WARN("enableInstantRateChangeSeek set, but gstreamer version not supported");
}
#endif
GstStructure *structure{
m_gstWrapper->gstStructureNew(kCustomInstantRateChangeEventName, "rate", G_TYPE_DOUBLE, m_rate, NULL)};
success = m_gstWrapper->gstElementSendEvent(m_context.pipeline,
Expand Down
5 changes: 4 additions & 1 deletion media/server/ipc/source/ServerManagerModuleService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,14 @@ void ServerManagerModuleService::setConfiguration(::google::protobuf::RpcControl
common::MaxResourceCapabilitites maxResource{request->resources().maxplaybacks(),
request->resources().maxwebaudioplayers()};
const auto kClientDisplayName = request->has_clientdisplayname() ? request->clientdisplayname() : "";
const bool kEnableInstantRateChangeSeek =
request->has_enableinstantratechangeseek() ? request->enableinstantratechangeseek() : false;
bool success =
m_sessionServerManager.setConfiguration(request->sessionmanagementsocketname(),
convertSessionServerState(request->initialsessionserverstate()),
maxResource, kClientDisplayName, request->socketpermissions(),
request->socketowner(), request->socketgroup());
request->socketowner(), request->socketgroup(),
kEnableInstantRateChangeSeek);
m_sessionServerManager.setLogLevels(static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().defaultloglevels()),
static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().clientloglevels()),
static_cast<RIALTO_DEBUG_LEVEL>(request->loglevels().sessionserverloglevels()),
Expand Down
3 changes: 2 additions & 1 deletion media/server/main/include/MediaPipelineServerInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class MediaPipelineServerInternalFactory : public server::IMediaPipelineServerIn

std::unique_ptr<server::IMediaPipelineServerInternal> createMediaPipelineServerInternal(
std::weak_ptr<IMediaPipelineClient> client, const VideoRequirements &videoRequirements, int sessionId,
const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService) const override;
const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService,
bool enableInstantRateChangeSeek) const override;

/**
* @brief Create the generic media player factory object.
Expand Down
19 changes: 11 additions & 8 deletions media/server/main/interface/IMediaPipelineServerInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,20 @@ class IMediaPipelineServerInternalFactory : public IMediaPipelineFactory
/**
* @brief IMediaPipelineServerInternal factory method, returns a concrete implementation of IMediaPipeline
*
* @param[in] client : The Rialto media player client.
* @param[in] videoRequirements : The video decoder requirements for the MediaPipeline session
* @param[in] sessionId : The session id for this MediaPipeline.
* @param[in] shmBuffer : The shared buffer object.
* @param[in] decryptionService : The decryption service object.
* @param[in] client : The Rialto media player client.
* @param[in] videoRequirements : The video decoder requirements for the MediaPipeline session
* @param[in] sessionId : The session id for this MediaPipeline.
* @param[in] shmBuffer : The shared buffer object.
* @param[in] decryptionService : The decryption service object.
* @param[in] enableInstantRateChangeSeek : Defines if new rate change method can be used
*
* @retval the new backend instance or null on error.
*/
virtual std::unique_ptr<IMediaPipelineServerInternal> createMediaPipelineServerInternal(
std::weak_ptr<IMediaPipelineClient> client, const VideoRequirements &videoRequirements, int sessionId,
const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService) const = 0;
virtual std::unique_ptr<IMediaPipelineServerInternal>
createMediaPipelineServerInternal(std::weak_ptr<IMediaPipelineClient> client,
const VideoRequirements &videoRequirements, int sessionId,
const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer,
IDecryptionService &decryptionService, bool enableInstantRateChangeSeek) const = 0;
};

/**
Expand Down
6 changes: 4 additions & 2 deletions media/server/main/source/MediaPipelineServerInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ MediaPipelineServerInternalFactory::createMediaPipeline(std::weak_ptr<IMediaPipe

std::unique_ptr<server::IMediaPipelineServerInternal> MediaPipelineServerInternalFactory::createMediaPipelineServerInternal(
std::weak_ptr<IMediaPipelineClient> client, const VideoRequirements &videoRequirements, int sessionId,
const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService) const
const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService,
bool enableInstantRateChangeSeek) const
{
std::shared_ptr<IMediaPipelineClient> sharedClient = client.lock();
if (!sharedClient)
Expand All @@ -112,7 +113,8 @@ std::unique_ptr<server::IMediaPipelineServerInternal> MediaPipelineServerInterna
{
mediaPipeline =
std::make_unique<server::MediaPipelineServerInternal>(sharedClient, videoRequirements,
server::IGstGenericPlayerFactory::getFactory(),
server::IGstGenericPlayerFactory::createFactory(
enableInstantRateChangeSeek),
sessionId, shmBuffer,
server::IMainThreadFactory::createFactory(),
common::ITimerFactory::getFactory(),
Expand Down
2 changes: 2 additions & 0 deletions media/server/service/include/IPlaybackService.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ class IPlaybackService
virtual void setMaxPlaybacks(int maxPlaybacks) = 0;
virtual void setMaxWebAudioPlayers(int maxWebAudio) = 0;
virtual void setClientDisplayName(const std::string &clientDisplayName) const = 0;
virtual void setEnableInstantRateChangeSeek(bool enableInstantRateChangeSeek) = 0;

virtual bool isActive() const = 0;
virtual bool getSharedMemory(int32_t &fd, uint32_t &size) const = 0;
virtual int getMaxPlaybacks() const = 0;
virtual int getMaxWebAudioPlayers() const = 0;
virtual bool getEnableInstantRateChangeSeek() const = 0;
virtual std::shared_ptr<ISharedMemoryBuffer> getShmBuffer() const = 0;
virtual IMediaPipelineService &getMediaPipelineService() const = 0;
virtual IWebAudioPlayerService &getWebAudioPlayerService() const = 0;
Expand Down
3 changes: 2 additions & 1 deletion media/server/service/include/ISessionServerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class ISessionServerManager
virtual bool setConfiguration(const std::string &socketName, const common::SessionServerState &state,
const common::MaxResourceCapabilitites &maxResource,
const std::string &clientDisplayName, unsigned int socketPermissions,
const std::string &socketOwner, const std::string &socketGroup) = 0;
const std::string &socketOwner, const std::string &socketGroup,
bool enableInstantRateChangeSeek) = 0;
virtual bool setState(const common::SessionServerState &state) = 0;
virtual void setLogLevels(RIALTO_DEBUG_LEVEL defaultLogLevels, RIALTO_DEBUG_LEVEL clientLogLevels,
RIALTO_DEBUG_LEVEL sessionServerLogLevels, RIALTO_DEBUG_LEVEL ipcLogLevels,
Expand Down
9 changes: 5 additions & 4 deletions media/server/service/source/MediaPipelineService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ bool MediaPipelineService::createSession(int sessionId, const std::shared_ptr<IM
auto shmBuffer = m_playbackService.getShmBuffer();
m_mediaPipelines.emplace(
std::make_pair(sessionId,
m_mediaPipelineFactory->createMediaPipelineServerInternal(mediaPipelineClient,
VideoRequirements{maxWidth, maxHeight},
sessionId, shmBuffer,
m_decryptionService)));
m_mediaPipelineFactory
->createMediaPipelineServerInternal(mediaPipelineClient,
VideoRequirements{maxWidth, maxHeight}, sessionId,
shmBuffer, m_decryptionService,
m_playbackService.getEnableInstantRateChangeSeek())));
if (!m_mediaPipelines.at(sessionId))
{
RIALTO_SERVER_LOG_ERROR("Could not create MediaPipeline for session with id: %d", sessionId);
Expand Down
Loading

0 comments on commit 9a10024

Please sign in to comment.