Railto initial support

- set 'native audio' flags for RialtoAudioSink
- set maxVideoWidth/Height for secondary video
- initial cbcs support

Change-Id: Ibd76b4c6e196d306fba183377222bbe7b0d90e54
Signed-off-by: Eugene Mutavchi <Ievgen_Mutavchi@comcast.com>
diff --git a/src/third_party/starboard/rdk/shared/BUILD.gn b/src/third_party/starboard/rdk/shared/BUILD.gn
index b0b23eb..6dfbcbd 100644
--- a/src/third_party/starboard/rdk/shared/BUILD.gn
+++ b/src/third_party/starboard/rdk/shared/BUILD.gn
@@ -34,6 +34,7 @@
   rdk_enable_securityagent = true
   rdk_enable_ocdm = true
   rdk_enable_cryptography = true
+  rdk_enable_cbcs = false
 }
 
 pkg_config("glib") {
@@ -87,6 +88,8 @@
 static_library("starboard_platform") {
   check_includes = false
 
+  defines = []
+
   sources = [
     # Shared sources
     "//starboard/shared/gles/system_gles2.cc",
@@ -484,6 +487,10 @@
     configs += [ ":ocdm" ]
   }
 
+  if (rdk_enable_cbcs) {
+    defines += [ "ENABLE_CBCS=1" ]
+  }
+
   public_deps = [
     "//starboard:starboard_headers_only",
     "//starboard/common",
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 c8f10ec..982e7a7 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
@@ -429,16 +429,16 @@
   GstBuffer* iv = nullptr;
   GstBuffer* key = nullptr;
   uint32_t subsample_count = 0u;
-  uint32_t encryption_scheme = kSbDrmEncryptionSchemeAesCtr;
 
   const GValue* value = nullptr;
 
-  if ( gst_structure_get_uint(info, "encryption_scheme", &encryption_scheme) ) {
-    if (encryption_scheme != kSbDrmEncryptionSchemeAesCtr) {
-      GST_ELEMENT_ERROR (self, STREAM, DECRYPT, ("Decryption failed"), ("Unsupported encryption scheme = %d", encryption_scheme));
-      goto exit;
-    }
+#if !(defined(ENABLE_CBCS) && ENABLE_CBCS)
+  const char* cipher_mode = gst_structure_get_string(info, "cipher-mode");
+  if ( g_strcmp0(cipher_mode, "cbcs") == 0 ) {
+    GST_ELEMENT_ERROR (self, STREAM, DECRYPT, ("Decryption failed"), ("Unsupported chipher-mode = %s", cipher_mode));
+    goto exit;
   }
+#endif
 
   value = gst_structure_get_value(info, "kid");
   if (!value) {
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 d5ce9a6..79074cb 100644
--- a/src/third_party/starboard/rdk/shared/player/player_internal.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_internal.cc
@@ -124,6 +124,11 @@
       gst_object_unref(GST_OBJECT(factory));
       enable_native_audio = true;
     }
+    else if ((factory = gst_element_factory_find("rialtomseaudiosink"))) {
+      guint rank = gst_plugin_feature_get_rank((GstPluginFeature*)factory);
+      gst_object_unref(GST_OBJECT(factory));
+      enable_native_audio = (rank >= GST_RANK_PRIMARY);
+    }
     g_once_init_leave (&init, 1);
   }
 
@@ -1950,6 +1955,21 @@
       g_object_set(G_OBJECT(element), "async", TRUE, nullptr);
     }
   }
+
+  if ( !self->max_video_capabilities_.empty() ) {
+    const gchar* klass_str =
+      gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (element), "klass");
+    if ( strstr(klass_str, "Sink") && strstr(klass_str, "Video") ) {
+      GObjectClass* oclass = G_OBJECT_GET_CLASS(element);
+      if ( g_object_class_find_property(oclass, "maxVideoWidth") &&
+           g_object_class_find_property(oclass, "maxVideoHeight") ) {
+        uint32_t width = 0, height = 0;
+        ParseMaxVideoCapabilities(self->max_video_capabilities_.c_str(), &width, &height, nullptr);
+        g_object_set(G_OBJECT(element), "maxVideoWidth", width, "maxVideoHeight", height, nullptr);
+      }
+    }
+  }
+
 }
 
 void PlayerImpl::MarkEOS(SbMediaType stream_type) {
@@ -2089,16 +2109,19 @@
             sample_type == kSbMediaTypeVideo ? "video" : "audio");
     SB_DCHECK(drm_system_);
 
-    GST_LOG("Encryption scheme %s",
-            sample_infos[0].drm_info->encryption_scheme == kSbDrmEncryptionSchemeAesCtr ? "Ctr" :
-            (sample_infos[0].drm_info->encryption_scheme == kSbDrmEncryptionSchemeAesCbc ? "Cbc" : "Unknown") );
-
     GstBuffer* subsamples = nullptr;
     GstBuffer* iv = nullptr;
     GstBuffer* key = nullptr;
     uint32_t subsamples_count = 0u;
     uint32_t iv_size = 0u;
+
     const int8_t kEmptyArray[kMaxIvSize / 2] = {0};
+    const auto encryption_scheme = sample_infos[0].drm_info->encryption_scheme;
+    const char* cipher_mode =
+      (encryption_scheme == kSbDrmEncryptionSchemeAesCtr) ? "cenc" :
+      (encryption_scheme == kSbDrmEncryptionSchemeAesCbc  ? "cbcs" : "unknown");
+
+    GST_LOG("Encryption cipher-mode: %s", cipher_mode);
 
     key = gst_buffer_new_allocate(
         nullptr, sample_infos[0].drm_info->identifier_size, nullptr);
@@ -2144,9 +2167,17 @@
       "iv", GST_TYPE_BUFFER, iv,
       "subsample_count", G_TYPE_UINT, subsamples_count,
       "subsamples", GST_TYPE_BUFFER, subsamples,
-      "encryption_scheme", G_TYPE_UINT, sample_infos[0].drm_info->encryption_scheme,
+      "cipher-mode", G_TYPE_STRING, cipher_mode,
       NULL);
 
+    if (encryption_scheme == kSbDrmEncryptionSchemeAesCbc) {
+      const auto& encryption_pattern = sample_infos[0].drm_info->encryption_pattern;
+      gst_structure_set(info,
+        "crypt_byte_block", G_TYPE_UINT, encryption_pattern.crypt_byte_block,
+        "skip_byte_block", G_TYPE_UINT, encryption_pattern.skip_byte_block,
+        NULL);
+    }
+
     gst_buffer_add_protection_meta(buffer, info);
 
     gst_buffer_unref(iv);