static void gst_scream_data_queue_rtp_item_free(GstScreamDataQueueRtpItem *item) { if (((GstDataQueueItem *)item)->object) { gst_mini_object_unref(((GstDataQueueItem *)item)->object); } g_slice_free(GstScreamDataQueueRtpItem, item); }
void test_unref_threaded() { GstBuffer *buffer; GstMiniObject *mobj; int i; xmlfile = "gstminiobject_test_unref_threaded"; std_log(LOG_FILENAME_LINE, "Test Started test_unref_threaded"); buffer = gst_buffer_new_and_alloc (4); mobj = GST_MINI_OBJECT (buffer); for (i = 0; i < num_threads * refs_per_thread; ++i) gst_mini_object_ref (mobj); MAIN_START_THREADS (num_threads, thread_unref, mobj); MAIN_STOP_THREADS (); ASSERT_MINI_OBJECT_REFCOUNT (mobj, "miniobject", 1); /* final unref */ gst_mini_object_unref (mobj); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
GstBuffer* gst_omxbuffertransport_new (GOmxPort *port, OMX_BUFFERHEADERTYPE *buffer) { GstOmxBufferTransport *tdt_buf; tdt_buf = (GstOmxBufferTransport*) gst_mini_object_new(GST_TYPE_OMXBUFFERTRANSPORT); g_return_val_if_fail(tdt_buf != NULL, NULL); GST_BUFFER_SIZE(tdt_buf) = buffer->nFilledLen; GST_BUFFER_DATA(tdt_buf) = buffer->pBuffer; gst_buffer_set_caps(GST_BUFFER (tdt_buf), port->caps); if (GST_BUFFER_DATA(tdt_buf) == NULL) { gst_mini_object_unref(GST_MINI_OBJECT(tdt_buf)); return NULL; } tdt_buf->omxbuffer = buffer; tdt_buf->port = port; GST_LOG("end new\n"); return GST_BUFFER(tdt_buf); }
static void gst_app_sink_dispose (GObject * obj) { GstAppSink *appsink = GST_APP_SINK (obj); GstMiniObject *queue_obj; GST_OBJECT_LOCK (appsink); if (appsink->priv->caps) { gst_caps_unref (appsink->priv->caps); appsink->priv->caps = NULL; } if (appsink->priv->notify) { appsink->priv->notify (appsink->priv->user_data); } appsink->priv->user_data = NULL; appsink->priv->notify = NULL; GST_OBJECT_UNLOCK (appsink); g_mutex_lock (appsink->priv->mutex); if (appsink->priv->preroll) { gst_buffer_unref (appsink->priv->preroll); appsink->priv->preroll = NULL; } while ((queue_obj = g_queue_pop_head (appsink->priv->queue))) gst_mini_object_unref (queue_obj); g_mutex_unlock (appsink->priv->mutex); G_OBJECT_CLASS (parent_class)->dispose (obj); }
/** * gst_v4l2_buffer_pool_destroy: * @pool: the pool * * Free all resources in the pool and the pool itself. */ void gst_v4l2_buffer_pool_destroy (GstV4l2BufferPool * pool) { gint n; GST_V4L2_BUFFER_POOL_LOCK (pool); pool->running = FALSE; GST_V4L2_BUFFER_POOL_UNLOCK (pool); GST_DEBUG_OBJECT (pool->v4l2elem, "destroy pool"); /* after this point, no more buffers will be queued or dequeued; no buffer * from pool->buffers that is NULL will be set to a buffer, and no buffer that * is not NULL will be pushed out. */ /* miniobjects have no dispose, so they can't break ref-cycles, as buffers ref * the pool, we need to unref the buffer to properly finalize te pool */ for (n = 0; n < pool->buffer_count; n++) { GstBuffer *buf; GST_V4L2_BUFFER_POOL_LOCK (pool); buf = GST_BUFFER (pool->buffers[n]); GST_V4L2_BUFFER_POOL_UNLOCK (pool); if (buf) /* we own the ref if the buffer is in pool->buffers; drop it. */ gst_buffer_unref (buf); } gst_mini_object_unref (GST_MINI_OBJECT (pool)); }
static void gst_value_mini_object_free (GValue * value) { if (value->data[0].v_pointer) { gst_mini_object_unref (GST_MINI_OBJECT_CAST (value->data[0].v_pointer)); } }
/** * gst_mini_object_replace: * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to * be replaced * @newdata: pointer to new mini-object * * Atomically modifies a pointer to point to a new mini-object. * The reference count of @olddata is decreased and the reference count of * @newdata is increased. * * Either @newdata and the value pointed to by @olddata may be NULL. * * Returns: TRUE if @newdata was different from @olddata */ gboolean gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata) { GstMiniObject *olddata_val; g_return_val_if_fail (olddata != NULL, FALSE); GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p (%d) with %p (%d)", *olddata, *olddata ? (*olddata)->refcount : 0, newdata, newdata ? newdata->refcount : 0); olddata_val = g_atomic_pointer_get ((gpointer *) olddata); if (G_UNLIKELY (olddata_val == newdata)) return FALSE; if (newdata) gst_mini_object_ref (newdata); while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata, olddata_val, newdata))) { olddata_val = g_atomic_pointer_get ((gpointer *) olddata); if (G_UNLIKELY (olddata_val == newdata)) break; } if (olddata_val) gst_mini_object_unref (olddata_val); return olddata_val != newdata; }
/** * gst_mini_object_replace: * @olddata: pointer to a pointer to a mini-object to be replaced * @newdata: pointer to new mini-object * * Modifies a pointer to point to a new mini-object. The modification * is done atomically, and the reference counts are updated correctly. * Either @newdata and the value pointed to by @olddata may be NULL. */ void gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata) { GstMiniObject *olddata_val; g_return_if_fail (olddata != NULL); #ifdef DEBUG_REFCOUNT GST_CAT_LOG (GST_CAT_REFCOUNTING, "replace %p (%d) with %p (%d)", *olddata, *olddata ? (*olddata)->refcount : 0, newdata, newdata ? newdata->refcount : 0); #endif olddata_val = g_atomic_pointer_get ((gpointer *) olddata); if (olddata_val == newdata) return; if (newdata) gst_mini_object_ref (newdata); while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata, olddata_val, newdata)) { olddata_val = g_atomic_pointer_get ((gpointer *) olddata); } if (olddata_val) gst_mini_object_unref (olddata_val); }
void gst_pvr_bufferpool_stop_running (GstPvrBufferPool * self, gboolean unwrap) { gboolean empty = FALSE; g_return_if_fail (self); GST_PVR_BUFFERPOOL_LOCK (self); self->running = FALSE; GST_PVR_BUFFERPOOL_UNLOCK (self); GST_DEBUG_OBJECT (self->element, "free available buffers"); /* free all buffers on the freelist */ while (!empty) { GstDucatiBuffer *buf; GST_PVR_BUFFERPOOL_LOCK (self); buf = g_queue_pop_head (self->free_buffers); GST_PVR_BUFFERPOOL_UNLOCK (self); if (buf) gst_buffer_unref (GST_BUFFER (buf)); else empty = TRUE; } if (unwrap) g_queue_foreach (self->used_buffers, unwrap_buffer, self); gst_mini_object_unref (GST_MINI_OBJECT (self)); }
void poll_the_bus (GstBus * bus) { GstMessage *message; gboolean carry_on = TRUE; while (carry_on) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10); if (message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: /* we should check if we really finished here */ GST_DEBUG ("Got an EOS"); carry_on = FALSE; break; case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: /* We shouldn't see any segement messages, since we didn't do a segment seek */ GST_WARNING ("Saw a Segment start/stop"); fail_if (TRUE); break; case GST_MESSAGE_ERROR: fail_error_message (message); default: break; } gst_mini_object_unref (GST_MINI_OBJECT (message)); } } }
void MiniObject::unref() { if (Private::ObjectStore::take(this)) { gst_mini_object_unref(GST_MINI_OBJECT(m_object)); delete this; } }
static void gst_app_sink_dispose (GObject * obj) { GstAppSink *appsink = GST_APP_SINK_CAST (obj); GstAppSinkPrivate *priv = appsink->priv; GstMiniObject *queue_obj; GST_OBJECT_LOCK (appsink); if (priv->caps) { gst_caps_unref (priv->caps); priv->caps = NULL; } if (priv->notify) { priv->notify (priv->user_data); } priv->user_data = NULL; priv->notify = NULL; GST_OBJECT_UNLOCK (appsink); g_mutex_lock (priv->mutex); while ((queue_obj = g_queue_pop_head (priv->queue))) gst_mini_object_unref (queue_obj); gst_buffer_replace (&priv->preroll, NULL); gst_caps_replace (&priv->preroll_caps, NULL); gst_caps_replace (&priv->last_caps, NULL); g_mutex_unlock (priv->mutex); G_OBJECT_CLASS (parent_class)->dispose (obj); }
static gboolean queue_object (APP_STATE_T * state, GstMiniObject * obj, gboolean synchronous) { gboolean res = TRUE; g_mutex_lock (state->queue_lock); if (state->flushing) { gst_mini_object_unref (obj); res = FALSE; goto beach; } g_async_queue_push (state->queue, obj); if (synchronous) { /* Waiting for object to be handled */ do { g_cond_wait (state->cond, state->queue_lock); } while (!state->flushing && state->popped_obj != obj); } beach: g_mutex_unlock (state->queue_lock); return res; }
static GstFlowReturn gst_app_sink_render_common (GstBaseSink * psink, GstMiniObject * data, gboolean is_list) { GstAppSink *appsink = GST_APP_SINK (psink); gboolean emit; g_mutex_lock (appsink->priv->mutex); if (appsink->priv->flushing) goto flushing; GST_DEBUG_OBJECT (appsink, "pushing render buffer%s %p on queue (%d)", is_list ? " list" : "", data, appsink->priv->queue->length); while (appsink->priv->max_buffers > 0 && appsink->priv->queue->length >= appsink->priv->max_buffers) { if (appsink->priv->drop) { GstMiniObject *obj; /* we need to drop the oldest buffer/list and try again */ obj = g_queue_pop_head (appsink->priv->queue); GST_DEBUG_OBJECT (appsink, "dropping old buffer/list %p", obj); gst_mini_object_unref (obj); } else { GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d", appsink->priv->queue->length, appsink->priv->max_buffers); /* wait for a buffer to be removed or flush */ g_cond_wait (appsink->priv->cond, appsink->priv->mutex); if (appsink->priv->flushing) goto flushing; } } /* we need to ref the buffer when pushing it in the queue */ g_queue_push_tail (appsink->priv->queue, gst_mini_object_ref (data)); g_cond_signal (appsink->priv->cond); emit = appsink->priv->emit_signals; g_mutex_unlock (appsink->priv->mutex); if (is_list) { if (appsink->priv->callbacks.new_buffer_list) appsink->priv->callbacks.new_buffer_list (appsink, appsink->priv->user_data); } else { if (appsink->priv->callbacks.new_buffer) appsink->priv->callbacks.new_buffer (appsink, appsink->priv->user_data); else if (emit) g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_BUFFER], 0); } return GST_FLOW_OK; flushing: { GST_DEBUG_OBJECT (appsink, "we are flushing"); g_mutex_unlock (appsink->priv->mutex); return GST_FLOW_WRONG_STATE; } }
static void gst_render_bridge_finalize (GstBufferClassSink * bcsink) { GST_DEBUG_OBJECT (bcsink, "ENTER"); if (G_LIKELY (bcsink->pool)) { gst_mini_object_unref (GST_MINI_OBJECT (bcsink->pool)); bcsink->pool = NULL; } G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (bcsink)); }
static void gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer) { GstV4l2BufferPool *pool; gboolean resuscitated = FALSE; gint index; pool = buffer->pool; index = buffer->vbuffer.index; GST_LOG_OBJECT (pool->v4l2elem, "finalizing buffer %p %d", buffer, index); GST_V4L2_BUFFER_POOL_LOCK (pool); if (pool->running) { if (pool->requeuebuf) { if (!gst_v4l2_buffer_pool_qbuf (pool, buffer)) { GST_WARNING ("could not requeue buffer %p %d", buffer, index); } else { resuscitated = TRUE; } } else { resuscitated = TRUE; /* XXX double check this... I think it is ok to not synchronize this * w.r.t. destruction of the pool, since the buffer is still live and * the buffer holds a ref to the pool.. */ g_async_queue_push (pool->avail_buffers, buffer); } } else { GST_LOG_OBJECT (pool->v4l2elem, "the pool is shutting down"); } if (resuscitated) { /* FIXME: check that the caps didn't change */ GST_LOG_OBJECT (pool->v4l2elem, "reviving buffer %p, %d", buffer, index); gst_buffer_ref (GST_BUFFER (buffer)); GST_BUFFER_SIZE (buffer) = 0; GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT); pool->buffers[index] = buffer; } GST_V4L2_BUFFER_POOL_UNLOCK (pool); if (!resuscitated) { GST_LOG_OBJECT (pool->v4l2elem, "buffer %p (data %p, len %u) not recovered, unmapping", buffer, GST_BUFFER_DATA (buffer), buffer->mmap_length); gst_mini_object_unref (GST_MINI_OBJECT (pool)); v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), buffer->mmap_length); GST_MINI_OBJECT_CLASS (v4l2buffer_parent_class)->finalize (GST_MINI_OBJECT (buffer)); } }
static MXFMetadataFileDescriptor * mxf_jpeg2000_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, MXFEssenceElementWriteFunc * handler, gpointer * mapping_data) { MXFMetadataRGBAPictureEssenceDescriptor *ret; GstStructure *s; guint32 fourcc; s = gst_caps_get_structure (caps, 0); if (strcmp (gst_structure_get_name (s), "image/x-jpc") != 0 || !gst_structure_get_fourcc (s, "fourcc", &fourcc)) { GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps); return NULL; } ret = (MXFMetadataRGBAPictureEssenceDescriptor *) gst_mini_object_new (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR); memcpy (&ret->parent.parent.essence_container, &jpeg2000_essence_container_ul, 16); memcpy (&ret->parent.picture_essence_coding, &jpeg2000_picture_essence_coding, 16); if (fourcc == GST_MAKE_FOURCC ('s', 'R', 'G', 'B')) { ret->n_pixel_layout = 3; ret->pixel_layout = g_new0 (guint8, 6); ret->pixel_layout[0] = 'R'; ret->pixel_layout[1] = 8; ret->pixel_layout[2] = 'G'; ret->pixel_layout[3] = 8; ret->pixel_layout[4] = 'B'; ret->pixel_layout[5] = 8; } else if (fourcc == GST_MAKE_FOURCC ('s', 'Y', 'U', 'V')) { ret->n_pixel_layout = 3; ret->pixel_layout = g_new0 (guint8, 6); ret->pixel_layout[0] = 'Y'; ret->pixel_layout[1] = 8; ret->pixel_layout[2] = 'U'; ret->pixel_layout[3] = 8; ret->pixel_layout[4] = 'V'; ret->pixel_layout[5] = 8; } else { g_assert_not_reached (); } if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret->parent, caps)) { gst_mini_object_unref (GST_MINI_OBJECT_CAST (ret)); return NULL; } *handler = mxf_jpeg2000_write_func; return (MXFMetadataFileDescriptor *) ret; }
static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event) { GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); if (typefind->mode != MODE_NORMAL) { /* need to do more? */ gst_mini_object_unref (GST_MINI_OBJECT (event)); return FALSE; } return gst_pad_push_event (typefind->sink, event); }
static void gst_app_sink_flush_unlocked (GstAppSink * appsink) { GstMiniObject *obj; GST_DEBUG_OBJECT (appsink, "flush stop appsink"); appsink->priv->is_eos = FALSE; gst_buffer_replace (&appsink->priv->preroll, NULL); while ((obj = g_queue_pop_head (appsink->priv->queue))) gst_mini_object_unref (obj); g_cond_signal (appsink->priv->cond); }
static void send_eos_event (GstElement * element) { GstEvent *event = gst_event_new_eos (); fail_unless (g_list_length (events) == 0); fail_unless (gst_pad_push_event (mysrcpad, event), "Pushing EOS event failed"); fail_unless (g_list_length (events) == 1); fail_unless (events->data == event); gst_mini_object_unref ((GstMiniObject *) events->data); events = g_list_remove (events, event); }
static void gst_discoverer_container_info_finalize (GstDiscovererContainerInfo * info) { GList *tmp; for (tmp = ((GstDiscovererContainerInfo *) info)->streams; tmp; tmp = tmp->next) gst_mini_object_unref ((GstMiniObject *) tmp->data); gst_discoverer_stream_info_list_free (info->streams); gst_discoverer_stream_info_finalize ((GstDiscovererStreamInfo *) info); }
static void flush_stop (APP_STATE_T * state) { GstMiniObject *object = NULL; g_mutex_lock (state->queue_lock); while ((object = GST_MINI_OBJECT_CAST (g_async_queue_try_pop (state->queue)))) { gst_mini_object_unref (object); } flush_internal (state); state->popped_obj = NULL; state->flushing = FALSE; g_mutex_unlock (state->queue_lock); }
static void thread_unref (GstMiniObject * mobj) { int j; THREAD_START (); for (j = 0; j < refs_per_thread; ++j) { gst_mini_object_unref (mobj); if (j % num_threads == 0) THREAD_SWITCH (); } }
/** * gst_value_take_mini_object: * @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type * @mini_object: mini object value to take * * Set the contents of a %GST_TYPE_MINI_OBJECT derived #GValue to * @mini_object. * Takes over the ownership of the caller's reference to @mini_object; * the caller doesn't have to unref it any more. */ void gst_value_take_mini_object (GValue * value, GstMiniObject * mini_object) { gpointer *pointer_p; g_return_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value)); g_return_if_fail (mini_object == NULL || GST_IS_MINI_OBJECT (mini_object)); pointer_p = &value->data[0].v_pointer; /* takes additional refcount */ gst_mini_object_replace ((GstMiniObject **) pointer_p, mini_object); /* remove additional refcount */ if (mini_object) gst_mini_object_unref (mini_object); }
static void gst_discoverer_stream_info_finalize (GstDiscovererStreamInfo * info) { if (info->next) gst_mini_object_unref ((GstMiniObject *) info->next); if (info->caps) gst_caps_unref (info->caps); if (info->tags) gst_tag_list_free (info->tags); if (info->misc) gst_structure_free (info->misc); }
static void gst_ducati_buffer_finalize (GstDucatiBuffer * self) { PVR2DERROR pvr_error; GstPvrBufferPool *pool = self->pool; gboolean resuscitated = FALSE; GST_LOG_OBJECT (pool->element, "finalizing buffer %p", self); GST_PVR_BUFFERPOOL_LOCK (pool); g_queue_remove (pool->used_buffers, self); if (pool->running) { resuscitated = TRUE; GST_LOG_OBJECT (pool->element, "reviving buffer %p", self); g_queue_push_head (pool->free_buffers, self); } else { GST_LOG_OBJECT (pool->element, "the pool is shutting down"); } GST_PVR_BUFFERPOOL_UNLOCK (pool); if (resuscitated) { GST_LOG_OBJECT (pool->element, "reviving buffer %p, %d", self, index); gst_buffer_ref (GST_BUFFER (self)); GST_BUFFER_SIZE (self) = 0; } if (!resuscitated) { GST_LOG_OBJECT (pool->element, "buffer %p (data %p, len %u) not recovered, freeing", self, GST_BUFFER_DATA (self), GST_BUFFER_SIZE (self)); if (self->wrapped) { pvr_error = PVR2DMemFree (pool->pvr_context, self->src_mem); if (pvr_error != PVR2D_OK) { GST_ERROR_OBJECT (pool->element, "Failed to Unwrap buffer memory" "returned %d", pvr_error); } self->wrapped = FALSE; } MemMgr_Free ((void *) GST_BUFFER_DATA (self)); GST_BUFFER_DATA (self) = NULL; gst_mini_object_unref (GST_MINI_OBJECT (pool)); GST_MINI_OBJECT_CLASS (buffer_parent_class)->finalize (GST_MINI_OBJECT (self)); } }
static gboolean param_mini_object_validate (GParamSpec * pspec, GValue * value) { GstMiniObject *mini_object = value->data[0].v_pointer; gboolean changed = FALSE; if (mini_object && !g_value_type_compatible (G_OBJECT_TYPE (mini_object), pspec->value_type)) { gst_mini_object_unref (mini_object); value->data[0].v_pointer = NULL; changed = TRUE; } return changed; }
static void gst_discoverer_info_finalize (GstDiscovererInfo * info) { g_free (info->uri); if (info->stream_info) gst_mini_object_unref ((GstMiniObject *) info->stream_info); if (info->misc) gst_structure_free (info->misc); g_list_free (info->stream_list); if (info->tags) gst_tag_list_free (info->tags); }
static gboolean param_mini_object_validate (GParamSpec * pspec, GValue * value) { GstParamSpecMiniObject *ospec = GST_PARAM_SPEC_MINI_OBJECT (pspec); GstMiniObject *mini_object = value->data[0].v_pointer; gboolean changed = FALSE; if (mini_object && !g_value_type_compatible (G_OBJECT_TYPE (mini_object), G_PARAM_SPEC_VALUE_TYPE (ospec))) { gst_mini_object_unref (mini_object); value->data[0].v_pointer = NULL; changed = TRUE; } return changed; }
static void flush_start (APP_STATE_T * state) { GstMiniObject *object = NULL; g_mutex_lock (state->queue_lock); state->flushing = TRUE; g_cond_broadcast (state->cond); g_mutex_unlock (state->queue_lock); while ((object = g_async_queue_try_pop (state->queue))) { gst_mini_object_unref (object); } g_mutex_lock (state->queue_lock); flush_internal (state); state->popped_obj = NULL; g_mutex_unlock (state->queue_lock); }