static GstFlowReturn gst_shm_sink_render (GstBaseSink * bsink, GstBuffer * buf) { GstShmSink *self = GST_SHM_SINK (bsink); int rv; GstMapInfo map; GST_OBJECT_LOCK (self); while (self->wait_for_connection && !self->clients) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { GST_OBJECT_UNLOCK (self); return GST_FLOW_FLUSHING; } } while (!gst_shm_sink_can_render (self, GST_BUFFER_TIMESTAMP (buf))) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { GST_OBJECT_UNLOCK (self); return GST_FLOW_FLUSHING; } } gst_buffer_map (buf, &map, GST_MAP_READ); rv = sp_writer_send_buf (self->pipe, (char *) map.data, map.size, GST_BUFFER_TIMESTAMP (buf)); gst_buffer_unmap (buf, &map); if (rv == -1) { ShmBlock *block = NULL; gchar *shmbuf = NULL; while ((block = sp_writer_alloc_block (self->pipe, gst_buffer_get_size (buf))) == NULL) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { GST_OBJECT_UNLOCK (self); return GST_FLOW_FLUSHING; } } while (self->wait_for_connection && !self->clients) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { sp_writer_free_block (block); GST_OBJECT_UNLOCK (self); return GST_FLOW_FLUSHING; } } shmbuf = sp_writer_block_get_buf (block); gst_buffer_extract (buf, 0, shmbuf, gst_buffer_get_size (buf)); sp_writer_send_buf (self->pipe, shmbuf, gst_buffer_get_size (buf), GST_BUFFER_TIMESTAMP (buf)); sp_writer_free_block (block); } GST_OBJECT_UNLOCK (self); return GST_FLOW_OK; }
static GstFlowReturn gst_shm_sink_render (GstBaseSink * bsink, GstBuffer * buf) { GstShmSink *self = GST_SHM_SINK (bsink); int rv; GST_OBJECT_LOCK (self); while (self->wait_for_connection && !self->clients) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { GST_OBJECT_UNLOCK (self); return GST_FLOW_WRONG_STATE; } } rv = sp_writer_send_buf (self->pipe, (char *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); if (rv == -1) { ShmBlock *block = NULL; gchar *shmbuf = NULL; while ((block = sp_writer_alloc_block (self->pipe, GST_BUFFER_SIZE (buf))) == NULL) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { GST_OBJECT_UNLOCK (self); return GST_FLOW_WRONG_STATE; } } while (self->wait_for_connection && !self->clients) { g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self)); if (self->unlock) { sp_writer_free_block (block); GST_OBJECT_UNLOCK (self); return GST_FLOW_WRONG_STATE; } } shmbuf = sp_writer_block_get_buf (block); memcpy (shmbuf, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); sp_writer_send_buf (self->pipe, shmbuf, GST_BUFFER_SIZE (buf)); sp_writer_free_block (block); } GST_OBJECT_UNLOCK (self); return GST_FLOW_OK; }
static void gst_shm_sink_allocator_free (GstAllocator * allocator, GstMemory * mem) { GstShmSinkMemory *mymem = (GstShmSinkMemory *) mem; if (mymem->block) { GST_OBJECT_LOCK (mymem->sink); sp_writer_free_block (mymem->block); GST_OBJECT_UNLOCK (mymem->sink); gst_object_unref (mymem->sink); } gst_object_unref (mem->allocator); g_slice_free (GstShmSinkMemory, mymem); }
static void gst_shm_sink_free_buffer (gpointer data) { ShmPipe *pipe; ShmBlock *block = data; GstShmSink *self; pipe = sp_writer_block_get_pipe (block); self = sp_get_data (pipe); GST_OBJECT_LOCK (self); sp_writer_free_block (block); GST_OBJECT_UNLOCK (self); g_object_unref (self); }
/** * shm_writer_send_buffer * @self: the #ShmWriter with which to send the data buffer * @buffer: the data buffer to send to all connected clients * @len: the length of the data @buffer * * Sends a buffer of data to all connected clients. The data is internally * copied into the appropriate shm area so the passed buffer doesn't need * to be saved. * * Returns: the number of clients the buffer was successfully sent to or %-1 * on error. This number only signifies that it was sent successfully, * not that the clients processed it successfully. */ int shm_writer_send_buffer (ShmWriter *self, const gchar *buffer, gsize len) { ShmWriterPrivate *priv = self->priv; ShmBlock *block; gchar *buf; int ret; if (!priv->open) { g_debug ("ShmWriter not open"); return SHM_WRITER_FAILURE; } /* Allocating, copying, and freeing all this may seem silly, * but the data needs to be in the correct range in memory * in order to share it with other processes */ g_mutex_lock (priv->lock); block = sp_writer_alloc_block (priv->writer, len); if (block == NULL) { g_debug ("ShmWriter: unable to allocate block"); g_mutex_unlock (priv->lock); return SHM_WRITER_FAILURE; } buf = sp_writer_block_get_buf (block); memcpy (buf, buffer, len); ret = sp_writer_send_buf (priv->writer, buf, len); sp_writer_free_block (block); g_mutex_unlock (priv->lock); return ret; }
static void gst_shm_sink_free_buffer (gpointer data) { ShmBlock *block = data; sp_writer_free_block (block); }