static gboolean dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri, GError ** error) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler); gchar *location; location = gst_uri_get_location (uri); if (location == NULL) goto no_location; if (!set_properties_for_channel (GST_ELEMENT (dvbbasebin), location)) goto set_properties_failed; /* FIXME: here is where we parse channels.conf */ g_free (location); return TRUE; /* ERRORS */ no_location: { g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI, "No details to DVB URI"); return FALSE; } set_properties_failed: { g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI, "Could not set properties from DVB URI"); g_free (location); return FALSE; } }
static GstPad * dvb_base_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name) { GstPad *pad; GstPad *ghost; gchar *pad_name; if (name == NULL) name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ); pad = gst_element_get_request_pad (GST_DVB_BASE_BIN (element)->mpegtsparse, name); if (pad == NULL) return NULL; pad_name = gst_pad_get_name (pad); ghost = gst_ghost_pad_new (pad_name, pad); g_free (pad_name); gst_element_add_pad (element, ghost); gst_element_no_more_pads (element); return ghost; }
static void dvb_base_bin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object); switch (prop_id) { case PROP_ADAPTER: case PROP_FRONTEND: case PROP_DISEQC_SRC: case PROP_FREQUENCY: case PROP_POLARITY: case PROP_SYMBOL_RATE: case PROP_BANDWIDTH: case PROP_CODE_RATE_HP: case PROP_CODE_RATE_LP: case PROP_GUARD: case PROP_MODULATION: case PROP_TRANS_MODE: case PROP_HIERARCHY: case PROP_INVERSION: case PROP_STATS_REPORTING_INTERVAL: g_object_get_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value); break; case PROP_PROGRAM_NUMBERS: g_object_get_property (G_OBJECT (dvbbasebin->mpegtsparse), pspec->name, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static void dvb_base_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object); switch (prop_id) { case PROP_ADAPTER: case PROP_DISEQC_SRC: case PROP_FRONTEND: case PROP_FREQUENCY: case PROP_POLARITY: case PROP_SYMBOL_RATE: case PROP_BANDWIDTH: case PROP_CODE_RATE_HP: case PROP_CODE_RATE_LP: case PROP_GUARD: case PROP_MODULATION: case PROP_TRANS_MODE: case PROP_HIERARCHY: case PROP_INVERSION: case PROP_STATS_REPORTING_INTERVAL: /* FIXME: check if we can tune (state < PLAYING || program-numbers == "") */ g_object_set_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value); break; case PROP_PROGRAM_NUMBERS: dvb_base_bin_set_program_numbers (dvbbasebin, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message) { DvbBaseBin *dvbbasebin; dvbbasebin = GST_DVB_BASE_BIN (bin); if (message->type == GST_MESSAGE_ELEMENT && GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->mpegtsparse)) { const gchar *structure_name = gst_structure_get_name (message->structure); if (strcmp (structure_name, "pat") == 0) dvb_base_bin_pat_info_cb (dvbbasebin, message->structure); else if (strcmp (structure_name, "pmt") == 0) dvb_base_bin_pmt_info_cb (dvbbasebin, message->structure); /*else if (strcmp (structure_name, "nit") == 0) dvb_base_bin_nit_info_cb (dvbbasebin, message->structure); else if (strcmp (structure_name, "sdt") == 0) dvb_base_bin_sdt_info_cb (dvbbasebin, message->structure); else if (strcmp (structure_name, "eit") == 0) dvb_base_bin_eit_info_cb (dvbbasebin, message->structure); */ /* forward the message on */ gst_element_post_message (GST_ELEMENT_CAST (bin), message); } else { /* chain up */ GST_BIN_CLASS (parent_class)->handle_message (bin, message); } }
static GstPad * dvb_base_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (element); GstPad *pad; GstPad *ghost; gchar *pad_name; GST_DEBUG_OBJECT (dvbbasebin, "New pad requested %s", GST_STR_NULL (name)); if (dvbbasebin->tsparse == NULL) return NULL; if (name == NULL) name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ); pad = gst_element_get_request_pad (dvbbasebin->tsparse, name); if (pad == NULL) return NULL; pad_name = gst_pad_get_name (pad); ghost = gst_ghost_pad_new (pad_name, pad); g_free (pad_name); gst_element_add_pad (element, ghost); return ghost; }
static void dvb_base_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object); switch (prop_id) { case PROP_ADAPTER: case PROP_DISEQC_SRC: case PROP_FRONTEND: case PROP_FREQUENCY: case PROP_POLARITY: case PROP_SYMBOL_RATE: case PROP_BANDWIDTH: case PROP_CODE_RATE_HP: case PROP_CODE_RATE_LP: case PROP_GUARD: case PROP_MODULATION: case PROP_TRANS_MODE: case PROP_HIERARCHY: case PROP_INVERSION: case PROP_STATS_REPORTING_INTERVAL: case PROP_TUNING_TIMEOUT: case PROP_DELSYS: case PROP_PILOT: case PROP_ROLLOFF: case PROP_STREAM_ID: case PROP_BANDWIDTH_HZ: case PROP_ISDBT_LAYER_ENABLED: case PROP_ISDBT_PARTIAL_RECEPTION: case PROP_ISDBT_SOUND_BROADCASTING: case PROP_ISDBT_SB_SUBCHANNEL_ID: case PROP_ISDBT_SB_SEGMENT_IDX: case PROP_ISDBT_SB_SEGMENT_COUNT: case PROP_ISDBT_LAYERA_FEC: case PROP_ISDBT_LAYERA_MODULATION: case PROP_ISDBT_LAYERA_SEGMENT_COUNT: case PROP_ISDBT_LAYERA_TIME_INTERLEAVING: case PROP_ISDBT_LAYERB_FEC: case PROP_ISDBT_LAYERB_MODULATION: case PROP_ISDBT_LAYERB_SEGMENT_COUNT: case PROP_ISDBT_LAYERB_TIME_INTERLEAVING: case PROP_ISDBT_LAYERC_FEC: case PROP_ISDBT_LAYERC_MODULATION: case PROP_ISDBT_LAYERC_SEGMENT_COUNT: case PROP_ISDBT_LAYERC_TIME_INTERLEAVING: case PROP_LNB_SLOF: case PROP_LNB_LOF1: case PROP_LNB_LOF2: case PROP_INTERLEAVING: /* FIXME: check if we can tune (state < PLAYING || program-numbers == "") */ g_object_set_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value); break; case PROP_PROGRAM_NUMBERS: dvb_base_bin_set_program_numbers (dvbbasebin, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message) { DvbBaseBin *dvbbasebin; dvbbasebin = GST_DVB_BASE_BIN (bin); /* note: message->src might be a GstPad, so use element cast w/o typecheck */ if (GST_ELEMENT_CAST (message->src) == dvbbasebin->tsparse) { GstMpegtsSection *section = gst_message_parse_mpegts_section (message); if (section) { switch (GST_MPEGTS_SECTION_TYPE (section)) { case GST_MPEGTS_SECTION_PAT: dvb_base_bin_pat_info_cb (dvbbasebin, section); break; case GST_MPEGTS_SECTION_PMT: dvb_base_bin_pmt_info_cb (dvbbasebin, section); break; default: break; } gst_mpegts_section_unref (section); } } /* chain up */ GST_BIN_CLASS (parent_class)->handle_message (bin, message); }
static gboolean dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri) { gboolean ret; gchar *protocol; DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler); protocol = gst_uri_get_protocol (uri); if (strcmp (protocol, "dvb") != 0) { ret = FALSE; } else { gchar *location = gst_uri_get_location (uri); if (location != NULL) { ret = set_properties_for_channel (G_OBJECT (dvbbasebin), location); g_free (location); } else ret = FALSE; } /* here is where we parse channels.conf */ g_free (protocol); return ret; }
static void dvb_base_bin_finalize (GObject * object) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object); g_hash_table_destroy (dvbbasebin->streams); g_hash_table_destroy (dvbbasebin->programs); if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); }
static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad) { GstGhostPad *ghost; GstPad *target; g_return_if_fail (GST_IS_DVB_BASE_BIN (element)); ghost = GST_GHOST_PAD (pad); target = gst_ghost_pad_get_target (ghost); gst_element_release_request_pad (GST_ELEMENT (GST_DVB_BASE_BIN (element)-> mpegtsparse), target); gst_object_unref (target); gst_element_remove_pad (element, pad); }
static void dvb_base_bin_dispose (GObject * object) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object); if (!dvbbasebin->disposed) { /* remove mpegtsparse BEFORE dvbsrc, since the mpegtsparse::pad-removed * signal handler uses dvbsrc */ dvb_base_bin_reset (dvbbasebin); gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->mpegtsparse); gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc); gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->buffer_queue); dvbbasebin->disposed = TRUE; } if (G_OBJECT_CLASS (parent_class)->dispose) G_OBJECT_CLASS (parent_class)->dispose (object); }
static void foreach_stream_build_filter (gpointer key, gpointer value, gpointer user_data) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (user_data); DvbBaseBinStream *stream = (DvbBaseBinStream *) value; gchar *tmp, *pid; GST_DEBUG ("stream %d usecount %d", stream->pid, stream->usecount); if (stream->usecount > 0) { /* TODO: use g_strjoinv FTW */ tmp = dvbbasebin->filter; pid = g_strdup_printf ("%d", stream->pid); dvbbasebin->filter = g_strjoin (":", pid, dvbbasebin->filter, NULL); g_free (pid); g_free (tmp); } }
static gboolean dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri, GError ** error) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler); GError *err = NULL; gchar *location; location = gst_uri_get_location (uri); if (location == NULL) goto no_location; /* FIXME: here is where we parse channels.conf */ if (!set_properties_for_channel (GST_ELEMENT (dvbbasebin), location, &err)) goto set_properties_failed; g_free (location); return TRUE; post_error_and_exit: { gst_element_message_full (GST_ELEMENT (dvbbasebin), GST_MESSAGE_ERROR, err->domain, err->code, g_strdup (err->message), NULL, __FILE__, GST_FUNCTION, __LINE__); g_propagate_error (error, err); return FALSE; } no_location: { g_set_error (&err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI, "No details to DVB URI"); goto post_error_and_exit; } set_properties_failed: { g_free (location); if (!err) g_set_error (&err, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE, "Could not find information for channel"); goto post_error_and_exit; } }
static GstStateChangeReturn dvb_base_bin_change_state (GstElement * element, GstStateChange transition) { DvbBaseBin *dvbbasebin; GstStateChangeReturn ret; dvbbasebin = GST_DVB_BASE_BIN (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (dvbbasebin->tsparse == NULL) { GST_ELEMENT_ERROR (dvbbasebin, CORE, MISSING_PLUGIN, (NULL), ("No 'tsparse' element, check your GStreamer installation.")); return GST_STATE_CHANGE_FAILURE; } break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: 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: break; } return ret; }
static gboolean dvb_base_bin_ts_pad_probe_cb (GstPad * pad, GstBuffer * buf, 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 TRUE; }
static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message) { DvbBaseBin *dvbbasebin; dvbbasebin = GST_DVB_BASE_BIN (bin); if (message->type == GST_MESSAGE_ELEMENT && GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) { const GstStructure *s = gst_message_get_structure (message); const gchar *structure_name = gst_structure_get_name (s); if (strcmp (structure_name, "pat") == 0) dvb_base_bin_pat_info_cb (dvbbasebin, s); else if (strcmp (structure_name, "pmt") == 0) dvb_base_bin_pmt_info_cb (dvbbasebin, s); } /* chain up */ GST_BIN_CLASS (parent_class)->handle_message (bin, message); }
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 GstStateChangeReturn dvb_base_bin_change_state (GstElement * element, GstStateChange transition) { DvbBaseBin *dvbbasebin; GstStateChangeReturn ret; dvbbasebin = GST_DVB_BASE_BIN (element); ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: dvb_base_bin_init_cam (dvbbasebin); break; case GST_STATE_CHANGE_PAUSED_TO_READY: dvb_base_bin_reset (dvbbasebin); break; default: break; } return ret; }
static void dvb_base_bin_dispose (GObject * object) { DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object); if (!dvbbasebin->disposed) { /* remove mpegtsparse BEFORE dvbsrc, since the mpegtsparse::pad-removed * signal handler uses dvbsrc */ dvb_base_bin_reset (dvbbasebin); if (dvbbasebin->tsparse != NULL) gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->tsparse); gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc); gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->buffer_queue); g_free (dvbbasebin->program_numbers); gst_poll_free (dvbbasebin->poll); gst_object_unref (dvbbasebin->task); g_rec_mutex_clear (&dvbbasebin->lock); dvbbasebin->disposed = TRUE; } if (G_OBJECT_CLASS (parent_class)->dispose) G_OBJECT_CLASS (parent_class)->dispose (object); }