amldemux: CF1 integration amldemux into aamp pipe [1/2]

PD#SWPL-131110

Problem:
integration amldemux into aamp pipe

Solution:
integration amldemux into aamp pipe

Verify:
(detail info)

Change-Id: Ic8522d23f1c8fe4aa8f49bc0fca5b306962d5c24
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/src/aml_defs.h b/src/aml_defs.h
index 328dc85..3bee998 100644
--- a/src/aml_defs.h
+++ b/src/aml_defs.h
@@ -45,16 +45,20 @@
     }                                                           \
     G_STMT_END
 /** default size **/
+/** dmx section filter buffer size **/
+#define SECTION_FILTER_BUF_SIZE 1024 * 1024
+/** dmx es buffer threshold **/
+#define AMLHWDMX_MAX_ES_BUF_SIZE 10 * 1024 * 1024
+#define AMLHWDMX_MIN_ES_BUF_SIZE 4 * 1024 * 1024
 /* clear adaptor size */
-#define BUFFER_SIZE (188 * 20)
+#define MAX_BUFFER_SIZE (AMLHWDMX_MAX_ES_BUF_SIZE / 188 * 188)
+#define LOW_BUFFER_SIZE (188 * 10)
+#define BUFFER_SIZE LOW_BUFFER_SIZE
 /* secure adaptor size */
 #define SEC_BUF_QUEUE_MAX_SIZE 128
 #define SEC_BUF_QUEUE_MIN_SIZE 0
 #define SEC_BUF_QUEUE_NEEDED_SIZE 1
 #define SEC_BUF_QUEUE_UNLIMIT_SIZE -1
-/** dmx es buffer threshold **/
-#define AMLHWDMX_MAX_ES_BUF_SIZE 10 * 1024 * 1024
-#define AMLHWDMX_MIN_ES_BUF_SIZE 4 * 1024 * 1024
 /* dmx es buffer pts threshold(ms) */
 #define AMLHWDMX_MAX_ES_BUF_PTS_DIFF (500 * GST_MSECOND)
 /* other size */
diff --git a/src/gstamladapterpipe.c b/src/gstamladapterpipe.c
index 1ea9b78..be00a31 100644
--- a/src/gstamladapterpipe.c
+++ b/src/gstamladapterpipe.c
@@ -27,12 +27,14 @@
 {
     /* adpater collecting clear data */
     GstAdapter *adapter;
+    guint prob_peek_offset;
 };
 
 struct _GstSecureAdapter
 {
     /* adpater collecting secure dma buf */
     GstQueueArray *sec_buf_q;
+    guint prob_peek_idx;
 };
 
 struct _GstAdapterPipe
@@ -51,11 +53,7 @@
     gboolean flushing;
     /* flowreturn obtained by src task */
     GstFlowReturn srcresult;
-
-    /* amount needed/low/max in adapter by src task */
-    guint needed;
-    guint low;
-    guint max;
+    GstAdapterPipeStatus status;
     union
     {
         GstClearAdapter clear_ap;
@@ -66,7 +64,6 @@
 GstFlowReturn gst_amladapterpipe_init(GstAdapterPipe *pipe, GstAdapterPipeDataType type, gboolean is_secure, gboolean is_unlimit);
 static GstFlowReturn gst_amladapterpipe_dispose(GstAdapterPipe *pipe);
 static GstFlowReturn gst_amladapterpipe_clear_unlock(GstAdapterPipe *pipe);
-static guint gst_amladapterpipe_available_unlock(GstAdapterPipe *pipe);
 static gboolean gst_amladapterpipe_overrun_unlock(GstAdapterPipe *pipe);
 static gboolean gst_amladapterpipe_underrun_unlock(GstAdapterPipe *pipe);
 static GstFlowReturn gst_amladapterpipe_push_uncheck_unlock(GstAdapterPipe *pipe, GstBuffer *buffer);
@@ -82,21 +79,40 @@
     pipe->secure = is_secure;
     pipe->unlimit = is_unlimit;
     pipe->srcresult = GST_FLOW_OK;
+
+    pipe->status.pushed_size = 0;
+    pipe->status.poped_size = 0;
+
+    pipe->status.low_num = SEC_BUF_QUEUE_MIN_SIZE;
+    pipe->status.max_num = SEC_BUF_QUEUE_MAX_SIZE;
+    pipe->status.needed_num = SEC_BUF_QUEUE_NEEDED_SIZE;
+
+    pipe->status.low_size = LOW_BUFFER_SIZE;
+    pipe->status.max_size = MAX_BUFFER_SIZE;
+    pipe->status.needed_size = LOW_BUFFER_SIZE;
+    pipe->status.cur_size = 0;
+
     if (pipe->secure)
     {
         pipe->s.secure_ap.sec_buf_q = gst_queue_array_new(SEC_BUF_QUEUE_MAX_SIZE);
         g_return_val_if_fail(pipe->s.secure_ap.sec_buf_q, GST_FLOW_ERROR);
-        pipe->low = SEC_BUF_QUEUE_MIN_SIZE;
-        pipe->max = SEC_BUF_QUEUE_MAX_SIZE;
-        pipe->needed = SEC_BUF_QUEUE_NEEDED_SIZE;
+
+        pipe->status.cur_num = 0;
+        pipe->status.pushed_num = 0;
+        pipe->status.poped_num = 0;
+
+        pipe->s.secure_ap.prob_peek_idx = 0;
     }
     else
     {
         pipe->s.clear_ap.adapter = gst_adapter_new();
         g_return_val_if_fail(pipe->s.clear_ap.adapter, GST_FLOW_ERROR);
-        pipe->low = BUFFER_SIZE;
-        pipe->max = 10 * BUFFER_SIZE;
-        pipe->needed = BUFFER_SIZE;
+
+        pipe->status.cur_num = (pipe->status.low_num + pipe->status.max_num) / 2;
+        pipe->status.pushed_num = pipe->status.cur_num;
+        pipe->status.poped_num = pipe->status.cur_num;
+
+        pipe->s.clear_ap.prob_peek_offset = 0;
     }
 
     return GST_FLOW_OK;
@@ -130,39 +146,34 @@
             while ((obj = gst_queue_array_pop_head(pipe->s.secure_ap.sec_buf_q)))
                 gst_mini_object_unref(obj);
         }
+
+        pipe->status.cur_num = 0;
+        pipe->status.pushed_num = 0;
+        pipe->status.poped_num = 0;
+
+        pipe->s.secure_ap.prob_peek_idx = 0;
     }
     else
     {
         if (pipe->s.clear_ap.adapter)
             gst_adapter_clear(pipe->s.clear_ap.adapter);
+
+        pipe->s.clear_ap.prob_peek_offset = 0;
     }
 
+    pipe->status.cur_size = 0;
+    pipe->status.pushed_size = 0;
+    pipe->status.poped_size = 0;
+
     return GST_FLOW_OK;
 }
 
-static guint gst_amladapterpipe_available_unlock(GstAdapterPipe *pipe)
-{
-    guint available;
-    if (pipe->secure)
-    {
-        available = gst_queue_array_get_length(pipe->s.secure_ap.sec_buf_q);
-    }
-    else
-    {
-        available = gst_adapter_available(pipe->s.clear_ap.adapter);
-    }
-    GST_DEBUG("pipe:%p, type:%d, available:%d, low:%d, max:%d, needed:%d", pipe, pipe->type, available, pipe->low, pipe->max, pipe->needed);
-    return available;
-}
-
 static gboolean gst_amladapterpipe_overrun_unlock(GstAdapterPipe *pipe)
 {
-    guint available;
-
-    available = gst_amladapterpipe_available_unlock(pipe);
-    if (available > pipe->max)
+    if (pipe->status.cur_num > pipe->status.max_num || pipe->status.cur_size > pipe->status.max_size)
     {
-        GST_DEBUG("pipe:%p, type:%d, overrun, available:%d, max:%d", pipe, pipe->type, available, pipe->max);
+        GST_DEBUG("pipe:%p, type:%d, overrun, [status.cur_num:%d, status.max_num:%d], [status.cur_size:%d, status.max_size:%d]",
+                  pipe, pipe->type, pipe->status.cur_num, pipe->status.max_num, pipe->status.cur_size, pipe->status.max_size);
         return TRUE;
     }
     else
@@ -171,12 +182,10 @@
 
 static gboolean gst_amladapterpipe_underrun_unlock(GstAdapterPipe *pipe)
 {
-    guint available;
-
-    available = gst_amladapterpipe_available_unlock(pipe);
-    if (available < pipe->needed)
+    if (pipe->status.cur_num < pipe->status.needed_num || pipe->status.cur_size < pipe->status.needed_size)
     {
-        GST_DEBUG("pipe:%p, type:%d, overrun, available:%d, needed:%d", pipe, pipe->type, available, pipe->needed);
+        GST_DEBUG("pipe:%p, type:%d, overrun, [status.cur_num:%d, status.needed_num:%d], [status.cur_size:%d, status.needed_size:%d]",
+                  pipe, pipe->type, pipe->status.cur_num, pipe->status.needed_num, pipe->status.cur_size, pipe->status.needed_size);
         return TRUE;
     }
     else
@@ -186,10 +195,18 @@
 static GstFlowReturn gst_amladapterpipe_push_uncheck_unlock(GstAdapterPipe *pipe, GstBuffer *buffer)
 {
     if (pipe->secure)
+    {
         gst_queue_array_push_tail(pipe->s.secure_ap.sec_buf_q, buffer);
+        pipe->status.cur_num++;
+        pipe->status.pushed_num++;
+    }
     else
         gst_adapter_push(pipe->s.clear_ap.adapter, buffer);
-    GST_DEBUG("pipe:%p, type:%d, pushed in buffer %p", pipe, pipe->type, buffer);
+
+    pipe->status.cur_size += gst_buffer_get_size(buffer);
+    pipe->status.pushed_size += gst_buffer_get_size(buffer);
+
+    GST_DEBUG("pipe:%p, type:%d, pushed in buffer %p, status.cur_num:%d, status.cur_size:%d", pipe, pipe->type, buffer, pipe->status.cur_num, pipe->status.cur_size);
 
     return GST_FLOW_OK;
 }
@@ -201,14 +218,30 @@
     ret = GST_FLOW_OK;
 
     if (pipe->secure)
+    {
         *buffer = (GstBuffer *)gst_queue_array_pop_head(pipe->s.secure_ap.sec_buf_q);
+    }
     else
+    {
         *buffer = gst_adapter_take_buffer(pipe->s.clear_ap.adapter, BUFFER_SIZE);
+    }
 
     if (*buffer == NULL)
+    {
         ret = GST_FLOW_AMLAP_EMPTY;
+    }
+    else
+    {
+        if (pipe->secure)
+        {
+            pipe->status.cur_num--;
+            pipe->status.poped_num++;
+        }
+        pipe->status.cur_size -= gst_buffer_get_size(*buffer);
+        pipe->status.poped_size += gst_buffer_get_size(*buffer);
+    }
 
-    GST_DEBUG("pipe:%p, type:%d, poped out buffer %p, ret:%d", pipe, pipe->type, *buffer, ret);
+    GST_DEBUG("pipe:%p, type:%d, poped out buffer %p, status.cur_num:%d, status.cur_size:%d, ret:%d", pipe, pipe->type, *buffer, pipe->status.cur_num, pipe->status.cur_size, ret);
     return ret;
 }
 
@@ -271,13 +304,16 @@
     return ret;
 }
 
-guint gst_amladapterpipe_available(GstAdapterPipe *pipe)
+gboolean gst_amladapterpipe_get_status(GstAdapterPipe *pipe, GstAdapterPipeStatus *status)
 {
-    guint available;
+    g_return_val_if_fail(pipe, FALSE);
+    g_return_val_if_fail(status, FALSE);
+
     GST_ADAPTER_PIPE_MUTEX_LOCK(pipe);
-    available = gst_amladapterpipe_available_unlock(pipe);
+    memcpy(status, &pipe->status, sizeof(GstAdapterPipeStatus));
     GST_ADAPTER_PIPE_MUTEX_UNLOCK(pipe);
-    return available;
+
+    return TRUE;
 }
 
 GstFlowReturn gst_amladapterpipe_push(GstAdapterPipe *pipe, GstBuffer *buffer)
@@ -286,20 +322,18 @@
     g_return_val_if_fail(buffer, GST_FLOW_ERROR);
 
     GstFlowReturn ret;
-    guint available;
 
     GST_ADAPTER_PIPE_MUTEX_LOCK(pipe);
 
     if (pipe->flushing)
         goto flushing;
 
-    available = gst_amladapterpipe_available_unlock(pipe);
-    while (!pipe->unlimit && available > pipe->max)
+    while (!pipe->unlimit && (pipe->status.cur_num + 1 > pipe->status.max_num || pipe->status.cur_size + gst_buffer_get_size(buffer) > pipe->status.max_size))
     {
-        GST_DEBUG("pipe:%p, type:%d, reached max, available:%d, max:%d, waitting sig", pipe, pipe->type, available, pipe->max);
+        GST_DEBUG("pipe:%p, type:%d, reached max, [status.cur_num:%d, status.max_num:%d], [status.cur_size:%d, status.max_size:%d], waitting sig",
+                  pipe, pipe->type, pipe->status.cur_num, pipe->status.max_num, pipe->status.cur_size, pipe->status.max_size);
         GST_ADAPTER_PIPE_WAIT(pipe);
         GST_DEBUG("pipe:%p, type:%d, waitted", pipe, pipe->type);
-        available = gst_amladapterpipe_available_unlock(pipe);
     }
 
     if (pipe->flushing)
@@ -307,10 +341,10 @@
 
     ret = gst_amladapterpipe_push_uncheck_unlock(pipe, buffer);
 
-    available = gst_amladapterpipe_available_unlock(pipe);
-    if (!pipe->unlimit && available >= pipe->needed)
+    if (!pipe->unlimit && (pipe->status.cur_num >= pipe->status.needed_num && pipe->status.cur_size >= pipe->status.needed_size))
     {
-        GST_DEBUG("pipe:%p, type:%d, reachd needed, available:%d, needed:%d, emit sig", pipe, pipe->type, available, pipe->needed);
+        GST_DEBUG("pipe:%p, type:%d, reachd needed, [status.cur_num:%d, status.needed_num:%d], [status.cur_size:%d, status.needed_size:%d], emit sig",
+                  pipe, pipe->type, pipe->status.cur_num, pipe->status.needed_num, pipe->status.cur_size, pipe->status.needed_size);
         GST_ADAPTER_PIPE_SIGNAL(pipe);
     }
 
@@ -320,7 +354,8 @@
         goto done;
     }
 
-    GST_DEBUG("pipe:%p, type:%d, pushed buf:%p(%d bytes), available:%d", pipe, pipe->type, buffer, gst_buffer_get_size(buffer), available);
+    GST_DEBUG("pipe:%p, type:%d, pushed buf:%p(%d bytes), status.cur_num:%d, status.cur_size:%d",
+              pipe, pipe->type, buffer, gst_buffer_get_size(buffer), pipe->status.cur_num, pipe->status.cur_size);
 done:
     GST_ADAPTER_PIPE_MUTEX_UNLOCK(pipe);
     return ret;
@@ -338,20 +373,18 @@
     g_return_val_if_fail(buffer, GST_FLOW_ERROR);
 
     GstFlowReturn ret;
-    guint available;
 
     GST_ADAPTER_PIPE_MUTEX_LOCK(pipe);
 
     if (pipe->flushing)
         goto flushing;
 
-    available = gst_amladapterpipe_available_unlock(pipe);
-    while (!pipe->unlimit && available < pipe->needed && !pipe->eos)
+    while (!pipe->unlimit && (pipe->status.cur_num < pipe->status.needed_num || pipe->status.cur_size < pipe->status.needed_size) && !pipe->eos)
     {
-        GST_DEBUG("pipe:%p, type:%d, need more, Available:%d, needed:%d", pipe, pipe->type, available, pipe->needed);
+        GST_DEBUG("pipe:%p, type:%d, need more, [status.cur_num:%d, status.needed_num:%d], [status.cur_size:%d, status.needed_size:%d]",
+                  pipe, pipe->type, pipe->status.cur_num, pipe->status.needed_num, pipe->status.cur_size, pipe->status.needed_size);
         gboolean waitted;
         GST_ADAPTER_PIPE_WAITT_TIME(pipe, 20, waitted);
-        available = gst_amladapterpipe_available_unlock(pipe);
         if (!waitted)
         {
             GST_DEBUG("pipe:%p, type:%d, timeout. need continue", pipe, pipe->type);
@@ -368,17 +401,19 @@
     ret = gst_amladapterpipe_pop_uncheck_unlock(pipe, buffer);
     if (ret == GST_FLOW_AMLAP_EMPTY)
     {
-        GST_DEBUG("pipe:%p, type:%d, poped buf:%p, available:%d, pipe empty, need retry", pipe, pipe->type, *buffer, available);
+        GST_DEBUG("pipe:%p, type:%d, poped buf:%p, status.cur_num:%d, status.cur_size:%d, pipe empty, need retry",
+                  pipe, pipe->type, *buffer, pipe->status.cur_num, pipe->status.cur_size);
         goto done;
     }
 
-    GST_DEBUG("pipe:%p, type:%d, poped buf:%p(%d bytes), available:%d", pipe, pipe->type, *buffer, gst_buffer_get_size(*buffer), available);
+    GST_DEBUG("pipe:%p, type:%d, poped buf:%p(%d bytes), status.cur_num:%d, status.cur_size:%d",
+              pipe, pipe->type, *buffer, gst_buffer_get_size(*buffer), pipe->status.cur_num, pipe->status.cur_size);
 
 done:
-    available = gst_amladapterpipe_available_unlock(pipe);
-    if (!pipe->unlimit && available <= pipe->low)
+    if (!pipe->unlimit && (pipe->status.cur_num <= pipe->status.low_num || pipe->status.cur_size <= pipe->status.low_size))
     {
-        GST_DEBUG("pipe:%p, type:%d, buffer low, available:%d, low:%d", pipe, pipe->type, available, pipe->low);
+        GST_DEBUG("pipe:%p, type:%d, buffer low, [status.cur_num:%d, status.low_num:%d], [status.cur_size:%d, status.low_size:%d]",
+                  pipe, pipe->type, pipe->status.cur_num, pipe->status.low_num, pipe->status.cur_size, pipe->status.low_size);
         GST_ADAPTER_PIPE_SIGNAL(pipe);
     }
     GST_ADAPTER_PIPE_MUTEX_UNLOCK(pipe);
@@ -390,42 +425,59 @@
     goto done;
 }
 
-GstFlowReturn gst_amladapterpipe_peek(GstAdapterPipe *pipe, guint idx, GstBuffer **buffer)
+GstFlowReturn gst_amladapterpipe_peek(GstAdapterPipe *pipe, GstBuffer **buffer)
 {
     g_return_val_if_fail(pipe, GST_FLOW_ERROR);
     g_return_val_if_fail(buffer, GST_FLOW_ERROR);
 
     GstFlowReturn ret;
-    guint available;
 
-    ret = GST_FLOW_OK;
+    ret = GST_FLOW_AMLAP_EMPTY;
     *buffer = NULL;
 
     GST_ADAPTER_PIPE_MUTEX_LOCK(pipe);
 
     if (pipe->secure)
     {
-        if (gst_queue_array_get_length(pipe->s.secure_ap.sec_buf_q) <= idx)
+        if (gst_queue_array_get_length(pipe->s.secure_ap.sec_buf_q) <= pipe->s.secure_ap.prob_peek_idx)
         {
             GST_DEBUG("pipe:%p, type:%d, peek err. q len < idx", pipe, pipe->type);
         }
         else
         {
-            *buffer = (GstBuffer *)gst_queue_array_peek_nth(pipe->s.secure_ap.sec_buf_q, idx);
+            *buffer = (GstBuffer *)gst_queue_array_peek_nth(pipe->s.secure_ap.sec_buf_q, pipe->s.secure_ap.prob_peek_idx);
+            if (*buffer)
+            {
+                gst_buffer_ref(*buffer);
+                pipe->s.secure_ap.prob_peek_idx++;
+                ret = GST_FLOW_OK;
+            }
         }
     }
     else
     {
-        // TODO: add peek flow for using adaptor
-        *buffer = gst_adapter_take_buffer(pipe->s.clear_ap.adapter, BUFFER_SIZE);
+        guint available = gst_adapter_available(pipe->s.clear_ap.adapter);
+        if (available < BUFFER_SIZE + pipe->s.clear_ap.prob_peek_offset)
+        {
+            GST_DEBUG("pipe:%p, type:%d, peek err. q available:%d < BUFFER_SIZE", pipe, pipe->type, available);
+        }
+        else
+        {
+            GstMapInfo map;
+            memset(&map, 0, sizeof(map));
+            *buffer = gst_buffer_new_and_alloc(BUFFER_SIZE);
+            if (*buffer)
+            {
+                gst_buffer_map(*buffer, &map, GST_MAP_WRITE);
+                gst_adapter_copy(pipe->s.clear_ap.adapter, map.data, pipe->s.clear_ap.prob_peek_offset, BUFFER_SIZE);
+                gst_buffer_unmap(*buffer, &map);
+                pipe->s.clear_ap.prob_peek_offset += BUFFER_SIZE;
+                ret = GST_FLOW_OK;
+            }
+        }
     }
 
-    if (*buffer == NULL)
-        ret = GST_FLOW_AMLAP_EMPTY;
-    else
-        gst_buffer_ref(*buffer);
-
-    GST_DEBUG("pipe:%p, type:%d, peeked buf:%p(idx:%d, %d bytes), ret:%d", pipe, pipe->type, *buffer, idx, *buffer ? gst_buffer_get_size(*buffer) : -1, ret);
+    GST_DEBUG("pipe:%p, type:%d, peeked buf:%p(%d bytes), ret:%d", pipe, pipe->type, *buffer, *buffer ? gst_buffer_get_size(*buffer) : -1, ret);
     GST_ADAPTER_PIPE_MUTEX_UNLOCK(pipe);
     return ret;
 }
diff --git a/src/gstamladapterpipe.h b/src/gstamladapterpipe.h
index fd1eaa6..05eebda 100644
--- a/src/gstamladapterpipe.h
+++ b/src/gstamladapterpipe.h
@@ -71,24 +71,45 @@
 
 #define GST_FLOW_AMLAP_EMPTY GST_FLOW_CUSTOM_SUCCESS
 
+typedef struct _GstAdapterPipe GstAdapterPipe;
+typedef struct _GstAdapterPipeStatus GstAdapterPipeStatus;
+
+struct _GstAdapterPipeStatus
+{
+    /* statistics */
+    guint pushed_num;
+    guint pushed_size;
+    guint poped_num;
+    guint poped_size;
+
+    /* amount needed/low/max in adapter by src task */
+    guint needed_num;
+    guint low_num;
+    guint max_num;
+    guint cur_num;
+
+    guint needed_size;
+    guint low_size;
+    guint max_size;
+    guint cur_size;
+};
+
 typedef enum
 {
     GST_AP_TS = 0,
     GST_AP_ES = 1,
 } GstAdapterPipeDataType;
 
-typedef struct _GstAdapterPipe GstAdapterPipe;
-
 GstAdapterPipe *gst_amladapterpipe_new();
 GstAdapterPipe *gst_amladapterpipe_new_full(GstAdapterPipeDataType type, gboolean is_secure, gboolean is_unlimit);
 void gst_amladapterpipe_free(GstAdapterPipe *pipe);
 GstFlowReturn gst_amladapterpipe_reset(GstAdapterPipe *pipe);
 GstFlowReturn gst_amladapterpipe_clear(GstAdapterPipe *pipe);
-guint gst_amladapterpipe_available(GstAdapterPipe *pipe);
+gboolean gst_amladapterpipe_get_status(GstAdapterPipe *pipe, GstAdapterPipeStatus *status);
 GstFlowReturn gst_amladapterpipe_push(GstAdapterPipe *pipe, GstBuffer *buffer);
 GstFlowReturn gst_amladapterpipe_push_uncheck(GstAdapterPipe *pipe, GstBuffer *buffer);
 GstFlowReturn gst_amladapterpipe_pop(GstAdapterPipe *pipe, GstBuffer **buffer);
-GstFlowReturn gst_amladapterpipe_peek(GstAdapterPipe *pipe, guint idx, GstBuffer **buffer);
+GstFlowReturn gst_amladapterpipe_peek(GstAdapterPipe *pipe, GstBuffer **buffer);
 GstFlowReturn gst_amladapterpipe_set_flushing(GstAdapterPipe *pipe, gboolean flushing);
 GstFlowReturn gst_amladapterpipe_is_flushing(GstAdapterPipe *pipe, gboolean *flushing);
 void gst_amladapterpipe_set_eos(GstAdapterPipe *pipe);
diff --git a/src/gstamldmx.c b/src/gstamldmx.c
index 683c599..126f4ec 100644
--- a/src/gstamldmx.c
+++ b/src/gstamldmx.c
@@ -35,14 +35,16 @@
 #include "amlSetting.hpp"
 
 #define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf"
+#define GST_CAPS_FEATURE_SECURE_TS "secure:AesEnc"
 
 /* caps */
 static GstStaticPadTemplate sink_template =
     GST_STATIC_PAD_TEMPLATE("sink",
                             GST_PAD_SINK,
                             GST_PAD_ALWAYS,
-                            GST_STATIC_CAPS("video/mpegts, "
-                                            "systemstream = (boolean) true "));
+                            GST_STATIC_CAPS(
+                                // "video/mpegts, systemstream = (boolean) true; "
+                                "video/mpegts(" GST_CAPS_FEATURE_SECURE_TS "), systemstream = (boolean) true; "));
 
 static GstStaticPadTemplate video_src_template =
     GST_STATIC_PAD_TEMPLATE("video_%u",
@@ -84,9 +86,10 @@
 static void gst_amlhwdmx_buffer_unmap(GstAmlhwdmx *amlhwdmx, GstBuffer *buffer, GstMapInfo *info);
 static void gst_amlhwdmx_reset(GstAmlhwdmx *amlhwdmx);
 /* local function definition */
+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_mem(GstAmlhwdmx *amlhwdmx);
+static gboolean gst_amlhwdmx_check_filters_mem_status_test(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);
@@ -128,7 +131,6 @@
         set_osd_blank(1);
         set_dmx_source();
 
-        amlhwdmx->sinkpad.adapter_pipe = gst_amladapterpipe_new_full(GST_AP_TS, amlhwdmx->is_secure, FALSE); // new adaptor and do stream control
 
         snprintf(node, sizeof(node), "/dev/dvb0.dvr%d", amlhwdmx->dmx_dev_id);
         snprintf(node2, sizeof(node2), "/dev/dvb0.demux%d", amlhwdmx->dmx_dev_id);
@@ -139,6 +141,15 @@
         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:
+    {
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED");
+
+        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)
         {
@@ -152,13 +163,13 @@
             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_NULL_TO_READY | dvb_set_demux_source ret:%d", dmxret);
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | dvb_set_demux_source ret:%d", dmxret);
 
         /*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_NULL_TO_READY | pat gst_amldmxwrap_alloc_filter ret:%d pat_fid:%d", dmxret, 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_NULL_TO_READY | pat gst_amldmxwrap_set_cb ret:%d", dmxret);
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_set_cb ret:%d", dmxret);
         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;
@@ -167,19 +178,13 @@
         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_NULL_TO_READY | pat gst_amldmxwrap_sec_secfilter ret:%d", dmxret);
-        dmxret = gst_amldmxwrap_set_bufsize(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid, 8 * 1024);
-        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_NULL_TO_READY | pat gst_amldmxwrap_set_bufsize ret:%d", dmxret);
+        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);
 
         /*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_NULL_TO_READY | pat gst_amldmxwrap_start_filter ret:%d", dmxret);
-
-        break;
-    }
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-    {
-        // amlhwdmx->flags |= GST_AML_DMX_PROB;
+        GST_LOG_OBJECT(amlhwdmx, "GST_STATE_CHANGE_READY_TO_PAUSED | pat gst_amldmxwrap_start_filter ret:%d", dmxret);
 
         if (amlhwdmx->suf & GST_INIT_PLAY)
         {
@@ -536,11 +541,35 @@
     GST_DEBUG_OBJECT(amlhwdmx, "trace out");
 }
 
+static void gst_amlhwdmx_start_es_streams(GstAmlhwdmx *amlhwdmx)
+{
+    int dmxret = 0;
+    gint *es_fid = NULL;
+    struct dmx_pes_filter_params *es_fpara = NULL;
+
+    for (gint i = 0; i < amlhwdmx->srcpad_num; i++)
+    {
+
+        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",
+                         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);
+        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_pad_start_task(amlhwdmx->srcpads[i].pad, (GstTaskFunction)gst_amlhwdmx_src_loop, &amlhwdmx->srcpads[i], NULL);
+    }
+}
+
 static void gst_amlhwdmx_wait(GstAmlhwdmx *amlhwdmx)
 {
     while (!(amlhwdmx->flags & GST_AML_DMX_FLUSHING))
     {
-        if (gst_amlhwdmx_check_mem(amlhwdmx))
+        if (gst_amlhwdmx_check_filters_mem_status_test(amlhwdmx))
             break;
         usleep(50 * 1000);
         GST_DEBUG_OBJECT(amlhwdmx, "waitting for filters mem");
@@ -568,7 +597,9 @@
         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;
+        // 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_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",
@@ -698,7 +729,14 @@
         // TODO need check to update is_secure flag
         GstCaps *caps = NULL;
         gst_event_parse_caps(event, &caps);
-        GST_DEBUG_OBJECT(amlhwdmx, "caps:%s", gst_caps_to_string(caps));
+
+        GstCapsFeatures *features = gst_caps_get_features(caps, 0);
+        if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_SECURE_TS))
+        {
+            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);
         break;
     }
     case GST_EVENT_STREAM_START:
@@ -1076,13 +1114,21 @@
 
     amlhwdmx = (GstAmlhwdmx *)parent;
 
-    GST_DEBUG_OBJECT(sinkpad, "got buf:%p size:%d, available:%d", buffer, gst_buffer_get_size(buffer), gst_amladapterpipe_available(amlhwdmx->sinkpad.adapter_pipe));
-    g_print("sink | got  buf:%p size:%d, available:%d\n", buffer, gst_buffer_get_size(buffer), gst_amladapterpipe_available(amlhwdmx->sinkpad.adapter_pipe));
+    if (G_UNLIKELY(NULL == amlhwdmx->sinkpad.adapter_pipe))
+    {
+        amlhwdmx->sinkpad.adapter_pipe = gst_amladapterpipe_new_full(GST_AP_TS, amlhwdmx->is_secure, FALSE); // new adaptor and do stream control
+    }
+
+    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");
 
     ret = gst_amladapterpipe_push(amlhwdmx->sinkpad.adapter_pipe, buffer);
 
+    GST_DEBUG_OBJECT(sinkpad, "pushed buf:%p size:%d, pts: %" GST_TIME_FORMAT,
+                     buffer, gst_buffer_get_size(buffer), GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
     return ret;
 }
 
@@ -1283,10 +1329,11 @@
 
 static gboolean gst_amlhwdmx_query(GstPad *pad, GstObject *parent, GstQuery *query)
 {
-    g_print("\n\n||||||| tracein gst_amlhwdmx_query\n\n");
     GstAmlhwdmx *amlhwdmx = (GstAmlhwdmx *)parent;
     gboolean res = FALSE;
 
+    GST_DEBUG_OBJECT(pad, "trace in query: %" GST_PTR_FORMAT, query);
+
     switch (GST_QUERY_TYPE(query))
     {
     case GST_QUERY_SEEKING:
@@ -1313,12 +1360,39 @@
         res = FALSE;
         break;
     }
+
     default:
         /* FIXME : ADD GST_QUERY_CONVERT */
-        res = gst_pad_query_default(pad, parent, query);
         break;
     }
-    g_print("\n\n||||||| res:%d\n\n", res);
+
+    res = gst_pad_query_default(pad, parent, query);
+
+    switch (GST_QUERY_TYPE(query))
+    {
+    case GST_QUERY_ACCEPT_CAPS:
+    {
+        if (res)
+        {
+            GstCaps *caps = NULL;
+            gst_query_parse_accept_caps(query, &caps);
+            if (caps)
+            {
+                GstCapsFeatures *features = gst_caps_get_features(caps, 0);
+                if (features && gst_caps_features_contains(features, GST_CAPS_FEATURE_SECURE_TS))
+                {
+                    amlhwdmx->is_secure = TRUE;
+                    GST_DEBUG_OBJECT(pad, "query accept caps:%s, is_secure:%d", gst_caps_to_string(caps), amlhwdmx->is_secure);
+                }
+            }
+        }
+        break;
+    }
+    default:
+        break;
+    }
+
+    GST_DEBUG_OBJECT(pad, "trace out res:%d, query: %" GST_PTR_FORMAT, res, query);
     return res;
 }
 
@@ -1337,114 +1411,88 @@
     }
 }
 
-static gboolean gst_amlhwdmx_check_mem(GstAmlhwdmx *amlhwdmx)
+static gboolean gst_amlhwdmx_check_filters_mem_status_test(GstAmlhwdmx *amlhwdmx)
 {
-    struct dmx_mem_info info;
+    struct dmx_filter_mem_info info_all;
+    gboolean ret = TRUE;
+    gboolean pts_check_result = TRUE;
+    gboolean mem_check_result = TRUE;
 
-    memset(&info, 0, sizeof(info));
-    for (gint i = 0; i < amlhwdmx->srcpad_num; i++)
+    memset(&info_all, 0, sizeof(struct dmx_filter_mem_info));
+    if (-1 == gst_amldmxwrap_get_filters_mem_info(amlhwdmx->dmx_fd, &info_all))
     {
-        guint es_fid;
-        guint stream_type;
-        guint pid;
+        GST_ERROR_OBJECT(amlhwdmx, "check fail(get mem info failed error:%s)", strerror(errno));
+        return FALSE;
+    }
 
-        es_fid = amlhwdmx->srcpads[i].es_fid;
-        stream_type = gst_amlhwdmx_convert_type_gst2dmx(amlhwdmx->srcpads[i].stream_type);
-        pid = amlhwdmx->srcpads[i].pid;
-        if (stream_type == DMX_VIDEO_TYPE)
+    GST_DEBUG_OBJECT(amlhwdmx, "filters num:%d", info_all.filter_num);
+    if (info_all.filter_num > 0)
+    {
+        for (int i = 0; i < info_all.filter_num; i++)
         {
-            GST_DEBUG_OBJECT(amlhwdmx, "check pad[%d] es_fid:%d, stream_type:%d, pid:%d", i, es_fid, stream_type, pid);
+            struct dmx_mem_info *info = &info_all.info[i].filter_info;
 
-            if (gst_amldmxwrap_get_filter_mem_info(amlhwdmx->dmx_dev_id, es_fid, stream_type, pid, &info) == -1)
-            {
-                GST_ERROR_OBJECT(amlhwdmx, "dmx get mem info failed error:%s", strerror(errno));
-                return FALSE;
-            }
-            GST_DEBUG_OBJECT(amlhwdmx, "dmx_total_size:0x%x, dmx_buf_phy_start:0x%x, dmx_free_size:0x%x, dvb_core_total_size:0x%x, dvb_core_free_size:0x%x, wp_offset:0x%x, newest_pts:%llu",
-                             info.dmx_total_size, info.dmx_buf_phy_start, info.dmx_free_size, info.dvb_core_total_size, info.dvb_core_free_size, info.wp_offset, info.newest_pts);
+            GST_DEBUG("filter[idx:%d type:%d pid:%d] | \
+                       dmx_total_size:%d, dmx_buf_phy_start:0x%x, dmx_free_size:%d | \
+                       dvb_core_total_size:%d, dvb_core_free_size:%d | \
+                       wp_offset:0x%x, newest_pts:%llu",
+                      i, info_all.info[i].type, info_all.info[i].pid,
+                      info->dmx_total_size, info->dmx_buf_phy_start, info->dmx_free_size,
+                      info->dvb_core_total_size, info->dvb_core_free_size,
+                      info->wp_offset, info->newest_pts);
 
-#if 0
-            /*
-                flow rate control method 1:
-                    DMX driver return err free size when using ioctl:DMX_GET_FILTER_MEM_INFO.
-                    this free size didn't take into account the updated rp position of decoder.
-                    DMX has a patch to solve this problem, but it is not merged(https://scgit.amlogic.com/#/c/319330/).
-                    Temporarily retain the process for future expansion.
-            */
+            if (DMX_VIDEO_TYPE == info_all.info[i].type)
             {
-                if (info.dmx_free_size < AMLHWDMX_MIN_ES_BUF_SIZE)
-                    return FALSE;
-            }
-#endif
+                GstClockTime newest_video_pts = GST_CLOCK_TIME_NONE;
 
-#if 0
-        /*
-            flow rate control method 2:
-                DMX recommends using pts diff for flow rate control.
-                In amldemux, only the latest es buffer pts pushed out can be obtained, but the latest decoded frame pts cannot be obtained.
-                Therefore, the following implementation process cannot complete the flow rate control.
-                Temporarily retain the process for future expansion.
-         */
-        {
-            GstClockTime newest_pts = info.newest_pts / 90 * GST_MSECOND;
-            GST_DEBUG_OBJECT(amlhwdmx->srcpads[i].pad, "now pts: %" GST_TIME_FORMAT ", pushed pts: %" GST_TIME_FORMAT,
-                            GST_TIME_ARGS(newest_pts),
-                            GST_TIME_ARGS(amlhwdmx->srcpads[i].newest_pts));
+                newest_video_pts = info_all.info[i].filter_info.newest_pts / 90 * GST_MSECOND;
 
-            if (amlhwdmx->srcpads[i].newest_pts == GST_CLOCK_TIME_NONE)
-                continue;
-            if (newest_pts < amlhwdmx->srcpads[i].newest_pts)
-            {
-                GST_ERROR_OBJECT(amlhwdmx->srcpads[i].pad, "meet err here, pushed pts should never greater than now pts");
-                return FALSE;
-            }
-            if (newest_pts - amlhwdmx->srcpads[i].newest_pts > AMLHWDMX_MAX_ES_BUF_PTS_DIFF)
-            {
-                GST_ERROR_OBJECT(amlhwdmx->srcpads[i].pad, "pts diff: %" GST_TIME_FORMAT ", Threshold exceeded, check fail",
-                                GST_TIME_ARGS(newest_pts - amlhwdmx->srcpads[i].newest_pts));
-                return FALSE;
-            }
-        }
-#endif
-
-#if 1
-            /*
-                flow rate control method 3:
-                    using decoded_pts to do flow rate control
-                    using custom upstream event and signal to get latest decoded_pts
-            */
-            {
-                GstClockTime newest_pts = info.newest_pts / 90 * GST_MSECOND;
-                GST_DEBUG_OBJECT(amlhwdmx->srcpads[i].pad, "now pts: %" GST_TIME_FORMAT ", decoded pts: %" GST_TIME_FORMAT,
-                                 GST_TIME_ARGS(newest_pts),
+                GST_DEBUG_OBJECT(amlhwdmx->srcpads[i].pad, "check video pts(now video pts: %" GST_TIME_FORMAT ", decoded video pts: %" GST_TIME_FORMAT ")",
+                                 GST_TIME_ARGS(newest_video_pts),
                                  GST_TIME_ARGS(amlhwdmx->sinkpad.decoded_pts));
 
-                if (amlhwdmx->sinkpad.decoded_pts == GST_CLOCK_TIME_NONE)
-                    return TRUE;
-                else if (newest_pts < amlhwdmx->sinkpad.decoded_pts)
+                if (GST_CLOCK_TIME_NONE == amlhwdmx->sinkpad.decoded_pts)
                 {
-                    GST_ERROR_OBJECT(amlhwdmx->srcpads[i].pad, "meet err here, pushed pts should never greater than now pts");
-                    return FALSE;
+                    pts_check_result = TRUE;
                 }
-                else if (newest_pts - amlhwdmx->sinkpad.decoded_pts > AMLHWDMX_MAX_ES_BUF_PTS_DIFF)
+                else if (newest_video_pts < amlhwdmx->sinkpad.decoded_pts)
                 {
-                    GST_ERROR_OBJECT(amlhwdmx->srcpads[i].pad, "pts diff: %" GST_TIME_FORMAT ", Threshold exceeded, check fail",
-                                     GST_TIME_ARGS(newest_pts - amlhwdmx->sinkpad.decoded_pts));
-                    return FALSE;
+                    GST_ERROR_OBJECT(amlhwdmx->srcpads[i].pad, "check video pts fail(pushed pts should never greater than now pts)");
+                    pts_check_result = FALSE;
+                }
+                else if (newest_video_pts - amlhwdmx->sinkpad.decoded_pts > AMLHWDMX_MAX_ES_BUF_PTS_DIFF)
+                {
+                    GST_ERROR_OBJECT(amlhwdmx->srcpads[i].pad, "check video pts fail(pts diff: %" GST_TIME_FORMAT ", Threshold exceeded)",
+                                     GST_TIME_ARGS(newest_video_pts - amlhwdmx->sinkpad.decoded_pts));
+                    pts_check_result = FALSE;
                 }
                 else
                 {
-                    GST_DEBUG_OBJECT(amlhwdmx->srcpads[i].pad, "pts diff: %" GST_TIME_FORMAT ", check ok",
-                                     GST_TIME_ARGS(newest_pts - amlhwdmx->sinkpad.decoded_pts));
-                    return TRUE;
+                    GST_DEBUG_OBJECT(amlhwdmx->srcpads[i].pad, "check video pts succ(pts diff: %" GST_TIME_FORMAT ")",
+                                     GST_TIME_ARGS(newest_video_pts - amlhwdmx->sinkpad.decoded_pts));
+                    pts_check_result = TRUE;
                 }
             }
-#endif
-            break;
+
+            if (info->dmx_free_size < (info->dmx_total_size / 10 * 2))
+            {
+                GST_DEBUG_OBJECT(amlhwdmx, "check mem fail(mem low for filter[type:%d pid:%d])", info_all.info[i].type, info_all.info[i].pid);
+                mem_check_result &= FALSE;
+            }
         }
     }
 
-    return TRUE;
+    if (amlhwdmx->flags & GST_AML_DMX_PROB)
+    {
+        ret = mem_check_result;
+    }
+    else
+    {
+        ret = pts_check_result;
+    }
+
+    GST_DEBUG_OBJECT(amlhwdmx, "check %s", ret ? "succ" : "fail");
+    return ret;
 }
 
 static void gst_amlhwdmx_loop(GstAmlhwdmx *amlhwdmx)
@@ -1470,6 +1518,14 @@
         break;
     }
 
+    if (NULL == amlhwdmx->sinkpad.adapter_pipe)
+    {
+        GST_DEBUG_OBJECT(amlhwdmx, "Waiting for initialization sink adapter pipe");
+        usleep(50 * 1000);
+        ret = GST_FLOW_CUSTOM_SUCCESS;
+        goto done;
+    }
+
     if (amlhwdmx->seekable && !amlhwdmx->is_secure)
     {
         guint64 cur_offset = amlhwdmx->offset;
@@ -1480,23 +1536,59 @@
     else if (!amlhwdmx->seekable)
     {
         GST_DEBUG_OBJECT(amlhwdmx, "flags:0x%x", amlhwdmx->flags);
-        if (amlhwdmx->flags & GST_AML_DMX_PROB)
+
+        if (amlhwdmx->flags & GST_AML_DMX_PROB_DONE)
         {
-            ret = gst_amladapterpipe_peek(amlhwdmx->sinkpad.adapter_pipe, amlhwdmx->sinkpad.prob_peek_idx, &buf);
-            GST_DEBUG("peek buffer:%p(idx:%d, %d bytes) is_secure:%d, ret:%d",
-                      buf,
-                      amlhwdmx->sinkpad.prob_peek_idx, buf ? gst_buffer_get_size(buf) : -1,
-                      amlhwdmx->is_secure, ret);
+            GST_DEBUG_OBJECT(amlhwdmx, "probe done. restarting es filters");
+
+            gst_amldmxwrap_stop_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pat_para.fid);
+            for (gint i = 0; i < amlhwdmx->sinkpad.pat_para.pat.program_num; i++)
+            {
+                gst_amldmxwrap_stop_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pmt_para[i].fid);
+            }
+
+            gst_amlhwdmx_start_es_streams(amlhwdmx);
+            amlhwdmx->flags &= ~GST_AML_DMX_PROB_DONE;
+            amlhwdmx->flags &= ~GST_AML_DMX_PROB;
+
+            GST_DEBUG_OBJECT(amlhwdmx, "probe done. restarted es filters");
+
+            ret = GST_FLOW_CUSTOM_SUCCESS;
+            goto done;
+        }
+        else if (amlhwdmx->flags & GST_AML_DMX_PROB)
+        {
+            ret = gst_amladapterpipe_peek(amlhwdmx->sinkpad.adapter_pipe, &buf);
+            if (buf)
+            {
+                GST_DEBUG("peek buffer:%p, is_secure:%d, ret:%d (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")",
+                          buf, amlhwdmx->is_secure, ret,
+                          gst_buffer_get_size(buf),
+                          GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
+                          GST_TIME_ARGS(GST_BUFFER_DURATION(buf)));
+            }
+            else
+            {
+                GST_DEBUG("peek buffer NULL");
+            }
             if (buf)
                 amlhwdmx->sinkpad.prob_peek_idx++;
         }
         else
         {
             ret = gst_amladapterpipe_pop(amlhwdmx->sinkpad.adapter_pipe, &buf);
-            GST_DEBUG("pop buffer:%p(%d bytes) is_secure:%d, ret:%d",
-                      buf,
-                      buf ? gst_buffer_get_size(buf) : -1,
-                      amlhwdmx->is_secure, ret);
+            if (buf)
+            {
+                GST_DEBUG("pop buffer:%p, is_secure:%d, ret:%d (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")",
+                          buf, amlhwdmx->is_secure, ret,
+                          gst_buffer_get_size(buf),
+                          GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
+                          GST_TIME_ARGS(GST_BUFFER_DURATION(buf)));
+            }
+            else
+            {
+                GST_DEBUG("pop buffer NULL");
+            }
         }
     }
     else
@@ -1593,7 +1685,7 @@
         break;
     }
 
-    GST_DEBUG_OBJECT(srcpad->pad, "push buf:%p (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")",
+    GST_DEBUG_OBJECT(srcpad->pad, "got buf:%p (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")",
                      buf,
                      gst_buffer_get_size(buf),
                      GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
@@ -1608,27 +1700,36 @@
 
     // gst_amlhwdmx_dump_es(srcpad, buf);
 
-    // if (srcpad->stream_type == GST_STREAM_TYPE_AUDIO)
+    // if (srcpad->stream_type == GST_STREAM_TYPE_VIDEO)
     // {
     //     char name[50];
     //     FILE *fd;
     //     GstMapInfo map;
+    //     GstMemory *mem;
+    //     gsize offset, maxsize;
 
+    //     GST_ERROR_OBJECT(amlhwdmx, "check dump");
     //     sprintf(name, "/data/test/%s.es", GST_PAD_NAME(srcpad->pad));
     //     fd = fopen(name, "ab");
     //     if (!fd)
     //         return;
 
-    //     memset(&map, 0, sizeof(map));
-    //     GST_ERROR_OBJECT(srcpad->pad, "before gst_amlhwdmx_buffer_map");
-    //     gst_buffer_map(buf, &map, GST_MAP_READ);
-    //     GST_ERROR_OBJECT(srcpad->pad, "write file");
-    //     fwrite(map.data, 1, map.size, fd);
-    //     gst_buffer_unmap(buf, &map);
-    //     GST_ERROR_OBJECT(srcpad->pad, "after gst_amlhwdmx_buffer_map");
+    //     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);
-    //     GST_ERROR_OBJECT(srcpad->pad, "trace out");
-    //     return;
     // }
 
     if (!srcpad->pushed_segment_event)
@@ -1644,8 +1745,21 @@
         srcpad->pushed_segment_event = TRUE;
     }
 
+    if (GST_CLOCK_TIME_NONE == amlhwdmx->sinkpad.decoded_pts && srcpad->stream_type == GST_STREAM_TYPE_VIDEO)
+    {
+        amlhwdmx->sinkpad.decoded_pts = GST_BUFFER_PTS(buf);
+        GST_DEBUG_OBJECT(srcpad->pad, "update init decoded video pts to first video es buf pts: %" GST_TIME_FORMAT,
+                         GST_TIME_ARGS(GST_BUFFER_PTS(buf)));
+    }
+
     gst_pad_push(srcpad->pad, buf);
 
+    GST_DEBUG_OBJECT(srcpad->pad, "pushed buf:%p (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")",
+                     buf,
+                     gst_buffer_get_size(buf),
+                     GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
+                     GST_TIME_ARGS(GST_BUFFER_DURATION(buf)));
+
 done:
     GST_DEBUG_OBJECT(srcpad->pad, "end of this loop, reason %d (%s)", ret, gst_flow_get_name(ret));
     return;
@@ -1680,45 +1794,49 @@
     amlhwdmx = (GstAmlhwdmx *)gst_pad_get_parent(srcpad->pad);
     GST_ERROR_OBJECT(amlhwdmx, "trace in");
 
-    if (srcpad->stream_type == GST_STREAM_TYPE_AUDIO)
+    // if (srcpad->stream_type == GST_STREAM_TYPE_AUDIO)
+    // {
+    //     sprintf(name, "/data/test/%s.es", GST_PAD_NAME(srcpad->pad));
+    //     fd = fopen(name, "ab");
+    //     if (!fd)
+    //         return;
+
+    //     memset(&map, 0, sizeof(map));
+    //     GST_ERROR_OBJECT(amlhwdmx, "before gst_amlhwdmx_buffer_map");
+    //     gst_buffer_map(buf, &map, GST_MAP_READ);
+    //     GST_ERROR_OBJECT(amlhwdmx, "write file");
+    //     fwrite(map.data, 1, map.size, fd);
+    //     gst_buffer_unmap(buf, &map);
+    //     GST_ERROR_OBJECT(amlhwdmx, "after gst_amlhwdmx_buffer_map");
+    //     fclose(fd);
+    //     GST_ERROR_OBJECT(amlhwdmx, "trace out");
+    //     return;
+    // }
+
+    if (srcpad->stream_type == GST_STREAM_TYPE_VIDEO)
     {
-        sprintf(name, "/data/test/%s.es", GST_PAD_NAME(srcpad->pad));
-        fd = fopen(name, "ab");
-        if (!fd)
-            return;
-
-        memset(&map, 0, sizeof(map));
-        GST_ERROR_OBJECT(amlhwdmx, "before gst_amlhwdmx_buffer_map");
-        gst_buffer_map(buf, &map, GST_MAP_READ);
-        GST_ERROR_OBJECT(amlhwdmx, "write file");
-        fwrite(map.data, 1, map.size, fd);
-        gst_buffer_unmap(buf, &map);
-        GST_ERROR_OBJECT(amlhwdmx, "after gst_amlhwdmx_buffer_map");
-        fclose(fd);
-        GST_ERROR_OBJECT(amlhwdmx, "trace out");
-        return;
-    }
-
-    if (!amlhwdmx->is_secure_es || (amlhwdmx->is_secure_es && !amlhwdmx->is_secure))
-    {
-        GST_ERROR_OBJECT(amlhwdmx, "check dump");
-        sprintf(name, "/data/test/%s.es", GST_PAD_NAME(srcpad->pad));
-        fd = fopen(name, "ab");
-        if (!fd)
-            return;
-
-        memset(&map, 0, sizeof(map));
-        GST_ERROR_OBJECT(amlhwdmx, "before gst_amlhwdmx_buffer_map");
-        if (gst_amlhwdmx_buffer_map(amlhwdmx, buf, &map) == GST_FLOW_OK)
+        if (!amlhwdmx->is_secure_es || (amlhwdmx->is_secure_es && !amlhwdmx->is_secure))
         {
-            GST_ERROR_OBJECT(amlhwdmx, "write file");
-            fwrite(map.data, 1, map.size, fd);
-            gst_amlhwdmx_buffer_unmap(amlhwdmx, buf, &map);
-        }
-        GST_ERROR_OBJECT(amlhwdmx, "after gst_amlhwdmx_buffer_map");
+            GST_ERROR_OBJECT(amlhwdmx, "check dump");
+            sprintf(name, "/data/test/%s.es", GST_PAD_NAME(srcpad->pad));
+            fd = fopen(name, "ab");
+            if (!fd)
+                return;
 
-        fclose(fd);
+            memset(&map, 0, sizeof(map));
+            GST_ERROR_OBJECT(amlhwdmx, "before gst_amlhwdmx_buffer_map");
+            if (gst_amlhwdmx_buffer_map(amlhwdmx, buf, &map) == GST_FLOW_OK)
+            {
+                GST_ERROR_OBJECT(amlhwdmx, "write file");
+                fwrite(map.data, 1, map.size, fd);
+                gst_amlhwdmx_buffer_unmap(amlhwdmx, buf, &map);
+            }
+            GST_ERROR_OBJECT(amlhwdmx, "after gst_amlhwdmx_buffer_map");
+
+            fclose(fd);
+        }
     }
+
     GST_ERROR_OBJECT(amlhwdmx, "trace out");
 }
 
@@ -1775,7 +1893,7 @@
 {
     GST_DEBUG_CATEGORY_INIT(gst_amlhwdmx_debug, "amlhwdmx", 0, "amlhwdmx");
 
-    return gst_element_register(plugin, "amlhwdmx", 300, GST_TYPE_AMLHWDMX);
+    return gst_element_register(plugin, "amlhwdmx", 200, GST_TYPE_AMLHWDMX);
 }
 
 /* PACKAGE: this is usually set by autotools depending on some _INIT macro
diff --git a/src/gstamldmx.h b/src/gstamldmx.h
index cc8f9e9..e10eff4 100644
--- a/src/gstamldmx.h
+++ b/src/gstamldmx.h
@@ -55,6 +55,7 @@
     GST_AML_DMX_FLUSHING = (1 << 0),
     GST_AML_DMX_EOS = (1 << 1),
     GST_AML_DMX_PROB = (1 << 2),
+    GST_AML_DMX_PROB_DONE = (1 << 3),
 } GstAmlDmxFlags;
 
 typedef struct _GstAmlhwdmx GstAmlhwdmx;
diff --git a/src/gstamldmxfilter.c b/src/gstamldmxfilter.c
index 558d314..3151a74 100644
--- a/src/gstamldmxfilter.c
+++ b/src/gstamldmxfilter.c
@@ -21,6 +21,7 @@
 #include "aml_defs.h"
 #include "gstamldmabufmgrwrap.h"
 #include <gst/allocators/gstdmabuf.h>
+#include <stdio.h>
 
 static gint get_prog_id(GstAmlhwdmx *amlhwdmx, int fid);
 static GstBuffer *gst_es_filter_construct_buf(GstDmxSrcStreamPad *spad, int dev_no, int fid, const guint *data, int len);
@@ -74,7 +75,7 @@
             GST_DEBUG_OBJECT(amlhwdmx, "pmt[%d] gst_amldmxwrap_sec_secfilter ret:%d, pmt_fid:%d, pmt pid:%d",
                              i, dmxret, amlhwdmx->sinkpad.pmt_para[i].fid, amlhwdmx->sinkpad.pmt_para[i].filter_para.pid);
 
-            dmxret = gst_amldmxwrap_set_bufsize(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pmt_para[i].fid, 8 * 1024);
+            dmxret = gst_amldmxwrap_set_bufsize(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pmt_para[i].fid, SECTION_FILTER_BUF_SIZE);
             GST_LOG_OBJECT(amlhwdmx, "pmt[%d]:%d gst_amldmxwrap_set_bufsize ret:%d", i, amlhwdmx->sinkpad.pmt_para[i].fid, dmxret);
 
             dmxret = gst_amldmxwrap_start_filter(amlhwdmx->dmx_dev_id, amlhwdmx->sinkpad.pmt_para[i].fid);
@@ -175,18 +176,12 @@
         }
         GST_DEBUG_OBJECT(amlhwdmx, "es[%d] gst_amldmxwrap_start_filter pid:%d, input:%d, output:%d, type:%d, flags:%d",
                          i, es_fpara->pid, es_fpara->input, es_fpara->output, es_fpara->pes_type, es_fpara->flags);
-
-        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",
-                         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);
-        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_pad_start_task(amlhwdmx->srcpads[i].pad, (GstTaskFunction)gst_amlhwdmx_src_loop, &amlhwdmx->srcpads[i], NULL);
     }
-    amlhwdmx->flags &= ~GST_AML_DMX_PROB;
+    amlhwdmx->flags |= GST_AML_DMX_PROB_DONE;
+
+    GST_LOG_OBJECT(amlhwdmx, "emit no-more-pads signal");
+    gst_element_no_more_pads (GST_ELEMENT (amlhwdmx));
+
     GST_LOG_OBJECT(amlhwdmx, "found %d streams", amlhwdmx->srcpad_num);
 }
 
@@ -205,28 +200,57 @@
     amlhwdmx = (GstAmlhwdmx *)gst_pad_get_parent(dmx_src_pad->pad);
     adapter_pipe = dmx_src_pad->adapter_pipe;
 
+    GST_DEBUG_OBJECT(dmx_src_pad->pad, "trace in | dev_no:%d, fid:%d, data:%p, len:%d", dev_no, fid, data, len);
+
     if (amlhwdmx->flags & GST_AML_DMX_PROB)
     {
         GST_DEBUG_OBJECT(dmx_src_pad->pad, "ignore es buffer in probe state ");
         return;
     }
 
-    GST_DEBUG_OBJECT(dmx_src_pad->pad, "trace in | dev_no:%d, fid:%d, data:%p, len:%d", dev_no, fid, data, len);
-
     buf = gst_es_filter_construct_buf(dmx_src_pad, dev_no, fid, data, len);
     if (!buf)
         return;
 
-    GST_DEBUG_OBJECT(dmx_src_pad->pad, "got buf:%p (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT "), available:%d",
+    // if (dmx_src_pad->stream_type == GST_STREAM_TYPE_VIDEO)
+    // {
+    //     char name[50];
+    //     FILE *fd;
+    //     GstMapInfo map;
+    //     GstMemory *mem;
+    //     gsize offset, maxsize;
+
+    //     GST_ERROR_OBJECT(amlhwdmx, "check dump");
+    //     sprintf(name, "/data/test/%s-cb.es", GST_PAD_NAME(dmx_src_pad->pad));
+    //     fd = fopen(name, "ab");
+    //     if (!fd)
+    //         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);
+    // }
+
+    GST_DEBUG_OBJECT(dmx_src_pad->pad, "got buf:%p (size:%d start: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ")",
                      buf,
                      gst_buffer_get_size(buf),
                      GST_TIME_ARGS(GST_BUFFER_PTS(buf)),
-                     GST_TIME_ARGS(GST_BUFFER_DURATION(buf)),
-                     gst_amladapterpipe_available(adapter_pipe));
+                     GST_TIME_ARGS(GST_BUFFER_DURATION(buf)));
 
     gst_amladapterpipe_push(adapter_pipe, buf);
-
-    GST_DEBUG_OBJECT(dmx_src_pad->pad, "trace out");
 }
 
 void gst_es_filter_reset(GstAmlhwdmx *amlhwdmx)
diff --git a/src/gstamldmxwrap.c b/src/gstamldmxwrap.c
index 25f8ad4..6c524cd 100644
--- a/src/gstamldmxwrap.c
+++ b/src/gstamldmxwrap.c
@@ -124,7 +124,8 @@
 
         if (!cnt)
         {
-            usleep(20 * 1000);
+            // usleep(20 * 1000);
+            usleep(1000);
             continue;
         }
 
@@ -676,42 +677,26 @@
     return DVB_SUCCESS;
 }
 
-DVB_RESULT gst_amldmxwrap_get_filter_mem_info(gint dev_no, gint fhandle, guint stream_type, guint pid, struct dmx_mem_info *info)
+DVB_RESULT gst_amldmxwrap_get_filters_mem_info(int32_t dev_fd, struct dmx_filter_mem_info *info_all)
 {
-    dvb_dmx_t *dmx = NULL;
-    dvb_dmx_filter_t *filter = NULL;
-    struct dmx_filter_mem_info filter_mem_info;
-
-    GST_DEBUG("trace in");
-
-    memset(&filter_mem_info, 0, sizeof(struct dmx_filter_mem_info));
-
-    if (dmx_get_dev(dev_no, &dmx))
-    {
-        GST_ERROR("get dmx error");
-        return DVB_FAILURE;
-    }
-
-    filter = dmx_get_filter(dmx, fhandle);
-    if (!filter)
-    {
-        GST_ERROR("get filter error");
-        return DVB_FAILURE;
-    }
-
-    filter_mem_info.filter_num = 1;
-    filter_mem_info.info[0].type = stream_type;
-    filter_mem_info.info[0].pid = pid;
-    if (ioctl(filter->fd, DMX_GET_FILTER_MEM_INFO, &filter_mem_info) < 0)
+    memset(info_all, 0, sizeof(struct dmx_filter_mem_info));
+    if (ioctl(dev_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;
     }
 
-    memcpy(info, &filter_mem_info.info[0].filter_info, sizeof(struct dmx_mem_info));
-    GST_DEBUG("[fid:%d type:%d pid:%d] dmx_total_size:%d, dmx_buf_phy_start:0x%x, dmx_free_size:%d, dvb_core_total_size:%d, dvb_core_free_size:%d",
-              fhandle, stream_type, pid,
-              info->dmx_total_size, info->dmx_buf_phy_start, info->dmx_free_size, info->dvb_core_total_size, info->dvb_core_free_size);
+    GST_DEBUG("got filters num:%d", info_all->filter_num);
+    if (info_all->filter_num > 0)
+    {
+        for (int i = 0; i < info_all->filter_num; i++)
+        {
+            struct dmx_mem_info *test_info = &info_all->info[i].filter_info;
+            GST_DEBUG("filter[idx:%d type:%d pid:%d] dmx_total_size:%d, dmx_buf_phy_start:0x%x, dmx_free_size:%d, dvb_core_total_size:%d, dvb_core_free_size:%d",
+                      i, info_all->info[i].type, info_all->info[i].pid,
+                      test_info->dmx_total_size, test_info->dmx_buf_phy_start, test_info->dmx_free_size, test_info->dvb_core_total_size, test_info->dvb_core_free_size);
+        }
+    }
 
     return DVB_SUCCESS;
 }
diff --git a/src/gstamldmxwrap.h b/src/gstamldmxwrap.h
index 386e17c..160965a 100644
--- a/src/gstamldmxwrap.h
+++ b/src/gstamldmxwrap.h
@@ -114,7 +114,7 @@
  */
 DVB_RESULT gst_amldmxwrap_get_es(gint dev_no, gint fhandle, guint8 *data, guint size);
 
-DVB_RESULT gst_amldmxwrap_get_filter_mem_info(gint dev_no, gint fhandle, guint stream_type, guint pid, struct dmx_mem_info *info);
+DVB_RESULT gst_amldmxwrap_get_filters_mem_info(int32_t dev_fd, struct dmx_filter_mem_info *info_all);
 
 DVB_RESULT gst_amldmxwrap_set_filter_buf(gint dev_no, gint fhandle, guint size);
 #endif /* __GST_AML_DMX_WRAP_H__ */
\ No newline at end of file