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