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