amldemux: CB1 support push mode seek [1/1]
PD#SWPL-131112
Problem:
support push mode seek
Solution:
support push mode seek
Verify:
(detail info)
Change-Id: Ibdad606d5b4f260efe2e78d21ba3fd1d1bdbe965
Signed-off-by: xuesong.jiang <xuesong.jiang@amlogic.com>
diff --git a/src/gstamladapterpipe.c b/src/gstamladapterpipe.c
index be00a31..c29e919 100644
--- a/src/gstamladapterpipe.c
+++ b/src/gstamladapterpipe.c
@@ -376,14 +376,16 @@
GST_ADAPTER_PIPE_MUTEX_LOCK(pipe);
- if (pipe->flushing)
- goto flushing;
-
while (!pipe->unlimit && (pipe->status.cur_num < pipe->status.needed_num || pipe->status.cur_size < pipe->status.needed_size) && !pipe->eos)
{
+ gboolean waitted;
+
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;
+
+ if (pipe->flushing)
+ goto flushing;
+
GST_ADAPTER_PIPE_WAITT_TIME(pipe, 20, waitted);
if (!waitted)
{
@@ -395,9 +397,6 @@
break;
}
- if (pipe->flushing)
- goto flushing;
-
ret = gst_amladapterpipe_pop_uncheck_unlock(pipe, buffer);
if (ret == GST_FLOW_AMLAP_EMPTY)
{
diff --git a/src/gstamldmx.c b/src/gstamldmx.c
index 75fa6f7..57c64ee 100644
--- a/src/gstamldmx.c
+++ b/src/gstamldmx.c
@@ -76,6 +76,8 @@
static gboolean gst_amlhwdmx_src_activate_mode(GstPad *srcpad, GstObject *parent, GstPadMode mode, gboolean active);
static void gst_amlhwdmx_loop(GstAmlhwdmx *amlhwdmx);
static gboolean gst_amlhwdmx_sink_event(GstPad *sinkpad, GstObject *parent, GstEvent *event);
+static gboolean gst_amlhwdmx_flush_start(GstAmlhwdmx *amlhwdmx);
+static gboolean gst_amlhwdmx_flush_stop(GstAmlhwdmx *amlhwdmx);
static GstFlowReturn gst_amlhwdmx_chain(GstPad *sinkpad, GstObject *parent, GstBuffer *buf);
static gboolean gst_amlhwdmx_query(GstPad *pad, GstObject *parent, GstQuery *query);
static gboolean gst_amlhwdmx_perform_seek(GstAmlhwdmx *amlhwdmx, GstEvent *event);
@@ -86,6 +88,7 @@
static void gst_amlhwdmx_reset(GstAmlhwdmx *amlhwdmx);
/* local function definition */
static void gst_amlhwdmx_start_es_streams(GstAmlhwdmx *amlhwdmx);
+static void gst_amlhwdmx_stop_es_streams(GstAmlhwdmx *amlhwdmx);
static void gst_amlhwdmx_wait(GstAmlhwdmx *amlhwdmx);
static gboolean gst_amlhwdmx_write(GstAmlhwdmx *amlhwdmx, GstBuffer *buffer);
static gboolean gst_amlhwdmx_check_filters_mem_status(GstAmlhwdmx *amlhwdmx);
@@ -524,8 +527,8 @@
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] set pesfilter ret:%d, pmt_fid:%d, es pid:%d",
- i, dmxret, *es_fid, es_fpara->pid);
+ GST_DEBUG_OBJECT(amlhwdmx, "stream[%d] set pesfilter ret:%d | es_fid:%d | params - pid:%d, input:%d, output:%d, pes_type:%d, flags:%d",
+ i, dmxret, *es_fid, es_fpara->pid, es_fpara->input, es_fpara->output, es_fpara->pes_type, es_fpara->flags);
if (!amlhwdmx->is_secure && GST_STREAM_TYPE_VIDEO == amlhwdmx->srcpads[i].stream_type)
es_ring_buf_size = AMLHWDMX_CLEAR_VIDEO_ES_RING_BUF_SIZE;
@@ -540,6 +543,20 @@
}
}
+static void gst_amlhwdmx_stop_es_streams(GstAmlhwdmx *amlhwdmx)
+{
+ int dmxret = 0;
+
+ for (gint i = 0; i < amlhwdmx->srcpad_num; i++)
+ {
+ if (amlhwdmx->srcpads[i].es_fid != -1)
+ {
+ dmxret = gst_amldmxwrap_stop_filter(amlhwdmx->dmx_dev_id, amlhwdmx->srcpads[i].es_fid);
+ gst_pad_pause_task(amlhwdmx->srcpads[i].pad);
+ }
+ }
+}
+
static void gst_amlhwdmx_wait(GstAmlhwdmx *amlhwdmx)
{
while (!(amlhwdmx->flags & GST_AML_DMX_FLUSHING))
@@ -620,18 +637,14 @@
case GST_EVENT_FLUSH_START:
{
+ gst_amlhwdmx_flush_start(amlhwdmx);
+ gst_pad_event_default(sinkpad, parent, event);
break;
}
case GST_EVENT_FLUSH_STOP:
{
- AMLHWDMX_CONTEXT_LOCK(amlhwdmx);
- g_list_foreach(amlhwdmx->cached_events, (GFunc)gst_mini_object_unref, NULL);
- g_list_free(amlhwdmx->cached_events);
- gst_amladapterpipe_clear(amlhwdmx->sinkpad.adapter_pipe);
- /* loop may have decided to end itself as a result of flush WRONG_STATE */
- gst_task_start(amlhwdmx->sinkpad.task);
- GST_LOG_OBJECT(amlhwdmx, "loop started");
- AMLHWDMX_CONTEXT_UNLOCK(amlhwdmx);
+ gst_amlhwdmx_flush_stop(amlhwdmx);
+ gst_pad_event_default(sinkpad, parent, event);
break;
}
case GST_EVENT_SEEK:
@@ -697,9 +710,61 @@
}
}
gst_event_unref(event);
+
return result;
}
+static gboolean gst_amlhwdmx_flush_start(GstAmlhwdmx *amlhwdmx)
+{
+ AMLHWDMX_CONTEXT_LOCK(amlhwdmx);
+
+ gst_task_pause(amlhwdmx->sinkpad.task);
+
+ gst_amldmxwrap_set_flushing(amlhwdmx->dmx_dev_id, TRUE);
+
+ if (amlhwdmx->sinkpad.adapter_pipe)
+ gst_amladapterpipe_set_flushing(amlhwdmx->sinkpad.adapter_pipe, TRUE);
+ for (gint i = 0; i < amlhwdmx->srcpad_num; i++)
+ {
+ if (amlhwdmx->srcpads[i].adapter_pipe)
+ gst_amladapterpipe_set_flushing(amlhwdmx->srcpads[i].adapter_pipe, TRUE);
+ }
+
+ gst_amlhwdmx_stop_es_streams(amlhwdmx);
+
+ AMLHWDMX_CONTEXT_UNLOCK(amlhwdmx);
+
+ return TRUE;
+}
+
+static gboolean gst_amlhwdmx_flush_stop(GstAmlhwdmx *amlhwdmx)
+{
+ AMLHWDMX_CONTEXT_LOCK(amlhwdmx);
+
+ g_list_foreach(amlhwdmx->cached_events, (GFunc)gst_mini_object_unref, NULL);
+ g_list_free(amlhwdmx->cached_events);
+
+ if (amlhwdmx->sinkpad.adapter_pipe)
+ gst_amladapterpipe_set_flushing(amlhwdmx->sinkpad.adapter_pipe, FALSE);
+ for (gint i = 0; i < amlhwdmx->srcpad_num; i++)
+ {
+ if (amlhwdmx->srcpads[i].adapter_pipe)
+ gst_amladapterpipe_set_flushing(amlhwdmx->srcpads[i].adapter_pipe, FALSE);
+ }
+
+ gst_amldmxwrap_set_flushing(amlhwdmx->dmx_dev_id, FALSE);
+
+ gst_amlhwdmx_start_es_streams(amlhwdmx);
+
+ amlhwdmx->sinkpad.decoded_pts = GST_CLOCK_TIME_NONE;
+
+ gst_task_start(amlhwdmx->sinkpad.task);
+
+ AMLHWDMX_CONTEXT_UNLOCK(amlhwdmx);
+
+ return TRUE;
+}
+
static gboolean gst_amlhwdmx_sink_activate(GstPad *sinkpad, GstObject *parent)
{
GstAmlhwdmx *amlhwdmx = (GstAmlhwdmx *)parent;
@@ -951,8 +1016,9 @@
{
GstAmlhwdmx *amlhwdmx = (GstAmlhwdmx *)gst_pad_get_parent(pad);
GstEventType type = GST_EVENT_TYPE(event);
+ gboolean ret = TRUE;
- GST_DEBUG_OBJECT(amlhwdmx, "event: %" GST_PTR_FORMAT, event);
+ GST_DEBUG_OBJECT(pad, "event: %" GST_PTR_FORMAT, event);
switch (type)
{
@@ -964,28 +1030,58 @@
const gchar *name = gst_structure_get_name(s);
if (name && (strstr(name, "private_signal") != NULL))
{
- GST_DEBUG_OBJECT(amlhwdmx, "got private_signal event");
+ GST_DEBUG_OBJECT(pad, "got private_signal event");
gpointer obj_ptr = NULL;
const gchar *sig_name = NULL;
gst_structure_get(s, "obj_ptr", G_TYPE_POINTER, &obj_ptr, NULL);
sig_name = gst_structure_get_string(s, "sig_name");
- GST_DEBUG_OBJECT(amlhwdmx, "obj_ptr:%p, sig_name:%s", obj_ptr, sig_name);
+ GST_DEBUG_OBJECT(pad, "obj_ptr:%p, sig_name:%s", obj_ptr, sig_name);
if (obj_ptr && sig_name)
{
- GST_DEBUG_OBJECT(amlhwdmx, "connecting signal");
+ GST_DEBUG_OBJECT(pad, "connecting signal");
amlhwdmx->sinkpad.obj_ptr = obj_ptr;
amlhwdmx->sinkpad.update_pts_sig_id = g_signal_connect(obj_ptr, sig_name, G_CALLBACK(gst_amlhwdmx_update_pts_cb), amlhwdmx);
- GST_DEBUG_OBJECT(amlhwdmx, "connected signal");
+ GST_DEBUG_OBJECT(pad, "connected signal");
}
}
+ else
+ {
+ goto upstream;
+ }
}
break;
}
- default:
+ case GST_EVENT_SEEK:
+ {
+ switch (GST_PAD_MODE(pad))
+ {
+ case GST_PAD_MODE_PUSH:
+ {
+ goto upstream;
+ }
+ case GST_PAD_MODE_PULL:
+ {
+ // TODO:add pull mode for local ts playback
+ break;
+ }
+ default:
+ {
+ GST_ERROR_OBJECT(pad, "pad not active");
+ ret = FALSE;
+ break;
+ }
+ }
break;
}
+ default:
+ {
+ upstream:
+ ret = gst_pad_event_default(pad, parent, event);
+ break;
+ }
+ }
- return TRUE;
+ return ret;
}
static GstFlowReturn gst_amlhwdmx_buffer_map(GstAmlhwdmx *amlhwdmx, GstBuffer *buffer, GstMapInfo *info)
@@ -1524,7 +1620,7 @@
case GST_FLOW_FLUSHING:
{
GST_DEBUG_OBJECT(amlhwdmx, "get flushing");
- goto pause;
+ goto done;
}
case GST_FLOW_AMLAP_EMPTY:
{
@@ -1583,20 +1679,20 @@
{
case GST_FLOW_FLUSHING:
{
- GST_DEBUG_OBJECT(amlhwdmx, "got flushing");
- goto pause;
+ GST_DEBUG_OBJECT(srcpad->pad, "got flushing");
+ goto done;
}
case GST_FLOW_AMLAP_EMPTY:
{
if (amlhwdmx->eosFlag)
{
- GST_DEBUG_OBJECT(amlhwdmx, "get upstream eos event and the cached data has been processed, push eos event");
+ GST_DEBUG_OBJECT(srcpad->pad, "get upstream eos event and the cached data has been processed, push eos event");
gst_pad_push_event(srcpad->pad, gst_event_new_eos());
goto pause;
}
else
{
- GST_DEBUG_OBJECT(amlhwdmx, "got empty adapter");
+ GST_DEBUG_OBJECT(srcpad->pad, "got empty adapter");
goto done;
}
}
@@ -1622,13 +1718,13 @@
// GstMemory *mem;
// gsize offset, maxsize;
- // GST_ERROR_OBJECT(amlhwdmx, "check dump");
+ // GST_ERROR_OBJECT(srcpad->pad, "check dump");
// sprintf(name, "/data/test/%s.es", GST_PAD_NAME(srcpad->pad));
// fd = fopen(name, "ab");
// if (!fd)
// return;
- // GST_ERROR_OBJECT(amlhwdmx, "before write");
+ // GST_ERROR_OBJECT(srcpad->pad, "before write");
// if (buf)
// {
diff --git a/src/gstamldmxwrap.c b/src/gstamldmxwrap.c
index 17f4852..d8973d0 100644
--- a/src/gstamldmxwrap.c
+++ b/src/gstamldmxwrap.c
@@ -58,8 +58,9 @@
gint dmx_src_fd;
gint dev_no;
gint running;
- pthread_t thread;
- pthread_mutex_t lock;
+ GstTask *task;
+ GRecMutex tlock;
+ GMutex lock;
dvb_dmx_filter_t filter[DMX_FILTER_COUNT];
} dvb_dmx_t;
@@ -112,12 +113,12 @@
sec_buf = (gchar *)malloc(SEC_BUF_SIZE);
prctl(PR_SET_NAME, "gst_amldmxwrap_data_thread");
- while (dmx->running)
+ while (g_atomic_int_get(&dmx->running))
{
cnt = 0;
mask = 0;
- pthread_mutex_lock(&dmx->lock);
+ g_mutex_lock(&dmx->lock);
for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
{
if (dmx->filter[fid].need_free)
@@ -142,7 +143,7 @@
}
}
- pthread_mutex_unlock(&dmx->lock);
+ g_mutex_unlock(&dmx->lock);
if (!cnt)
{
@@ -161,7 +162,7 @@
{
if (fds[i].revents & (POLLIN | POLLERR))
{
- pthread_mutex_lock(&dmx->lock);
+ g_mutex_lock(&dmx->lock);
filter = &dmx->filter[fids[i]];
if (!filter->enable || !filter->used || filter->need_free)
{
@@ -184,7 +185,7 @@
GST_DEBUG("read demux filter[%d] failed (%s) %d", fids[i], strerror(errno), errno);
}
}
- pthread_mutex_unlock(&dmx->lock);
+ g_mutex_unlock(&dmx->lock);
GST_DEBUG("tid[%x] ch[%d] %x bytes", sec_buf[0], fids[i], len);
if (len > 0 && filter->cb)
{
@@ -231,7 +232,7 @@
if (dmx_get_dev(dev_no, &dev))
return DVB_FAILURE;
- if (dev->running)
+ if (g_atomic_int_get(&dev->running))
{
GST_DEBUG("dmx already initialized");
return DVB_FAILURE;
@@ -250,9 +251,59 @@
}
dev->dev_no = dev_no;
- pthread_mutex_init(&dev->lock, NULL);
- dev->running = 1;
- pthread_create(&dev->thread, NULL, gst_amldmxwrap_data_thread, dev);
+ g_atomic_int_set(&dev->running, 1);
+
+ gst_amldmxwrap_start_fetch_data(dev_no);
+
+ return DVB_SUCCESS;
+}
+
+DVB_RESULT gst_amldmxwrap_start_fetch_data(gint dev_no)
+{
+ dvb_dmx_t *dev = NULL;
+
+ if (dmx_get_dev(dev_no, &dev))
+ return DVB_FAILURE;
+
+ if (!dev->task)
+ {
+ dev->task = gst_task_new((GstTaskFunction)gst_amldmxwrap_data_thread, dev, NULL);
+ g_rec_mutex_init(&dev->tlock);
+ g_mutex_init(&dev->lock);
+ gst_task_set_lock(dev->task, &dev->tlock);
+ }
+
+ gst_task_start(dev->task);
+
+ return DVB_SUCCESS;
+}
+
+DVB_RESULT gst_amldmxwrap_pause_fetch_data(gint dev_no)
+{
+ dvb_dmx_t *dev = NULL;
+
+ if (dmx_get_dev(dev_no, &dev))
+ return DVB_FAILURE;
+
+ if (!dev->task)
+ return DVB_FAILURE;
+
+ gst_task_pause(dev->task);
+
+ return DVB_SUCCESS;
+}
+
+DVB_RESULT gst_amldmxwrap_set_flushing(gint dev_no, gboolean flushing)
+{
+ dvb_dmx_t *dev = NULL;
+
+ if (dmx_get_dev(dev_no, &dev))
+ return DVB_FAILURE;
+
+ if (flushing)
+ g_atomic_int_set(&dev->running, 0);
+ else
+ g_atomic_int_set(&dev->running, 1);
return DVB_SUCCESS;
}
@@ -365,7 +416,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = &dev->filter[0];
for (fid = 0; fid < DMX_FILTER_COUNT; fid++)
{
@@ -378,7 +429,7 @@
if (fid >= DMX_FILTER_COUNT)
{
GST_DEBUG("filter id:%d, have no filter to alloc", fid);
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
return DVB_FAILURE;
}
@@ -388,7 +439,7 @@
if (fd == -1)
{
GST_DEBUG("cannot open \"%s\" (%s)", dev_name, strerror(errno));
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
return DVB_FAILURE;
}
@@ -398,7 +449,7 @@
filter[fid].used = 1;
*fhandle = fid;
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
// GST_DEBUG("fhandle = %d", fid);
return DVB_SUCCESS;
@@ -425,7 +476,7 @@
if (!params)
return DVB_FAILURE;
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -442,7 +493,7 @@
}
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
// GST_DEBUG("pid = %x", params->pid);
return ret;
}
@@ -468,7 +519,7 @@
if (!params)
return DVB_FAILURE;
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -493,7 +544,7 @@
}
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
// GST_DEBUG("pid = %x", params->pid);
return ret;
}
@@ -516,7 +567,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -528,7 +579,7 @@
}
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
return ret;
}
@@ -548,7 +599,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter)
@@ -556,7 +607,7 @@
filter->need_free = 1;
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
// GST_DEBUG("fhandle = %d", fhandle);
return DVB_SUCCESS;
@@ -580,7 +631,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter && !filter->enable)
@@ -596,7 +647,7 @@
}
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
gst_aml_dmabuf_mgr_set_filter_info(fhandle, filter->fd, 0);
@@ -620,7 +671,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter && filter->enable)
@@ -636,7 +687,7 @@
}
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
gst_aml_dmabuf_mgr_set_filter_info(fhandle, filter->fd, 1);
@@ -662,7 +713,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
filter = dmx_get_filter(dev, fhandle);
if (filter)
{
@@ -674,7 +725,7 @@
ret = DVB_FAILURE;
}
- pthread_mutex_unlock(&dev->lock);
+ g_mutex_unlock(&dev->lock);
// GST_DEBUG("ret = %d", ret);
return ret;
@@ -700,7 +751,7 @@
return DVB_FAILURE;
}
- pthread_mutex_lock(&dev->lock);
+ g_mutex_lock(&dev->lock);
for (i = 0; i < DMX_FILTER_COUNT; i++)
{
@@ -725,12 +776,16 @@
if (open_count == 0)
{
- dev->running = 0;
- pthread_join(dev->thread, NULL);
- }
+ g_atomic_int_set(&dev->running, 0);
- pthread_mutex_unlock(&dev->lock);
- pthread_mutex_destroy(&dev->lock);
+ gst_task_stop(dev->task);
+ g_rec_mutex_lock(&dev->tlock);
+ g_rec_mutex_unlock(&dev->tlock);
+ gst_task_join(dev->task);
+ gst_object_unref(dev->task);
+ g_rec_mutex_clear(&dev->tlock);
+ g_mutex_clear(&dev->lock);
+ }
if (dev->dmx_fd >= 0)
{
@@ -778,6 +833,12 @@
ret = poll(fd, 1, DMX_POLL_TIMEOUT);
if (ret <= 0)
{
+ if (!g_atomic_int_get(&dmx->running))
+ {
+ GST_DEBUG("flushing");
+ return DVB_SUCCESS;
+ }
+
GST_DEBUG("poll ret:%d timeout. need continue", ret);
continue;
}
diff --git a/src/gstamldmxwrap.h b/src/gstamldmxwrap.h
index b7ea507..1c4c962 100644
--- a/src/gstamldmxwrap.h
+++ b/src/gstamldmxwrap.h
@@ -134,4 +134,10 @@
DVB_RESULT gst_amldmxwrap_set_video_filters_es_buf_size(guint size);
DVB_RESULT gst_amldmxwrap_set_filter_ring_buf_size(gint dev_no, gint fhandle, guint size);
+
+DVB_RESULT gst_amldmxwrap_start_fetch_data(gint dev_no);
+
+DVB_RESULT gst_amldmxwrap_pause_fetch_data(gint dev_no);
+
+DVB_RESULT gst_amldmxwrap_set_flushing(gint dev_no, gboolean flushing);
#endif /* __GST_AML_DMX_WRAP_H__ */
\ No newline at end of file