Skip to content

Commit 41507fa

Browse files
smudri85aczs
andauthored
Removed blocking get_state calls from aml codec switch (#480)
Summary: Removed blocking get_state calls from aml codec switch Type: Fix Test Plan: UT/CT, Fullstack Jira: RDKEMW-13606, DELIA-70194 Co-authored-by: Adam Czynszak <92790185+aczs@users.noreply.github.com>
1 parent 654c3a2 commit 41507fa

7 files changed

Lines changed: 860 additions & 10 deletions

File tree

media/server/gstplayer/include/GstGenericPlayer.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,61 @@ class GstGenericPlayer : public IGstGenericPlayer, public IGstGenericPlayerPriva
321321
std::optional<firebolt::rialto::wrappers::AudioAttributesPrivate>
322322
createAudioAttributes(const std::unique_ptr<IMediaPipeline::MediaSource> &source) const;
323323

324+
/**
325+
* @brief Configures audio caps based on audio attributes.
326+
* Called by worker thread only!
327+
*
328+
* @param[in] pAttrib : The audio attributes.
329+
* @param[out] audioaac : Set to true if AAC, false otherwise.
330+
* @param[in] svpenabled : Whether SVP is enabled.
331+
* @param[in,out] appsrcCaps : The caps to configure.
332+
*/
333+
void configAudioCap(firebolt::rialto::wrappers::AudioAttributesPrivate *pAttrib, bool *audioaac, bool svpenabled,
334+
GstCaps **appsrcCaps);
335+
336+
/**
337+
* @brief Halts audio playback by setting playsink to READY and decodebin to PAUSED.
338+
* Called by worker thread only!
339+
*/
340+
void haltAudioPlayback();
341+
342+
/**
343+
* @brief Resumes audio playback by syncing playsink and decodebin with parent.
344+
* Called by worker thread only!
345+
*/
346+
void resumeAudioPlayback();
347+
348+
/**
349+
* @brief First-time codec switch from AC3 to AAC when no decoder exists yet.
350+
* Called by worker thread only!
351+
*
352+
* @param[in] newAudioCaps : The new audio caps to apply.
353+
*/
354+
void firstTimeSwitchFromAC3toAAC(GstCaps *newAudioCaps);
355+
356+
/**
357+
* @brief Switches the audio codec by unlinking old parser/decoder and linking new ones.
358+
* Called by worker thread only!
359+
*
360+
* @param[in] isAudioAAC : Whether the new codec is AAC.
361+
* @param[in] newAudioCaps : The new audio caps to apply.
362+
*
363+
* @retval true if codec was switched, false if same codec.
364+
*/
365+
bool switchAudioCodec(bool isAudioAAC, GstCaps *newAudioCaps);
366+
367+
/**
368+
* @brief Top-level audio track codec channel switch, ported from rdk_gstreamer_utils_soc.
369+
* Called by worker thread only!
370+
*/
371+
bool performAudioTrackCodecChannelSwitch(const void *pSampleAttr,
372+
firebolt::rialto::wrappers::AudioAttributesPrivate *pAudioAttr,
373+
uint32_t *pStatus, unsigned int *pui32Delay,
374+
long long *pAudioChangeTargetPts, // NOLINT(runtime/int)
375+
const long long *pcurrentDispPts, // NOLINT(runtime/int)
376+
unsigned int *audioChangeStage, GstCaps **appsrcCaps, bool *audioaac,
377+
bool svpenabled, GstElement *aSrc, bool *ret);
378+
324379
/**
325380
* @brief Sets text track position before pushing data
326381
*

media/server/gstplayer/source/GstGenericPlayer.cpp

Lines changed: 499 additions & 8 deletions
Large diffs are not rendered by default.

tests/common/externalLibraryMocks/GstWrapperMock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ class GstWrapperMock : public IGstWrapper
220220
MOCK_METHOD(gboolean, gstIsBaseParse, (GstElement * element), (const, override));
221221
MOCK_METHOD(void, gstBaseParseSetPtsInterpolation, (GstBaseParse * parse, gboolean ptsInterpolate),
222222
(const, override));
223+
MOCK_METHOD(GstStateChangeReturn, gstElementGetState,
224+
(GstElement * element, GstState *state, GstState *pending, GstClockTime timeout), (override));
225+
MOCK_METHOD(GstPad *, gstPadGetPeer, (GstPad * pad), (override));
226+
MOCK_METHOD(gboolean, gstPadUnlink, (GstPad * srcpad, GstPad *sinkpad), (override));
227+
MOCK_METHOD(GstPadLinkReturn, gstPadLink, (GstPad * srcpad, GstPad *sinkpad), (override));
228+
MOCK_METHOD(gboolean, gstBinRemove, (GstBin * bin, GstElement *element), (override));
229+
MOCK_METHOD(GstObject *, gstPadGetParent, (GstPad * pad), (override));
223230

224231
GstCaps *gstCapsNewSimple(const char *media_type, const char *fieldname, ...) const override
225232
{

tests/componenttests/server/tests/mediaPipeline/AudioSourceSwitchTest.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "MessageBuilders.h"
2727

2828
using testing::_;
29+
using testing::AtLeast;
30+
using testing::Invoke;
2931
using testing::Return;
3032
using testing::StrEq;
3133

@@ -39,11 +41,20 @@ namespace firebolt::rialto::server::ct
3941
class AudioSourceSwitchTest : public MediaPipelineTest
4042
{
4143
public:
42-
AudioSourceSwitchTest() = default;
43-
~AudioSourceSwitchTest() = default;
44+
AudioSourceSwitchTest() { m_audioSink = gst_element_factory_make("fakesrc", nullptr); }
45+
~AudioSourceSwitchTest() override { gst_object_unref(m_audioSink); }
4446

4547
void willSwitchAudioSource()
4648
{
49+
EXPECT_CALL(*m_glibWrapperMock, gObjectGetStub(_, StrEq("audio-sink"), _))
50+
.WillOnce(Invoke(
51+
[this](gpointer object, const gchar *first_property_name, void *element)
52+
{
53+
GstElement **elementPtr = reinterpret_cast<GstElement **>(element);
54+
*elementPtr = m_audioSink;
55+
}));
56+
EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(m_audioSink)).Times(AtLeast(0));
57+
EXPECT_CALL(*m_glibWrapperMock, gTypeName(G_OBJECT_TYPE(m_audioSink))).WillRepeatedly(Return("audio_sink"));
4758
EXPECT_CALL(*m_gstWrapperMock, gstCapsNewEmptySimple(StrEq("audio/mpeg"))).WillOnce(Return(&m_audioCaps));
4859
EXPECT_CALL(*m_gstWrapperMock,
4960
gstCapsSetSimpleStringStub(&m_audioCaps, StrEq("alignment"), G_TYPE_STRING, StrEq("nal")));
@@ -61,6 +72,7 @@ class AudioSourceSwitchTest : public MediaPipelineTest
6172
EXPECT_CALL(*m_gstWrapperMock, gstCapsIsEqual(&m_audioCaps, &m_oldCaps)).WillOnce(Return(FALSE));
6273
EXPECT_CALL(*m_gstWrapperMock, gstCapsToString(&m_oldCaps)).WillOnce(Return(&m_oldCapsStr));
6374
EXPECT_CALL(*m_glibWrapperMock, gFree(&m_oldCapsStr));
75+
EXPECT_CALL(*m_glibWrapperMock, gStrHasPrefix(_, StrEq("amlhalasink"))).WillOnce(Return(FALSE));
6476
EXPECT_CALL(*m_rdkGstreamerUtilsWrapperMock,
6577
performAudioTrackCodecChannelSwitch(_, _, _, _, _, _, _, _, _, _, kSvpEnabled,
6678
GST_ELEMENT(&m_audioAppSrc), _))
@@ -80,6 +92,7 @@ class AudioSourceSwitchTest : public MediaPipelineTest
8092
private:
8193
GstCaps m_oldCaps{};
8294
gchar m_oldCapsStr{};
95+
GstElement *m_audioSink{};
8396
};
8497
/*
8598
* Component Test: Switch audio source procedure test

0 commit comments

Comments
 (0)