static void gst_scream_queue_finalize(GObject *object) { GstScreamQueue *self = GST_SCREAM_QUEUE(object); GstDataQueueItem *item; while (!gst_data_queue_is_empty(self->approved_packets)) { gst_data_queue_pop(self->approved_packets, &item); item->destroy(item); } gst_object_unref(self->approved_packets); while ((item = (GstDataQueueItem *)g_async_queue_try_pop(self->incoming_packets))) { item->destroy(item); } g_async_queue_unref(self->incoming_packets); g_hash_table_unref(self->streams); g_hash_table_unref(self->adapted_stream_ids); g_hash_table_unref(self->ignored_stream_ids); if (self->scream_controller) { g_object_unref(self->scream_controller); } G_OBJECT_CLASS(parent_class)->finalize (object); }
static void gst_sctp_data_srcpad_loop(GstPad *pad) { GstSctpDecPad *sctpdec_pad = GST_SCTP_DEC_PAD(pad); GstDataQueueItem *item; if (gst_data_queue_pop(sctpdec_pad->packet_queue, &item)) { GstFlowReturn flow_ret; flow_ret = gst_pad_push(pad, GST_BUFFER(item->object)); item->object = NULL; if (G_UNLIKELY(flow_ret == GST_FLOW_FLUSHING || flow_ret == GST_FLOW_NOT_LINKED)) { GST_DEBUG_OBJECT(pad, "Push failed on packet source pad. Error: %s", gst_flow_get_name(flow_ret)); } else if (G_UNLIKELY(flow_ret != GST_FLOW_OK)) { GST_ERROR_OBJECT(pad, "Push failed on packet source pad. Error: %s", gst_flow_get_name(flow_ret)); } if (G_UNLIKELY(flow_ret != GST_FLOW_OK)) { GST_DEBUG_OBJECT(pad, "Pausing task because of an error"); gst_data_queue_set_flushing(sctpdec_pad->packet_queue, TRUE); gst_data_queue_flush(sctpdec_pad->packet_queue); gst_pad_pause_task(pad); } item->destroy(item); } else { GST_DEBUG_OBJECT(pad, "Pausing task because we're flushing"); gst_pad_pause_task(pad); } }
static void clear_packet_queue(GstAtomicQueue *queue) { GstDataQueueItem *item; while ((item = gst_atomic_queue_pop(queue))) { item->destroy(item); } }
static void gst_data_queue_cleanup (GstDataQueue * queue) { while (!g_queue_is_empty (queue->queue)) { GstDataQueueItem *item = g_queue_pop_head (queue->queue); /* Just call the destroy notify on the item */ item->destroy (item); } queue->cur_level.visible = 0; queue->cur_level.bytes = 0; queue->cur_level.time = 0; }
static void gst_data_queue_cleanup (GstDataQueue * queue) { GstDataQueuePrivate *priv = queue->priv; while (!gst_queue_array_is_empty (priv->queue)) { GstDataQueueItem *item = gst_queue_array_pop_head (priv->queue); /* Just call the destroy notify on the item */ item->destroy (item); } priv->cur_level.visible = 0; priv->cur_level.bytes = 0; priv->cur_level.time = 0; }
EXPORT_C #endif gboolean gst_data_queue_drop_head (GstDataQueue * queue, GType type) { gboolean res = FALSE; GList *item; GstDataQueueItem *leak = NULL; g_return_val_if_fail (GST_IS_DATA_QUEUE (queue), FALSE); GST_DEBUG ("queue:%p", queue); GST_DATA_QUEUE_MUTEX_LOCK (queue); for (item = g_queue_peek_head_link (queue->queue); item; item = item->next) { GstDataQueueItem *tmp = (GstDataQueueItem *) item->data; if (G_TYPE_CHECK_INSTANCE_TYPE (tmp->object, type)) { leak = tmp; break; } } if (!leak) goto done; g_queue_delete_link (queue->queue, item); if (leak->visible) queue->cur_level.visible--; queue->cur_level.bytes -= leak->size; queue->cur_level.time -= leak->duration; leak->destroy (leak); res = TRUE; done: GST_DATA_QUEUE_MUTEX_UNLOCK (queue); GST_DEBUG ("queue:%p , res:%d", queue, res); return res; }
static GstFlowReturn gst_eglglessink_queue_buffer (GstEglGlesSink * eglglessink, GstBuffer * buf) { GstDataQueueItem *item; GstFlowReturn last_flow; g_mutex_lock (eglglessink->render_lock); last_flow = eglglessink->last_flow; g_mutex_unlock (eglglessink->render_lock); if (last_flow != GST_FLOW_OK) return last_flow; item = g_slice_new0 (GstDataQueueItem); item->object = GST_MINI_OBJECT_CAST (buf); item->size = (buf ? GST_BUFFER_SIZE (buf) : 0); item->duration = (buf ? GST_BUFFER_DURATION (buf) : GST_CLOCK_TIME_NONE); item->visible = (buf ? TRUE : FALSE); item->destroy = (GDestroyNotify) queue_item_destroy; GST_DEBUG_OBJECT (eglglessink, "Queueing buffer %" GST_PTR_FORMAT, buf); if (buf) g_mutex_lock (eglglessink->render_lock); if (!gst_data_queue_push (eglglessink->queue, item)) { item->destroy (item); g_mutex_unlock (eglglessink->render_lock); GST_DEBUG_OBJECT (eglglessink, "Flushing"); return GST_FLOW_WRONG_STATE; } if (buf) { GST_DEBUG_OBJECT (eglglessink, "Waiting for buffer to be rendered"); g_cond_wait (eglglessink->render_cond, eglglessink->render_lock); GST_DEBUG_OBJECT (eglglessink, "Buffer rendered: %s", gst_flow_get_name (eglglessink->last_flow)); last_flow = eglglessink->last_flow; g_mutex_unlock (eglglessink->render_lock); } return (buf ? last_flow : GST_FLOW_OK); }
/** * gst_data_queue_drop_head: * @queue: The #GstDataQueue to drop an item from. * @type: The #GType of the item to drop. * * Pop and unref the head-most #GstMiniObject with the given #GType. * * Returns: TRUE if an element was removed. * * Since: 1.2.0 */ gboolean gst_data_queue_drop_head (GstDataQueue * queue, GType type) { gboolean res = FALSE; GstDataQueueItem *leak = NULL; guint idx; GstDataQueuePrivate *priv = queue->priv; g_return_val_if_fail (GST_IS_DATA_QUEUE (queue), FALSE); GST_DEBUG ("queue:%p", queue); GST_DATA_QUEUE_MUTEX_LOCK (queue); idx = gst_queue_array_find (priv->queue, is_of_type, GSIZE_TO_POINTER (type)); if (idx == -1) goto done; leak = gst_queue_array_drop_element (priv->queue, idx); if (leak->visible) priv->cur_level.visible--; priv->cur_level.bytes -= leak->size; priv->cur_level.time -= leak->duration; leak->destroy (leak); res = TRUE; done: GST_DATA_QUEUE_MUTEX_UNLOCK (queue); GST_DEBUG ("queue:%p , res:%d", queue, res); return res; }
static gpointer render_thread_func (GstEglGlesSink * eglglessink) { GstMessage *message; GValue val = { 0 }; GstDataQueueItem *item = NULL; GstFlowReturn last_flow = GST_FLOW_OK; g_value_init (&val, G_TYPE_POINTER); g_value_set_pointer (&val, g_thread_self ()); message = gst_message_new_stream_status (GST_OBJECT_CAST (eglglessink), GST_STREAM_STATUS_TYPE_ENTER, GST_ELEMENT_CAST (eglglessink)); gst_message_set_stream_status_object (message, &val); GST_DEBUG_OBJECT (eglglessink, "posting ENTER stream status"); gst_element_post_message (GST_ELEMENT_CAST (eglglessink), message); g_value_unset (&val); gst_egl_adaptation_bind_API (eglglessink->egl_context); while (gst_data_queue_pop (eglglessink->queue, &item)) { GstBuffer *buf = NULL; GstMiniObject *object = item->object; GST_DEBUG_OBJECT (eglglessink, "Handling object %" GST_PTR_FORMAT, object); if (GST_IS_BUFFER (object)) { GstCaps *caps; buf = GST_BUFFER_CAST (item->object); caps = GST_BUFFER_CAPS (buf); if (caps != eglglessink->configured_caps) { if (!gst_eglglessink_configure_caps (eglglessink, caps)) { g_mutex_lock (eglglessink->render_lock); eglglessink->last_flow = GST_FLOW_NOT_NEGOTIATED; g_cond_broadcast (eglglessink->render_cond); g_mutex_unlock (eglglessink->render_lock); item->destroy (item); break; } } if (eglglessink->configured_caps) { last_flow = gst_eglglessink_upload (eglglessink, buf); if (last_flow == GST_FLOW_OK) { last_flow = gst_eglglessink_render (eglglessink); } } else { GST_DEBUG_OBJECT (eglglessink, "No caps configured yet, not drawing anything"); } } else if (!object) { if (eglglessink->configured_caps) { last_flow = gst_eglglessink_render (eglglessink); } else { last_flow = GST_FLOW_OK; GST_DEBUG_OBJECT (eglglessink, "No caps configured yet, not drawing anything"); } } else { g_assert_not_reached (); } item->destroy (item); g_mutex_lock (eglglessink->render_lock); eglglessink->last_flow = last_flow; g_cond_broadcast (eglglessink->render_cond); g_mutex_unlock (eglglessink->render_lock); if (last_flow != GST_FLOW_OK) break; GST_DEBUG_OBJECT (eglglessink, "Successfully handled object"); } if (last_flow == GST_FLOW_OK) { g_mutex_lock (eglglessink->render_lock); eglglessink->last_flow = GST_FLOW_WRONG_STATE; g_cond_broadcast (eglglessink->render_cond); g_mutex_unlock (eglglessink->render_lock); } GST_DEBUG_OBJECT (eglglessink, "Shutting down thread"); /* EGL/GLES cleanup */ gst_egl_adaptation_cleanup (eglglessink->egl_context); if (eglglessink->configured_caps) { gst_caps_unref (eglglessink->configured_caps); eglglessink->configured_caps = NULL; } g_value_init (&val, G_TYPE_POINTER); g_value_set_pointer (&val, g_thread_self ()); message = gst_message_new_stream_status (GST_OBJECT_CAST (eglglessink), GST_STREAM_STATUS_TYPE_LEAVE, GST_ELEMENT_CAST (eglglessink)); gst_message_set_stream_status_object (message, &val); GST_DEBUG_OBJECT (eglglessink, "posting LEAVE stream status"); gst_element_post_message (GST_ELEMENT_CAST (eglglessink), message); g_value_unset (&val); return NULL; }