reintroduce channels

Bring back the channel object. Making a node and port on the client side
was rather awkward because of the async nature of many methods. It feels
better to have a specific communication channel object to interface with
a server side port.
Use port activate/deactivate to start/stop streams
Remove links from the ports. We let other objects install a callback on
the port to receive and route buffers.
This commit is contained in:
Wim Taymans 2016-07-20 17:29:34 +02:00
parent eefe6aacb9
commit e167d30296
26 changed files with 2840 additions and 675 deletions

View file

@ -74,18 +74,15 @@ gst_pinos_port_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
return TRUE;
}
static void
on_received_buffer (PinosPort *port, gpointer user_data)
static gboolean
on_received_buffer (PinosPort *port, PinosBuffer *pbuf, GError **error, gpointer user_data)
{
GstPinosPortSink *this = user_data;
GstEvent *ev;
PinosBuffer *pbuf;
PinosBufferIter it;
PinosBufferBuilder b;
gboolean have_out = FALSE;
pbuf = pinos_port_peek_buffer (port);
if (this->pinos_input) {
pinos_buffer_builder_init (&b);
}
@ -139,6 +136,7 @@ on_received_buffer (PinosPort *port, gpointer user_data)
pinos_buffer_builder_clear (&b);
}
}
return TRUE;
}
static void
@ -230,7 +228,7 @@ gst_pinos_port_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
PinosBuffer pbuf;
PinosPacketFormatChange fc;
pinos_port_buffer_builder_init (this->port, &builder);
pinos_buffer_builder_init (&builder);
fc.id = 0;
fc.format = cstr = gst_caps_to_string (caps);
pinos_buffer_builder_add_format_change (&builder, &fc);
@ -308,7 +306,7 @@ gst_pinos_port_sink_render_other (GstPinosPortSink * this, GstBuffer * buffer)
hdr.pts = GST_BUFFER_PTS (buffer) + GST_ELEMENT_CAST (this)->base_time;
hdr.dts_offset = 0;
pinos_port_buffer_builder_init (this->port, &builder);
pinos_buffer_builder_init (&builder);
pinos_buffer_builder_add_header (&builder, &hdr);
fdmem = gst_pinos_port_sink_get_fd_memory (this, buffer, &tmpfile);

View file

@ -99,7 +99,7 @@ fdpayload_data_destroy (gpointer user_data)
GST_DEBUG_OBJECT (this, "destroy %d", r.id);
pinos_port_buffer_builder_init (this->port, &b);
pinos_buffer_builder_init (&b);
pinos_buffer_builder_add_release_fd_payload (&b, &r);
pinos_buffer_builder_end (&b, &pbuf);
@ -110,17 +110,17 @@ fdpayload_data_destroy (gpointer user_data)
g_slice_free (FDPayloadData, data);
}
static void
on_received_buffer (PinosPort *port,
gpointer user_data)
static gboolean
on_received_buffer (PinosPort *port,
PinosBuffer *pbuf,
GError **error,
gpointer user_data)
{
GstPinosPortSrc *this = user_data;
PinosBuffer *pbuf;
PinosBufferIter it;
GstBuffer *buf = NULL;
GST_LOG_OBJECT (this, "got new buffer");
pbuf = pinos_port_peek_buffer (port);
pinos_buffer_iter_init (&it, pbuf);
while (pinos_buffer_iter_next (&it)) {
@ -199,7 +199,7 @@ on_received_buffer (PinosPort *port,
g_cond_signal (&this->cond);
}
return;
return TRUE;
}
static void
@ -462,7 +462,7 @@ gst_pinos_port_src_event (GstBaseSrc * src, GstEvent * event)
refresh.request_type = all_headers ? 1 : 0;
refresh.pts = running_time;
pinos_port_buffer_builder_init (this->port, &b);
pinos_buffer_builder_init (&b);
pinos_buffer_builder_add_refresh_request (&b, &refresh);
pinos_buffer_builder_end (&b, &pbuf);

View file

@ -275,34 +275,38 @@ static GstCaps *
gst_pinos_src_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
GstStructure *structure;
const gchar *name;
caps = gst_caps_make_writable (caps);
structure = gst_caps_get_structure (caps, 0);
name = gst_structure_get_name (structure);
if (gst_structure_has_name (structure, "video/x-raw")) {
if (g_str_has_prefix (name, "video/") || g_str_has_prefix (name, "image/")) {
gst_structure_fixate_field_nearest_int (structure, "width", 320);
gst_structure_fixate_field_nearest_int (structure, "height", 240);
gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
gst_structure_fixate_field_nearest_fraction (structure,
"pixel-aspect-ratio", 1, 1);
else
gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
NULL);
if (gst_structure_has_field (structure, "colorimetry"))
gst_structure_fixate_field_string (structure, "colorimetry", "bt601");
if (gst_structure_has_field (structure, "chroma-site"))
gst_structure_fixate_field_string (structure, "chroma-site", "mpeg2");
if (strcmp (name, "video/x-raw") == 0) {
if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
gst_structure_fixate_field_nearest_fraction (structure,
"pixel-aspect-ratio", 1, 1);
else
gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
NULL);
if (gst_structure_has_field (structure, "colorimetry"))
gst_structure_fixate_field_string (structure, "colorimetry", "bt601");
if (gst_structure_has_field (structure, "chroma-site"))
gst_structure_fixate_field_string (structure, "chroma-site", "mpeg2");
if (gst_structure_has_field (structure, "interlace-mode"))
gst_structure_fixate_field_string (structure, "interlace-mode",
"progressive");
else
gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
"progressive", NULL);
if (gst_structure_has_field (structure, "interlace-mode"))
gst_structure_fixate_field_string (structure, "interlace-mode",
"progressive");
else
gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
"progressive", NULL);
}
} else if (gst_structure_has_name (structure, "audio/x-raw")) {
gst_structure_fixate_field_string (structure, "format", "S16LE");
gst_structure_fixate_field_nearest_int (structure, "channels", 2);
@ -562,9 +566,16 @@ gst_pinos_src_stream_start (GstPinosSrc *pinossrc, GstCaps * caps)
}
g_object_get (pinossrc->stream, "properties", &props, NULL);
g_object_get (pinossrc->stream, "format", &format, NULL);
pinos_main_loop_unlock (pinossrc->loop);
if (format) {
caps = gst_caps_from_string (g_bytes_get_data (format, NULL));
gst_base_src_set_caps (GST_BASE_SRC (pinossrc), caps);
g_bytes_unref (format);
}
parse_stream_properties (pinossrc, props);
pinos_properties_free (props);
@ -600,6 +611,8 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc)
GstCaps *caps = NULL;
GstCaps *peercaps = NULL;
gboolean result = FALSE;
GBytes *possible;
gchar *str;
/* first see what is possible on our source pad */
thiscaps = gst_pad_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
@ -622,62 +635,57 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc)
/* no peer, work with our own caps then */
caps = thiscaps;
}
if (caps && !gst_caps_is_empty (caps)) {
GBytes *accepted;
gchar *str;
if (caps == NULL || gst_caps_is_empty (caps))
goto no_common_caps;
GST_DEBUG_OBJECT (basesrc, "have caps: %" GST_PTR_FORMAT, caps);
GST_DEBUG_OBJECT (basesrc, "have common caps: %" GST_PTR_FORMAT, caps);
/* open a connection with these caps */
str = gst_caps_to_string (caps);
accepted = g_bytes_new_take (str, strlen (str) + 1);
/* first disconnect */
pinos_main_loop_lock (pinossrc->loop);
if (pinos_stream_get_state (pinossrc->stream) != PINOS_STREAM_STATE_UNCONNECTED) {
GST_DEBUG_OBJECT (basesrc, "disconnect capture");
pinos_stream_disconnect (pinossrc->stream);
while (TRUE) {
PinosStreamState state = pinos_stream_get_state (pinossrc->stream);
if (state == PINOS_STREAM_STATE_UNCONNECTED)
break;
if (state == PINOS_STREAM_STATE_ERROR) {
g_bytes_unref (accepted);
goto connect_error;
}
pinos_main_loop_wait (pinossrc->loop);
}
}
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pinossrc->path);
pinos_stream_connect (pinossrc->stream,
PINOS_DIRECTION_INPUT,
pinossrc->path,
PINOS_STREAM_FLAG_AUTOCONNECT,
accepted);
/* open a connection with these caps */
str = gst_caps_to_string (caps);
possible = g_bytes_new_take (str, strlen (str) + 1);
/* first disconnect */
pinos_main_loop_lock (pinossrc->loop);
if (pinos_stream_get_state (pinossrc->stream) != PINOS_STREAM_STATE_UNCONNECTED) {
GST_DEBUG_OBJECT (basesrc, "disconnect capture");
pinos_stream_disconnect (pinossrc->stream);
while (TRUE) {
PinosStreamState state = pinos_stream_get_state (pinossrc->stream);
if (state == PINOS_STREAM_STATE_READY)
if (state == PINOS_STREAM_STATE_UNCONNECTED)
break;
if (state == PINOS_STREAM_STATE_ERROR)
if (state == PINOS_STREAM_STATE_ERROR) {
g_bytes_unref (possible);
goto connect_error;
}
pinos_main_loop_wait (pinossrc->loop);
}
pinos_main_loop_unlock (pinossrc->loop);
result = gst_pinos_src_stream_start (pinossrc, NULL);
} else {
if (caps)
gst_caps_unref (caps);
GST_DEBUG_OBJECT (basesrc, "no common caps");
}
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pinossrc->path);
pinos_stream_connect (pinossrc->stream,
PINOS_DIRECTION_INPUT,
pinossrc->path,
PINOS_STREAM_FLAG_AUTOCONNECT,
possible);
while (TRUE) {
PinosStreamState state = pinos_stream_get_state (pinossrc->stream);
if (state == PINOS_STREAM_STATE_READY)
break;
if (state == PINOS_STREAM_STATE_ERROR)
goto connect_error;
pinos_main_loop_wait (pinossrc->loop);
}
pinos_main_loop_unlock (pinossrc->loop);
result = gst_pinos_src_stream_start (pinossrc, NULL);
pinossrc->negotiated = result;
return result;
@ -696,7 +704,16 @@ no_caps:
("This element did not produce valid caps"));
if (thiscaps)
gst_caps_unref (thiscaps);
return TRUE;
return FALSE;
}
no_common_caps:
{
GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
("No supported formats found"),
("This element does not have formats in common with the peer"));
if (caps)
gst_caps_unref (caps);
return FALSE;
}
connect_error:
{