-
Notifications
You must be signed in to change notification settings - Fork 18
Feature/hdmi switch8.4 test #508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/v0.15.2
Are you sure you want to change the base?
Changes from all commits
84496a2
31c94c5
1467ce8
ffee15b
881e843
f9fd54a
c60ab3c
004ba6d
06af362
d831226
7f1c8ef
88573ba
e0a350d
acce42d
bca5ce1
9574d44
a483e98
0d20bae
cc4c8f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -123,6 +123,10 @@ const char *toString(const firebolt::rialto::MediaKeyErrorStatus &errorStatus) | |
| { | ||
| return "FAIL"; | ||
| } | ||
| case firebolt::rialto::MediaKeyErrorStatus::OUTPUT_RESTRICTED: | ||
| { | ||
| return "OUTPUT_RESTRICTED"; | ||
| } | ||
| } | ||
| return "UNKNOWN"; | ||
| } | ||
|
|
@@ -334,7 +338,7 @@ bool MediaKeysIpc::containsKey(int32_t keySessionId, const std::vector<uint8_t> | |
| } | ||
|
|
||
| MediaKeyErrorStatus MediaKeysIpc::createKeySession(KeySessionType sessionType, std::weak_ptr<IMediaKeysClient> client, | ||
| bool isLDL, int32_t &keySessionId) | ||
| bool isLDL, int32_t &keySessionId) | ||
|
|
||
| { | ||
| if (!reattachChannelIfRequired()) | ||
| { | ||
|
|
@@ -415,6 +419,7 @@ MediaKeyErrorStatus MediaKeysIpc::generateRequest(int32_t keySessionId, InitData | |
| break; | ||
| } | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this line |
||
| firebolt::rialto::GenerateRequestRequest request; | ||
| request.set_media_keys_handle(m_mediaKeysHandle); | ||
| request.set_key_session_id(keySessionId); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -292,7 +292,8 @@ enum class MediaKeyErrorStatus | |
| NOT_SUPPORTED, /**< The request parameters are not supported. */ | ||
| INVALID_STATE, /**< The object is in an invalid state for the operation. */ | ||
| INTERFACE_NOT_IMPLEMENTED, /**< The interface is not implemented. */ | ||
| BUFFER_TOO_SMALL /**< The size of the buffer is too small. */ | ||
| BUFFER_TOO_SMALL, /**< The size of the buffer is too small. */ | ||
| OUTPUT_RESTRICTED | ||
|
Comment on lines
+295
to
+296
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First note: Please add the Doxygen comment, as it was requested by the Copilot. |
||
| }; | ||
|
|
||
| /** | ||
|
|
@@ -473,6 +474,7 @@ struct PlaybackInfo | |
| int64_t currentPosition{-1}; /**< The current playback position */ | ||
| double volume{1.0}; /**< The current volume */ | ||
| }; | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this extra line |
||
| } // namespace firebolt::rialto | ||
|
|
||
| #endif // FIREBOLT_RIALTO_MEDIA_COMMON_H_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,6 +66,10 @@ convertMediaKeyErrorStatus(const firebolt::rialto::MediaKeyErrorStatus &errorSta | |
| { | ||
| return firebolt::rialto::ProtoMediaKeyErrorStatus::FAIL; | ||
| } | ||
| case firebolt::rialto::MediaKeyErrorStatus::OUTPUT_RESTRICTED: | ||
| { | ||
| // TODO | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implement this |
||
| } | ||
| } | ||
|
Comment on lines
+69
to
73
|
||
| return firebolt::rialto::ProtoMediaKeyErrorStatus::FAIL; | ||
|
Comment on lines
67
to
74
Comment on lines
66
to
74
Comment on lines
+69
to
74
Comment on lines
66
to
74
|
||
| } | ||
|
|
@@ -100,6 +104,7 @@ firebolt::rialto::InitDataType covertInitDataType(firebolt::rialto::GenerateRequ | |
| return firebolt::rialto::InitDataType::UNKNOWN; | ||
| } | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this line |
||
| } // namespace | ||
|
|
||
| namespace firebolt::rialto::server::ipc | ||
|
|
@@ -277,11 +282,12 @@ void MediaKeysModuleService::generateRequest(::google::protobuf::RpcController * | |
| ::google::protobuf::Closure *done) | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("entry:"); | ||
|
|
||
| MediaKeyErrorStatus status = m_cdmService.generateRequest(request->media_keys_handle(), request->key_session_id(), | ||
| covertInitDataType(request->init_data_type()), | ||
| std::vector<std::uint8_t>{request->init_data().begin(), | ||
| request->init_data().end()}); | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove those empty lines |
||
|
|
||
| response->set_error_status(convertMediaKeyErrorStatus(status)); | ||
| done->Run(); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,10 +18,40 @@ | |
| */ | ||
|
|
||
| #include <stdexcept> | ||
| #include <chrono> | ||
| #include <thread> | ||
|
|
||
| #include "MediaKeysServerInternal.h" | ||
| #include "RialtoServerLogging.h" | ||
|
|
||
| /*namespace | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove commented out code |
||
| { | ||
| const char *toString(const firebolt::rialto::MediaKeyErrorStatus &status) | ||
| { | ||
| switch (status) | ||
| { | ||
| case firebolt::rialto::MediaKeyErrorStatus::OK: | ||
| return "OK"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::FAIL: | ||
| return "FAIL"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::BAD_SESSION_ID: | ||
| return "BAD_SESSION_ID"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::INTERFACE_NOT_IMPLEMENTED: | ||
| return "INTERFACE_NOT_IMPLEMENTED"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::BUFFER_TOO_SMALL: | ||
| return "BUFFER_TOO_SMALL"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::NOT_SUPPORTED: | ||
| return "NOT_SUPPORTED"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::INVALID_STATE: | ||
| return "INVALID_STATE"; | ||
| case firebolt::rialto::MediaKeyErrorStatus::OUTPUT_RESTRICTED: | ||
| return "OUTPUT_RESTRICTED"; | ||
| } | ||
| return "Unknown"; | ||
| } | ||
| } */// namespace | ||
|
|
||
|
Comment on lines
+27
to
+53
Comment on lines
+27
to
+53
|
||
|
|
||
| namespace firebolt::rialto | ||
| { | ||
| const char *mediaKeyErrorStatusToString(const MediaKeyErrorStatus &status) | ||
|
|
@@ -51,6 +81,10 @@ std::shared_ptr<IMediaKeysFactory> IMediaKeysFactory::createFactory() | |
|
|
||
| namespace firebolt::rialto::server | ||
| { | ||
| constexpr std::chrono::milliseconds kOutputRestrictedRetryInterval{250}; | ||
| constexpr std::chrono::seconds kOutputRestrictedRetryTimeout{6}; | ||
| constexpr GstClockTime kStaleThreshold{4 * GST_SECOND}; | ||
|
|
||
|
Comment on lines
+84
to
+87
|
||
| int32_t generateSessionId() | ||
| { | ||
|
Comment on lines
+84
to
89
|
||
| static int32_t keySessionId{0}; | ||
|
|
@@ -140,12 +174,14 @@ MediaKeysServerInternal::MediaKeysServerInternal( | |
| { | ||
| throw std::runtime_error("MediaKeys construction failed"); | ||
| } | ||
|
|
||
| m_outputWasRestricted = false; | ||
| } | ||
|
|
||
| MediaKeysServerInternal::~MediaKeysServerInternal() | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("entry:"); | ||
|
|
||
| m_isShuttingDown = true; | ||
| auto task = [&]() | ||
| { | ||
| m_ocdmSystem.reset(); | ||
|
|
@@ -569,12 +605,83 @@ MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionIdInternal(int32_t | |
|
|
||
| MediaKeyErrorStatus MediaKeysServerInternal::decrypt(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps) | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("entry:"); | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE: entry:decrypt"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. revert this |
||
|
|
||
| MediaKeyErrorStatus status; | ||
| auto task = [&]() { status = decryptInternal(keySessionId, encrypted, caps); }; | ||
| MediaKeyErrorStatus status{MediaKeyErrorStatus::FAIL}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implementation should be moved to the decryptInternal, in such case you won't need atomics in MediaPipelineServerInternal.h and we will keep the right call order |
||
|
|
||
| if (GST_BUFFER_PTS_IS_VALID(encrypted)) | ||
| { | ||
| GstClockTime bufferPts = GST_BUFFER_PTS(encrypted); | ||
|
|
||
| if (!m_hasCurrentPositionPts.load() || bufferPts > m_currentPositionPts.load()) | ||
| { | ||
| m_currentPositionPts = bufferPts; | ||
| m_hasCurrentPositionPts = true; | ||
| } | ||
|
|
||
| // After OUTPUT_RESTRICTED recovery, drop buffered segments that are behind live playback. | ||
| const GstClockTime currentPos = m_currentPositionPts.load(); | ||
| if (m_outputWasRestricted.load() && m_hasCurrentPositionPts.load() && currentPos > bufferPts && | ||
| (currentPos - bufferPts) > kStaleThreshold) | ||
| { | ||
| const double lagSeconds = static_cast<double>(currentPos - bufferPts) / GST_SECOND; | ||
| RIALTO_SERVER_LOG_WARN("Dropping stale segment (%.3fs behind) after HDCP recovery", lagSeconds); | ||
| return MediaKeyErrorStatus::OK; // Drop silently, pretend decrypt succeeded | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we seek backwards? Decryption won't work :) |
||
| } | ||
| } | ||
|
|
||
| const auto deadline = std::chrono::steady_clock::now() + kOutputRestrictedRetryTimeout; | ||
| do | ||
| { | ||
| auto task = [&]() { status = decryptInternal(keySessionId, encrypted, caps); }; | ||
| m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task); | ||
| RIALTO_SERVER_LOG_DEBUG("DEBUG PURPOSE : Key session id :%d", keySessionId); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change the print |
||
| /* switch (status) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove commented out code |
||
| { | ||
| case firebolt::rialto::MediaKeyErrorStatus::OK: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : OK"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::FAIL: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : FAIL"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::BAD_SESSION_ID: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : BAD_SESSION_ID"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::INTERFACE_NOT_IMPLEMENTED: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : INTERFACE_NOT_IMPLEMENTED"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::BUFFER_TOO_SMALL: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : BUFFER_TOO_SMALL"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::NOT_SUPPORTED: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : NOT_SUPPORTED"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::INVALID_STATE: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : INVALID_STATE"); | ||
| break; | ||
| case firebolt::rialto::MediaKeyErrorStatus::OUTPUT_RESTRICTED: | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : Key session status : OUTPUT_RESTRICTED"); | ||
| break; | ||
| }*/ | ||
|
|
||
| if (status != MediaKeyErrorStatus::OUTPUT_RESTRICTED) | ||
| { | ||
| m_outputWasRestricted = false; | ||
| break; | ||
| } | ||
| m_outputWasRestricted = true; | ||
| if (m_isShuttingDown.load()) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Decrypt retry aborted — shutdown in progress"); | ||
| break; | ||
| } | ||
|
|
||
| RIALTO_SERVER_LOG_WARN("Decrypt returned OUTPUT_RESTRICTED, retrying after delay"); | ||
|
|
||
| std::this_thread::sleep_for(kOutputRestrictedRetryInterval); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't use sleeps in Rialto Server's production code.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use the Timer class for example |
||
|
|
||
| } while (std::chrono::steady_clock::now() < deadline); | ||
|
Comment on lines
+610
to
+683
Comment on lines
606
to
+683
Comment on lines
606
to
+683
Comment on lines
+610
to
+683
|
||
|
|
||
| m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task); | ||
| return status; | ||
| } | ||
|
|
||
|
|
@@ -604,12 +711,14 @@ bool MediaKeysServerInternal::isNetflixPlayreadyKeySystem() const | |
| return m_kKeySystem.find("netflix") != std::string::npos; | ||
| } | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this line |
||
| void MediaKeysServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler) | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("entry:"); | ||
| RIALTO_SERVER_LOG_ERROR("entry:"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. revert this |
||
| auto task = [&]() { heartbeatHandler.reset(); }; | ||
|
|
||
| m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task); | ||
| m_mainThread->enqueuePriorityTaskAndWait(m_mainThreadClientId, task); | ||
| RIALTO_SERVER_LOG_ERROR("exit:"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this print |
||
| } | ||
|
|
||
| MediaKeyErrorStatus MediaKeysServerInternal::getMetricSystemData(std::vector<uint8_t> &buffer) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -492,16 +492,31 @@ bool CdmService::isServerCertificateSupported(const std::string &keySystem) | |
|
|
||
| MediaKeyErrorStatus CdmService::decrypt(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps) | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("CdmService requested to decrypt, key session id: %d", keySessionId); | ||
|
|
||
| IMediaKeysServerInternal *mediaKeys{nullptr}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is not needed, revert it |
||
| { | ||
| std::lock_guard<std::mutex> lock{m_mediaKeysMutex}; | ||
| auto iter = m_sessionInfo.find(keySessionId); | ||
| if (iter == m_sessionInfo.end()) return MediaKeyErrorStatus::FAIL; | ||
| mediaKeys = m_mediaKeys[iter->second.mediaKeysHandle].get(); | ||
| // Increment ref counter to prevent destruction while in use | ||
| ++iter->second.refCounter; | ||
| } | ||
| auto status = mediaKeys->decrypt(keySessionId, encrypted, caps); | ||
| decrementSessionIdUsageCounter(keySessionId); // May trigger deferred release | ||
|
Comment on lines
+496
to
+506
|
||
| return status; | ||
|
|
||
| /* RIALTO_SERVER_LOG_DEBUG("CdmService requested to decrypt, key session id: %d", keySessionId); | ||
|
|
||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE : CdmService : decrypt entry"); | ||
| std::lock_guard<std::mutex> lock{m_mediaKeysMutex}; | ||
| auto mediaKeysHandleIter{m_sessionInfo.find(keySessionId)}; | ||
| if (mediaKeysHandleIter == m_sessionInfo.end()) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Media keys handle for mksId: %d does not exists", keySessionId); | ||
| return MediaKeyErrorStatus::FAIL; | ||
| } | ||
| return m_mediaKeys[mediaKeysHandleIter->second.mediaKeysHandle]->decrypt(keySessionId, encrypted, caps); | ||
| return m_mediaKeys[mediaKeysHandleIter->second.mediaKeysHandle]->decrypt(keySessionId, encrypted, caps);*/ | ||
| } | ||
|
|
||
| bool CdmService::isNetflixPlayreadyKeySystem(int32_t keySessionId) | ||
|
|
@@ -580,12 +595,28 @@ void CdmService::decrementSessionIdUsageCounter(int32_t keySessionId) | |
|
|
||
| void CdmService::ping(const std::shared_ptr<IHeartbeatProcedure> &heartbeatProcedure) | ||
| { | ||
| std::lock_guard<std::mutex> lock{m_mediaKeysMutex}; | ||
|
|
||
| std::unique_lock<std::mutex> lock{m_mediaKeysMutex, std::try_to_lock}; | ||
| if (!lock.owns_lock()) | ||
| { | ||
| // Server is alive but busy in decrypt retry — acknowledge ping | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fact, that the mutex is locked, doesn't mean that the decryption is ongoing, we can be blocked on something else as well. This change breaks the whole healthcheck mechanism in CdmService |
||
| RIALTO_SERVER_LOG_WARN("CdmService::ping - mutex busy (decrypt in progress), skipping CDM ping"); | ||
| return; // HeartbeatProcedure destructor sends success ack | ||
| } | ||
| for (const auto &mediaKeyPair : m_mediaKeys) | ||
| { | ||
| auto &mediaKeys = mediaKeyPair.second; | ||
| mediaKeys->ping(heartbeatProcedure->createHandler()); | ||
| } | ||
|
|
||
| /*std::lock_guard<std::mutex> lock{m_mediaKeysMutex}; | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE: ping entry"); | ||
| for (const auto &mediaKeyPair : m_mediaKeys) | ||
| { | ||
| auto &mediaKeys = mediaKeyPair.second; | ||
| mediaKeys->ping(heartbeatProcedure->createHandler()); | ||
| } | ||
| RIALTO_SERVER_LOG_ERROR("DEBUG PURPOSE: ping exit");*/ | ||
| } | ||
|
|
||
| MediaKeyErrorStatus CdmService::getMetricSystemData(int mediaKeysHandle, std::vector<uint8_t> &buffer) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,8 @@ target_include_directories( | |
|
|
||
| PRIVATE | ||
| include | ||
| ../common/interface/ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please look how directories are included in other CMake files and make the code consistent. |
||
| ../logging/include/ | ||
| ${GStreamerApp_INCLUDE_DIRS} | ||
| $<TARGET_PROPERTY:RialtoPlayerPublic,INTERFACE_INCLUDE_DIRECTORIES> | ||
| ${WRAPPER_INCLUDES} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the indentation