diff options
author | Edward Hervey <edward@collabora.com> | 2013-03-31 12:11:48 +0200 |
---|---|---|
committer | Edward Hervey <edward@collabora.com> | 2013-03-31 12:11:48 +0200 |
commit | 5e70c76b33b111e01b6fc9093338ad38be0fadd6 (patch) | |
tree | 79fa8aafe7d9f6b17cb5f0c35e09813fb2abada7 /sys/dvb | |
parent | 95f819109fca03fc0a0f66168fcc6d5aae08dcac (diff) | |
download | gstreamer-plugins-bad-5e70c76b33b111e01b6fc9093338ad38be0fadd6.tar.gz |
dvb: Move CAM handling to a separate GstTask
* No longer blocks in READY=>PAUSED (faster startup)
* No longer requires a pad probe
Diffstat (limited to 'sys/dvb')
-rw-r--r-- | sys/dvb/dvbbasebin.c | 78 | ||||
-rw-r--r-- | sys/dvb/dvbbasebin.h | 5 |
2 files changed, 56 insertions, 27 deletions
diff --git a/sys/dvb/dvbbasebin.c b/sys/dvb/dvbbasebin.c index c5e5c59f3..57ac5bb3c 100644 --- a/sys/dvb/dvbbasebin.c +++ b/sys/dvb/dvbbasebin.c @@ -99,8 +99,8 @@ static void dvb_base_bin_get_property (GObject * object, guint prop_id, static void dvb_base_bin_dispose (GObject * object); static void dvb_base_bin_finalize (GObject * object); -static GstPadProbeReturn dvb_base_bin_ts_pad_probe_cb (GstPad * pad, - GstPadProbeInfo * info, gpointer user_data); +static void dvb_base_bin_task (DvbBaseBin * basebin); + static GstStateChangeReturn dvb_base_bin_change_state (GstElement * element, GstStateChange transition); static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message); @@ -308,6 +308,7 @@ dvb_base_bin_reset (DvbBaseBin * dvbbasebin) cam_device_free (dvbbasebin->hwcam); dvbbasebin->hwcam = NULL; } + dvbbasebin->trycam = TRUE; } static gint16 initial_pids[] = { 0, 1, 0x10, 0x11, 0x12, 0x14, -1 }; @@ -334,8 +335,6 @@ dvb_base_bin_init (DvbBaseBin * dvbbasebin) /* Expose tsparse source pad */ pad = gst_element_get_static_pad (dvbbasebin->tsparse, "src"); - gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, - dvb_base_bin_ts_pad_probe_cb, dvbbasebin, NULL); ghost = gst_ghost_pad_new ("src", pad); gst_element_add_pad (GST_ELEMENT (dvbbasebin), ghost); @@ -358,6 +357,12 @@ dvb_base_bin_init (DvbBaseBin * dvbbasebin) i++; } dvb_base_bin_rebuild_filter (dvbbasebin); + + g_rec_mutex_init (&dvbbasebin->lock); + dvbbasebin->task = + gst_task_new ((GstTaskFunction) dvb_base_bin_task, dvbbasebin, NULL); + gst_task_set_lock (dvbbasebin->task, &dvbbasebin->lock); + dvbbasebin->poll = gst_poll_new_timer (); } static void @@ -560,28 +565,6 @@ dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin) dvbbasebin->pmtlist_changed = FALSE; } -static GstPadProbeReturn -dvb_base_bin_ts_pad_probe_cb (GstPad * pad, GstPadProbeInfo * info, - gpointer user_data) -{ - DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (user_data); - - if (dvbbasebin->hwcam) { - cam_device_poll (dvbbasebin->hwcam); - - if (dvbbasebin->pmtlist_changed) { - if (cam_device_ready (dvbbasebin->hwcam)) { - GST_DEBUG_OBJECT (dvbbasebin, "pmt list changed"); - dvb_base_bin_reset_pmtlist (dvbbasebin); - } else { - GST_DEBUG_OBJECT (dvbbasebin, "pmt list changed but CAM not ready"); - } - } - } - - return GST_PAD_PROBE_OK; -} - static void dvb_base_bin_init_cam (DvbBaseBin * dvbbasebin) { @@ -601,6 +584,8 @@ dvb_base_bin_init_cam (DvbBaseBin * dvbbasebin) } } + dvbbasebin->trycam = FALSE; + g_free (ca_file); } @@ -615,9 +600,16 @@ dvb_base_bin_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: - dvb_base_bin_init_cam (dvbbasebin); + gst_poll_set_flushing (dvbbasebin->poll, FALSE); + g_rec_mutex_lock (&dvbbasebin->lock); + gst_task_start (dvbbasebin->task); + g_rec_mutex_unlock (&dvbbasebin->lock); break; case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_poll_set_flushing (dvbbasebin->poll, TRUE); + g_rec_mutex_lock (&dvbbasebin->lock); + gst_task_stop (dvbbasebin->task); + g_rec_mutex_unlock (&dvbbasebin->lock); dvb_base_bin_reset (dvbbasebin); break; default: @@ -992,3 +984,35 @@ dvb_base_bin_program_destroy (gpointer data) g_free (program); } + +static void +dvb_base_bin_task (DvbBaseBin * basebin) +{ + gint pollres; + + GST_DEBUG_OBJECT (basebin, "In task"); + + /* If we haven't tried to open the cam, try now */ + if (G_UNLIKELY (basebin->trycam)) + dvb_base_bin_init_cam (basebin); + + /* poll with timeout */ + pollres = gst_poll_wait (basebin->poll, GST_SECOND / 4); + + if (G_UNLIKELY (pollres == -1)) { + gst_task_stop (basebin->task); + return; + } + if (basebin->hwcam) { + cam_device_poll (basebin->hwcam); + + if (basebin->pmtlist_changed) { + if (cam_device_ready (basebin->hwcam)) { + GST_DEBUG_OBJECT (basebin, "pmt list changed"); + dvb_base_bin_reset_pmtlist (basebin); + } else { + GST_DEBUG_OBJECT (basebin, "pmt list changed but CAM not ready"); + } + } + } +} diff --git a/sys/dvb/dvbbasebin.h b/sys/dvb/dvbbasebin.h index c73c553ae..27a91b540 100644 --- a/sys/dvb/dvbbasebin.h +++ b/sys/dvb/dvbbasebin.h @@ -51,6 +51,7 @@ struct _DvbBaseBin { GstElement *buffer_queue; GstElement *tsparse; CamDevice *hwcam; + gboolean trycam; GList *pmtlist; gboolean pmtlist_changed; gchar *filter; @@ -58,6 +59,10 @@ struct _DvbBaseBin { GHashTable *programs; gboolean disposed; + GstTask *task; + GstPoll *poll; + GRecMutex lock; + /* Cached value */ gchar *program_numbers; }; |