Merge "Revert "Adjust media buffer GC threshold"" into 24.lts.dev
diff --git a/plugin/CobaltImplementation.cpp b/plugin/CobaltImplementation.cpp
index 3be1428..a9ea8bb 100644
--- a/plugin/CobaltImplementation.cpp
+++ b/plugin/CobaltImplementation.cpp
@@ -258,6 +258,7 @@
       Block();
       SbRdkQuit();
       Wait(Thread::BLOCKED | Thread::STOPPED | Thread::STOPPING, Core::infinite);
+      std::quick_exit(0);
     }
 
     uint32_t Configure(PluginHost::IShell* service) {
diff --git a/plugin/CobaltJsonRpc.cpp b/plugin/CobaltJsonRpc.cpp
index 2125e64..6a70cd7 100644
--- a/plugin/CobaltJsonRpc.cpp
+++ b/plugin/CobaltJsonRpc.cpp
@@ -23,10 +23,6 @@
 #include "Cobalt.h"
 #include "Module.h"
 
-#ifndef SYSLOG_GLOBAL
-#define SYSLOG_GLOBAL(CATEGORY, PARAMETERS) SYSLOG(CATEGORY, PARAMETERS)
-#endif /* SYSLOG_GLOBAL */
-
 namespace WPEFramework {
 namespace Plugin {
 
@@ -210,14 +206,14 @@
   Exchange::IDictionary *dict(
     _cobalt->QueryInterface<Exchange::IDictionary>());
   if (dict == nullptr) {
-    SYSLOG_GLOBAL(Logging::Error, (_T("IDictionary is not implemented")));
+    SYSLOG(Logging::Error, (_T("IDictionary is not implemented")));
   } else {
     std::string json;
     if (!dict->Get("settings", "accessibility", json)) {
-      SYSLOG_GLOBAL(Logging::Error, (_T("Cannot get 'accessibility' setting")));
+      SYSLOG(Logging::Error, (_T("Cannot get 'accessibility' setting")));
     }
     else if (!response.FromString(json)) {
-      SYSLOG_GLOBAL(Logging::Error, (_T("Cannot convert to JSON object")));
+      SYSLOG(Logging::Error, (_T("Cannot convert to JSON object")));
     }
     else {
       result = Core::ERROR_NONE;
@@ -243,14 +239,14 @@
     Exchange::IDictionary *dict(
       _cobalt->QueryInterface<Exchange::IDictionary>());
     if (dict == nullptr) {
-      SYSLOG_GLOBAL(Logging::Error, (_T("IDictionary is not implemented")));
+      SYSLOG(Logging::Error, (_T("IDictionary is not implemented")));
     } else {
       std::string json;
       if (!param.ToString(json)) {
-        SYSLOG_GLOBAL(Logging::Error, (_T("Cannot convert to string")));
+        SYSLOG(Logging::Error, (_T("Cannot convert to string")));
       }
       else if (!dict->Set("settings", "accessibility", json)) {
-        SYSLOG_GLOBAL(Logging::Error, (_T("Cannot set 'accessibility' setting")));
+        SYSLOG(Logging::Error, (_T("Cannot set 'accessibility' setting")));
       }
       else {
         result = Core::ERROR_NONE;
diff --git a/plugin/Module.h b/plugin/Module.h
index f0d8629..ec9c6d5 100644
--- a/plugin/Module.h
+++ b/plugin/Module.h
@@ -24,5 +24,9 @@
 #include <core/core.h>
 #include <plugins/plugins.h>
 
+#if !defined(THUNDER_VERSION) && defined(THUNDER_VERSION_MAJOR)
+#define THUNDER_VERSION THUNDER_VERSION_MAJOR
+#endif
+
 #undef EXTERNAL
 #define EXTERNAL
diff --git a/src/third_party/starboard/rdk/shared/BUILD.gn b/src/third_party/starboard/rdk/shared/BUILD.gn
index 5b65b86..0f8d33e 100644
--- a/src/third_party/starboard/rdk/shared/BUILD.gn
+++ b/src/third_party/starboard/rdk/shared/BUILD.gn
@@ -85,6 +85,8 @@
 static_library("starboard_platform") {
   check_includes = false
 
+  # has_pedantic_warnings = true
+
   defines = []
 
   sources = [
diff --git a/src/third_party/starboard/rdk/shared/application_rdk.cc b/src/third_party/starboard/rdk/shared/application_rdk.cc
index 34dbf2b..cbfa0f7 100644
--- a/src/third_party/starboard/rdk/shared/application_rdk.cc
+++ b/src/third_party/starboard/rdk/shared/application_rdk.cc
@@ -45,6 +45,7 @@
 #include <sys/eventfd.h>
 #include <sys/timerfd.h>
 #include <unistd.h>
+#include <malloc.h>
 
 namespace third_party {
 namespace starboard {
@@ -139,6 +140,8 @@
   using ::starboard::shared::starboard::media::MimeSupportabilityCache;
   MimeSupportabilityCache::GetInstance()->SetCacheEnabled(true);
   KeySystemSupportabilityCache::GetInstance()->SetCacheEnabled(true);
+
+  ScheduleMemoryUsageCheck();
 }
 
 void Application::Teardown() {
@@ -388,6 +391,48 @@
   }, nullptr, 0);
 }
 
+void Application::ReleaseMemory() {
+  Inject(new Event(kSbEventTypeLowMemory, NULL, [](void*) {
+    malloc_trim(0);
+  }));
+}
+
+void Application::ScheduleMemoryUsageCheck(SbTime delay) {
+  SbEventSchedule([](void* data) {
+    SbTime back_off_timeout = Application::Get()->CheckMemoryUsage();
+    if (back_off_timeout && back_off_timeout != kSbTimeMax)
+      Application::Get()->ScheduleMemoryUsageCheck(back_off_timeout);
+  }, nullptr, delay);
+}
+
+SbTime Application::CheckMemoryUsage() {
+  static const int64_t kCPUMemoryPressureLimit = ([]() -> int64_t {
+    const char* env = std::getenv("COBALT_CPU_MEM_PRESSURE_IN_MB");
+    int64_t limit_in_mb = SB_INT64_C(400);
+    if( env ) {
+      int64_t t = strtol(env, nullptr, 0);
+      if ( t >= 0 )
+        limit_in_mb = t;
+    }
+    int64_t total_in_bytes = SbSystemGetTotalCPUMemory();
+    return std::min(total_in_bytes, limit_in_mb * 1024 * 1024);
+  })();
+
+  if (!kCPUMemoryPressureLimit)
+    return kSbTimeMax;
+
+  int64_t usage_in_bytes = SbSystemGetUsedCPUMemory();
+  if (kCPUMemoryPressureLimit < usage_in_bytes) {
+    SB_LOG(INFO) << "Triggering memory pressure event. Current CPU mem. usage: "
+                 << uint64_t(usage_in_bytes / 1024) << " kb, pressure limit: "
+                 << uint64_t(kCPUMemoryPressureLimit / 1024) << " kb.";
+    ReleaseMemory();
+    return 5 * kSbTimeSecond;
+  }
+
+  return kSbTimeSecond;
+}
+
 }  // namespace shared
 }  // namespace rdk
 }  // namespace starboard
diff --git a/src/third_party/starboard/rdk/shared/application_rdk.h b/src/third_party/starboard/rdk/shared/application_rdk.h
index d88180a..1bd3dda 100644
--- a/src/third_party/starboard/rdk/shared/application_rdk.h
+++ b/src/third_party/starboard/rdk/shared/application_rdk.h
@@ -104,6 +104,10 @@
   void BuildEssosContext();
   void FatalError();
 
+  void ScheduleMemoryUsageCheck(SbTime delay = kSbTimeSecond);
+  SbTime CheckMemoryUsage();
+  void ReleaseMemory();
+
   static EssTerminateListener terminateListener;
   static EssKeyListener keyListener;
   static EssSettingsListener settingsListener;
diff --git a/src/third_party/starboard/rdk/shared/audio_sink/gstreamer_audio_sink_type.cc b/src/third_party/starboard/rdk/shared/audio_sink/gstreamer_audio_sink_type.cc
index e1b5787..c78d6b1 100644
--- a/src/third_party/starboard/rdk/shared/audio_sink/gstreamer_audio_sink_type.cc
+++ b/src/third_party/starboard/rdk/shared/audio_sink/gstreamer_audio_sink_type.cc
@@ -128,7 +128,7 @@
   GstElement* audiosink_{nullptr};
   GMainLoop* mainloop_{nullptr};
   GMainContext* main_loop_context_{nullptr};
-  guint source_id_{0};
+  int source_id_{-1};
   bool destroying_{false};
   bool enough_data_{false};
   std::string file_name_;
@@ -193,7 +193,7 @@
   appsrc_ = gst_element_factory_make("appsrc", "source");
   GstAppSrcCallbacks callbacks = {&GStreamerAudioSink::AppSrcNeedData,
                                   &GStreamerAudioSink::AppSrcEnoughData,
-                                  nullptr};
+                                  nullptr, nullptr};
   gst_app_src_set_callbacks(GST_APP_SRC(appsrc_), &callbacks, this, nullptr);
   gst_app_src_set_max_bytes(GST_APP_SRC(appsrc_),
                             kFramesPerRequest * GetBytesPerFrame());
diff --git a/src/third_party/starboard/rdk/shared/configuration.cc b/src/third_party/starboard/rdk/shared/configuration.cc
index e92f732..070344c 100644
--- a/src/third_party/starboard/rdk/shared/configuration.cc
+++ b/src/third_party/starboard/rdk/shared/configuration.cc
@@ -76,6 +76,7 @@
     &::starboard::common::CobaltRasterizerTypeDefault,
     &::starboard::common::CobaltEnableJitDefault,
     &::starboard::common::CobaltFallbackSplashScreenTopicsDefault,
+    &::starboard::common::CobaltCanStoreCompiledJavascriptDefault,
 };
 
 }  // namespace
diff --git a/src/third_party/starboard/rdk/shared/drm/gst_decryptor_ocdm.cc b/src/third_party/starboard/rdk/shared/drm/gst_decryptor_ocdm.cc
index 42397ab..3c4642a 100644
--- a/src/third_party/starboard/rdk/shared/drm/gst_decryptor_ocdm.cc
+++ b/src/third_party/starboard/rdk/shared/drm/gst_decryptor_ocdm.cc
@@ -24,6 +24,7 @@
 
 #include <gst/gst.h>
 #include <gst/base/gstbasetransform.h>
+#include <gst/base/gstbytereader.h>
 
 #include <opencdm/open_cdm.h>
 
@@ -130,9 +131,26 @@
         gst_buffer_unmap(key, &map_info);
       }
 
+      uint32_t total_clear = 0;
+      uint32_t total_encrypted = 0;
+      GstMapInfo sample_map;
+      if (gst_buffer_map(subsamples, &sample_map, GST_MAP_READ)) {
+        GstByteReader* reader = gst_byte_reader_new(sample_map.data, sample_map.size);
+        for (uint32_t i = 0; i < subsample_count; ++i) {
+          uint16_t clear = 0;
+          uint32_t encrypted = 0;
+          gst_byte_reader_get_uint16_be(reader, &clear);
+          gst_byte_reader_get_uint32_be(reader, &encrypted);
+          total_clear += clear;
+          total_encrypted += encrypted;
+        }
+        gst_byte_reader_free(reader);
+        gst_buffer_unmap(subsamples, &sample_map);
+      }
+
       GST_TRACE_OBJECT(self, "buf=(%" GST_PTR_FORMAT "), "
-                       "subsample_count=%u, subsamples=(%p), iv=(%p), key=(%p : %s)",
-                       buffer, subsample_count, subsamples, iv, key, md5sum);
+                       "subsample_count=%u, subsamples=(%p), clear=%u, encrypted=%u, iv=(%p), key=(%p : %s)",
+                       buffer, subsample_count, subsamples, total_clear, total_encrypted, iv, key, md5sum);
 
       g_free(md5sum);
     }
@@ -230,7 +248,7 @@
     }
 
     if ( rc != 0 ) {
-      if ( rc == ERROR_INVALID_SESSION ) {
+      if ( rc == (int)ERROR_INVALID_SESSION ) {
         GST_DEBUG_OBJECT(self, "Invalid session. Probably due to player shutdown.");
         return GST_BASE_TRANSFORM_FLOW_DROPPED;
       }
diff --git a/src/third_party/starboard/rdk/shared/hang_detector.cc b/src/third_party/starboard/rdk/shared/hang_detector.cc
index 3112a9a..c3a5130 100644
--- a/src/third_party/starboard/rdk/shared/hang_detector.cc
+++ b/src/third_party/starboard/rdk/shared/hang_detector.cc
@@ -40,9 +40,9 @@
 namespace {
 
 #if defined(COBALT_BUILD_TYPE_GOLD)
-const uint32_t kMaxExpirationCount = 6;
+const int32_t kMaxExpirationCount = 6;
 #else
-const uint32_t kMaxExpirationCount = 18;
+const int32_t kMaxExpirationCount = 18;
 #endif
 
 pid_t get_tid() {
diff --git a/src/third_party/starboard/rdk/shared/main_rdk.cc b/src/third_party/starboard/rdk/shared/main_rdk.cc
index f34c9fd..8333a6c 100644
--- a/src/third_party/starboard/rdk/shared/main_rdk.cc
+++ b/src/third_party/starboard/rdk/shared/main_rdk.cc
@@ -60,7 +60,8 @@
 }
 
 static void InstallStopSignalHandlers() {
-  struct sigaction action = {0};
+  struct sigaction action;
+  memset (&action, 0, sizeof (action));
   action.sa_handler = RequestStop;
   action.sa_flags = 0;
   ::sigemptyset(&action.sa_mask);
diff --git a/src/third_party/starboard/rdk/shared/platform_configuration/BUILD.gn b/src/third_party/starboard/rdk/shared/platform_configuration/BUILD.gn
index db89e5e..1727d9d 100644
--- a/src/third_party/starboard/rdk/shared/platform_configuration/BUILD.gn
+++ b/src/third_party/starboard/rdk/shared/platform_configuration/BUILD.gn
@@ -60,6 +60,9 @@
 
     cflags_cc += [
       "-std=gnu++14",
+      "-Wno-literal-suffix",
+      # Generated by Audio Renderer and Audio Sink implementations.
+      "-Wno-reorder",
     ]
 
     if (is_qa || is_gold) {
@@ -131,15 +134,31 @@
     "-Wextra",
     "-Wunreachable-code",
   ]
+  if (!is_clang) {
+    cflags += [
+      "-Wno-expansion-to-defined",
+    ]
+  }
 }
 
 config("no_pedantic_warnings") {
   if (!is_clang) {
+    cflags = [
+      "-Wno-conversion",
+      "-Wno-deprecated-declarations",
+      "-Wno-ignored-qualifiers",
+      "-Wno-multichar",
+      "-Wno-sign-conversion",
+      "-Wno-unused-function",
+      "-Wno-unused-local-typedefs",
+      "-Wno-unused-parameter",
+      "-Wno-unused-variable",
+      "-Wno-unused-but-set-variable",
+    ]
     cflags_cc = [
-      "-Wno-literal-suffix",
       "-Wno-deprecated-copy",
       "-Wno-invalid-offsetof",
-      "-Wno-ignored-qualifiers",
+      "-Wno-literal-suffix",
       "-Wno-pessimizing-move",
     ]
   } else {
diff --git a/src/third_party/starboard/rdk/shared/platform_configuration/configuration.gni b/src/third_party/starboard/rdk/shared/platform_configuration/configuration.gni
index d9a3062..a1885b8 100644
--- a/src/third_party/starboard/rdk/shared/platform_configuration/configuration.gni
+++ b/src/third_party/starboard/rdk/shared/platform_configuration/configuration.gni
@@ -44,6 +44,9 @@
 no_pedantic_warnings_config_path =
   "//third_party/starboard/rdk/shared/platform_configuration:no_pedantic_warnings"
 
+pedantic_warnings_config_path =
+  "//third_party/starboard/rdk/shared/platform_configuration:pedantic_warnings"
+
 speed_config_path =
   "//third_party/starboard/rdk/shared/platform_configuration:speed"
 
diff --git a/src/third_party/starboard/rdk/shared/player/player_get_info.cc b/src/third_party/starboard/rdk/shared/player/player_get_info.cc
index 8094775..b4f0324 100644
--- a/src/third_party/starboard/rdk/shared/player/player_get_info.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_get_info.cc
@@ -34,10 +34,14 @@
 
 #if SB_API_VERSION >= 15
 void SbPlayerGetInfo(SbPlayer player, SbPlayerInfo* out_player_info) {
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->GetInfo(out_player_info);
 }
 #else   // SB_API_VERSION >= 15
 void SbPlayerGetInfo2(SbPlayer player, SbPlayerInfo2* out_player_info) {
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->GetInfo(out_player_info);
 }
 #endif  // SB_API_VERSION >= 15
diff --git a/src/third_party/starboard/rdk/shared/player/player_get_maximum_number_of_samples_per_write.cc b/src/third_party/starboard/rdk/shared/player/player_get_maximum_number_of_samples_per_write.cc
index edaf734..ffa7fcd 100644
--- a/src/third_party/starboard/rdk/shared/player/player_get_maximum_number_of_samples_per_write.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_get_maximum_number_of_samples_per_write.cc
@@ -35,5 +35,7 @@
 
 int SbPlayerGetMaximumNumberOfSamplesPerWrite(SbPlayer player,
                                               SbMediaType /*sample_type*/) {
+  if (player == kSbPlayerInvalid)
+    return 0;
   return player->MaxNumberOfSamplesPerWrite();
 }
diff --git a/src/third_party/starboard/rdk/shared/player/player_internal.cc b/src/third_party/starboard/rdk/shared/player/player_internal.cc
index 0236174..c90bc26 100644
--- a/src/third_party/starboard/rdk/shared/player/player_internal.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_internal.cc
@@ -416,6 +416,7 @@
   gst_app_src_set_emit_signals(GST_APP_SRC(appsrc), FALSE);
   gst_app_src_set_callbacks(GST_APP_SRC(appsrc), callbacks, user_data, nullptr);
   gst_app_src_set_max_bytes(GST_APP_SRC(appsrc), max_bytes);
+  gst_base_src_set_format(GST_BASE_SRC(appsrc), GST_FORMAT_TIME);
 
   GstCobaltSrc* src = GST_COBALT_SRC(element);
   gchar* name = g_strdup_printf("src_%u", src->priv->pad_number);
@@ -1133,6 +1134,7 @@
         CASE(State::kInitialPreroll);
         CASE(State::kPrerollAfterSeek);
         CASE(State::kPresenting);
+        CASE(State::kEnded);
     }
 #undef CASE
     return "unknown";
@@ -1259,7 +1261,7 @@
 
     int need_data = static_cast<int>(media) & ~decoder_state_data_;
     if (need_data == 0) {
-      GST_LOG_OBJECT(pipeline_, "Already sent 'kSbPlayerDecoderStateNeedsData' for media type: %d, ignoring new request", media);
+      GST_LOG_OBJECT(pipeline_, "Already sent 'kSbPlayerDecoderStateNeedsData' for media type: %d, ignoring new request", static_cast<int>(media));
       return;
     }
     if ((eos_data_ & need_data) == need_data) {
@@ -1591,8 +1593,8 @@
   }
   g_main_loop_unref(main_loop_);
   g_main_context_unref(main_loop_context_);
-  g_object_unref(pipeline_);
   GST_INFO_OBJECT(pipeline_, "BYE BYE player");
+  g_object_unref(pipeline_);
 }
 
 // static
@@ -1952,8 +1954,8 @@
 {
   GST_WARNING_OBJECT(self->pipeline_,
     "Decoder need data state = 0x%x,"
-    " video appsrc level = %lld kb,"
-    " audio appsrc level = %lld kb",
+    " video appsrc level = %" G_GUINT64_FORMAT " kb,"
+    " audio appsrc level = %" G_GUINT64_FORMAT " kb",
     self->decoder_state_data_,
     gst_app_src_get_current_level_bytes(GST_APP_SRC(self->video_appsrc_)) / 1024,
     gst_app_src_get_current_level_bytes(GST_APP_SRC(self->audio_appsrc_)) / 1024);
@@ -2108,13 +2110,37 @@
       sample_deallocate_func_(player_, context_, sample_infos[0].buffer);
       return;
   }
-  GstClockTime timestamp = sample_infos[0].timestamp * kSbTimeNanosecondsPerMicrosecond;
+
+#if defined(SB_RDK_ZERO_COPY_SAMPLE_WRITE) && SB_RDK_ZERO_COPY_SAMPLE_WRITE
+  using BufferInfo = std::tuple<SbPlayerDeallocateSampleFunc, SbPlayer, void*, const void*>;
+  GstBuffer* buffer =
+    gst_buffer_new_wrapped_full(
+      static_cast<GstMemoryFlags>(0),
+      const_cast<gpointer> (sample_infos[0].buffer),
+      sample_infos[0].buffer_size,
+      0,
+      sample_infos[0].buffer_size,
+      new BufferInfo(sample_deallocate_func_, player_, context_, sample_infos[0].buffer),
+      [](gpointer data) {
+        BufferInfo &info = *reinterpret_cast<BufferInfo*>(data);
+        auto deallocate_func = std::get<0>(info);
+        auto player = std::get<1>(info);
+        auto* context = std::get<2>(info);
+        const auto* buffer = std::get<3>(info);
+        deallocate_func(player, context, buffer);
+        delete &info;
+      });
+#else
+  G_GNUC_UNUSED gsize sz;
   GstBuffer* buffer =
       gst_buffer_new_allocate(nullptr, sample_infos[0].buffer_size, nullptr);
-  gsize sz = gst_buffer_fill(buffer, 0, sample_infos[0].buffer, sample_infos[0].buffer_size);
+  sz = gst_buffer_fill(buffer, 0, sample_infos[0].buffer, sample_infos[0].buffer_size);
   SB_DCHECK(sz == sample_infos[0].buffer_size);
-  GST_BUFFER_TIMESTAMP(buffer) = timestamp;
   sample_deallocate_func_(player_, context_, sample_infos[0].buffer);
+#endif
+
+  GstClockTime timestamp = sample_infos[0].timestamp * kSbTimeNanosecondsPerMicrosecond;
+  GST_BUFFER_TIMESTAMP(buffer) = timestamp;
 
   if (sample_infos[0].type == kSbMediaTypeVideo) {
 #if SB_API_VERSION >= 15
@@ -2281,7 +2307,7 @@
         seek_pos_ns =  seek_position_ * kSbTimeNanosecondsPerMicrosecond;
   }
 
-  if (GST_CLOCK_TIME_IS_VALID(seek_pos_ns) && seek_pos_ns > GST_BUFFER_TIMESTAMP(buffer)) {
+  if (GST_CLOCK_TIME_IS_VALID(seek_pos_ns) && GstClockTime(seek_pos_ns) > GST_BUFFER_TIMESTAMP(buffer)) {
     // Set dummy duration to let sink drop out-of-segment samples
     GST_BUFFER_DURATION (buffer) = GST_SECOND / 60;
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DECODE_ONLY);
@@ -2642,7 +2668,7 @@
         GST_INFO_OBJECT(pipeline_, "Ignore state change to playing: invalid min sample ts");
         return false;
       }
-      else if (seek_pos_ns > min_ts) {
+      else if (seek_pos_ns > GstClockTime(min_ts)) {
         GST_INFO_OBJECT(
           pipeline_,
           "Ignore state change to playing: no samples for seek time yet"
diff --git a/src/third_party/starboard/rdk/shared/player/player_seek.cc b/src/third_party/starboard/rdk/shared/player/player_seek.cc
index 6c8898e..69ddbce 100644
--- a/src/third_party/starboard/rdk/shared/player/player_seek.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_seek.cc
@@ -38,5 +38,7 @@
 #else   // SB_API_VERSION >= 15
 void SbPlayerSeek2(SbPlayer player, SbTime seek_to_timestamp, int ticket) {
 #endif  // SB_API_VERSION >= 15
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->Seek(seek_to_timestamp, ticket);
 }
diff --git a/src/third_party/starboard/rdk/shared/player/player_set_bounds.cc b/src/third_party/starboard/rdk/shared/player/player_set_bounds.cc
index 84c5627..20b9f7b 100644
--- a/src/third_party/starboard/rdk/shared/player/player_set_bounds.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_set_bounds.cc
@@ -39,5 +39,7 @@
                        int y,
                        int width,
                        int height) {
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->SetBounds(z_index, x, y, width, height);
 }
diff --git a/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc b/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc
index e5d2083..3923883 100644
--- a/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc
@@ -34,5 +34,7 @@
 #include "third_party/starboard/rdk/shared/player/player_internal.h"
 
 bool SbPlayerSetPlaybackRate(SbPlayer player, double playback_rate) {
+  if (player == kSbPlayerInvalid)
+    return false;
   return player->player_->SetRate(playback_rate);
 }
diff --git a/src/third_party/starboard/rdk/shared/player/player_set_volume.cc b/src/third_party/starboard/rdk/shared/player/player_set_volume.cc
index 0ad39dc..728fae3 100644
--- a/src/third_party/starboard/rdk/shared/player/player_set_volume.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_set_volume.cc
@@ -34,5 +34,7 @@
 #include "third_party/starboard/rdk/shared/player/player_internal.h"
 
 void SbPlayerSetVolume(SbPlayer player, double volume) {
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->SetVolume(volume);
 }
diff --git a/src/third_party/starboard/rdk/shared/player/player_write_end_of_stream.cc b/src/third_party/starboard/rdk/shared/player/player_write_end_of_stream.cc
index 23fef23..1b78f87 100644
--- a/src/third_party/starboard/rdk/shared/player/player_write_end_of_stream.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_write_end_of_stream.cc
@@ -34,5 +34,7 @@
 #include "third_party/starboard/rdk/shared/player/player_internal.h"
 
 void SbPlayerWriteEndOfStream(SbPlayer player, SbMediaType stream_type) {
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->MarkEOS(stream_type);
 }
diff --git a/src/third_party/starboard/rdk/shared/player/player_write_sample.cc b/src/third_party/starboard/rdk/shared/player/player_write_sample.cc
index ee4dc65..8336b8e 100644
--- a/src/third_party/starboard/rdk/shared/player/player_write_sample.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_write_sample.cc
@@ -42,6 +42,8 @@
                           SbMediaType sample_type,
                           const SbPlayerSampleInfo* sample_infos,
                           int number_of_sample_infos) {
+  if (player == kSbPlayerInvalid)
+    return;
   player->player_->WriteSample(sample_type, sample_infos,
                                number_of_sample_infos);
 }
diff --git a/src/third_party/starboard/rdk/shared/rdkservices.cc b/src/third_party/starboard/rdk/shared/rdkservices.cc
index 9baf609..6355fe5 100644
--- a/src/third_party/starboard/rdk/shared/rdkservices.cc
+++ b/src/third_party/starboard/rdk/shared/rdkservices.cc
@@ -1419,11 +1419,12 @@
   Refresh();
 
   ::starboard::ScopedLock lock(mutex_);
-  if (output_index < audio_configurations_.size()) {
-    *out_configuration = audio_configurations_[output_index];
+  size_t index = output_index;
+  if (index < audio_configurations_.size()) {
+    *out_configuration = audio_configurations_[index];
     return true;
   }
-  else if (output_index == 0) {
+  else if (index == 0) {
     InitAudioConfigurationForAudioPort("", out_configuration);
     return true;
   }
diff --git a/src/third_party/starboard/rdk/shared/rdkservices.h b/src/third_party/starboard/rdk/shared/rdkservices.h
index 43721a0..e317ebe 100644
--- a/src/third_party/starboard/rdk/shared/rdkservices.h
+++ b/src/third_party/starboard/rdk/shared/rdkservices.h
@@ -34,10 +34,10 @@
 
 struct ResolutionInfo {
   ResolutionInfo() {}
-  ResolutionInfo(uint32_t w, uint32_t h)
+  ResolutionInfo(int32_t w, int32_t h)
     : Width(w), Height(h) {}
-  uint32_t Width { 1920 };
-  uint32_t Height { 1080 };
+  int32_t Width { 1920 };
+  int32_t Height { 1080 };
 };
 
 class DisplayInfo {
diff --git a/src/third_party/starboard/rdk/shared/system/system_egl.cc b/src/third_party/starboard/rdk/shared/system/system_egl.cc
index 7eeb8ce..5149cd2 100644
--- a/src/third_party/starboard/rdk/shared/system/system_egl.cc
+++ b/src/third_party/starboard/rdk/shared/system/system_egl.cc
@@ -34,9 +34,13 @@
 #include "starboard/egl.h"
 
 #include "third_party/starboard/rdk/shared/application_rdk.h"
+#include "third_party/starboard/rdk/shared/log_override.h"
 
+#include <mutex>
 #include <essos-app.h>
 
+EssAppPlatformDisplayType EssContextGetAppPlatformDisplayType( EssCtx *ctx ) __attribute__((weak));
+
 #if !defined(EGL_VERSION_1_0) || !defined(EGL_VERSION_1_1) || \
     !defined(EGL_VERSION_1_2) || !defined(EGL_VERSION_1_3) || \
     !defined(EGL_VERSION_1_4)
@@ -45,6 +49,47 @@
 
 namespace {
 
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+static PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC gEglCreatePlatformWindowSurfaceEXT;
+static PFNEGLGETPLATFORMDISPLAYEXTPROC gEglGetPlatformDisplayEXT;
+
+bool isExtensionSupported(const char* extension_list, const char* extension) {
+  int len = strlen(extension);
+  const char* ptr = extension_list;
+  while ((ptr = strstr(ptr, extension))) {
+    if (ptr[len] == ' ' || ptr[len] == '\0')
+      return true;
+    ptr += len;
+  }
+  return false;
+}
+
+bool resolveEglPlatfromExtFns() {
+  static std::once_flag flag;
+  std::call_once(flag, [] {
+    const char* extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+    if (!isExtensionSupported(extensions, "EGL_EXT_platform_wayland")) {
+      SB_LOG(INFO) << "Wayland EGL platform extension is not supported. Supported extensions: " << extensions;
+    }
+    else {
+      gEglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
+      gEglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
+      if (!gEglGetPlatformDisplayEXT || !gEglCreatePlatformWindowSurfaceEXT) {
+        if (!gEglGetPlatformDisplayEXT)
+          SB_LOG(INFO) << "eglGetPlatformDisplayEXT is not available";
+        if (!gEglCreatePlatformWindowSurfaceEXT)
+          SB_LOG(INFO) << "eglCreatePlatformWindowSurfaceEXT is not available";
+        gEglGetPlatformDisplayEXT = nullptr;
+        gEglCreatePlatformWindowSurfaceEXT = nullptr;
+      } else {
+        SB_LOG(INFO) << "Successfully resolved EGL platform display extension functions.";
+      }
+    }
+  });
+  return gEglGetPlatformDisplayEXT && gEglCreatePlatformWindowSurfaceEXT;
+}
+#endif
+
 // Convenience functions that redirect to the intended function but "cast" the
 // type of the SbEglNative*Type parameter into the desired type. Depending on
 // the platform, the type of cast to use is different so either C-style casts or
@@ -69,16 +114,64 @@
                                       SbEglConfig config,
                                       SbEglNativeWindowType win,
                                       const SbEglInt32* attrib_list) {
-  return eglCreateWindowSurface(dpy, config, (EGLNativeWindowType)win,
-                                attrib_list);
+  SbEglSurface result = EGL_NO_SURFACE;
+
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+  if (gEglCreatePlatformWindowSurfaceEXT) {
+    result = gEglCreatePlatformWindowSurfaceEXT(dpy, config, (EGLNativeWindowType)win,
+                                                attrib_list);
+    if (result == EGL_NO_SURFACE)
+      SB_LOG(WARNING) << "eglCreatePlatformWindowSurfaceEXT failed, err: " << eglGetError();
+  }
+#endif
+
+  if (result == EGL_NO_SURFACE) {
+    result = eglCreateWindowSurface(dpy, config, (EGLNativeWindowType)win,
+                                    attrib_list);
+    if (result == EGL_NO_SURFACE)
+      SB_LOG(ERROR) << "eglCreateWindowSurface failed, err: " << eglGetError();
+  }
+
+  return result;
 }
 
 SbEglDisplay SbEglGetDisplay(SbEglNativeDisplayType display_id) {
   NativeDisplayType display_type;
   EssCtx *ctx = third_party::starboard::rdk::shared::Application::Get()->GetEssCtx();
-  if (EssContextGetEGLDisplayType(ctx, &display_type))
-    return eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display_type));
-  return eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display_id));
+
+  if (EssContextGetEGLDisplayType(ctx, &display_type) == false) {
+    SB_LOG(ERROR) << "EssContextGetEGLDisplayType failed! Going to try display_id=" << display_id << '.';
+    display_type = reinterpret_cast<NativeDisplayType>(display_id);
+  }
+
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+  if (EssContextGetAppPlatformDisplayType == nullptr) {
+    SB_LOG(INFO) << "'EssContextGetAppPlatformDisplayType' is not available. Fallback to eglGetDisplay.";
+  }
+  else if (EssContextGetAppPlatformDisplayType(ctx) != EssAppPlatformDisplayType_waylandExtension) {
+    SB_LOG(INFO) << "Essos app platform display type is not 'WaylandExtension' ("
+                 << EssContextGetAppPlatformDisplayType(ctx)
+                 << " != "
+                 << EssAppPlatformDisplayType_waylandExtension << ")."
+                 << " Fallback to eglGetDisplay.";
+  }
+  else if (!resolveEglPlatfromExtFns()) {
+    SB_LOG(INFO) << "eglGetPlatformDisplayEXT is not available or failed. Fallback to eglGetDisplay.";
+  }
+  else {
+    SbEglDisplay result = gEglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, reinterpret_cast<EGLNativeDisplayType>(display_type), nullptr);
+    if (result == EGL_NO_DISPLAY) {
+      SB_LOG(ERROR) << "eglGetPlatformDisplayEXT returned EGL_NO_DISPLAY. Fallback to eglGetDisplay.";
+      gEglGetPlatformDisplayEXT = nullptr;
+      gEglCreatePlatformWindowSurfaceEXT = nullptr;
+    } else {
+      SB_LOG(INFO) << "Using display=" << result << ", returned by eglGetPlatformDisplayEXT.";
+      return result;
+    }
+  }
+#endif
+
+  return eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display_type));
 }
 
 const SbEglInterface g_sb_egl_interface = {
diff --git a/src/third_party/starboard/rdk/shared/system/system_get_path.cc b/src/third_party/starboard/rdk/shared/system/system_get_path.cc
index f323d08..ec57651 100644
--- a/src/third_party/starboard/rdk/shared/system/system_get_path.cc
+++ b/src/third_party/starboard/rdk/shared/system/system_get_path.cc
@@ -210,26 +210,27 @@
     return false;
   }
 
-  char path[kSbFileMaxPath];
+  const int kPathSize = kSbFileMaxPath;
+  char path[kPathSize];
   path[0] = '\0';
 
   switch (path_id) {
     case kSbSystemPathContentDirectory:
-      if (!GetContentDirectory(path, kSbFileMaxPath)){
+      if (!GetContentDirectory(path, kPathSize)){
         return false;
       }
 #if SB_IS(EVERGREEN_COMPATIBLE)
-      if (!GetEvergreenContentPathOverride(path, kSbFileMaxPath)) {
+      if (!GetEvergreenContentPathOverride(path, kPathSize)) {
         return false;
       }
 #endif
       break;
 
     case kSbSystemPathCacheDirectory:
-      if (!GetCacheDirectory(path, kSbFileMaxPath)) {
+      if (!GetCacheDirectory(path, kPathSize)) {
         return false;
       }
-      if (starboard::strlcat<char>(path, "/cobalt", kSbFileMaxPath) >= kSbFileMaxPath) {
+      if (starboard::strlcat<char>(path, "/cobalt", kPathSize) >= kPathSize) {
         return false;
       }
       if (!SbDirectoryCreate(path)) {
@@ -238,17 +239,17 @@
       break;
 
     case kSbSystemPathDebugOutputDirectory:
-      if (!SbSystemGetPath(kSbSystemPathTempDirectory, path, kSbFileMaxPath)) {
+      if (!SbSystemGetPath(kSbSystemPathTempDirectory, path, kPathSize)) {
         return false;
       }
-      if (starboard::strlcat<char>(path, "/log", kSbFileMaxPath) >= kSbFileMaxPath) {
+      if (starboard::strlcat<char>(path, "/log", kPathSize) >= kPathSize) {
         return false;
       }
       SbDirectoryCreate(path);
       break;
 
     case kSbSystemPathTempDirectory:
-      if (!GetTemporaryDirectory(path, kSbFileMaxPath)) {
+      if (!GetTemporaryDirectory(path, kPathSize)) {
         return false;
       }
       SbDirectoryCreate(path);
@@ -260,10 +261,10 @@
     case kSbSystemPathFontConfigurationDirectory:
     case kSbSystemPathFontDirectory:
 #if SB_IS(EVERGREEN_COMPATIBLE)
-      if (!GetContentDirectory(path, kSbFileMaxPath)) {
+      if (!GetContentDirectory(path, kPathSize)) {
         return false;
       }
-      if (starboard::strlcat(path, "/fonts", kSbFileMaxPath) >= kSbFileMaxPath) {
+      if (starboard::strlcat(path, "/fonts", kPathSize) >= kPathSize) {
         return false;
       }
       break;
@@ -272,7 +273,7 @@
 #endif
 
     case kSbSystemPathStorageDirectory:
-      if (!GetStorageDirectory(path, kSbFileMaxPath)) {
+      if (!GetStorageDirectory(path, kPathSize)) {
           return false;
       }
       break;
diff --git a/src/third_party/starboard/rdk/shared/system/system_get_property.cc b/src/third_party/starboard/rdk/shared/system/system_get_property.cc
index 2ba20ce..6207ec2 100644
--- a/src/third_party/starboard/rdk/shared/system/system_get_property.cc
+++ b/src/third_party/starboard/rdk/shared/system/system_get_property.cc
@@ -51,7 +51,7 @@
 const char kPlatformName[] = "Linux";
 
 bool CopyStringAndTestIfSuccess(char* out_value,
-                                int value_length,
+                                size_t value_length,
                                 const char* from_value) {
   if (strlen(from_value) + 1 > value_length)
     return false;
@@ -59,7 +59,7 @@
   return true;
 }
 
-bool TryReadFromPropertiesFile(const char* prefix, size_t prefix_len, char* out_value, int value_length) {
+bool TryReadFromPropertiesFile(const char* prefix, size_t prefix_len, char* out_value, size_t value_length) {
   FILE* properties = fopen("/etc/device.properties", "r");
   if (!properties) {
     return false;