amldemux: refine code [1/1]

PD#SWPL-131110

Problem:
cfg dmx video es filter bufsize node
remove mute and unmute osd flow
refine dmx es buf and es ring buf size cfg
refine dmxwrap interface

Solution:
(detail info)

Verify:
(detail info)

Change-Id: I8a73a4859076c25da9122ce952f286fd7159fa09
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/src/amlSetting.hpp b/src/amlSetting.hpp
deleted file mode 100644
index bc529a9..0000000
--- a/src/amlSetting.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* GStreamer
- * Copyright (C) 2023 <xuesong.jiang@amlogic.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-static int set_osd_blank(int blank)
-{
-    const char *path1 = "/sys/class/graphics/fb0/blank";
-    const char *path3 = "/sys/class/graphics/fb0/osd_display_debug";
-    int fd;
-    char cmd[128] = {0};
-
-    fd = open(path3, O_CREAT | O_RDWR | O_TRUNC, 0644);
-    if (fd >= 0)
-    {
-        sprintf(cmd, "%d", blank);
-        write(fd, cmd, strlen(cmd));
-        close(fd);
-    }
-    fd = open(path1, O_CREAT | O_RDWR | O_TRUNC, 0644);
-    if (fd >= 0)
-    {
-        sprintf(cmd, "%d", blank);
-        write(fd, cmd, strlen(cmd));
-        close(fd);
-    }
-    return 0;
-}
-
-static int amsysfs_set_sysfs_str(const char *path, const char *val)
-{
-    int fd;
-    fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
-    if (fd >= 0)
-    {
-        write(fd, val, strlen(val));
-        close(fd);
-        return 0;
-    }
-    return -1;
-}
-
-static int set_dmx_source()
-{
-    amsysfs_set_sysfs_str("/sys/class/stb/source", "dmx0");
-    amsysfs_set_sysfs_str("/sys/class/stb/demux0_source", "hiu");
-    return 0;
-}
\ No newline at end of file
diff --git a/src/aml_defs.h b/src/aml_defs.h
index 3bee998..68c809b 100644
--- a/src/aml_defs.h
+++ b/src/aml_defs.h
@@ -50,6 +50,10 @@
 /** dmx es buffer threshold **/
 #define AMLHWDMX_MAX_ES_BUF_SIZE 10 * 1024 * 1024
 #define AMLHWDMX_MIN_ES_BUF_SIZE 4 * 1024 * 1024
+/** dmx es ring buffer threshold **/
+#define AMLHWDMX_CLEAR_VIDEO_ES_RING_BUF_SIZE AMLHWDMX_MAX_ES_BUF_SIZE
+#define AMLHWDMX_DEFAULT_ES_RING_BUF_SIZE 2 * 1024 * 1024
+
 /* clear adaptor size */
 #define MAX_BUFFER_SIZE (AMLHWDMX_MAX_ES_BUF_SIZE / 188 * 188)
 #define LOW_BUFFER_SIZE (188 * 10)
diff --git a/src/gstamldmx.c b/src/gstamldmx.c
index 126f4ec..75fa6f7 100644
--- a/src/gstamldmx.c
+++ b/src/gstamldmx.c
@@ -26,13 +26,12 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#include <sys/ioctl.h>
+#include <stdio.h>
 #include "gstamldmx.h"
 #include "gstamldmxfilter.h"
 #include "gstamldmxwrap.h"
 #include "gst/allocators/gstsecmemallocator.h"
 #include "aml_defs.h"
-#include "amlSetting.hpp"
 
 #define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf"
 #define GST_CAPS_FEATURE_SECURE_TS "secure:AesEnc"
@@ -89,11 +88,10 @@
 static void gst_amlhwdmx_start_es_streams(GstAmlhwdmx *amlhwdmx);
 static void gst_amlhwdmx_wait(GstAmlhwdmx *amlhwdmx);
 static gboolean gst_amlhwdmx_write(GstAmlhwdmx *amlhwdmx, GstBuffer *buffer);
-static gboolean gst_amlhwdmx_check_filters_mem_status_test(GstAmlhwdmx *amlhwdmx);
+static gboolean gst_amlhwdmx_check_filters_mem_status(GstAmlhwdmx *amlhwdmx);
 static void gst_amlhwdmx_update_pts_cb(gpointer elem, guint64 pts, gpointer user_data);
 static void gst_amlhwdmx_dump_es(GstDmxSrcStreamPad *srcpad, GstBuffer *buf);
 static void gst_amlhwdmx_dump_ts(GstBuffer *buffer, const char *file_name);
-static guint gst_amlhwdmx_convert_type_gst2dmx(GstStreamType type);
 
 /* Properties */
 enum
@@ -118,29 +116,19 @@
 gst_amlhwdmx_change_state(GstElement *element, GstStateChange transition)
 {
     GstStateChangeReturn ret;
+    gint dmxret;
 
     GstAmlhwdmx *amlhwdmx = GST_AMLHWDMX(element);
+    ret = GST_STATE_CHANGE_SUCCESS;
+    dmxret = 0;
+
     switch (transition)
     {
     case GST_STATE_CHANGE_NULL_TO_READY:
     {
-        int dmxret = 0;
-        char node[32] = {0};
-        char node2[20] = {0};
-
-        set_osd_blank(1);
-        set_dmx_source();
-
-
-        snprintf(node, sizeof(node), "/dev/dvb0.dvr%d", amlhwdmx->dmx_dev_id);
-        snprintf(node2, sizeof(node2), "/dev/dvb0.demux%d", amlhwdmx->dmx_dev_id);
-        amlhwdmx->dmx_src_fd = open(node, O_WRONLY);
-        amlhwdmx->dmx_fd = open(node2, O_RDONLY);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_NULL_TO_READY | open dvr fd:%d, dmx fd:%d", amlhwdmx->dmx_src_fd, amlhwdmx->dmx_fd);
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_NULL_TO_READY");
 
         dmxret = gst_amldmxwrap_open(amlhwdmx->dmx_dev_id);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_NULL_TO_READY | gst_amldmxwrap_open ret:%d", dmxret);
-
         break;
     }
     case GST_STATE_CHANGE_READY_TO_PAUSED:
@@ -149,27 +137,12 @@
 
         amlhwdmx->flags |= GST_AML_DMX_PROB;
 
-        int dmxret = 0;
-        GST_LOG_OBJECT(amlhwdmx, "set secure mode:%d to hw dmx", amlhwdmx->is_secure);
-        if (amlhwdmx->is_secure)
-        {
-            dmxret |= ioctl(amlhwdmx->dmx_src_fd, DMX_SET_INPUT, INPUT_LOCAL_SEC);
-            dmxret |= ioctl(amlhwdmx->dmx_fd, DMX_SET_INPUT, INPUT_LOCAL_SEC);
-            dmxret |= ioctl(amlhwdmx->dmx_fd, DMX_SET_HW_SOURCE, DMA_0);
-        }
-        else
-        {
-            dmxret |= ioctl(amlhwdmx->dmx_src_fd, DMX_SET_INPUT, INPUT_LOCAL);
-            dmxret |= ioctl(amlhwdmx->dmx_fd, DMX_SET_INPUT, INPUT_LOCAL);
-            dmxret |= ioctl(amlhwdmx->dmx_fd, DMX_SET_HW_SOURCE, DMA_0);
-        }
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | dvb_set_demux_source ret:%d", dmxret);
+        dmxret = gst_amldmxwrap_set_config(amlhwdmx->dmx_dev_id, amlhwdmx->is_secure);
 
         /*set PAT filter for HW demux*/
-        dmxret = gst_amldmxwrap_alloc_filter(amlhwdmx->dmx_dev_id, &amlhwdmx->sinkpad.pat_para.fid);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_alloc_filter ret:%d pat_fid:%d", dmxret, amlhwdmx->sinkpad.pat_para.fid);
-        dmxret = gst_amldmxwrap_set_cb(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, gst_parse_pat_cb, amlhwdmx);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_set_cb ret:%d", dmxret);
+        dmxret |= gst_amldmxwrap_alloc_filter(amlhwdmx->dmx_dev_id, &amlhwdmx->sinkpad.pat_para.fid);
+        dmxret |= gst_amldmxwrap_set_cb(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, gst_parse_pat_cb, amlhwdmx);
+
         memset(&amlhwdmx->sinkpad.pat_para.filter_para, 0, sizeof(amlhwdmx->sinkpad.pat_para.filter_para));
         amlhwdmx->sinkpad.pat_para.filter_para.pid = 0;
         amlhwdmx->sinkpad.pat_para.filter_para.filter.filter[0] = 0;
@@ -177,14 +150,11 @@
         amlhwdmx->sinkpad.pat_para.filter_para.flags = DMX_CHECK_CRC;
         if (amlhwdmx->is_secure)
             amlhwdmx->sinkpad.pat_para.filter_para.flags |= DMX_MEM_SEC_LEVEL2;
-        dmxret = gst_amldmxwrap_sec_secfilter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, &amlhwdmx->sinkpad.pat_para.filter_para);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_sec_secfilter ret:%d", dmxret);
-        dmxret = gst_amldmxwrap_set_bufsize(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, SECTION_FILTER_BUF_SIZE);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_set_bufsize ret:%d", dmxret);
+        dmxret |= gst_amldmxwrap_sec_secfilter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, &amlhwdmx->sinkpad.pat_para.filter_para);
+        dmxret |= gst_amldmxwrap_set_bufsize(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, SECTION_FILTER_BUF_SIZE);
 
         /*start PAT filter for HW demux*/
-        dmxret = gst_amldmxwrap_start_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_start_filter ret:%d", dmxret);
+        dmxret |= gst_amldmxwrap_start_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid);
 
         if (amlhwdmx->suf & GST_INIT_PLAY)
         {
@@ -195,18 +165,22 @@
     }
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
     {
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_PAUSED_TO_PLAYING");
         break;
     }
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
     {
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_PLAYING_TO_PAUSED");
         break;
     }
     case GST_STATE_CHANGE_PAUSED_TO_READY:
     {
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_PAUSED_TO_READY");
         break;
     }
     case GST_STATE_CHANGE_READY_TO_NULL:
     {
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_NULL");
         gst_amlhwdmx_reset(amlhwdmx);
         gst_amldmxwrap_close(0);
         break;
@@ -215,8 +189,15 @@
         break;
     }
 
+    if (-1 == dmxret)
+    {
+        ret = GST_STATE_CHANGE_FAILURE;
+        goto done;
+    }
+
     ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
 
+done:
     return ret;
 }
 /* GObject vmethod implementations */
@@ -316,8 +297,6 @@
     }
     amlhwdmx->sinkpad.decoded_pts = GST_CLOCK_TIME_NONE;
 
-    amlhwdmx->dmx_src_fd = -1;
-    amlhwdmx->dmx_fd = -1;
     amlhwdmx->srcpad_num = 0;
     amlhwdmx->fd_allocator = NULL;
     gst_amlhwdmx_reset(amlhwdmx);
@@ -329,7 +308,6 @@
     amlhwdmx->sinkpad.task = gst_task_new((GstTaskFunction)gst_amlhwdmx_loop, amlhwdmx, NULL); // push mode
     g_rec_mutex_init(&amlhwdmx->sinkpad.task_lock);
     gst_task_set_lock(amlhwdmx->sinkpad.task, &amlhwdmx->sinkpad.task_lock);
-    GST_DEBUG_OBJECT(amlhwdmx, "trace out");
 }
 
 static void gst_amlhwdmx_dispose(GObject *object)
@@ -490,23 +468,12 @@
 
 static void gst_amlhwdmx_reset(GstAmlhwdmx *amlhwdmx)
 {
-    GST_DEBUG_OBJECT(amlhwdmx, "trace in");
     // reset filter
     gst_es_filter_reset(amlhwdmx);
     gst_pmt_filter_reset(amlhwdmx);
     gst_pat_filter_reset(amlhwdmx);
     GST_DEBUG_OBJECT(amlhwdmx, "after reset PAT & PMT & ES filter");
 
-    if (amlhwdmx->dmx_fd > 0)
-    {
-        close(amlhwdmx->dmx_fd);
-        amlhwdmx->dmx_fd = -1;
-    }
-    if (amlhwdmx->dmx_src_fd > 0)
-    {
-        close(amlhwdmx->dmx_src_fd);
-        amlhwdmx->dmx_src_fd = -1;
-    }
     amlhwdmx->dmx_dev_id = 0;
     amlhwdmx->audio_stream_num = 0;
     amlhwdmx->selected_program_no = DEFAULT_PROGRAM_NO;
@@ -536,30 +503,38 @@
     amlhwdmx->caps = NULL;
     amlhwdmx->seek_event = NULL;
     amlhwdmx->needQueryTsInfo = TRUE;
-
-    set_osd_blank(0);
-    GST_DEBUG_OBJECT(amlhwdmx, "trace out");
 }
 
 static void gst_amlhwdmx_start_es_streams(GstAmlhwdmx *amlhwdmx)
 {
     int dmxret = 0;
     gint *es_fid = NULL;
+    guint es_ring_buf_size = 0;
     struct dmx_pes_filter_params *es_fpara = NULL;
 
     for (gint i = 0; i < amlhwdmx->srcpad_num; i++)
     {
+        if (GST_STREAM_TYPE_VIDEO == amlhwdmx->srcpads[i].stream_type)
+        {
+            dmxret = gst_amldmxwrap_set_video_filters_es_buf_size(AMLHWDMX_MAX_ES_BUF_SIZE); // set video es fitlter buf size to AMLHWDMX_MAX_ES_BUF_SIZE
+            GST_DEBUG_OBJECT(amlhwdmx, "stream[%d] find video es filter. set filter buf size to:%d ret:%d", i, AMLHWDMX_MAX_ES_BUF_SIZE, dmxret);
+        }
 
         es_fid = &amlhwdmx->srcpads[i].es_fid;
         es_fpara = &amlhwdmx->srcpads[i].es_fpara;
 
         dmxret = gst_amldmxwrap_set_pesfilter(amlhwdmx->dmx_dev_id, *es_fid, es_fpara);
-        GST_DEBUG_OBJECT(amlhwdmx, "stream[%d] gst_amldmxwrap_set_pesfilter ret:%d, pmt_fid:%d, es pid:%d",
+        GST_DEBUG_OBJECT(amlhwdmx, "stream[%d] set pesfilter ret:%d, pmt_fid:%d, es pid:%d",
                          i, dmxret, *es_fid, es_fpara->pid);
-        dmxret = gst_amldmxwrap_set_filter_buf(amlhwdmx->dmx_dev_id, *es_fid, AMLHWDMX_MAX_ES_BUF_SIZE);
-        GST_DEBUG_OBJECT(amlhwdmx, "stream[%d] gst_amldmxwrap_set_filter_buf ret:%d", i, dmxret);
+
+        if (!amlhwdmx->is_secure && GST_STREAM_TYPE_VIDEO == amlhwdmx->srcpads[i].stream_type)
+            es_ring_buf_size = AMLHWDMX_CLEAR_VIDEO_ES_RING_BUF_SIZE;
+        else
+            es_ring_buf_size = AMLHWDMX_DEFAULT_ES_RING_BUF_SIZE;
+        dmxret = gst_amldmxwrap_set_filter_ring_buf_size(amlhwdmx->dmx_dev_id, *es_fid, es_ring_buf_size);
+        GST_DEBUG_OBJECT(amlhwdmx, "stream[%d] set filter ring buf size:%d ret:%d", i, es_ring_buf_size, dmxret);
         dmxret = gst_amldmxwrap_start_filter(amlhwdmx->dmx_dev_id, *es_fid);
-        GST_DEBUG_OBJECT(amlhwdmx, "es[%d] gst_amldmxwrap_start_filter ret:%d", i, dmxret);
+        GST_DEBUG_OBJECT(amlhwdmx, "es[%d] start filter ret:%d", i, dmxret);
 
         gst_pad_start_task(amlhwdmx->srcpads[i].pad, (GstTaskFunction)gst_amlhwdmx_src_loop, &amlhwdmx->srcpads[i], NULL);
     }
@@ -569,9 +544,9 @@
 {
     while (!(amlhwdmx->flags & GST_AML_DMX_FLUSHING))
     {
-        if (gst_amlhwdmx_check_filters_mem_status_test(amlhwdmx))
+        if (gst_amlhwdmx_check_filters_mem_status(amlhwdmx))
             break;
-        usleep(50 * 1000);
+        g_usleep(50 * 1000);
         GST_DEBUG_OBJECT(amlhwdmx, "waitting for filters mem");
     }
 }
@@ -581,6 +556,7 @@
     GstMapInfo map;
     GstFlowReturn ret = GST_FLOW_OK;
     ssize_t actual_write = 0;
+    DVB_RESULT dmx_ret = DVB_SUCCESS;
 
     ret = gst_amlhwdmx_buffer_map(amlhwdmx, buffer, &map);
     if (ret != GST_FLOW_OK)
@@ -593,64 +569,27 @@
 
     if (amlhwdmx->is_secure)
     {
-        GST_DEBUG_OBJECT(amlhwdmx, "dbg");
         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 / 188 * 188;
-        // TODO:need check if data size is not integer multiple of 188
+        ts_sec_data.buf_start = (guint)map.data; // TODO:need check if data size is not integer multiple of 188
         ts_sec_data.buf_end = (guint)map.data + map.size;
-        GST_DEBUG_OBJECT(amlhwdmx, "map.data:0x%p", map.data);
-
         GST_DEBUG_OBJECT(amlhwdmx, "secure mode write buf_start:%p, buf_end:%p, size:%d, actual_write:%d",
                          (void *)ts_sec_data.buf_start, (void *)ts_sec_data.buf_end, sizeof(ts_sec_data), actual_write);
 
-        GST_DEBUG_OBJECT(amlhwdmx, "before write");
-        actual_write = write(amlhwdmx->dmx_src_fd, (const void *)(&ts_sec_data), sizeof(ts_sec_data));
-        GST_DEBUG_OBJECT(amlhwdmx, "after write");
+        dmx_ret = gst_amldmxwrap_write(amlhwdmx->dmx_dev_id, (gchar *)(&ts_sec_data), sizeof(ts_sec_data));
     }
     else
     {
-#if 0
-        /* dump ts data before inject into DMX */
-        FILE *fd = fopen("/data/test/write.ts", "ab");
-        fwrite(map.data, 1, map.size, fd);
-        fclose(fd);
-#endif
-
-        gchar *offset = (gchar *)map.data;
-        ssize_t remaining = map.size;
-        GST_DEBUG_OBJECT(amlhwdmx, "try to write ts data into DMX. buf:%p, offset:%p, size:%d dvr fd:%d", buffer, offset, remaining, amlhwdmx->dmx_src_fd);
-        while (remaining)
-        {
-            actual_write = write(amlhwdmx->dmx_src_fd, (const void *)offset, (size_t)remaining);
-            if (actual_write == remaining)
-            {
-                GST_DEBUG_OBJECT(amlhwdmx, "write ts data done.");
-                remaining = 0;
-                break;
-            }
-            else if (actual_write == -1)
-            {
-                GST_DEBUG_OBJECT(amlhwdmx, "write ts data error. It is likely to be caused by insufficient es buffer. Need sleep and try again");
-                usleep(50 * 1000);
-            }
-            else if (actual_write < remaining)
-            {
-                remaining -= actual_write;
-                offset += actual_write;
-                GST_DEBUG_OBJECT(amlhwdmx, "write ts data continue. It is likely to be caused by insufficient es buffer. Need sleep and try again");
-                usleep(50 * 1000);
-            }
-            else if (actual_write > remaining)
-            {
-                GST_ERROR_OBJECT(amlhwdmx, "write ts data out of bounds. Meet real errors");
-                break;
-            }
-        }
+        GST_DEBUG_OBJECT(amlhwdmx, "try to write ts data into DMX. buf:%p, data:%p, size:%d", buffer, (gchar *)map.data, map.size);
+        dmx_ret = gst_amldmxwrap_write(amlhwdmx->dmx_dev_id, (gchar *)map.data, map.size);
     }
+
+    if (DVB_FAILURE == dmx_ret)
+        ret = GST_FLOW_ERROR;
+
     gst_amlhwdmx_buffer_unmap(amlhwdmx, buffer, &map);
 done:
+    GST_DEBUG_OBJECT(amlhwdmx, "write buf ret:%d", ret);
     return ret;
 }
 
@@ -662,7 +601,6 @@
     gboolean result = TRUE;
 
     GST_DEBUG_OBJECT(amlhwdmx, "event: %" GST_PTR_FORMAT, event);
-    g_print("event: %s\n", GST_EVENT_TYPE_NAME(event));
 
     switch (GST_EVENT_TYPE(event))
     {
@@ -875,8 +813,6 @@
         res = gst_task_join(amlhwdmx->sinkpad.task);
     }
 
-    GST_DEBUG("trace in active:%d, res:%d", active, res);
-
     return res;
 }
 
@@ -897,7 +833,6 @@
         res = gst_pad_stop_task(sinkpad);
         amlhwdmx->seekable = FALSE;
     }
-    GST_DEBUG("trace in res:%d", res);
 
     return res;
 }
@@ -1121,7 +1056,6 @@
 
     GST_DEBUG_OBJECT(sinkpad, "got buf:%p size:%d, pts: %" GST_TIME_FORMAT,
                      buffer, gst_buffer_get_size(buffer), GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
-    g_print("sink | got  buf:%p size:%d\n", buffer, gst_buffer_get_size(buffer));
 
     // gst_amlhwdmx_dump_ts(buffer, "/data/test/chain.ts");
 
@@ -1396,22 +1330,7 @@
     return res;
 }
 
-static guint gst_amlhwdmx_convert_type_gst2dmx(GstStreamType type)
-{
-    switch (type)
-    {
-    case GST_STREAM_TYPE_VIDEO:
-        return DMX_VIDEO_TYPE;
-    case GST_STREAM_TYPE_AUDIO:
-        return DMX_AUDIO_TYPE;
-    case GST_STREAM_TYPE_TEXT:
-        return DMX_SUBTITLE_TYPE;
-    default:
-        return DMX_SECTION_TYPE;
-    }
-}
-
-static gboolean gst_amlhwdmx_check_filters_mem_status_test(GstAmlhwdmx *amlhwdmx)
+static gboolean gst_amlhwdmx_check_filters_mem_status(GstAmlhwdmx *amlhwdmx)
 {
     struct dmx_filter_mem_info info_all;
     gboolean ret = TRUE;
@@ -1419,7 +1338,7 @@
     gboolean mem_check_result = TRUE;
 
     memset(&info_all, 0, sizeof(struct dmx_filter_mem_info));
-    if (-1 == gst_amldmxwrap_get_filters_mem_info(amlhwdmx->dmx_fd, &info_all))
+    if (-1 == gst_amldmxwrap_get_filters_mem_info(amlhwdmx->dmx_dev_id, &info_all))
     {
         GST_ERROR_OBJECT(amlhwdmx, "check fail(get mem info failed error:%s)", strerror(errno));
         return FALSE;
@@ -1521,7 +1440,7 @@
     if (NULL == amlhwdmx->sinkpad.adapter_pipe)
     {
         GST_DEBUG_OBJECT(amlhwdmx, "Waiting for initialization sink adapter pipe");
-        usleep(50 * 1000);
+        g_usleep(50 * 1000);
         ret = GST_FLOW_CUSTOM_SUCCESS;
         goto done;
     }
@@ -1690,11 +1609,6 @@
                      gst_buffer_get_size(buf),
                      GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
                      GST_TIME_ARGS(GST_BUFFER_DURATION(buf)));
-    g_print("src  | push buf:%p (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")\n",
-            buf,
-            gst_buffer_get_size(buf),
-            GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
-            GST_TIME_ARGS(GST_BUFFER_DURATION(buf)));
 
     srcpad->newest_pts = GST_BUFFER_PTS(buf);
 
@@ -1715,20 +1629,15 @@
     //         return;
 
     //     GST_ERROR_OBJECT(amlhwdmx, "before write");
-    //     g_print("jxsdbgaaaa before write\n");
     //     if (buf)
     //     {
 
-    //         g_print("jxsdbgaaaa before map\n");
     //         memset(&map, 0, sizeof(map));
     //         gst_buffer_map(buf, &map, GST_MAP_READ);
-    //         g_print("jxsdbgaaaa map.data:%p, map.size:%d\n", map.data, map.size);
     //         fwrite(map.data, 1, map.size, fd);
     //         gst_buffer_unmap(buf, &map);
     //     }
 
-    //     g_print("jxsdbgaaaa after write\n");
-
     //     fclose(fd);
     // }
 
diff --git a/src/gstamldmx.h b/src/gstamldmx.h
index e10eff4..f04d9bb 100644
--- a/src/gstamldmx.h
+++ b/src/gstamldmx.h
@@ -132,8 +132,6 @@
     gboolean is_secure_es;
 
     int32_t dmx_dev_id;
-    int32_t dmx_fd;
-    int32_t dmx_src_fd;
 
     /* params of stream info */
     gint audio_stream_num;
diff --git a/src/gstamldmxfilter.c b/src/gstamldmxfilter.c
index 3151a74..64ff36b 100644
--- a/src/gstamldmxfilter.c
+++ b/src/gstamldmxfilter.c
@@ -227,19 +227,15 @@
     //         return;
 
     //     GST_ERROR_OBJECT(amlhwdmx, "before write");
-    //     g_print("jxsdbgaaaa before write\n");
     //     if(buf)
     //     {
 
-    //         g_print("jxsdbgaaaa before map\n");
     //         memset(&map, 0, sizeof(map));
     //         gst_buffer_map(buf, &map, GST_MAP_READ);
-    //         g_print("jxsdbgaaaa map.data:%p, map.size:%d\n", map.data, map.size);
     //         fwrite(map.data, 1, map.size, fd);
     //         gst_buffer_unmap(buf, &map);
     //     }
 
-    //     g_print("jxsdbgaaaa after write\n");
 
     //     fclose(fd);
     // }
@@ -398,7 +394,7 @@
     if (sec_data->pts_dts_flag & 0x1)
         GST_BUFFER_DTS(buf) = sec_data->dts / 90 * GST_MSECOND;
 
-    GST_DEBUG_OBJECT(amlhwdmx, "jxsdbg sec_data->pts:%llu, sec_data->dts:%llu, GST_BUFFER_PTS(buf):%llu, GST_BUFFER_DTS(buf):%llu",
+    GST_DEBUG_OBJECT(amlhwdmx, "sec_data->pts:%llu, sec_data->dts:%llu, GST_BUFFER_PTS(buf):%llu, GST_BUFFER_DTS(buf):%llu",
                      sec_data->pts, sec_data->dts,
                      GST_BUFFER_PTS(buf), GST_BUFFER_DTS(buf));
 
@@ -511,7 +507,7 @@
         data_end = data_start + data_size;
 
         GST_MEMDUMP_OBJECT(amlhwdmx, "non-sec-header: ", (const guint8 *)non_secure_es, sizeof(struct dmx_non_sec_es_header));
-        GST_DEBUG_OBJECT(amlhwdmx, "jxsdbg | offset:0x%x | pts_dts_flag:%d, pts:0x%llx, dts:0x%llx | data[%p-%p], data_size:%d",
+        GST_DEBUG_OBJECT(amlhwdmx, "offset:0x%x | pts_dts_flag:%d, pts:0x%llx, dts:0x%llx | data[%p-%p], data_size:%d",
                          offset, pts_dts_flag, pts, dts, (void *)data_start, (void *)data_end, data_size);
         offset = offset + sizeof(struct dmx_non_sec_es_header) + data_size;
     }
diff --git a/src/gstamldmxwrap.c b/src/gstamldmxwrap.c
index 6c524cd..17f4852 100644
--- a/src/gstamldmxwrap.c
+++ b/src/gstamldmxwrap.c
@@ -54,6 +54,8 @@
 
 typedef struct
 {
+    gint dmx_fd;
+    gint dmx_src_fd;
     gint dev_no;
     gint running;
     pthread_t thread;
@@ -64,6 +66,26 @@
 
 static dvb_dmx_t dmx_devices[DMX_COUNT];
 
+static int amsysfs_set_sysfs_str(const char *path, const char *val)
+{
+    int fd;
+    fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
+    if (fd >= 0)
+    {
+        write(fd, val, strlen(val));
+        close(fd);
+        return 0;
+    }
+    return -1;
+}
+
+static int set_dmx_source()
+{
+    amsysfs_set_sysfs_str("/sys/class/stb/source", "dmx0");
+    amsysfs_set_sysfs_str("/sys/class/stb/demux0_source", "hiu");
+    return 0;
+}
+
 static inline DVB_RESULT dmx_get_dev(gint dev_no, dvb_dmx_t **dev)
 {
     if ((dev_no < 0) || (dev_no >= DMX_COUNT))
@@ -124,8 +146,8 @@
 
         if (!cnt)
         {
-            // usleep(20 * 1000);
-            usleep(1000);
+            // g_usleep(20 * 1000);
+            g_usleep(1000);
             continue;
         }
 
@@ -203,6 +225,8 @@
 DVB_RESULT gst_amldmxwrap_open(gint dev_no)
 {
     dvb_dmx_t *dev = NULL;
+    char node[32] = {0};
+    char node2[20] = {0};
 
     if (dmx_get_dev(dev_no, &dev))
         return DVB_FAILURE;
@@ -213,8 +237,19 @@
         return DVB_FAILURE;
     }
 
-    dev->dev_no = dev_no;
+    set_dmx_source();
 
+    snprintf(node, sizeof(node), "/dev/dvb0.dvr%d", dev_no);
+    snprintf(node2, sizeof(node2), "/dev/dvb0.demux%d", dev_no);
+    dev->dmx_src_fd = open(node, O_WRONLY);
+    dev->dmx_fd = open(node2, O_RDONLY);
+    if (dev->dmx_src_fd < 0 || dev->dmx_fd < 0)
+    {
+        GST_DEBUG("open dmx device fail");
+        return DVB_FAILURE;
+    }
+
+    dev->dev_no = dev_no;
     pthread_mutex_init(&dev->lock, NULL);
     dev->running = 1;
     pthread_create(&dev->thread, NULL, gst_amldmxwrap_data_thread, dev);
@@ -222,6 +257,94 @@
     return DVB_SUCCESS;
 }
 
+/**\brief set dmx config
+ * \param dmx device number
+ * \param is secure scenes
+ * \return DVB_SUCCESS On success, DVB_FAILURE on error.
+ */
+DVB_RESULT gst_amldmxwrap_set_config(gint dev_no, gboolean is_secure)
+{
+    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;
+    }
+
+    if (is_secure)
+    {
+        dmxret |= ioctl(dev->dmx_src_fd, DMX_SET_INPUT, INPUT_LOCAL_SEC);
+        dmxret |= ioctl(dev->dmx_fd, DMX_SET_INPUT, INPUT_LOCAL_SEC);
+        dmxret |= ioctl(dev->dmx_fd, DMX_SET_HW_SOURCE, DMA_0);
+    }
+    else
+    {
+        dmxret |= ioctl(dev->dmx_src_fd, DMX_SET_INPUT, INPUT_LOCAL);
+        dmxret |= ioctl(dev->dmx_fd, DMX_SET_INPUT, INPUT_LOCAL);
+        dmxret |= ioctl(dev->dmx_fd, DMX_SET_HW_SOURCE, DMA_0);
+    }
+
+    return dmxret;
+}
+
+/**\brief write data into dmx
+ * \param dmx device number
+ * \param data data ptr
+ * \param size data size
+ * \return DVB_SUCCESS On success, DVB_FAILURE on error.
+ */
+DVB_RESULT gst_amldmxwrap_write(gint dev_no, gchar *data, guint size)
+{
+    dvb_dmx_t *dev = NULL;
+    DVB_RESULT dmxret = DVB_SUCCESS;
+    gchar *offset = 0;
+    ssize_t actual_write = 0;
+    ssize_t remaining = 0;
+
+    if (dmx_get_dev(dev_no, &dev))
+    {
+        GST_DEBUG("demux allocate failed, wrong dmx device no %d", dev_no);
+        return DVB_FAILURE;
+    }
+
+    offset = data;
+    remaining = size;
+    GST_DEBUG("try to write ts data into DMX. offset:%p, size:%d", offset, remaining);
+    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)
+        {
+            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)
+        {
+            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);
+        }
+        else if (actual_write > remaining)
+        {
+            GST_ERROR("write ts data out of bounds. Meet real errors");
+            dmxret = DVB_FAILURE;
+            break;
+        }
+    }
+    GST_DEBUG("write return:%d", dmxret);
+    return dmxret;
+}
+
 /**\brief allocate dmx filter
  * \param dmx device number
  * \param get dmx filter index
@@ -609,6 +732,18 @@
     pthread_mutex_unlock(&dev->lock);
     pthread_mutex_destroy(&dev->lock);
 
+    if (dev->dmx_fd >= 0)
+    {
+        close(dev->dmx_fd);
+        dev->dmx_fd = -1;
+    }
+
+    if (dev->dmx_src_fd >= 0)
+    {
+        close(dev->dmx_src_fd);
+        dev->dmx_src_fd = -1;
+    }
+
     GST_INFO("trace out");
     return ret;
 }
@@ -677,10 +812,18 @@
     return DVB_SUCCESS;
 }
 
-DVB_RESULT gst_amldmxwrap_get_filters_mem_info(int32_t dev_fd, struct dmx_filter_mem_info *info_all)
+DVB_RESULT gst_amldmxwrap_get_filters_mem_info(gint dev_no, struct dmx_filter_mem_info *info_all)
 {
+    dvb_dmx_t *dmx = NULL;
+
+    if (dmx_get_dev(dev_no, &dmx))
+    {
+        GST_ERROR("get dmx error");
+        return DVB_FAILURE;
+    }
+
     memset(info_all, 0, sizeof(struct dmx_filter_mem_info));
-    if (ioctl(dev_fd, DMX_GET_FILTER_MEM_INFO, info_all) < 0)
+    if (ioctl(dmx->dmx_fd, DMX_GET_FILTER_MEM_INFO, info_all) < 0)
     {
         GST_ERROR("dmx filter get mem info fail(%s) %d", strerror(errno), errno);
         return DVB_FAILURE;
@@ -701,7 +844,23 @@
     return DVB_SUCCESS;
 }
 
-DVB_RESULT gst_amldmxwrap_set_filter_buf(gint dev_no, gint fhandle, guint size)
+DVB_RESULT gst_amldmxwrap_set_video_filters_es_buf_size(guint size)
+{
+    const char *path = "/sys/module/dvb_demux/parameters/video_buf_size";
+    gint fd;
+    gchar cmd[128] = {0};
+
+    fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
+    if (fd < 0)
+        return DVB_FAILURE;
+
+    sprintf(cmd, "%d", size);
+    write(fd, cmd, strlen(cmd));
+    close(fd);
+    return DVB_SUCCESS;
+}
+
+DVB_RESULT gst_amldmxwrap_set_filter_ring_buf_size(gint dev_no, gint fhandle, guint size)
 {
     dvb_dmx_t *dmx = NULL;
     dvb_dmx_filter_t *filter = NULL;
diff --git a/src/gstamldmxwrap.h b/src/gstamldmxwrap.h
index 160965a..b7ea507 100644
--- a/src/gstamldmxwrap.h
+++ b/src/gstamldmxwrap.h
@@ -46,6 +46,21 @@
  */
 DVB_RESULT gst_amldmxwrap_close(gint dev_no);
 
+/**\brief set dmx config
+ * \param dmx device number
+ * \param is secure scenes
+ * \return DVB_SUCCESS On success, DVB_FAILURE on error.
+ */
+DVB_RESULT gst_amldmxwrap_set_config(gint dev_no, gboolean is_secure);
+
+/**\brief write data into dmx
+ * \param dmx device number
+ * \param data data ptr
+ * \param size data size
+ * \return DVB_SUCCESS On success, DVB_FAILURE on error.
+ */
+DVB_RESULT gst_amldmxwrap_write(gint dev_no, gchar *data, guint size);
+
 /**\brief allocate dmx filter
  * \param dmx device number
  * \param get dmx filter index
@@ -114,7 +129,9 @@
  */
 DVB_RESULT gst_amldmxwrap_get_es(gint dev_no, gint fhandle, guint8 *data, guint size);
 
-DVB_RESULT gst_amldmxwrap_get_filters_mem_info(int32_t dev_fd, struct dmx_filter_mem_info *info_all);
+DVB_RESULT gst_amldmxwrap_get_filters_mem_info(gint dev_no, struct dmx_filter_mem_info *info_all);
 
-DVB_RESULT gst_amldmxwrap_set_filter_buf(gint dev_no, gint fhandle, guint size);
+DVB_RESULT gst_amldmxwrap_set_video_filters_es_buf_size(guint size);
+
+DVB_RESULT gst_amldmxwrap_set_filter_ring_buf_size(gint dev_no, gint fhandle, guint size);
 #endif /* __GST_AML_DMX_WRAP_H__ */
\ No newline at end of file