📄 gstbasetransform.c
字号:
if (bclass->transform) ret = bclass->transform (trans, inbuf, *outbuf); else ret = GST_FLOW_NOT_SUPPORTED; } /* if we got renegotiated we can configure now */ if (trans->pending_configure) { gboolean success; success = gst_base_transform_configure_caps (trans, GST_PAD_CAPS (trans->sinkpad), GST_PAD_CAPS (trans->srcpad)); trans->pending_configure = FALSE; if (!success) goto configure_failed; }skip: /* only unref input buffer if we allocated a new outbuf buffer */ if (*outbuf != inbuf) gst_buffer_unref (inbuf);done: return ret; /* ERRORS */not_negotiated: { gst_buffer_unref (inbuf); GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED, ("not negotiated"), ("not negotiated")); return GST_FLOW_NOT_NEGOTIATED; }no_size: { gst_buffer_unref (inbuf); GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED, ("subclass did not specify output size"), ("subclass did not specify output size")); return GST_FLOW_ERROR; }no_buffer: { gst_buffer_unref (inbuf); GST_DEBUG_OBJECT (trans, "could not get buffer from pool: %s", gst_flow_get_name (ret)); return ret; }configure_failed: { if (*outbuf != inbuf) gst_buffer_unref (inbuf); GST_DEBUG_OBJECT (trans, "could not negotiate"); return GST_FLOW_NOT_NEGOTIATED; }}static gbooleangst_base_transform_check_get_range (GstPad * pad){ GstBaseTransform *trans; gboolean ret; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); ret = gst_pad_check_pull_range (trans->sinkpad); gst_object_unref (trans); return ret;}/* FIXME, getrange is broken, need to pull range from the other * end based on the transform_size result. */static GstFlowReturngst_base_transform_getrange (GstPad * pad, guint64 offset, guint length, GstBuffer ** buffer){ GstBaseTransform *trans; GstFlowReturn ret; GstBuffer *inbuf; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); ret = gst_pad_pull_range (trans->sinkpad, offset, length, &inbuf); if (ret == GST_FLOW_OK) { g_mutex_lock (trans->transform_lock); ret = gst_base_transform_handle_buffer (trans, inbuf, buffer); g_mutex_unlock (trans->transform_lock); } gst_object_unref (trans); return ret;}static GstFlowReturngst_base_transform_chain (GstPad * pad, GstBuffer * buffer){ GstBaseTransform *trans; GstFlowReturn ret; GstClockTime last_stop = GST_CLOCK_TIME_NONE; GstBuffer *outbuf = NULL; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); /* calculate end position of the incoming buffer */ if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) { if (GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE) last_stop = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer); else last_stop = GST_BUFFER_TIMESTAMP (buffer); } /* protect transform method and concurrent buffer alloc */ g_mutex_lock (trans->transform_lock); ret = gst_base_transform_handle_buffer (trans, buffer, &outbuf); g_mutex_unlock (trans->transform_lock); /* outbuf can be NULL, this means a dropped buffer, if we have a buffer but * GST_BASE_TRANSFORM_FLOW_DROPPED we will not push either. */ if (outbuf != NULL) { if ((ret == GST_FLOW_OK)) { /* Remember last stop position */ if ((last_stop != GST_CLOCK_TIME_NONE) && (trans->segment.format == GST_FORMAT_TIME)) gst_segment_set_last_stop (&trans->segment, GST_FORMAT_TIME, last_stop); /* apply DISCONT flag if the buffer is not yet marked as such */ if (trans->priv->discont) { if (!GST_BUFFER_IS_DISCONT (outbuf)) { outbuf = gst_buffer_make_metadata_writable (outbuf); GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); } trans->priv->discont = FALSE; } ret = gst_pad_push (trans->srcpad, outbuf); } else gst_buffer_unref (outbuf); } /* convert internal flow to OK and mark discont for the next buffer. */ if (ret == GST_BASE_TRANSFORM_FLOW_DROPPED) { trans->priv->discont = TRUE; ret = GST_FLOW_OK; } gst_object_unref (trans); return ret;}static voidgst_base_transform_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec){ GstBaseTransform *trans; trans = GST_BASE_TRANSFORM (object); switch (prop_id) { case PROP_QOS: gst_base_transform_set_qos_enabled (trans, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; }}static voidgst_base_transform_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec){ GstBaseTransform *trans; trans = GST_BASE_TRANSFORM (object); switch (prop_id) { case PROP_QOS: g_value_set_boolean (value, gst_base_transform_is_qos_enabled (trans)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; }}/* not a vmethod of anything, just an internal method */static gbooleangst_base_transform_activate (GstBaseTransform * trans, gboolean active){ GstBaseTransformClass *bclass; gboolean result = TRUE; bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); if (active) { if (trans->priv->pad_mode == GST_ACTIVATE_NONE && bclass->start) result &= bclass->start (trans); GST_OBJECT_LOCK (trans); if (GST_PAD_CAPS (trans->sinkpad) && GST_PAD_CAPS (trans->srcpad)) trans->have_same_caps = gst_caps_is_equal (GST_PAD_CAPS (trans->sinkpad), GST_PAD_CAPS (trans->srcpad)) || trans->passthrough; else trans->have_same_caps = trans->passthrough; GST_DEBUG_OBJECT (trans, "have_same_caps %d", trans->have_same_caps); trans->negotiated = FALSE; trans->have_newsegment = FALSE; gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED); trans->priv->proportion = 1.0; trans->priv->earliest_time = -1; trans->priv->discont = FALSE; GST_OBJECT_UNLOCK (trans); } else { /* We must make sure streaming has finished before resetting things * and calling the ::stop vfunc */ GST_PAD_STREAM_LOCK (trans->sinkpad); GST_PAD_STREAM_UNLOCK (trans->sinkpad); trans->have_same_caps = FALSE; /* We can only reset the passthrough mode if the instance told us to handle it in configure_caps */ if (bclass->passthrough_on_same_caps) { gst_base_transform_set_passthrough (trans, FALSE); } gst_caps_replace (&trans->cache_caps1, NULL); gst_caps_replace (&trans->cache_caps2, NULL); if (trans->priv->pad_mode != GST_ACTIVATE_NONE && bclass->stop) result &= bclass->stop (trans); } return result;}static gbooleangst_base_transform_sink_activate_push (GstPad * pad, gboolean active){ gboolean result = TRUE; GstBaseTransform *trans; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); result = gst_base_transform_activate (trans, active); if (result) trans->priv->pad_mode = active ? GST_ACTIVATE_PUSH : GST_ACTIVATE_NONE; gst_object_unref (trans); return result;}static gbooleangst_base_transform_src_activate_pull (GstPad * pad, gboolean active){ gboolean result = FALSE; GstBaseTransform *trans; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); result = gst_pad_activate_pull (trans->sinkpad, active); if (result) result &= gst_base_transform_activate (trans, active); if (result) trans->priv->pad_mode = active ? GST_ACTIVATE_PULL : GST_ACTIVATE_NONE; gst_object_unref (trans); return result;}/** * gst_base_transform_set_passthrough: * @trans: the #GstBaseTransform to set * @passthrough: boolean indicating passthrough mode. * * Set passthrough mode for this filter by default. This is mostly * useful for filters that do not care about negotiation. * * Always TRUE for filters which don't implement either a transform * or transform_ip method. * * MT safe. */voidgst_base_transform_set_passthrough (GstBaseTransform * trans, gboolean passthrough){ GstBaseTransformClass *bclass; g_return_if_fail (trans != NULL); bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); GST_OBJECT_LOCK (trans); if (passthrough == FALSE) { if (bclass->transform_ip || bclass->transform) trans->passthrough = FALSE; } else { trans->passthrough = TRUE; } GST_DEBUG_OBJECT (trans, "set passthrough %d", trans->passthrough); GST_OBJECT_UNLOCK (trans);}/** * gst_base_transform_is_passthrough: * @trans: the #GstBaseTransform to query * * See if @trans is configured as a passthrough transform. * * Returns: TRUE is the transform is configured in passthrough mode. * * MT safe. */gbooleangst_base_transform_is_passthrough (GstBaseTransform * trans){ gboolean result; g_return_val_if_fail (trans != NULL, FALSE); GST_OBJECT_LOCK (trans); result = trans->passthrough; GST_OBJECT_UNLOCK (trans); return result;}/** * gst_base_transform_set_in_place: * @trans: the #GstBaseTransform to modify * @in_place: Boolean value indicating that we would like to operate * on in_place buffers. * * Determines whether a non-writable buffer will be copied before passing * to the transform_ip function. * <itemizedlist> * <listitem>Always TRUE if no transform function is implemented.</listitem> * <listitem>Always FALSE if ONLY transform_ip function is implemented.</listitem> * </itemizedlist> * * MT safe. */voidgst_base_transform_set_in_place (GstBaseTransform * trans, gboolean in_place){ GstBaseTransformClass *bclass; g_return_if_fail (trans != NULL); bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); GST_OBJECT_LOCK (trans); if (in_place) { if (bclass->transform_ip) { GST_DEBUG_OBJECT (trans, "setting in_place TRUE"); trans->always_in_place = TRUE; } } else { if (bclass->transform) { GST_DEBUG_OBJECT (trans, "setting in_place FALSE"); trans->always_in_place = FALSE; } } GST_OBJECT_UNLOCK (trans);}/** * gst_base_transform_is_in_place: * @trans: the #GstBaseTransform to query * * See if @trans is configured as a in_place transform. * * Returns: TRUE is the transform is configured in in_place mode. * * MT safe. */gbooleangst_base_transform_is_in_place (GstBaseTransform * trans){ gboolean result; g_return_val_if_fail (trans != NULL, FALSE); GST_OBJECT_LOCK (trans); result = trans->always_in_place; GST_OBJECT_UNLOCK (trans); return result;}/** * gst_base_transform_update_qos: * @trans: a #GstBaseTransform * @proportion: the proportion * @diff: the diff against the clock * @timestamp: the timestamp of the buffer generating the QoS * * Set the QoS parameters in the transform. * * Since: 0.10.5 * * MT safe. */voidgst_base_transform_update_qos (GstBaseTransform * trans, gdouble proportion, GstClockTimeDiff diff, GstClockTime timestamp){ g_return_if_fail (trans != NULL); GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, "qos: proportion: %lf, diff %" G_GINT64_FORMAT ", timestamp %" GST_TIME_FORMAT, proportion, diff, GST_TIME_ARGS (timestamp)); GST_OBJECT_LOCK (trans); trans->priv->proportion = proportion; trans->priv->earliest_time = timestamp + diff; GST_OBJECT_UNLOCK (trans);}/** * gst_base_transform_set_qos_enabled: * @trans: a #GstBaseTransform * @enabled: new state * * Enable or disable QoS handling in the transform. * * Since: 0.10.5 * * MT safe. */voidgst_base_transform_set_qos_enabled (GstBaseTransform * trans, gboolean enabled){ g_return_if_fail (trans != NULL); GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, "enabled: %d", enabled); GST_OBJECT_LOCK (trans); trans->priv->qos_enabled = enabled; GST_OBJECT_UNLOCK (trans);}/** * gst_base_transform_is_qos_enabled: * @trans: a #GstBaseTransform * * Queries if the transform will handle QoS. * * Returns: TRUE if QoS is enabled. * * Since: 0.10.5 * * MT safe. */gbooleangst_base_transform_is_qos_enabled (GstBaseTransform * trans){ gboolean result; g_return_val_if_fail (trans != NULL, FALSE); GST_OBJECT_LOCK (trans); result = trans->priv->qos_enabled; GST_OBJECT_UNLOCK (trans); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -