diff options
-rw-r--r-- | docs/libs/gst-plugins-base-libs-sections.txt | 1 | ||||
-rw-r--r-- | gst-libs/gst/app/gstappsrc.c | 120 | ||||
-rw-r--r-- | gst-libs/gst/app/gstappsrc.h | 2 | ||||
-rw-r--r-- | win32/common/libgstapp.def | 1 |
4 files changed, 108 insertions, 16 deletions
diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 65a8b3fb5..6dee9c09b 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -34,6 +34,7 @@ gst_app_src_set_emit_signals GstAppSrcCallbacks gst_app_src_set_callbacks gst_app_src_push_buffer +gst_app_src_push_sample gst_app_src_end_of_stream <SUBSECTION Standard> GstAppSrcClass diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c index 5bffa7e33..9d27a67c8 100644 --- a/gst-libs/gst/app/gstappsrc.c +++ b/gst-libs/gst/app/gstappsrc.c @@ -34,7 +34,10 @@ * 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 * 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 * 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 * ways: * - * The push model, in which the application repeatedly calls the push-buffer method - * with a new buffer. Optionally, the queue size in the appsrc can be controlled - * with the enough-data and need-data signals by respectively stopping/starting - * the push-buffer calls. This is a typical mode of operation for the - * stream-type "stream" and "seekable". Use this model when implementing various - * network protocols or hardware devices. + * The push model, in which the application repeatedly calls the push-buffer/push-sample + * method with a new buffer/sample. Optionally, the queue size in the appsrc + * can be controlled with the enough-data and need-data signals by respectively + * stopping/starting the push-buffer/push-sample calls. This is a typical + * mode of operation for the stream-type "stream" and "seekable". Use this + * model when implementing various network protocols or hardware devices. * * 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 @@ -144,6 +147,7 @@ enum /* actions */ SIGNAL_PUSH_BUFFER, SIGNAL_END_OF_STREAM, + SIGNAL_PUSH_SAMPLE, 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, GstBuffer * buffer); +static GstFlowReturn gst_app_src_push_sample_action (GstAppSrc * appsrc, + GstSample * sample); 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, 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: * @appsrc: the appsrc @@ -498,6 +531,7 @@ gst_app_src_class_init (GstAppSrcClass * klass) basesrc_class->query = gst_app_src_query; 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; 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; - 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 */ if (priv->stream_type == GST_APP_STREAM_TYPE_STREAM) 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) res = priv->callbacks.seek_data (appsrc, desired_position, priv->user_data); else { @@ -1186,8 +1220,8 @@ seek_error: void gst_app_src_set_caps (GstAppSrc * appsrc, const GstCaps * caps) { - GstCaps *new_caps; GstAppSrcPrivate *priv; + gboolean caps_changed; 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); GST_OBJECT_LOCK (appsrc); - GST_DEBUG_OBJECT (appsrc, "setting caps to %" GST_PTR_FORMAT, caps); - - new_caps = caps ? gst_caps_copy (caps) : NULL; - g_queue_push_tail (priv->queue, new_caps); - gst_caps_replace (&priv->last_caps, new_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; + GST_DEBUG_OBJECT (appsrc, "setting caps to %" GST_PTR_FORMAT, caps); + g_queue_push_tail (priv->queue, new_caps); + gst_caps_replace (&priv->last_caps, new_caps); + } 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: * @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); } +/** + * 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 * action signal. */ 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); } +/* 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: * @appsrc: a #GstAppSrc diff --git a/gst-libs/gst/app/gstappsrc.h b/gst-libs/gst/app/gstappsrc.h index d88c8234e..f793ce67b 100644 --- a/gst-libs/gst/app/gstappsrc.h +++ b/gst-libs/gst/app/gstappsrc.h @@ -107,6 +107,7 @@ struct _GstAppSrcClass /* actions */ GstFlowReturn (*push_buffer) (GstAppSrc *appsrc, GstBuffer *buffer); GstFlowReturn (*end_of_stream) (GstAppSrc *appsrc); + GstFlowReturn (*push_sample) (GstAppSrc *appsrc, GstSample *sample); /*< private >*/ 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_end_of_stream (GstAppSrc *appsrc); +GstFlowReturn gst_app_src_push_sample (GstAppSrc *appsrc, GstSample *sample); void gst_app_src_set_callbacks (GstAppSrc * appsrc, GstAppSrcCallbacks *callbacks, diff --git a/win32/common/libgstapp.def b/win32/common/libgstapp.def index 32b3cd1bb..550ca3f08 100644 --- a/win32/common/libgstapp.def +++ b/win32/common/libgstapp.def @@ -22,6 +22,7 @@ EXPORTS gst_app_src_get_stream_type gst_app_src_get_type gst_app_src_push_buffer + gst_app_src_push_sample gst_app_src_set_callbacks gst_app_src_set_caps gst_app_src_set_emit_signals |