appsrc: Add push_sample() convenience function for easy appsink -> appsrc use
https://bugzilla.gnome.org/show_bug.cgi?id=728379
This commit is contained in:
parent
7e78fe0d1e
commit
617f72b526
@ -34,6 +34,7 @@ gst_app_src_set_emit_signals
|
|||||||
GstAppSrcCallbacks
|
GstAppSrcCallbacks
|
||||||
gst_app_src_set_callbacks
|
gst_app_src_set_callbacks
|
||||||
gst_app_src_push_buffer
|
gst_app_src_push_buffer
|
||||||
|
gst_app_src_push_sample
|
||||||
gst_app_src_end_of_stream
|
gst_app_src_end_of_stream
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GstAppSrcClass
|
GstAppSrcClass
|
||||||
|
@ -34,7 +34,10 @@
|
|||||||
* describing the format of the data that will be pushed with appsrc. An
|
* describing the format of the data that will be pushed with appsrc. An
|
||||||
* exception to this is when pushing buffers with unknown caps, in which case no
|
* exception to this is when pushing buffers with unknown caps, in which case no
|
||||||
* caps should be set. This is typically true of file-like sources that push raw
|
* caps should be set. This is typically true of file-like sources that push raw
|
||||||
* byte buffers.
|
* byte buffers. If you don't want to explicitly set the caps you can use
|
||||||
|
* gst_app_src_push_sample, this method get the caps associated with the
|
||||||
|
* sample and set them on appsrc replacing any previous setted caps if
|
||||||
|
* different from that of the sample.
|
||||||
*
|
*
|
||||||
* The main way of handing data to the appsrc element is by calling the
|
* The main way of handing data to the appsrc element is by calling the
|
||||||
* gst_app_src_push_buffer() method or by emitting the push-buffer action signal.
|
* gst_app_src_push_buffer() method or by emitting the push-buffer action signal.
|
||||||
@ -62,12 +65,12 @@
|
|||||||
* These signals allow the application to operate the appsrc in two different
|
* These signals allow the application to operate the appsrc in two different
|
||||||
* ways:
|
* ways:
|
||||||
*
|
*
|
||||||
* The push model, in which the application repeatedly calls the push-buffer method
|
* The push model, in which the application repeatedly calls the push-buffer/push-sample
|
||||||
* with a new buffer. Optionally, the queue size in the appsrc can be controlled
|
* method with a new buffer/sample. Optionally, the queue size in the appsrc
|
||||||
* with the enough-data and need-data signals by respectively stopping/starting
|
* can be controlled with the enough-data and need-data signals by respectively
|
||||||
* the push-buffer calls. This is a typical mode of operation for the
|
* stopping/starting the push-buffer/push-sample calls. This is a typical
|
||||||
* stream-type "stream" and "seekable". Use this model when implementing various
|
* mode of operation for the stream-type "stream" and "seekable". Use this
|
||||||
* network protocols or hardware devices.
|
* model when implementing various network protocols or hardware devices.
|
||||||
*
|
*
|
||||||
* The pull model where the need-data signal triggers the next push-buffer call.
|
* The pull model where the need-data signal triggers the next push-buffer call.
|
||||||
* This mode is typically used in the "random-access" stream-type. Use this
|
* This mode is typically used in the "random-access" stream-type. Use this
|
||||||
@ -144,6 +147,7 @@ enum
|
|||||||
/* actions */
|
/* actions */
|
||||||
SIGNAL_PUSH_BUFFER,
|
SIGNAL_PUSH_BUFFER,
|
||||||
SIGNAL_END_OF_STREAM,
|
SIGNAL_END_OF_STREAM,
|
||||||
|
SIGNAL_PUSH_SAMPLE,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
@ -236,6 +240,8 @@ static gboolean gst_app_src_query (GstBaseSrc * src, GstQuery * query);
|
|||||||
|
|
||||||
static GstFlowReturn gst_app_src_push_buffer_action (GstAppSrc * appsrc,
|
static GstFlowReturn gst_app_src_push_buffer_action (GstAppSrc * appsrc,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
|
static GstFlowReturn gst_app_src_push_sample_action (GstAppSrc * appsrc,
|
||||||
|
GstSample * sample);
|
||||||
|
|
||||||
static guint gst_app_src_signals[LAST_SIGNAL] = { 0 };
|
static guint gst_app_src_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
@ -463,6 +469,33 @@ gst_app_src_class_init (GstAppSrcClass * klass)
|
|||||||
push_buffer), NULL, NULL, __gst_app_marshal_ENUM__BOXED,
|
push_buffer), NULL, NULL, __gst_app_marshal_ENUM__BOXED,
|
||||||
GST_TYPE_FLOW_RETURN, 1, GST_TYPE_BUFFER);
|
GST_TYPE_FLOW_RETURN, 1, GST_TYPE_BUFFER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstAppSrc::push-sample:
|
||||||
|
* @appsrc: the appsrc
|
||||||
|
* @sample: a sample from which extract buffer to push
|
||||||
|
*
|
||||||
|
* Extract a buffer from the provided sample and adds the extracted buffer
|
||||||
|
* to the queue of buffers that the appsrc element will
|
||||||
|
* push to its source pad. This function set the appsrc caps based on the caps
|
||||||
|
* in the sample and reset the caps if they change.
|
||||||
|
* Only the caps and the buffer of the provided sample are used and not
|
||||||
|
* for example the segment in the sample.
|
||||||
|
* This function does not take ownership of the
|
||||||
|
* sample so the sample needs to be unreffed after calling this function.
|
||||||
|
*
|
||||||
|
* When the block property is TRUE, this function can block until free space
|
||||||
|
* becomes available in the queue.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
gst_app_src_signals[SIGNAL_PUSH_SAMPLE] =
|
||||||
|
g_signal_new ("push-sample", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSrcClass,
|
||||||
|
push_sample), NULL, NULL, __gst_app_marshal_ENUM__BOXED,
|
||||||
|
GST_TYPE_FLOW_RETURN, 1, GST_TYPE_SAMPLE);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstAppSrc::end-of-stream:
|
* GstAppSrc::end-of-stream:
|
||||||
* @appsrc: the appsrc
|
* @appsrc: the appsrc
|
||||||
@ -498,6 +531,7 @@ gst_app_src_class_init (GstAppSrcClass * klass)
|
|||||||
basesrc_class->query = gst_app_src_query;
|
basesrc_class->query = gst_app_src_query;
|
||||||
|
|
||||||
klass->push_buffer = gst_app_src_push_buffer_action;
|
klass->push_buffer = gst_app_src_push_buffer_action;
|
||||||
|
klass->push_sample = gst_app_src_push_sample_action;
|
||||||
klass->end_of_stream = gst_app_src_end_of_stream;
|
klass->end_of_stream = gst_app_src_end_of_stream;
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (GstAppSrcPrivate));
|
g_type_class_add_private (klass, sizeof (GstAppSrcPrivate));
|
||||||
@ -897,13 +931,13 @@ gst_app_src_do_seek (GstBaseSrc * src, GstSegment * segment)
|
|||||||
|
|
||||||
desired_position = segment->position;
|
desired_position = segment->position;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (appsrc, "seeking to %" G_GINT64_FORMAT ", format %s",
|
|
||||||
desired_position, gst_format_get_name (segment->format));
|
|
||||||
|
|
||||||
/* no need to try to seek in streaming mode */
|
/* no need to try to seek in streaming mode */
|
||||||
if (priv->stream_type == GST_APP_STREAM_TYPE_STREAM)
|
if (priv->stream_type == GST_APP_STREAM_TYPE_STREAM)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (appsrc, "seeking to %" G_GINT64_FORMAT ", format %s",
|
||||||
|
desired_position, gst_format_get_name (segment->format));
|
||||||
|
|
||||||
if (priv->callbacks.seek_data)
|
if (priv->callbacks.seek_data)
|
||||||
res = priv->callbacks.seek_data (appsrc, desired_position, priv->user_data);
|
res = priv->callbacks.seek_data (appsrc, desired_position, priv->user_data);
|
||||||
else {
|
else {
|
||||||
@ -1186,8 +1220,8 @@ seek_error:
|
|||||||
void
|
void
|
||||||
gst_app_src_set_caps (GstAppSrc * appsrc, const GstCaps * caps)
|
gst_app_src_set_caps (GstAppSrc * appsrc, const GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCaps *new_caps;
|
|
||||||
GstAppSrcPrivate *priv;
|
GstAppSrcPrivate *priv;
|
||||||
|
gboolean caps_changed;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_APP_SRC (appsrc));
|
g_return_if_fail (GST_IS_APP_SRC (appsrc));
|
||||||
|
|
||||||
@ -1196,11 +1230,18 @@ gst_app_src_set_caps (GstAppSrc * appsrc, const GstCaps * caps)
|
|||||||
g_mutex_lock (&priv->mutex);
|
g_mutex_lock (&priv->mutex);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (appsrc);
|
GST_OBJECT_LOCK (appsrc);
|
||||||
GST_DEBUG_OBJECT (appsrc, "setting caps to %" GST_PTR_FORMAT, caps);
|
if (caps && priv->last_caps)
|
||||||
|
caps_changed = !gst_caps_is_equal (caps, priv->last_caps);
|
||||||
|
else
|
||||||
|
caps_changed = (caps != priv->last_caps);
|
||||||
|
|
||||||
|
if (caps_changed) {
|
||||||
|
GstCaps *new_caps;
|
||||||
new_caps = caps ? gst_caps_copy (caps) : NULL;
|
new_caps = caps ? gst_caps_copy (caps) : NULL;
|
||||||
|
GST_DEBUG_OBJECT (appsrc, "setting caps to %" GST_PTR_FORMAT, caps);
|
||||||
g_queue_push_tail (priv->queue, new_caps);
|
g_queue_push_tail (priv->queue, new_caps);
|
||||||
gst_caps_replace (&priv->last_caps, new_caps);
|
gst_caps_replace (&priv->last_caps, new_caps);
|
||||||
|
}
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (appsrc);
|
GST_OBJECT_UNLOCK (appsrc);
|
||||||
|
|
||||||
@ -1620,6 +1661,18 @@ eos:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_app_src_push_sample_internal (GstAppSrc * appsrc, GstSample * sample)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer;
|
||||||
|
GstCaps *caps;
|
||||||
|
g_return_val_if_fail (GST_IS_SAMPLE (sample), GST_FLOW_ERROR);
|
||||||
|
caps = gst_sample_get_caps (sample);
|
||||||
|
gst_app_src_set_caps (appsrc, caps);
|
||||||
|
buffer = gst_sample_get_buffer (sample);
|
||||||
|
return gst_app_src_push_buffer_full (appsrc, buffer, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_app_src_push_buffer:
|
* gst_app_src_push_buffer:
|
||||||
* @appsrc: a #GstAppSrc
|
* @appsrc: a #GstAppSrc
|
||||||
@ -1641,6 +1694,33 @@ gst_app_src_push_buffer (GstAppSrc * appsrc, GstBuffer * buffer)
|
|||||||
return gst_app_src_push_buffer_full (appsrc, buffer, TRUE);
|
return gst_app_src_push_buffer_full (appsrc, buffer, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_app_src_push_sample:
|
||||||
|
* @appsrc: a #GstAppSrc
|
||||||
|
* @sample: (transfer none): a #GstSample from wich extract buffer to
|
||||||
|
* push and caps to set
|
||||||
|
*
|
||||||
|
* Extract a buffer from the provided sample and adds it to the queue of
|
||||||
|
* buffers that the appsrc element will push to its source pad. Any
|
||||||
|
* previous caps setted on appsrc will be replaced by the caps associated
|
||||||
|
* with the sample if not equal.
|
||||||
|
*
|
||||||
|
* When the block property is TRUE, this function can block until free
|
||||||
|
* space becomes available in the queue.
|
||||||
|
*
|
||||||
|
* Returns: #GST_FLOW_OK when the buffer was successfuly queued.
|
||||||
|
* #GST_FLOW_FLUSHING when @appsrc is not PAUSED or PLAYING.
|
||||||
|
* #GST_FLOW_EOS when EOS occured.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
GstFlowReturn
|
||||||
|
gst_app_src_push_sample (GstAppSrc * appsrc, GstSample * sample)
|
||||||
|
{
|
||||||
|
return gst_app_src_push_sample_internal (appsrc, sample);
|
||||||
|
}
|
||||||
|
|
||||||
/* push a buffer without stealing the ref of the buffer. This is used for the
|
/* push a buffer without stealing the ref of the buffer. This is used for the
|
||||||
* action signal. */
|
* action signal. */
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
@ -1649,6 +1729,14 @@ gst_app_src_push_buffer_action (GstAppSrc * appsrc, GstBuffer * buffer)
|
|||||||
return gst_app_src_push_buffer_full (appsrc, buffer, FALSE);
|
return gst_app_src_push_buffer_full (appsrc, buffer, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* push a sample without stealing the ref. This is used for the
|
||||||
|
* action signal. */
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_app_src_push_sample_action (GstAppSrc * appsrc, GstSample * sample)
|
||||||
|
{
|
||||||
|
return gst_app_src_push_sample_internal (appsrc, sample);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_app_src_end_of_stream:
|
* gst_app_src_end_of_stream:
|
||||||
* @appsrc: a #GstAppSrc
|
* @appsrc: a #GstAppSrc
|
||||||
|
@ -107,6 +107,7 @@ struct _GstAppSrcClass
|
|||||||
/* actions */
|
/* actions */
|
||||||
GstFlowReturn (*push_buffer) (GstAppSrc *appsrc, GstBuffer *buffer);
|
GstFlowReturn (*push_buffer) (GstAppSrc *appsrc, GstBuffer *buffer);
|
||||||
GstFlowReturn (*end_of_stream) (GstAppSrc *appsrc);
|
GstFlowReturn (*end_of_stream) (GstAppSrc *appsrc);
|
||||||
|
GstFlowReturn (*push_sample) (GstAppSrc *appsrc, GstSample *sample);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
@ -140,6 +141,7 @@ gboolean gst_app_src_get_emit_signals (GstAppSrc *appsrc);
|
|||||||
|
|
||||||
GstFlowReturn gst_app_src_push_buffer (GstAppSrc *appsrc, GstBuffer *buffer);
|
GstFlowReturn gst_app_src_push_buffer (GstAppSrc *appsrc, GstBuffer *buffer);
|
||||||
GstFlowReturn gst_app_src_end_of_stream (GstAppSrc *appsrc);
|
GstFlowReturn gst_app_src_end_of_stream (GstAppSrc *appsrc);
|
||||||
|
GstFlowReturn gst_app_src_push_sample (GstAppSrc *appsrc, GstSample *sample);
|
||||||
|
|
||||||
void gst_app_src_set_callbacks (GstAppSrc * appsrc,
|
void gst_app_src_set_callbacks (GstAppSrc * appsrc,
|
||||||
GstAppSrcCallbacks *callbacks,
|
GstAppSrcCallbacks *callbacks,
|
||||||
|
@ -22,6 +22,7 @@ EXPORTS
|
|||||||
gst_app_src_get_stream_type
|
gst_app_src_get_stream_type
|
||||||
gst_app_src_get_type
|
gst_app_src_get_type
|
||||||
gst_app_src_push_buffer
|
gst_app_src_push_buffer
|
||||||
|
gst_app_src_push_sample
|
||||||
gst_app_src_set_callbacks
|
gst_app_src_set_callbacks
|
||||||
gst_app_src_set_caps
|
gst_app_src_set_caps
|
||||||
gst_app_src_set_emit_signals
|
gst_app_src_set_emit_signals
|
||||||
|
Loading…
x
Reference in New Issue
Block a user