+ GstCaps *caps;
+
+ /* TRUE: send them if the new caps have them */
+ gboolean send_streamheader = FALSE;
+ GstStructure *s;
+
+
+ /* before we queue the buffer, we check if we need to queue streamheader
+ * buffers (because it's a new client, or because they changed) */
+ caps = gst_buffer_get_caps (buffer); /* cleaned up after streamheader */
+ if (!client->caps) {
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] no previous caps for this client, send streamheader",
+ client->fd.fd);
+ send_streamheader = TRUE;
+ client->caps = gst_caps_ref (caps);
+ } else {
+ /* there were previous caps recorded, so compare */
+ if (!gst_caps_is_equal (caps, client->caps)) {
+ const GValue *sh1, *sh2;
+
+ /* caps are not equal, but could still have the same streamheader */
+ s = gst_caps_get_structure (caps, 0);
+ if (!gst_structure_has_field (s, "streamheader")) {
+ /* no new streamheader, so nothing new to send */
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] new caps do not have streamheader, not sending",
+ client->fd.fd);
+ } else {
+ /* there is a new streamheader */
+ s = gst_caps_get_structure (client->caps, 0);
+ if (!gst_structure_has_field (s, "streamheader")) {
+ /* no previous streamheader, so send the new one */
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] previous caps did not have streamheader, sending",
+ client->fd.fd);
+ send_streamheader = TRUE;
+ } else {
+ /* both old and new caps have streamheader set */
+ sh1 = gst_structure_get_value (s, "streamheader");
+ s = gst_caps_get_structure (caps, 0);
+ sh2 = gst_structure_get_value (s, "streamheader");
+ if (gst_value_compare (sh1, sh2) != GST_VALUE_EQUAL) {
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] new streamheader different from old, sending",
+ client->fd.fd);
+ send_streamheader = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ if (G_UNLIKELY (send_streamheader)) {
+ const GValue *sh;
+ GArray *buffers;
+ int i;
+
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] sending streamheader from caps %" GST_PTR_FORMAT,
+ client->fd.fd, caps);
+ s = gst_caps_get_structure (caps, 0);
+ if (!gst_structure_has_field (s, "streamheader")) {
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] no new streamheader, so nothing to send", client->fd.fd);
+ } else {
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] sending streamheader from caps %" GST_PTR_FORMAT,
+ client->fd.fd, caps);
+ sh = gst_structure_get_value (s, "streamheader");
+ g_assert (G_VALUE_TYPE (sh) == GST_TYPE_ARRAY);
+ buffers = g_value_peek_pointer (sh);
+ for (i = 0; i < buffers->len; ++i) {
+ GValue *bufval;
+ GstBuffer *buffer;
+
+ bufval = &g_array_index (buffers, GValue, i);
+ g_assert (G_VALUE_TYPE (bufval) == GST_TYPE_BUFFER);
+ buffer = g_value_peek_pointer (bufval);
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] queueing streamheader buffer of length %d",
+ client->fd.fd, GST_BUFFER_SIZE (buffer));
+ gst_buffer_ref (buffer);
+
+ if (sink->protocol == GST_TCP_PROTOCOL_GDP) {
+ guint8 *header;
+ guint len;
+
+ if (!gst_dp_header_from_buffer (buffer, sink->header_flags, &len,
+ &header)) {
+ GST_DEBUG_OBJECT (sink,
+ "[fd %5d] could not create header, removing client",
+ client->fd.fd);
+ return FALSE;
+ }
+ gst_multi_fd_sink_client_queue_data (sink, client, (gchar *) header,
+ len);
+ }
+
+ client->sending = g_slist_append (client->sending, buffer);
+ }
+ }
+ }
+
+ gst_caps_unref (caps);
+ caps = NULL;
+ /* now we can send the buffer, possibly sending a GDP header first */