Netflix 5.3 modifications

To build Netflix 5.3 with Rialto, Netflix 5.3 bitbake has to be modified:

diff --git a/recipes-extended/netflix/netflix_5.3.bb b/recipes-extended/netflix/netflix_5.3.bb
index 7a2560a..418728c 100644
--- a/recipes-extended/netflix/netflix_5.3.bb
+++ b/recipes-extended/netflix/netflix_5.3.bb
@@ -47,13 +47,13 @@ BBCLASSEXTEND = "native"
 
 INHIBIT_PACKAGE_STRIP= "1"
 INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
-DEPENDS += " openjpeg lcms fdk-aac gstreamer1.0 python-native freetype icu jpeg libpng libmng libwebp harfbuzz libnl nghttp2 expat openssl c-ares curl-netflix graphite2 util-linux glib-2.0 iarmmgrs cjson tremor libogg systemd nodejs-native wayland essos  elfutils wpeframework  wpeframework-clientlibraries playready-cdm-rdk rdk-gstreamer-utils dwz-native libdwarf libunwind"
-RDEPENDS_${PN} += "devicesettings rdk-gstreamer-utils"
+DEPENDS += " openjpeg lcms fdk-aac gstreamer1.0 python-native freetype icu jpeg libpng libmng libwebp harfbuzz libnl nghttp2 expat openssl c-ares curl-netflix graphite2 util-linux glib-2.0 iarmmgrs cjson tremor libogg systemd nodejs-native wayland essos  elfutils wpeframework  wpeframework-clientlibraries playready-cdm-rdk rdk-gstreamer-utils dwz-native libdwarf libunwind rialto rialto-ocdm"
+RDEPENDS_${PN} += "devicesettings rdk-gstreamer-utils rialto rialto-ocdm"
 
 DEPENDS +=  "${@bb.utils.contains('DISTRO_FEATURES', 'rdk_svp', 'gst-svp-ext', '', d)}"
 RDEPENDS_${PN} += "${@bb.utils.contains('DISTRO_FEATURES', 'rdk_svp', 'gst-svp-ext', '', d)}"
 
-OCDM = "${@bb.utils.contains('DISTRO_FEATURES', 'netflix_drm_ocdm', 1, 0, d)}"
+OCDM = "1"
 NETFLIX_DRM = "${@ "ocdm" if ${OCDM} else "rdkplayready" }"
 DEPENDS += "${@ " wpeframework rdkservices rdkservices-comcast"  if ${OCDM} else "" }"
 
@@ -242,7 +242,7 @@ do_install_append() {
     fi
 }
 
-EXTRA_OECMAKE += "${@bb.utils.contains('DISTRO_FEATURES', 'rdk_svp', "-DRDK_SVP=ENABLED", "", d)}"
+# EXTRA_OECMAKE += "${@bb.utils.contains('DISTRO_FEATURES', 'rdk_svp', "-DRDK_SVP=ENABLED", "", d)}"
 EXTRA_OECMAKE += "${@bb.utils.contains('DISTRO_FEATURES', 'dynamic_svp_decryption', "-DDYNAMIC_SVP_DECRYPTION=ENABLED", "", d)}"
 EXTRA_OECMAKE += "${@ "-DDPI_REFERENCE_DRM_OCDM=1" if ${OCDM} else "-DDPI_REFERENCE_DRM_RDK_PLAYREADY=1" }"
 
@@ -293,6 +293,7 @@ EXTRA_OECMAKE += " \
     -DCURL_LIB="${STAGING_LIBDIR}/netflix/libcurl.a" \
     ${SOC_DPI_REFERENCE_TTS} \
     -DDNSLIST=1 \
+    -DUSE_RIALTO=1 \
     -DUSE_CURL_NETFLIX=1"
 
 EXTRA_OECMAKE += " -DCMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES=${STAGING_INCDIR} "
@@ -317,7 +318,7 @@ CXXFLAGS += " -I${STAGING_INCDIR}/openjpeg-2.3"
 CXXFLAGS += " -I${STAGING_INCDIR}/rdk-playready -I${STAGING_INCDIR}/rdk-playready/inc -I${STAGING_INCDIR}/rdk-playready/oem/ansi/inc -I${STAGING_INCDIR}/rdk-playready/oem/common/inc -I${STAGING_INCDIR}/rdk-playready/oem/comcast -I${STAGING_INCDIR}/rdk-playready/base"
 CXXFLAGS += " -DNO_NICETHREAD_SETPRIORITY"
 #If Netflix is a wayland client we need to use westeros sink
-CXXFLAGS += "${@bb.utils.contains('DISTRO_FEATURES', 'netflix_wayland_client', " -DWESTEROS_SINK", "", d)}"
+# CXXFLAGS += "${@bb.utils.contains('DISTRO_FEATURES', 'netflix_wayland_client', " -DWESTEROS_SINK", "", d)}"
 # Included to overcome Netflix crash in morty builds which uses gcc 6.2 compiler. Refer DELIA-24039/COMCASTNYW-175 for further reference.
 # Disable FASTMALLOC_NEW since we are moving all compilers to gcc 6.2 or greater
 CXXFLAGS += " -DENABLE_GLOBAL_FASTMALLOC_NEW=0"

After bitbake modification, Netflix has to be built using bitbake netflix. When compilation is finished, some code modifications have to be applied:

diff --git a/partner/dpi/gstreamer/CMakeLists.txt b/partner/dpi/gstreamer/CMakeLists.txt
index 7081489..1e5ac32 100644
--- a/partner/dpi/gstreamer/CMakeLists.txt
+++ b/partner/dpi/gstreamer/CMakeLists.txt
@@ -204,10 +204,14 @@ if(FORCE_HDR_DV_MODE)
     add_definitions("-DFORCE_HDR_DV_MODE=1")
 endif()
 
-if(FP_FAKE_INITBUFFER)
+if(FP_FAKE_INITBUFFER AND NOT USE_RIALTO)
      add_definitions("-DFP_FAKE_INITBUFFER=1")
 endif()
 
+if(USE_RIALTO)
+     add_definitions("-DUSE_RIALTO=1")
+endif()
+
 if(USE_FIRST_VFRAME_CALLBACK)
      add_definitions("-DUSE_FIRST_VFRAME_CALLBACK=1")
 endif()
diff --git a/partner/dpi/gstreamer/ESPlayerGstGenericPort.cpp b/partner/dpi/gstreamer/ESPlayerGstGenericPort.cpp
index d66b1bc..65ad350 100644
--- a/partner/dpi/gstreamer/ESPlayerGstGenericPort.cpp
+++ b/partner/dpi/gstreamer/ESPlayerGstGenericPort.cpp
@@ -569,9 +569,16 @@ void ESPlayerGstGenericPort::ProcessFrame() {
             // Lock mutex to ensure state change does not happen until seamless audio switch is completed
            mPlaybackGroup->AudioSwitchMutexLock();
 
+          #ifdef USE_RIALTO
+          Log::warn(TRACE_MEDIAPLAYBACK, "Using performAudioTrackCodecChannelSwitch for Rialto");
+          if (performAudioTrackCodecChannelSwitchRialto(&(mPlaybackGroup->mGstUtilsPlaybackGroup), pSampleAttr, pAudioAttr,
+                                                        pstatus, &delay, &mAudioChangeTargetPts, &mCurrentDispPts, &_audio_change_stage, &mAppsrcCaps,
+                                                        &mAudioAAC, netflix::device::sConfiguration->svpEnabled, mSrc, &retVal) == true)
+          #else
           if (rdk_gstreamer_utils::performAudioTrackCodecChannelSwitch(&(mPlaybackGroup->mGstUtilsPlaybackGroup), pSampleAttr, pAudioAttr,
                                                                        pstatus, &delay, &mAudioChangeTargetPts, &mCurrentDispPts, &_audio_change_stage, &mAppsrcCaps,
                                                                        &mAudioAAC, netflix::device::sConfiguration->svpEnabled, mSrc, &retVal) == true)
+          #endif
           {
             if (!retVal)
             {
@@ -1363,3 +1370,80 @@ void ESPlayerGstGenericPort::firstSampleAvailable()
     Signal(AVAIL_FIRST_SAMPLE);
     pinch();
 }
+
+bool ESPlayerGstGenericPort::performAudioTrackCodecChannelSwitchRialto(
+  rdk_gstreamer_utils::rdkGstreamerUtilsPlaybackGrp *pgstUtilsPlaybackGroup, const void *pSampleAttr, rdk_gstreamer_utils::AudioAttributes *
pAudioAttr,
+  uint32_t *pStatus, unsigned int *pui32Delay, llong *pAudioChangeTargetPts, const llong *currentDispPts,
+  unsigned int *audio_change_stage, GstCaps **appsrcCaps, bool *audioaac, bool svpenabled, GstElement *aSrc, bool *ret)
+{
+    Log::warn(TRACE_MEDIAPLAYBACK," performAudioTrackCodecChannelSwitchRialto()");
+    if (*pStatus != 0 || pSampleAttr == nullptr || pAudioAttr == nullptr ) {
+        Log::warn(TRACE_MEDIAPLAYBACK, "performAudioTrackCodecChannelSwitchRialto() No audio data ready yet");
+        *pui32Delay = 100; //delay of 100ms
+        return false;
+    }
+
+    Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): Audio change current disp pts %lld\n",
+              *currentDispPts);
+
+    gint64 currentPts = GST_CLOCK_TIME_NONE;
+
+    // Rialto Server's pipeline should be in PAUSED state here. Query position before switching it to READY
+    GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
+    if (gst_element_query(pgstUtilsPlaybackGroup->gstPipeline, query))
+        gst_query_parse_position(query, 0, &currentPts);
+    gst_query_unref(query);
+
+    GstEvent* flush_start = NULL;
+    GstEvent* flush_stop  = NULL;
+    *pAudioChangeTargetPts = *currentDispPts;
+    *audio_change_stage = AUDCHG_ALIGN;
+    *pui32Delay = 0;
+     pgstUtilsPlaybackGroup->isAudioAAC = *audioaac;
+
+    Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): Sending flush-start event to rialto sink");
+    flush_start = gst_event_new_flush_start();
+    *ret = gst_element_send_event(aSrc, flush_start);
+    if (!*ret)
+        Log::warn(TRACE_MEDIAPLAYBACK,"failed to send flush-start event");
+
+    Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): Sending flush-stop event to rialto sink");
+    flush_stop = gst_event_new_flush_stop(TRUE);
+    *ret = gst_element_send_event(aSrc, flush_stop);
+    if (!*ret)
+        Log::warn(TRACE_MEDIAPLAYBACK,"failed to send flush-stop event");
+
+    if (pgstUtilsPlaybackGroup->curAudioPlaysinkBin)
+    {
+      GstState current_state, pending;
+      Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): Switching audio sink to READY");
+      gst_element_set_state(pgstUtilsPlaybackGroup->curAudioPlaysinkBin, GST_STATE_READY);
+      gst_element_get_state(pgstUtilsPlaybackGroup->curAudioPlaysinkBin, &current_state, &pending, GST_CLOCK_TIME_NONE);
+      Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto():Current AudioPlaySinkBin State = %d", current_state);
+
+      Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): Switching audio sink to previous state");
+      gst_element_sync_state_with_parent(pgstUtilsPlaybackGroup->curAudioPlaysinkBin);
+      gst_element_get_state(pgstUtilsPlaybackGroup->curAudioPlaysinkBin, &current_state, &pending, GST_CLOCK_TIME_NONE);
+      Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): AudioPlaysinkbin State = %d Pending = %d",
+                current_state, pending);
+      gchar *oldCapsString = gst_caps_to_string(*appsrcCaps);
+      Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): Old caps: %s" , oldCapsString);
+      g_free(oldCapsString);
+      rdk_gstreamer_utils::configAudioCap(pAudioAttr, audioaac, svpenabled, appsrcCaps);
+      gchar *newCapsString = gst_caps_to_string(*appsrcCaps);
+      Log::warn(TRACE_MEDIAPLAYBACK,"performAudioTrackCodecChannelSwitchRialto(): New caps: %s" , newCapsString);
+      g_free(newCapsString);
+
+      if(GST_CLOCK_TIME_NONE != currentPts)
+      {
+        *pAudioChangeTargetPts = currentPts / (1000*1000);
+        Log::warn(TRACE_MEDIAPLAYBACK, "performAudioTrackCodecChannelSwitchRialto(): *pAudioChangeTargetPts: %lld", *pAudioChangeTargetPts);
+      }
+      else
+      {
+        Log::warn(TRACE_MEDIAPLAYBACK, "performAudioTrackCodecChannelSwitchRialto(): *pAudioChangeTargetPts use *currentDispPts: %lld", *pAudioChangeTargetPts);
+      }
+    }
+
+    return true;
+}
diff --git a/partner/dpi/gstreamer/ESPlayerGstGenericPort.h b/partner/dpi/gstreamer/ESPlayerGstGenericPort.h
index 3a725b0..bfb7ed2 100644
--- a/partner/dpi/gstreamer/ESPlayerGstGenericPort.h
+++ b/partner/dpi/gstreamer/ESPlayerGstGenericPort.h
@@ -126,6 +126,12 @@ public:
     void UnregisterCallbacksToAppSrc();
     uint32_t getMinBuffersBeforeReady();
     void ProcessAudioGap(const ISampleAttributes *pSampleAttr);
+    bool performAudioTrackCodecChannelSwitchRialto(struct rdk_gstreamer_utils::rdkGstreamerUtilsPlaybackGrp *pgstUtilsPlaybackGroup,
+                                                   const void *pSampleAttr, rdk_gstreamer_utils::AudioAttributes *pAudioAttr,
+                                                   uint32_t *pStatus, unsigned int *pui32Delay,
+                                                   llong *pAudioChangeTargetPts, const llong *pcurrentDispPts,
+                                                   unsigned int *audio_change_stage, GstCaps **appsrcCaps,
+                                                   bool *audioaac, bool svpenabled, GstElement *aSrc, bool *ret);
     std::shared_ptr<SampleWriterNative> mSampleWriter;
     MediaType mMediaType;
     unsigned int _current_data;
diff --git a/partner/dpi/gstreamer/PlaybackGroupNative.cpp b/partner/dpi/gstreamer/PlaybackGroupNative.cpp
index 3c7d557..c2a06a7 100644
--- a/partner/dpi/gstreamer/PlaybackGroupNative.cpp
+++ b/partner/dpi/gstreamer/PlaybackGroupNative.cpp
@@ -34,7 +34,7 @@ extern void ApplicationManagerContentStopped(void);
 #if defined(GST_GL)
 #include "VideoSinkGStreamer.h"
 #endif
-#define VIDEO_SINK_NAME "westerossink"
+#define VIDEO_SINK_NAME "rialtomsevideosink"
 #define VIDEO_DECODER_NAME "westerossink"
 #define TOO_FAR_AHEAD_THRESHOLD_SECONDS 20
 #define UHD_WITDH   3840
@@ -304,7 +304,7 @@ PlaybackGroupNative::PlaybackGroupNative(ESManagerNative& ESManager, uint32_t pi
     Log::info(TRACE_MEDIACONTROL, "Enabling audio downmixing to stereo");
     g_object_set(mGstPipeline, "audio-filter", capsfilter, NULL);
   }
-  mVideoSink = createWesterosSink();
+  mVideoSink = nullptr;
 #if defined(GST_GL)
   mVideoSinkGst.reset(new VideoSinkGStreamer());
   g_object_set(mGstPipeline, "video-sink", mVideoSinkGst->createVideoSink(), NULL);
diff --git a/partner/dpi/gstreamer/ocdm/CMakeLists.txt b/partner/dpi/gstreamer/ocdm/CMakeLists.txt
index f9f8d78..5212371 100644
--- a/partner/dpi/gstreamer/ocdm/CMakeLists.txt
+++ b/partner/dpi/gstreamer/ocdm/CMakeLists.txt
@@ -88,11 +88,12 @@ endif ()
 if (DPI_REFERENCE_DRM_OCDM)
     set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${HAVE_DPI_DIRECTORY}/ocdm)
     add_library(drmocdm ${LIBRARY_TYPE} ${PLAYREADY_SOURCES})
-    target_link_libraries(drmocdm ocdm gstreamer-1.0 glib-2.0 gobject-2.0 gstaudio-1.0 gstapp-1.0 gstvideo-1.0 gstbase-1.0 WPEFrameworkProtocols WPEFrameworkDefinitions WPEFrameworkCore WPEFrameworkTracing )
+    target_link_libraries(drmocdm ocdmRialto gstreamer-1.0 glib-2.0 gobject-2.0 gstaudio-1.0 gstapp-1.0 gstvideo-1.0 gstbase-1.0 WPEFrameworkProtocols WPEFrameworkDefinitions WPEFrameworkCore WPEFrameworkTracing )
     target_include_directories(drmocdm PUBLIC ${CMAKE_CURRENT_LIST_DIR})
     target_compile_options(drmocdm PRIVATE -fvisibility=hidden)
     set_target_properties(drmocdm PROPERTIES OUTPUT_NAME "drmsystem")
 
+    target_compile_options(drmocdm PUBLIC -DPLAYREADY -DPLAYREADY4_0 -DDRM_BUILD_PROFILE=900 -DDRM_SUPPORT_ASSEMBLY=0 -DDRM_SUPPORT_DATASTORE_PREALLOC=1 -DDRM_SUPPORT_ECCPROFILING=0 -DDRM_SUPPORT_FORCE_ALIGN=1 -DDRM_SUPPORT_INLINEDWORDCPY=0 -DDRM_SUPPORT_FILE_LOCKING=1 -DDRM_SUPPORT_MULTI_THREADING=0 -DDRM_SUPPORT_NATIVE_64BIT_TYPES=1 -DDRM_SUPPORT_PRECOMPUTE_GTABLE=1 -DDRM_SUPPORT_SECUREOEMHAL=0 -DDRM_SUPPORT_SECUREOEMHAL_PLAY_ONLY=0 -DDRM_SUPPORT_TRACING=1 -DDRM_SUPPORT_TOOLS_NET_IO=0 -DDRM_COMPILE_FOR_NORMAL_WORLD=0 -DDRM_COMPILE_FOR_SECURE_WORLD=1)
     set_target_properties(drmocdm PROPERTIES ADDITIONAL_CLEAN_FILES ${HAVE_DPI_DIRECTORY}/ocdm)
 
     if (DPI_REFERENCE_DRM_DO_PLUGIN)

When patch is applied, bitbake -C configure netflix has to be executed.

Rdk Gstreamer Utils modifications

To build rdk-gstreamer-utils with Rialto, its bitbake has to be modified:



diff --git a/recipes-extended/gstreamer-netflix-platform/rdk-gstreamer-utils.bb b/recipes-extended/gstreamer-netflix-platform/rdk-gstreamer-utils.bb
index 9dfe370..fc67ee9 100644
--- a/recipes-extended/gstreamer-netflix-platform/rdk-gstreamer-utils.bb
+++ b/recipes-extended/gstreamer-netflix-platform/rdk-gstreamer-utils.bb
@@ -5,6 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=175792518e4ac015ab6696d16c4f607e"
 SRCREV = "${AUTOREV}"
 
 DEPENDS += " gstreamer1.0 gstreamer1.0-plugins-base"
+RDEPENDS_${PN} += " rialto-gstreamer"
 
 SRC_URI = "${RDK_GENERIC_ROOT_GIT}/gstreamer-netflix-platform/generic;protocol=${RDK_GIT_PROTOCOL};branch=${RDK_GIT_BRANCH}"


Some modifications have to be applied in rdk-gstreamer-utils code:

diff --git a/rdk_gstreamer_utils.cpp b/rdk_gstreamer_utils.cpp
index d9248871..ff3248b5 100644
--- a/rdk_gstreamer_utils.cpp
+++ b/rdk_gstreamer_utils.cpp
@@ -78,7 +78,7 @@ namespace rdk_gstreamer_utils {
     {
         const char* audiodecodername = getAudioDecoderName_soc();
         GstElement* audiodecoder = retrieveGstElementByName(pipeline, audiodecodername);
-        GstElement* videodecoder = retrieveGstElementByName(pipeline, "westerossink"); //default on RDK platforms
+        GstElement* videodecoder = retrieveGstElementByName(pipeline, "rialtomsevideosink"); //default on RDK platforms
         const char* AudioUnderflowSignal = getAudioUnderflowSignalName_soc();
         const char* VideoUnderflowSignal = getVideoUnderflowSignalName_soc();
 
@@ -216,7 +216,7 @@ namespace rdk_gstreamer_utils {
     {
         return switchToAudioMasterMode_soc();
     }
-    
+
     void setKeyFrameFlag(GstBuffer *gstBuffer,bool val)
     {
         setKeyFrameFlag_soc(gstBuffer,val);
diff --git a/realtek/rdk_gstreamer_utils_soc.cpp b/realtek/rdk_gstreamer_utils_soc.cpp
index 25f70ec1..ae5dd165 100644
--- a/realtek/rdk_gstreamer_utils_soc.cpp
+++ b/realtek/rdk_gstreamer_utils_soc.cpp
@@ -105,8 +105,8 @@ namespace rdk_gstreamer_utils
     GstElement * configureUIAudioSink_soc(bool TTSenabled)
     {
         GstElement *audioSink = NULL;
-        LOG_RGU("configureUIAudioSink_soc: : connecting rtkaudiosink");
-        audioSink = gst_element_factory_make ("rtkaudiosink","rtkaudiosink");
+        LOG_RGU("configureUIAudioSink_soc: : connecting rialtowebaudiosink");
+        audioSink = gst_element_factory_make ("rialtowebaudiosink","rialtowebaudiosink");
         g_object_set(G_OBJECT(audioSink), "media-tunnel",  FALSE, NULL);
         g_object_set(G_OBJECT(audioSink), "audio-service",  TRUE, NULL);
 
@@ -870,7 +870,7 @@ namespace rdk_gstreamer_utils
 
     bool getDelayTimerEnabled_soc()
     {
-        return true;
+        return false;
     }
 
     void switchToAudioMasterMode_soc()
diff --git a/rialto/rdk_gstreamer_utils_soc.cpp b/rialto/rdk_gstreamer_utils_soc.cpp
index 26ea04d4..67b3c852 100644
--- a/rialto/rdk_gstreamer_utils_soc.cpp
+++ b/rialto/rdk_gstreamer_utils_soc.cpp
@@ -77,8 +77,8 @@ namespace rdk_gstreamer_utils
     GstElement * configureUIAudioSink_soc(bool TTSenabled)
     {
         GstElement *audioSink = NULL;
-        LOG_RGU("configureUIAudioSink_soc: : connecting rialtouiaudiosink");
-        audioSink = gst_element_factory_make ("rialtouiaudiosink","rialtouiaudiosink");
+        LOG_RGU("configureUIAudioSink_soc: : connecting rialtowebaudiosink");
+        audioSink = gst_element_factory_make ("rialtowebaudiosink","rialtowebaudiosink");
 
         return audioSink;
     }
@@ -181,7 +181,7 @@ namespace rdk_gstreamer_utils
         // no op. To be implemented if required later
         return;
     }
-    
+
     void setKeyFrameFlag_soc(GstBuffer *gstBuffer,bool val)
     {
         // no op. To be implemented if required later
@@ -190,7 +190,7 @@ namespace rdk_gstreamer_utils
 
     bool getDelayTimerEnabled_soc()
     {
-        return true;
+        return false;
     }
 
     void SetAudioServerParam_soc(bool enabled)

After applying those changes, component has to be rebuilt using bitbake -C configure rdk-gstreamer-utils