amlhwdmx: CB1 add load control for aucpu [1/1]

PD#SWPL-179501

Problem:
audio ts write to fast in vmx dual ts scene
this will cause high load on aucpu
which in turn causes aucpu output all zero audio es data

Solution:
For a single audio secure ts, write 3008 size data to dmx each time
Sleep 10ms after each write

Verify:
(detail info)

Change-Id: If3da84f556554ce47d2454ba2d4dc16f871f1cfd
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/aml-hwdemux/aml_defs.h b/aml-hwdemux/aml_defs.h
index af51a6c..3458450 100644
--- a/aml-hwdemux/aml_defs.h
+++ b/aml-hwdemux/aml_defs.h
@@ -88,6 +88,8 @@
 /** default size **/
 /* dmx section filter buffer size */
 #define SECTION_FILTER_BUF_SIZE 1024 * 1024
+/* dmx sec audio ts segemented size */
+#define AMLHWDMX_SEC_AUDIO_TS_SEGMENTED_BUF_SIZE 3008
 /* dmx es buffer threshold */
 #define AMLHWDMX_SEC_DMC_BUF_SIZE 44 * 1024 * 1024
 #define AMLHWDMX_MAX_ES_BUF_SIZE 10 * 1024 * 1024
@@ -97,7 +99,6 @@
 #define AMLHWDMX_CLEAR_VIDEO_ES_RING_BUF_SIZE AMLHWDMX_MAX_ES_BUF_SIZE
 #define AMLHWDMX_DEFAULT_ES_RING_BUF_SIZE 2 * 1024 * 1024
 #define AMLHWDMX_DEFAULT_LBM_THRESHOLD 200 // ms
-
 /* dmx es buffer head size */
 #define NON_SEC_BUF_HEADER_SIZE (32)
 #define SEC_BUF_HEADER_SIZE (40)
diff --git a/aml-hwdemux/gstamldmx.c b/aml-hwdemux/gstamldmx.c
index 0c4aad0..2a0ee28 100644
--- a/aml-hwdemux/gstamldmx.c
+++ b/aml-hwdemux/gstamldmx.c
@@ -585,6 +585,7 @@
     amlhwdmx->is_live = DEFAULT_IS_LIVE;
     amlhwdmx->is_secure = DEFAULT_IS_SECURE;
     amlhwdmx->is_secure_es = DEFAULT_IS_SECURE_ES;
+    amlhwdmx->is_primary = TRUE;
     amlhwdmx->lb_th = AMLHWDMX_DEFAULT_LBM_THRESHOLD;
     amlhwdmx->caps = NULL;
     amlhwdmx->seek_event = NULL;
@@ -722,12 +723,43 @@
 #else
         struct dmx_sec_ts_data ts_sec_data;
         memset(&ts_sec_data, 0, sizeof(ts_sec_data));
-        ts_sec_data.buf_start = (guint)map.data;
-        ts_sec_data.buf_end = (guint)map.data + map.size;
-        GST_DEBUG_OBJECT(amlhwdmx, "secure mode write buf_start:%p, buf_end:%p, size:%d",
-                         (void *)ts_sec_data.buf_start, (void *)ts_sec_data.buf_end, sizeof(ts_sec_data));
 
-        dmx_ret = gst_amldmxwrap_write(amlhwdmx->dmx_dev_id, (gchar *)(&ts_sec_data), sizeof(ts_sec_data));
+        if (amlhwdmx->is_primary)
+        {
+            ts_sec_data.buf_start = (guint)map.data;
+            ts_sec_data.buf_end = (guint)map.data + map.size;
+            GST_DEBUG_OBJECT(amlhwdmx, "secure mode write buf_start:%p, buf_end:%p, size:%d",
+                            (void *)ts_sec_data.buf_start, (void *)ts_sec_data.buf_end, sizeof(ts_sec_data));
+            dmx_ret = gst_amldmxwrap_write(amlhwdmx->dmx_dev_id, (gchar *)(&ts_sec_data), sizeof(ts_sec_data));
+        }
+        else
+        {
+            ssize_t segmented_size = AMLHWDMX_SEC_AUDIO_TS_SEGMENTED_BUF_SIZE;
+            guint offset = (guint)map.data;
+            ssize_t remaining = map.size;
+
+            while (remaining)
+            {
+                ssize_t write_size = remaining < segmented_size ? remaining : segmented_size;
+                ts_sec_data.buf_start = offset;
+                ts_sec_data.buf_end = offset + write_size;
+
+                dmx_ret = gst_amldmxwrap_write(amlhwdmx->dmx_dev_id, (gchar *)(&ts_sec_data), sizeof(ts_sec_data));
+                if (G_UNLIKELY(DVB_FAILURE == dmx_ret))
+                {
+                    ret = GST_FLOW_ERROR;
+                    goto done;
+
+                }
+                remaining -= write_size;
+                offset += write_size;
+                GST_DEBUG_OBJECT(amlhwdmx, "secure mode write addr:%p, size:%d | sgmented_addr:%p, sgmented_size:%d",
+                                 map.data, map.size, (void *)offset, write_size);
+
+                /* sleep 10ms for aucpu load control in only secure audio ts scene */
+                g_usleep(10 * 1000);
+            }
+        }
 #endif
     }
     else
@@ -815,9 +847,13 @@
     {
         // TODO need check to update is_secure flag
         GstCaps *caps = NULL;
+        GstCapsFeatures *features = NULL;
+        GstStructure *structure = NULL;
+        gboolean is_primary = FALSE;
+
         gst_event_parse_caps(event, &caps);
 
-        GstCapsFeatures *features = gst_caps_get_features(caps, 0);
+        features = gst_caps_get_features(caps, 0);
         if (features &&
                        (gst_caps_features_contains(features, GST_CAPS_FEATURE_SECURE_TS) ||
                         gst_caps_features_contains(features, GST_CAPS_FEATURE_MEMORY_SECMEM_MEMORY)))
@@ -825,7 +861,15 @@
             GST_DEBUG_OBJECT(amlhwdmx, "caps contain feature secure:aes-128");
             amlhwdmx->is_secure = TRUE;
         }
-        GST_DEBUG_OBJECT(amlhwdmx, "caps:%s, is_secure:%d", gst_caps_to_string(caps), amlhwdmx->is_secure);
+
+        structure= gst_caps_get_structure(caps, 0);
+        if (structure && gst_structure_get_boolean( structure, "primary", &is_primary))
+        {
+            amlhwdmx->is_primary = is_primary;
+        }
+        gst_amldmxwrap_set_primary(amlhwdmx->dmx_dev_id, amlhwdmx->is_primary);
+
+        GST_DEBUG_OBJECT(amlhwdmx, "caps:%s, is_secure:%d, is_primary:%d", gst_caps_to_string(caps), amlhwdmx->is_secure, amlhwdmx->is_primary);
         break;
     }
     case GST_EVENT_STREAM_START:
diff --git a/aml-hwdemux/gstamldmx.h b/aml-hwdemux/gstamldmx.h
index 8b7239e..654bdca 100644
--- a/aml-hwdemux/gstamldmx.h
+++ b/aml-hwdemux/gstamldmx.h
@@ -138,6 +138,7 @@
     gboolean is_live;              /* ReadWriteable */
     gboolean is_secure;
     gboolean is_secure_es;
+    gboolean is_primary;
 
     int32_t dmx_dev_id;
 
diff --git a/aml-hwdemux/gstamldmxwrap.c b/aml-hwdemux/gstamldmxwrap.c
index 9f95177..b1bbca7 100644
--- a/aml-hwdemux/gstamldmxwrap.c
+++ b/aml-hwdemux/gstamldmxwrap.c
@@ -76,6 +76,7 @@
     gint dmx_src_fd;
     gint dev_no;
     gint running;
+    gboolean is_primary;
     GstTask *task;
     GRecMutex tlock;
     GMutex lock;
@@ -512,6 +513,24 @@
     return dmxret;
 }
 
+DVB_RESULT gst_amldmxwrap_set_primary(gint dev_no, gboolean is_primary)
+{
+    dvb_dmx_t *dev = NULL;
+    DVB_RESULT dmxret = DVB_SUCCESS;
+
+    if (dmx_get_dev(dev_no, &dev))
+    {
+        GST_DEBUG("demux allocate failed, wrong dmx device no %d", dev_no);
+        return DVB_FAILURE;
+    }
+
+    dev->is_primary = is_primary;
+
+    GST_DEBUG("dmx[%d] dmx_fd:%d, dmx_src_fd:%d, set primary to %d", dev_no, dev->dmx_fd, dev->dmx_src_fd, dev->is_primary);
+
+    return dmxret;
+}
+
 /**\brief write data into dmx
  * \param dmx device number
  * \param data data ptr
@@ -525,6 +544,7 @@
     gchar *offset = 0;
     ssize_t actual_write = 0;
     ssize_t remaining = 0;
+    ssize_t segmented_size = 0;
 
     if (dmx_get_dev(dev_no, &dev))
     {
@@ -534,30 +554,43 @@
 
     offset = data;
     remaining = size;
-    GST_DEBUG("try to write ts data into DMX. offset:%p, size:%d", offset, remaining);
+    if (dev->is_primary)
+        segmented_size = remaining;
+    else
+        segmented_size = AMLHWDMX_SEC_AUDIO_TS_SEGMENTED_BUF_SIZE;
+    GST_DEBUG("try to write ts data into DMX. offset:%p, size:%d, segmented_size:%d", offset, remaining, segmented_size);
     while (remaining)
     {
-        actual_write = write(dev->dmx_src_fd, (const void *)offset, (size_t)remaining);
-        if (actual_write == remaining)
-        {
-            GST_DEBUG("write ts data done.");
-            remaining = 0;
-            dmxret = DVB_SUCCESS;
-            break;
-        }
-        else if (actual_write == -1)
+        ssize_t write_size = remaining < segmented_size ? remaining : segmented_size;
+
+        actual_write = write(dev->dmx_src_fd, (const void *)offset, (size_t)write_size);
+        if (actual_write == -1)
         {
             GST_DEBUG("write ts data error. It is likely to be caused by insufficient es buffer. Need sleep and try again");
             g_usleep(50 * 1000);
         }
-        else if (actual_write < remaining)
+        else if (actual_write <= write_size)
         {
+            if (actual_write == write_size)
+            {
+                GST_DEBUG("write ts data done for this sub sgement.");
+            }
+            else if (actual_write < write_size)
+            {
+                GST_DEBUG("write ts data continue. It is likely to be caused by insufficient es buffer. Need sleep and try again");
+                g_usleep(50 * 1000);
+            }
+
             remaining -= actual_write;
             offset += actual_write;
-            GST_DEBUG("write ts data continue. It is likely to be caused by insufficient es buffer. Need sleep and try again");
-            g_usleep(50 * 1000);
+            if (remaining)
+            {
+                g_usleep(10 * 1000);
+                continue;
+            }
+            GST_DEBUG("write ts data done.");
         }
-        else if (actual_write > remaining)
+        else if (actual_write > write_size)
         {
             GST_ERROR("write ts data out of bounds. Meet real errors");
             dmxret = DVB_FAILURE;
diff --git a/aml-hwdemux/gstamldmxwrap.h b/aml-hwdemux/gstamldmxwrap.h
index 01f7d66..35e8140 100644
--- a/aml-hwdemux/gstamldmxwrap.h
+++ b/aml-hwdemux/gstamldmxwrap.h
@@ -56,6 +56,8 @@
  */
 DVB_RESULT gst_amldmxwrap_set_config(gint dev_no, gboolean is_secure);
 
+DVB_RESULT gst_amldmxwrap_set_primary(gint dev_no, gboolean is_primary);
+
 /**\brief write data into dmx
  * \param dmx device number
  * \param data data ptr