[NTS] Fast Playback test case failures#523
Conversation
|
Pull request must be merged with a description containing the required fields, Summary: If there is no jira releated to this change, please put 'Jira: NO-JIRA'. Description can be changed by editing the top comment on your pull request and making a new commit. |
There was a problem hiding this comment.
Pull request overview
Fixes premature audio/video underflow reporting in the GStreamer generic player setup by ignoring underflow callbacks while the sink/decoder still reports buffered frames (non-zero FIFO depth). This aligns underflow signaling with actual depletion and prevents fast-playback-related test failures.
Changes:
- Guard audio/video underflow callbacks to no-op when
fifoDepth > 0. - Add unit tests asserting underflow is not scheduled when
fifoDepthis non-zero for both audio and video.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
media/server/gstplayer/source/tasks/generic/SetupElement.cpp |
Ignores underflow callbacks when FIFO depth is non-zero to prevent premature underflow scheduling. |
tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetupElementTest.cpp |
Adds unit coverage for the new “ignore underflow when fifoDepth > 0” behavior for audio and video. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d11ae39 to
e38c32a
Compare
|
tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.cpp:263:5: performance: Variable 'testContext' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList] |
| TEST_F(SetupElementTest, shouldNotReportVideoUnderflowWhenFifoDepthIsNonZero) | ||
| { | ||
| shouldSetupVideoDecoderElementOnly(); | ||
| triggerSetupElement(); | ||
|
|
||
| ASSERT_TRUE(testContext->m_videoUnderflowCallback); | ||
| EXPECT_CALL(testContext->m_gstPlayer, scheduleVideoUnderflow()).Times(0); | ||
|
|
f48c93a to
0d2a258
Compare
| auto videoUnderflowCallback = reinterpret_cast<void (*)(GstElement *, guint, gpointer, gpointer)>( | ||
| testContext->m_videoUnderflowCallback); | ||
| videoUnderflowCallback(testContext->m_element, 1, nullptr, &testContext->m_gstPlayer); | ||
| TEST_F(SetupElementTest, shouldReportFirstVideoFrame) |
|
tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetupElementTest.cpp:174:1: error: Unmatched '{'. Configuration: ''. [syntaxError] |
b56c353 to
1450d87
Compare
1450d87 to
599a0a5
Compare
| ASSERT_TRUE(testContext->m_videoUnderflowCallback); | ||
| EXPECT_CALL(testContext->m_gstPlayer, scheduleVideoUnderflow()).Times(0); | ||
|
|
||
| triggerVideoUnderflowCallback(); | ||
| } |
| ASSERT_TRUE(testContext->m_audioUnderflowCallback); | ||
| EXPECT_CALL(testContext->m_gstPlayer, scheduleAudioUnderflow()).Times(0); | ||
|
|
||
| triggerAudioUnderflowCallback(); | ||
| } |
| #include <memory> | ||
| #include <string> | ||
|
|
||
| #include "GenericTasksTestsContext.h" | ||
|
|
1c5fafb to
ddce17b
Compare
| if (fifoDepth > 0) | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("Ignoring audio underflow callback - fifoDepth is %u", fifoDepth); | ||
| return; | ||
| } |
| if (fifoDepth > 0) | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("Ignoring video underflow callback - fifoDepth is %u", fifoDepth); | ||
| return; | ||
| } |
|
Coverage statistics of your commit: |
ddce17b to
e832f8d
Compare
|
Coverage statistics of your commit: |
1 similar comment
|
Coverage statistics of your commit: |
…properties (#485) Summary: 'report-decode-errors' and 'queued-frames' properties missing from RialtoMSEVideoSink Type: Feature Test Plan: UT/CT, Fullstack Jira: RDKEMW-12692
Summary: Fix premature underflow signal when buffer is still rendering frames
Type: Fix
Test Plan: UT/CT, Fullstack
Jira: RDKEMW-15056
bdbe3ed to
5cb1188
Compare
| void SetReportDecodeErrors::execute() const | ||
| { | ||
| RIALTO_SERVER_LOG_DEBUG("Executing SetReportDecodeErrors for %s source", common::convertMediaSourceType(m_type)); | ||
|
|
||
| m_context.pendingReportDecodeErrorsForVideo = m_reportDecodeErrors; | ||
|
|
||
| if (!m_context.pipeline) | ||
| { | ||
| RIALTO_SERVER_LOG_WARN("Pipeline not available yet - cannot apply report-decode-errors setting"); | ||
| return; | ||
| } | ||
|
|
||
| m_player.setReportDecodeErrors(); | ||
| } |
| auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(), | ||
| [sourceId](const auto &src) { return src.second == sourceId; }); | ||
| if (sourceIter == m_attachedSources.end()) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Failed - Source not found"); | ||
| return false; | ||
| } | ||
|
|
||
| return m_gstPlayer->setReportDecodeErrors(sourceIter->first, reportDecodeErrors); | ||
| } |
| auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(), | ||
| [sourceId](const auto &src) { return src.second == sourceId; }); | ||
| if (sourceIter == m_attachedSources.end()) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Failed - Source not found"); | ||
| return false; | ||
| } | ||
| return m_gstPlayer->getQueuedFrames(queuedFrames); | ||
| } |
| * This method is asynchronous | ||
| * | ||
| * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource() | ||
| * @param[in] queuedFrames : Number of queued frames |
| auto mediaPipelineIter = m_mediaPipelines.find(sessionId); | ||
| if (mediaPipelineIter == m_mediaPipelines.end()) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId); |
| auto mediaPipelineIter = m_mediaPipelines.find(sessionId); | ||
| if (mediaPipelineIter == m_mediaPipelines.end()) | ||
| { | ||
| RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId); |
| void MediaPipelineModuleServiceTests::mediaPipelineServiceWillSetReportDecodeErrors() | ||
| { | ||
| expectRequestSuccess(); | ||
| EXPECT_CALL(m_mediaPipelineServiceMock, setReportDecodeErrors(kHardcodedSessionId, _, kReportDecodeErrorsVal)) | ||
| .WillOnce(Return(true)); | ||
| } | ||
|
|
||
| void MediaPipelineModuleServiceTests::mediaPipelineServiceWillFailToSetReportDecodeErrors() | ||
| { | ||
| expectRequestFailure(); | ||
| EXPECT_CALL(m_mediaPipelineServiceMock, setReportDecodeErrors(kHardcodedSessionId, _, kReportDecodeErrorsVal)) | ||
| .WillOnce(Return(false)); | ||
| } |
| void MediaPipelineModuleServiceTests::mediaPipelineServiceWillGetQueuedFrames() | ||
| { | ||
| expectRequestSuccess(); | ||
| EXPECT_CALL(m_mediaPipelineServiceMock, getQueuedFrames(kHardcodedSessionId, _, _)) | ||
| .WillOnce(DoAll(SetArgReferee<2>(kQueuedFramesVal), Return(true))); | ||
| } | ||
|
|
||
| void MediaPipelineModuleServiceTests::mediaPipelineServiceWillFailToGetQueuedFrames() | ||
| { | ||
| expectRequestFailure(); | ||
| EXPECT_CALL(m_mediaPipelineServiceMock, getQueuedFrames(kHardcodedSessionId, _, _)).WillOnce(Return(false)); | ||
| } |
| void MediaPipelineModuleServiceTests::sendSetReportDecodeErrorsRequestAndReceiveResponse() | ||
| { | ||
| firebolt::rialto::SetReportDecodeErrorsRequest request; | ||
| firebolt::rialto::SetReportDecodeErrorsResponse response; | ||
|
|
||
| request.set_session_id(kHardcodedSessionId); | ||
| request.set_report_decode_errors(kReportDecodeErrorsVal); | ||
|
|
||
| m_service->setReportDecodeErrors(m_controllerMock.get(), &request, &response, m_closureMock.get()); | ||
| } | ||
|
|
||
| void MediaPipelineModuleServiceTests::sendSetReportDecodeErrorsRequestAndReceiveFail() | ||
| { | ||
| firebolt::rialto::SetReportDecodeErrorsRequest request; | ||
| firebolt::rialto::SetReportDecodeErrorsResponse response; | ||
|
|
||
| request.set_session_id(kHardcodedSessionId); | ||
| request.set_report_decode_errors(kReportDecodeErrorsVal); | ||
|
|
||
| m_service->setReportDecodeErrors(m_controllerMock.get(), &request, &response, m_closureMock.get()); | ||
| } |
| void MediaPipelineModuleServiceTests::sendGetQueuedFramesRequestAndReceiveResponse() | ||
| { | ||
| firebolt::rialto::GetQueuedFramesRequest request; | ||
| firebolt::rialto::GetQueuedFramesResponse response; | ||
|
|
||
| request.set_session_id(kHardcodedSessionId); | ||
|
|
||
| m_service->getQueuedFrames(m_controllerMock.get(), &request, &response, m_closureMock.get()); | ||
|
|
||
| EXPECT_EQ(response.queued_frames(), kQueuedFramesVal); | ||
| } | ||
|
|
||
| void MediaPipelineModuleServiceTests::sendGetQueuedFramesRequestAndReceiveFail() | ||
| { | ||
| firebolt::rialto::GetQueuedFramesRequest request; | ||
| firebolt::rialto::GetQueuedFramesResponse response; | ||
|
|
||
| request.set_session_id(kHardcodedSessionId); | ||
|
|
||
| m_service->getQueuedFrames(m_controllerMock.get(), &request, &response, m_closureMock.get()); | ||
| } |
Summary: Fix premature underflow signal when buffer is still rendering frames
Type: Fix
Test Plan: UT/CT, Fullstack
Jira: RDKEMW-15056