subscribe: rework some more

Track senders in the subscribe object and aggregate events from all
connected clients. This allows each client to get a complete view of all
the objects of pulsevideo. With all the source objects available, we can
then to the selection of the source on each client.

Remove the CreatSourceOutput on the Client1 object but let the client
select a good source and call CreateSourceOutput directly on the source.
This avoid going through the server to get a connection and the client
can just as well select a source.
Add a state property to the source and make it such that it can do async
state changes.

Remove the source provider object, each client can now directly see the
objects of another clients so there is no need for intermediate objects
in the server.
This commit is contained in:
Wim Taymans 2015-04-27 09:05:14 +02:00
parent 89c7955f3d
commit 417cd76f3e
17 changed files with 603 additions and 388 deletions

View file

@ -28,6 +28,7 @@
struct _PvV4l2SourcePrivate
{
GstElement *pipeline;
GstElement *src;
GstElement *sink;
GSocket *socket;
@ -40,13 +41,70 @@ setup_pipeline (PvV4l2Source *source)
{
PvV4l2SourcePrivate *priv = source->priv;
priv->pipeline = gst_parse_launch ("v4l2src ! video/x-raw,width=640,height=480,framerate=30/1 ! "
"pvfdpay ! multisocketsink buffers-max=2 buffers-soft-max=1 "
"recover-policy=latest sync-method=latest name=sink sync=true "
"enable-last-sample=false", NULL);
priv->pipeline = gst_parse_launch ("v4l2src name=src ! "
"video/x-raw,width=640,height=480,framerate=30/1 ! "
"pvfdpay ! "
"multisocketsink "
"buffers-max=2 "
"buffers-soft-max=1 "
"recover-policy=latest "
"sync-method=latest "
"name=sink "
"sync=true "
"enable-last-sample=false",
NULL);
priv->sink = gst_bin_get_by_name (GST_BIN (priv->pipeline), "sink");
priv->src = gst_bin_get_by_name (GST_BIN (priv->pipeline), "src");
}
gst_element_set_state (priv->pipeline, GST_STATE_READY);
static void
collect_capabilities (PvSource * source)
{
PvV4l2SourcePrivate *priv = PV_V4L2_SOURCE (source)->priv;
GstCaps *res;
GstQuery *query;
query = gst_query_new_caps (NULL);
gst_element_query (priv->src, query);
gst_query_parse_caps_result (query, &res);
g_print ("%s\n", gst_caps_to_string (res));
gst_query_unref (query);
}
static gboolean
v4l2_set_state (PvSource *source, PvSourceState state)
{
PvV4l2SourcePrivate *priv = PV_V4L2_SOURCE (source)->priv;
switch (state) {
case PV_SOURCE_STATE_SUSPENDED:
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
break;
case PV_SOURCE_STATE_INIT:
gst_element_set_state (priv->pipeline, GST_STATE_READY);
collect_capabilities (source);
break;
case PV_SOURCE_STATE_IDLE:
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
break;
case PV_SOURCE_STATE_RUNNING:
gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
break;
case PV_SOURCE_STATE_ERROR:
break;
}
pv_source_update_state (source, state);
return TRUE;
}
static GVariant *
v4l2_get_capabilities (PvSource *source, GVariant *props)
{
return NULL;
}
static void
@ -80,10 +138,13 @@ on_socket_notify (GObject *gobject,
static PvSourceOutput *
v4l2_create_source_output (PvSource *source, GVariant *props, const gchar *prefix)
{
PvV4l2SourcePrivate *priv = PV_V4L2_SOURCE (source)->priv;
PvSourceOutput *output;
output = PV_SOURCE_CLASS (pv_v4l2_source_parent_class)->create_source_output (source, props, prefix);
gst_element_set_state (priv->pipeline, GST_STATE_READY);
g_signal_connect (output, "notify::socket", (GCallback) on_socket_notify, source);
return output;
@ -111,6 +172,8 @@ pv_v4l2_source_class_init (PvV4l2SourceClass * klass)
gobject_class->finalize = v4l2_source_finalize;
source_class->get_capabilities = v4l2_get_capabilities;
source_class->set_state = v4l2_set_state;
source_class->create_source_output = v4l2_create_source_output;
source_class->release_source_output = v4l2_release_source_output;
}