Search
SailfishOS Open Build Service
>
Projects
>
home:sledge
:
branches:nemo:devel:hw:ti:omap4:common
>
gstreamer
> cumulative.patch
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File cumulative.patch of Package gstreamer
From 87db30f1b1d99dbc4f2d7cf7814e863c31958b24 Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Sat, 13 Feb 2010 15:29:13 -0600 Subject: [PATCH 01/11] gst-launch: add --loop argument if --loop is specified, automatically seek to beginning of clip when EOS is received --- tools/gst-launch.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/gst-launch.c b/tools/gst-launch.c index b801d03..a468c69 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -923,6 +923,7 @@ main (int argc, char *argv[]) gboolean trace = FALSE; gboolean eos_on_shutdown = FALSE; gboolean check_index = FALSE; + gboolean loop = FALSE; gchar *savefile = NULL; gchar *exclude_args = NULL; #ifndef GST_DISABLE_OPTION_PARSING @@ -951,6 +952,8 @@ main (int argc, char *argv[]) N_("Force EOS on sources before shutting the pipeline down"), NULL}, {"index", 'i', 0, G_OPTION_ARG_NONE, &check_index, N_("Gather and print index statistics"), NULL}, + {"loop", 'l', 0, G_OPTION_ARG_NONE, &loop, + N_("Repeat clip in loop without rebuilding pipeline"), NULL}, GST_TOOLS_GOPTION_VERSION, {NULL} }; @@ -1154,7 +1157,18 @@ main (int argc, char *argv[]) } tfthen = gst_util_get_timestamp (); - caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING); + do { + caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING); + if (loop && (caught_error == ELR_NO_ERROR)) { + PRINT (_("Looping ...\n")); + gst_element_seek (pipeline, 1.0, + GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, + GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + } else { + break; + } + } while (TRUE); if (eos_on_shutdown && caught_error == ELR_INTERRUPT) { PRINT (_("EOS on shutdown enabled -- Forcing EOS on the pipeline\n")); waiting_eos = TRUE; -- 1.7.9.5 From 50b817e381e90eeb2b19503be3dc49808ea65b5c Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Sun, 4 Apr 2010 09:14:34 -0500 Subject: [PATCH 02/11] Changes to make it possible to LD_PRELOAD libttif 1) if GST_USING_PRINTF_EXTENSION, then prepend the fmt string with "<%P> " and pass object as a normal arg. When using TTIF, you want the whole fmt string, including the object name prefix, to be constant. This way, only the fmt string pointer needs to be logged. 2) GstDebugTraceLocation: small optimization to stash __FILE__, __LINE__, and GST_FUNCTION together and pass as a single ptr.. the optimization is probably lost in the noise with the default printf() based traces, but makes more of a difference with faster trace systems Incorporate modifications by Ricardo Salveti de Araujo in order to work out some errors from recent versions of GStreamer. --- gst/gstinfo.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++----- gst/gstinfo.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 125 insertions(+), 11 deletions(-) diff --git a/gst/gstinfo.c b/gst/gstinfo.c index 266feed..2268768 100644 --- a/gst/gstinfo.c +++ b/gst/gstinfo.c @@ -435,6 +435,32 @@ _gst_debug_init (void) /* we can't do this further above, because we initialize the GST_CAT_DEFAULT struct */ #define GST_CAT_DEFAULT _GST_CAT_DEBUG + +/** + * gst_debug_log2: + * @category: category to log + * @level: level of the message is in + * @location: the file, function name, and line number of the location that + * emitted the message + * @object: the object this message relates to or NULL if none + * @format: a printf style format string + * @...: optional arguments for the format + * + * Logs the given message using the currently registered debugging handlers. + */ +void +gst_debug_log2 (GstDebugCategory * category, GstDebugLevel level, + const GstDebugTraceLocation * location, + GObject * object, const gchar * format, ...) +{ + va_list var_args; + + va_start (var_args, format); + gst_debug_log_valist2 (category, level, location, object, format, var_args); + va_end (var_args); +} + + /** * gst_debug_log: * @category: category to log @@ -506,13 +532,40 @@ gst_debug_log_valist (GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function, gint line, GObject * object, const gchar * format, va_list args) { + GstDebugTraceLocation location = { + .file = file, + .function = function, + .line = line + }; + gst_debug_log_valist2 (category, level, &location, object, format, args); +} + + +/** + * gst_debug_log_valist2: + * @category: category to log + * @level: level of the message is in + * @location: the file, function name, and line number of the location that + * emitted the message + * @object: the object this message relates to or NULL if none + * @format: a printf style format string + * @args: optional arguments for the format + * + * Logs the given message using the currently registered debugging handlers. + */ +void +gst_debug_log_valist2 (GstDebugCategory * category, GstDebugLevel level, + const GstDebugTraceLocation * location, + GObject * object, const gchar * format, va_list args) +{ GstDebugMessage message; LogFuncEntry *entry; GSList *handler; g_return_if_fail (category != NULL); - g_return_if_fail (file != NULL); - g_return_if_fail (function != NULL); + g_return_if_fail (location != NULL); + g_return_if_fail (location->file != NULL); + g_return_if_fail (location->function != NULL); g_return_if_fail (format != NULL); /* The predefined macro __FILE__ is always the exact path given to the @@ -530,8 +583,9 @@ gst_debug_log_valist (GstDebugCategory * category, GstDebugLevel level, while (handler) { entry = handler->data; handler = g_slist_next (handler); - entry->func (category, level, file, function, line, object, &message, - entry->user_data); + // TODO: change GstLogFunction and pass GstDebugTraceLocation ptr instead.. + entry->func (category, level, location->file, location->function, + location->line, object, &message, entry->user_data); } g_free (message.message); va_end (message.arguments); @@ -604,7 +658,7 @@ gst_info_structure_to_string (GstStructure * s) return gst_structure_to_string (s); } -static gchar * +gchar * gst_debug_print_object (gpointer ptr) { GObject *object = (GObject *) ptr; @@ -719,7 +773,7 @@ gst_debug_print_object (gpointer ptr) #ifdef HAVE_PRINTF_EXTENSION -static gchar * +gchar * gst_debug_print_segment (gpointer ptr) { GstSegment *segment = (GstSegment *) ptr; diff --git a/gst/gstinfo.h b/gst/gstinfo.h index f841cd7..3abdb2d 100644 --- a/gst/gstinfo.h +++ b/gst/gstinfo.h @@ -177,6 +177,8 @@ struct _GstDebugCategory { const gchar * name; const gchar * description; + + void *ext; /**< for use by LD_PRELOADED trace extension */ }; /********** some convenience macros for debugging **********/ @@ -260,6 +262,14 @@ typedef void (*GstLogFunction) (GstDebugCategory * category, /* FIXME 0.11: move this into private headers */ void _gst_debug_init (void); +typedef struct { + const gchar *file; + const gchar *function; + const gint line; +} GstDebugTraceLocation; + +#define GST_DEBUG_TRACE_LOCATION() \ + { __FILE__, GST_FUNCTION, __LINE__ } #ifdef GST_USING_PRINTF_EXTENSION @@ -273,6 +283,13 @@ void gst_debug_log (GstDebugCategory * category, const gchar * format, ...) G_GNUC_NO_INSTRUMENT; +void gst_debug_log2 (GstDebugCategory * category, + GstDebugLevel level, + const GstDebugTraceLocation *location, + GObject * object, + const gchar * format, + ...) G_GNUC_NO_INSTRUMENT; + #else /* GST_USING_PRINTF_EXTENSION */ void gst_debug_log (GstDebugCategory * category, @@ -284,6 +301,13 @@ void gst_debug_log (GstDebugCategory * category, const gchar * format, ...) G_GNUC_PRINTF (7, 8) G_GNUC_NO_INSTRUMENT; +void gst_debug_log2 (GstDebugCategory * category, + GstDebugLevel level, + const GstDebugTraceLocation *location, + GObject * object, + const gchar * format, + ...) G_GNUC_PRINTF (5, 6) G_GNUC_NO_INSTRUMENT; + #endif /* GST_USING_PRINTF_EXTENSION */ void gst_debug_log_valist (GstDebugCategory * category, @@ -321,8 +345,21 @@ const gchar * _gst_debug_nameof_funcptr (GstDebugFuncPtr func) G_GNUC_NO_INSTRUMENT; +void gst_debug_log_valist2 (GstDebugCategory * category, + GstDebugLevel level, + const GstDebugTraceLocation *location, + GObject * object, + const gchar * format, + va_list args) G_GNUC_NO_INSTRUMENT; + const gchar * gst_debug_message_get (GstDebugMessage * message); +gchar * gst_debug_print_object (gpointer ptr); + +#ifdef HAVE_PRINTF_EXTENSION +gchar * gst_debug_print_segment (gpointer ptr); +#endif + void gst_debug_log_default (GstDebugCategory * category, GstDebugLevel level, const gchar * file, @@ -507,19 +544,41 @@ GST_EXPORT GstDebugLevel __gst_debug_min; * debugging messages. You will probably want to use one of the ones described * below. */ +#if defined(GST_USING_PRINTF_EXTENSION) && defined(G_HAVE_GNUC_VARARGS) +#define GST_CAT_LEVEL_LOG_obj(cat,level,object,str,args...) G_STMT_START{ \ + if (G_UNLIKELY (level <= __gst_debug_min)) { \ + const GstDebugTraceLocation loc = GST_DEBUG_TRACE_LOCATION(); \ + gst_debug_log2 ((cat), (level), &loc, NULL, "%"GST_PTR_FORMAT" "str, \ + (object), ##args ); \ + } \ +}G_STMT_END +#define GST_CAT_LEVEL_LOG_noobj(cat,level,object,str,args...) G_STMT_START{\ + if (G_UNLIKELY (level <= __gst_debug_min)) { \ + const GstDebugTraceLocation loc = GST_DEBUG_TRACE_LOCATION(); \ + gst_debug_log2 ((cat), (level), &loc, NULL, (str), ##args ); \ + } \ +}G_STMT_END +#else +# define GST_CAT_LEVEL_LOG_obj GST_CAT_LEVEL_LOG +# define GST_CAT_LEVEL_LOG_noobj GST_CAT_LEVEL_LOG +#endif + + #ifdef G_HAVE_ISO_VARARGS #define GST_CAT_LEVEL_LOG(cat,level,object,...) G_STMT_START{ \ - if (G_UNLIKELY (level <= __gst_debug_min)) { \ - gst_debug_log ((cat), (level), __FILE__, GST_FUNCTION, __LINE__, \ - (GObject *) (object), __VA_ARGS__); \ + if (G_UNLIKELY (level <= __gst_debug_min)) { \ + const GstDebugTraceLocation loc = GST_DEBUG_TRACE_LOCATION(); \ + gst_debug_log2 ((cat), (level), &loc, (GObject *) (object), \ + __VA_ARGS__); \ } \ }G_STMT_END #else /* G_HAVE_GNUC_VARARGS */ #ifdef G_HAVE_GNUC_VARARGS #define GST_CAT_LEVEL_LOG(cat,level,object,args...) G_STMT_START{ \ if (G_UNLIKELY (level <= __gst_debug_min)) { \ - gst_debug_log ((cat), (level), __FILE__, GST_FUNCTION, __LINE__, \ - (GObject *) (object), ##args ); \ + const GstDebugTraceLocation loc = GST_DEBUG_TRACE_LOCATION(); \ + gst_debug_log2 ((cat), (level), &loc, (GObject *) (object), \ + ##args ); \ } \ }G_STMT_END #else /* no variadic macros, use inline */ @@ -1256,6 +1315,7 @@ GST_TRACE (const char *format, ...) #if defined(__GNUC__) && __GNUC__ >= 3 # pragma GCC poison gst_debug_log +# pragma GCC poison gst_debug_log2 # pragma GCC poison gst_debug_log_valist # pragma GCC poison _gst_debug_category_new #endif -- 1.7.9.5 From c5d25857d78fb61b29ba192ccf32bd012ef51f1a Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Wed, 19 May 2010 15:48:09 -0500 Subject: [PATCH 03/11] add GstQueryBuffers query This query is used by buffer allocator, for example a video sink element, to find out any minimum buffer requirements of upstream elements that uses pad_alloc() to allocate buffers. For example, some cameras may have need for additional padding/boarder around the frame (for vstab), or some video decoders may have requirements for a certain minimum number of buffers (so they can hold refs to reference-frames) --- gst/gstquark.c | 3 +- gst/gstquark.h | 7 ++- gst/gstquery.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gst/gstquery.h | 16 ++++++- 4 files changed, 164 insertions(+), 3 deletions(-) diff --git a/gst/gstquark.c b/gst/gstquark.c index 91a2012..0459b4e 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -50,7 +50,8 @@ static const gchar *_quark_strings[] = { "intermediate", "GstMessageStepStart", "active", "eos", "sink-message", "message", "GstMessageQOS", "running-time", "stream-time", "jitter", "quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress", - "code", "text", "percent", "timeout" + "code", "text", "percent", "timeout", + "GstQueryBuffers", "caps", "count", "width", "height" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index 6e16ee5..350f9fc 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -132,8 +132,13 @@ typedef enum _GstQuarkId GST_QUARK_TEXT = 103, GST_QUARK_PERCENT = 104, GST_QUARK_TIMEOUT = 105, + GST_QUARK_QUERY_BUFFERS = 106, + GST_QUARK_CAPS = 107, + GST_QUARK_COUNT = 108, + GST_QUARK_WIDTH = 109, + GST_QUARK_HEIGHT = 110, - GST_QUARK_MAX = 106 + GST_QUARK_MAX = 111 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquery.c b/gst/gstquery.c index 2b1c382..1d7f5f9 100644 --- a/gst/gstquery.c +++ b/gst/gstquery.c @@ -96,6 +96,7 @@ static GstQueryTypeDefinition standard_definitions[] = { {GST_QUERY_BUFFERING, "buffering", "Buffering status", 0}, {GST_QUERY_CUSTOM, "custom", "Custom query", 0}, {GST_QUERY_URI, "uri", "URI of the source or sink", 0}, + {GST_QUERY_BUFFERS, "buffers", "Minimum buffer requirements", 0}, {GST_QUERY_NONE, NULL, NULL, 0} }; @@ -1490,3 +1491,143 @@ gst_query_parse_uri (GstQuery * query, gchar ** uri) *uri = g_value_dup_string (gst_structure_id_get_value (query->structure, GST_QUARK (URI))); } + +/** + * gst_query_new_buffers: + * @caps: the #GstCaps for the buffers that are going to be allocated + * + * Constructs a new buffer requirements query object to query buffer + * requirements for a particular caps. Use gst_query_unref() when done + * with it. + * + * Returns: A #GstQuery + */ +GstQuery * +gst_query_new_buffers (GstCaps * caps) +{ + GstQuery *query; + GstStructure *structure; + + /* XXX could add size here, for linear (non YUV/RGB) buffers? But I'm not + * entirely sure what is the use-case for that.. it should be easy enough + * to add more optional reply fields later + */ + structure = gst_structure_id_new (GST_QUARK (QUERY_BUFFERS), + GST_QUARK (CAPS), GST_TYPE_CAPS, caps, + GST_QUARK (COUNT), G_TYPE_INT, -1, + GST_QUARK (WIDTH), G_TYPE_INT, -1, + GST_QUARK (HEIGHT), G_TYPE_INT, -1, NULL); + + query = gst_query_new (GST_QUERY_BUFFERS, structure); + + return query; +} + +/** + * gst_query_set_buffers_count: + * @count: minimum number of buffers required + * + * Answer a buffers query by setting the minimum number of buffers required. + * If there is no minimum buffer count requirement, don't set this field in + * the query. + */ +void +gst_query_set_buffers_count (GstQuery * query, gint count) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERS); + + structure = gst_query_get_structure (query); + gst_structure_id_set (structure, GST_QUARK (COUNT), G_TYPE_INT, count, NULL); +} + +/** + * gst_query_set_buffers_dimensions: + * @width: minimum buffer width + * @height: minimum buffer height + * + * Answer a buffers query by setting the minimum buffer dimensions required. + * If there is no minimum buffer dimensions (beyond the width/height specified + * in the #GstCaps), don't set this field in the query. + */ +void +gst_query_set_buffers_dimensions (GstQuery * query, gint width, gint height) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERS); + + structure = gst_query_get_structure (query); + gst_structure_id_set (structure, + GST_QUARK (WIDTH), G_TYPE_INT, width, + GST_QUARK (HEIGHT), G_TYPE_INT, height, NULL); +} + +/** + * gst_query_parse_buffers_caps: + * @query: a #GstQuery + * @caps: the storage for the #GstCaps pointer, or NULL + * + * Parse a buffers query. + */ +void +gst_query_parse_buffers_caps (GstQuery * query, const GstCaps ** caps) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERS); + + structure = gst_query_get_structure (query); + if (caps) + *caps = gst_value_get_caps (gst_structure_id_get_value (structure, + GST_QUARK (CAPS))); +} + +/** + * gst_query_parse_buffers_count: + * @query: a #GstQuery + * @count: the storage for minimum number of buffers, or NULL + * + * Parse a buffers query answer to see the minimum number of buffers + * required. A returned value of -1 means there is no minimum requirement + */ +void +gst_query_parse_buffers_count (GstQuery * query, gint * count) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERS); + + structure = gst_query_get_structure (query); + if (count) + *count = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (COUNT))); +} + +/** + * gst_query_parse_buffers_dimensions: + * @query: a #GstQuery + * @width: the storage for minimum width, or NULL + * @height: the storage for minimum height, or NULL + * + * Parse a buffers query answer to see the minimum buffer dimensions required. + * A returned value of -1 for either dimension means there is no minimum + * requirement in that axis + */ +void +gst_query_parse_buffers_dimensions (GstQuery * query, gint * width, + gint * height) +{ + GstStructure *structure; + + g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERS); + + structure = gst_query_get_structure (query); + if (width) + *width = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (WIDTH))); + if (height) + *height = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (HEIGHT))); +} diff --git a/gst/gstquery.h b/gst/gstquery.h index 2166537..8dd710a 100644 --- a/gst/gstquery.h +++ b/gst/gstquery.h @@ -31,6 +31,7 @@ #include <gst/gstminiobject.h> #include <gst/gststructure.h> #include <gst/gstformat.h> +#include <gst/gstcaps.h> G_BEGIN_DECLS @@ -51,6 +52,9 @@ G_BEGIN_DECLS * @GST_QUERY_CUSTOM: a custom application or element defined query. Since * 0.10.22. * @GST_QUERY_URI: query the URI of the source or sink. Since 0.10.22. + * @GST_QUERY_BUFFERS: query the upstream users of pad_alloc()'d buffers to + * find any particular requirements about buffer size (padding) or numbers of + * buffers. Since ?.?.?. * * Standard predefined Query types */ @@ -69,7 +73,8 @@ typedef enum { GST_QUERY_FORMATS, GST_QUERY_BUFFERING, GST_QUERY_CUSTOM, - GST_QUERY_URI + GST_QUERY_URI, + GST_QUERY_BUFFERS } GstQueryType; /** @@ -336,6 +341,15 @@ GstQuery * gst_query_new_uri (void) G_GNUC_MALLOC; void gst_query_parse_uri (GstQuery *query, gchar **uri); void gst_query_set_uri (GstQuery *query, const gchar *uri); +/* buffer requirements query */ +GstQuery * gst_query_new_buffers (GstCaps * caps); +void gst_query_set_buffers_count (GstQuery * query, gint count); +void gst_query_set_buffers_dimensions (GstQuery * query, gint width, gint height); +void gst_query_parse_buffers_caps (GstQuery * query, const GstCaps ** caps); +void gst_query_parse_buffers_count (GstQuery * query, gint * count); +void gst_query_parse_buffers_dimensions (GstQuery * query, gint * width, gint * height); + + G_END_DECLS #endif /* __GST_QUERY_H__ */ -- 1.7.9.5 From 63715d9880d74b65295b0d5a3dff7a97f72e30c7 Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Mon, 24 May 2010 16:49:20 -0500 Subject: [PATCH 04/11] Add GstEventCrop event This event can be used to set cropping / region-of-interest to take effect on the following buffer. --- gst/gstevent.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gst/gstevent.h | 11 ++++++++++ gst/gstquark.c | 3 ++- gst/gstquark.h | 5 ++++- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/gst/gstevent.c b/gst/gstevent.c index 8c323aa..50218d2 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -116,6 +116,7 @@ static GstEventQuarks event_quarks[] = { {GST_EVENT_TAG, "tag", 0}, {GST_EVENT_BUFFERSIZE, "buffersize", 0}, {GST_EVENT_SINK_MESSAGE, "sink-message", 0}, + {GST_EVENT_CROP, "crop", 0}, {GST_EVENT_QOS, "qos", 0}, {GST_EVENT_SEEK, "seek", 0}, {GST_EVENT_NAVIGATION, "navigation", 0}, @@ -1303,3 +1304,65 @@ gst_event_parse_sink_message (GstEvent * event, GstMessage ** msg) GST_MESSAGE (gst_value_dup_mini_object (gst_structure_id_get_value (event->structure, GST_QUARK (MESSAGE)))); } + +/** + * gst_event_new_crop: + * @top: the new offset to top of sub-image + * @left: the new offset to left of sub-image + * @width: the new width + * @height: the new height + * + * Create a new crop event. + */ +GstEvent * +gst_event_new_crop (gint top, gint left, gint width, gint height) +{ + GstEvent *event; + GstStructure *structure; + + GST_CAT_INFO (GST_CAT_EVENT, "creating crop event: %d,%d %dx%d", + top, left, width, height); + + structure = gst_structure_id_new (GST_QUARK (EVENT_CROP), + GST_QUARK (TOP), G_TYPE_INT, top, + GST_QUARK (LEFT), G_TYPE_INT, left, + GST_QUARK (WIDTH), G_TYPE_INT, width, + GST_QUARK (HEIGHT), G_TYPE_INT, height, NULL); + event = gst_event_new_custom (GST_EVENT_CROP, structure); + + return event; +} + +/** + * gst_event_parse_crop: + * @event: The event to query + * @top: A pointer to store top offset in + * @left: A pointer to store left offset in + * @width: A pointer to store width in + * @height: A pointer to store height in + * + * Parse the crop event. + */ +void +gst_event_parse_crop (GstEvent * event, gint * top, gint * left, + gint * width, gint * height) +{ + const GstStructure *structure; + + g_return_if_fail (GST_IS_EVENT (event)); + g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_CROP); + + structure = gst_event_get_structure (event); + if (top) + *top = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (TOP))); + if (left) + *left = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (LEFT))); + if (width) + *width = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (WIDTH))); + if (height) + *height = g_value_get_int (gst_structure_id_get_value (structure, + GST_QUARK (HEIGHT))); +} diff --git a/gst/gstevent.h b/gst/gstevent.h index 20e8ef0..744cfb2 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -94,6 +94,10 @@ typedef enum { * send messages that should be emitted in sync with * rendering. * Since: 0.10.26 + * @GST_EVENT_CROP: An event that can set horizontal (pan/scan) and vertical + * (tilt/scan) offset and width/height within a larger + * image. This event precedes the buffer to which it + * applies. * @GST_EVENT_QOS: A quality message. Used to indicate to upstream elements * that the downstream elements should adjust their processing * rate. @@ -134,6 +138,7 @@ typedef enum { GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), + GST_EVENT_CROP = GST_EVENT_MAKE_TYPE (10, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), /* upstream events */ GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, FLAG(UPSTREAM)), GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, FLAG(UPSTREAM)), @@ -524,6 +529,12 @@ GstEvent* gst_event_new_step (GstFormat format, guint64 amoun void gst_event_parse_step (GstEvent *event, GstFormat *format, guint64 *amount, gdouble *rate, gboolean *flush, gboolean *intermediate); +/* crop event */ +GstEvent * gst_event_new_crop (gint top, gint left, gint width, gint height); +void gst_event_parse_crop (GstEvent * event, gint * top, gint * left, + gint * width, gint * height); + + G_END_DECLS #endif /* __GST_EVENT_H__ */ diff --git a/gst/gstquark.c b/gst/gstquark.c index 0459b4e..51ab561 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -51,7 +51,8 @@ static const gchar *_quark_strings[] = { "message", "GstMessageQOS", "running-time", "stream-time", "jitter", "quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress", "code", "text", "percent", "timeout", - "GstQueryBuffers", "caps", "count", "width", "height" + "GstQueryBuffers", "caps", "count", "width", "height", + "GstEventCrop", "top", "left" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index 350f9fc..d73c611 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -137,8 +137,11 @@ typedef enum _GstQuarkId GST_QUARK_COUNT = 108, GST_QUARK_WIDTH = 109, GST_QUARK_HEIGHT = 110, + GST_QUARK_EVENT_CROP = 111, + GST_QUARK_TOP = 112, + GST_QUARK_LEFT = 113, - GST_QUARK_MAX = 111 + GST_QUARK_MAX = 114 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; -- 1.7.9.5 From 65774ab5a7dc664187cb453c3b5fb59a5d0d954b Mon Sep 17 00:00:00 2001 From: Alessandro Decina <alessandro.decina@collabora.co.uk> Date: Fri, 6 May 2011 08:40:26 +0200 Subject: [PATCH 05/11] Add GST_EVENT_LIVE_FLUSH. This is needed by live sources to unblock buffer_alloc going from PLAYING to PAUSED. Currently basesrc assumes that ::create can always be unblocked. When going from PLAYING to PAUSED it can happen that a live source is blocked in a buffer_alloc call and so we need a way to unblock it. --- gst/gstevent.c | 8 ++++++++ gst/gstevent.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/gst/gstevent.c b/gst/gstevent.c index 50218d2..41f356d 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -111,6 +111,7 @@ static GstEventQuarks event_quarks[] = { {GST_EVENT_UNKNOWN, "unknown", 0}, {GST_EVENT_FLUSH_START, "flush-start", 0}, {GST_EVENT_FLUSH_STOP, "flush-stop", 0}, + {GST_EVENT_LIVE_FLUSH, "live-flush", 0}, {GST_EVENT_EOS, "eos", 0}, {GST_EVENT_NEWSEGMENT, "newsegment", 0}, {GST_EVENT_TAG, "tag", 0}, @@ -462,6 +463,13 @@ gst_event_new_flush_stop (void) return gst_event_new (GST_EVENT_FLUSH_STOP); } + +GstEvent * +gst_event_new_live_flush (void) +{ + return gst_event_new (GST_EVENT_LIVE_FLUSH); +} + /** * gst_event_new_eos: * diff --git a/gst/gstevent.h b/gst/gstevent.h index 744cfb2..bbe28b9 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -132,6 +132,7 @@ typedef enum { /* bidirectional events */ GST_EVENT_FLUSH_START = GST_EVENT_MAKE_TYPE (1, FLAG(BOTH)), GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH) | FLAG(SERIALIZED)), + GST_EVENT_LIVE_FLUSH = GST_EVENT_MAKE_TYPE (3, FLAG(BOTH)), /* downstream serialized events */ GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_NEWSEGMENT = GST_EVENT_MAKE_TYPE (6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), @@ -460,6 +461,7 @@ void gst_event_set_seqnum (GstEvent *event, guint32 seqnum /* flush events */ GstEvent * gst_event_new_flush_start (void) G_GNUC_MALLOC; GstEvent * gst_event_new_flush_stop (void) G_GNUC_MALLOC; +GstEvent * gst_event_new_live_flush (void) G_GNUC_MALLOC; /* EOS event */ GstEvent * gst_event_new_eos (void) G_GNUC_MALLOC; -- 1.7.9.5 From bd3be1d0ab9fec5b1fcfba0058eebdaea97dc934 Mon Sep 17 00:00:00 2001 From: Alessandro Decina <alessandro.decina@collabora.co.uk> Date: Fri, 6 May 2011 09:29:46 +0200 Subject: [PATCH 06/11] Refresh gstreamer-sections.txt --- docs/gst/gstreamer-sections.txt | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 5fc6ec6..cd0eab7 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -720,6 +720,21 @@ GST_IS_ELEMENT_FACTORY GST_ELEMENT_FACTORY_CLASS GST_IS_ELEMENT_FACTORY_CLASS GST_TYPE_ELEMENT_FACTORY +GST_ELEMENT_FACTORY_KLASS_DECODER +GST_ELEMENT_FACTORY_KLASS_DEMUXER +GST_ELEMENT_FACTORY_KLASS_DEPAYLOADER +GST_ELEMENT_FACTORY_KLASS_ENCODER +GST_ELEMENT_FACTORY_KLASS_FORMATTER +GST_ELEMENT_FACTORY_KLASS_MEDIA_AUDIO +GST_ELEMENT_FACTORY_KLASS_MEDIA_IMAGE +GST_ELEMENT_FACTORY_KLASS_MEDIA_METADATA +GST_ELEMENT_FACTORY_KLASS_MEDIA_SUBTITLE +GST_ELEMENT_FACTORY_KLASS_MEDIA_VIDEO +GST_ELEMENT_FACTORY_KLASS_MUXER +GST_ELEMENT_FACTORY_KLASS_PARSER +GST_ELEMENT_FACTORY_KLASS_PAYLOADER +GST_ELEMENT_FACTORY_KLASS_SINK +GST_ELEMENT_FACTORY_KLASS_SRC <SUBSECTION Private> gst_element_factory_get_type GST_ELEMENT_FACTORY_KLASS_DECODER @@ -812,6 +827,7 @@ gst_event_set_seqnum gst_event_new_flush_start gst_event_new_flush_stop +gst_event_new_live_flush gst_event_new_eos @@ -832,6 +848,9 @@ gst_event_new_qos_full gst_event_parse_qos gst_event_parse_qos_full +gst_event_new_crop +gst_event_parse_crop + GstSeekType GstSeekFlags gst_event_new_seek @@ -1070,12 +1089,23 @@ GST_LEVEL_DEFAULT GstDebugColorFlags GstDebugCategory GstDebugGraphDetails +GstDebugTraceLocation GST_STR_NULL GST_DEBUG_PAD_NAME GST_FUNCTION GstLogFunction gst_debug_log gst_debug_log_valist +gst_debug_log2 +gst_debug_log_valist2 +gst_debug_print_object +gst_debug_print_segment +gst_query_new_buffers +gst_query_parse_buffers_caps +gst_query_parse_buffers_count +gst_query_parse_buffers_dimensions +gst_query_set_buffers_count +gst_query_set_buffers_dimensions gst_debug_message_get gst_debug_log_default gst_debug_level_get_name @@ -1106,6 +1136,8 @@ gst_debug_get_all_categories gst_debug_construct_term_color gst_debug_construct_win_color GST_CAT_LEVEL_LOG +GST_CAT_LEVEL_LOG_noobj +GST_CAT_LEVEL_LOG_obj GST_CAT_ERROR_OBJECT GST_CAT_WARNING_OBJECT GST_CAT_INFO_OBJECT @@ -1146,6 +1178,7 @@ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS gst_debug_print_stack_trace GST_TIME_FORMAT GST_TIME_ARGS +GST_DEBUG_TRACE_LOCATION <SUBSECTION Standard> GST_TYPE_DEBUG_COLOR_FLAGS GST_TYPE_DEBUG_LEVEL @@ -1949,6 +1982,7 @@ GST_IS_PLUGIN_FEATURE GST_PLUGIN_FEATURE_CLASS GST_IS_PLUGIN_FEATURE_CLASS GST_PLUGIN_FEATURE_GET_CLASS +GST_PLUGIN_FEATURE_LIST_DEBUG GST_TYPE_PLUGIN_FEATURE GST_TYPE_RANK <SUBSECTION Private> -- 1.7.9.5 From d2389eac4766c944f5f059d0c34397590da7395f Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Wed, 26 May 2010 14:42:40 -0500 Subject: [PATCH 07/11] basetransform: don't do unnecessary pad_alloc() Don't allocate a buffer in passthrough mode. --- libs/gst/base/gstbasetransform.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 4408ef2..1c59561 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -2473,14 +2473,26 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, no_qos: - /* first try to allocate an output buffer based on the currently negotiated - * format. While we call pad-alloc we could renegotiate the srcpad format or - * have a new suggestion for upstream buffer-alloc. - * In any case, outbuf will contain a buffer suitable for doing the configured - * transform after this function. */ - ret = gst_base_transform_prepare_output_buffer (trans, inbuf, outbuf); - if (G_UNLIKELY (ret != GST_FLOW_OK)) - goto no_buffer; + if (trans->passthrough) { + /* I'm not yet sure if we should bypass allocating output buffer in case of + * passthrough, or if I should override the prepare_output_buffer vmethod.. + * I think the argument for always doing buffer allocation is to give a + * chance for upstream caps-renegotiation.. except I think the existing + * gst_base_transform_buffer_alloc() which itself does a pad_alloc() should + * be sufficient.. + */ + GST_DEBUG_OBJECT (trans, "reuse input buffer"); + *outbuf = inbuf; + } else { + /* first try to allocate an output buffer based on the currently negotiated + * format. While we call pad-alloc we could renegotiate the srcpad format or + * have a new suggestion for upstream buffer-alloc. + * In any case, outbuf will contain a buffer suitable for doing the configured + * transform after this function. */ + ret = gst_base_transform_prepare_output_buffer (trans, inbuf, outbuf); + if (G_UNLIKELY (ret != GST_FLOW_OK)) + goto no_buffer; + } /* now perform the needed transform */ if (trans->passthrough) { -- 1.7.9.5 From b18d6e0628943b36ad5e78bb070210e58a54d813 Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Wed, 13 Jun 2012 18:53:29 -0500 Subject: [PATCH 08/11] hack: disable buffer writability check For private buffer metadata (ie. elements that attach their own private bookkeeping data to a buffer), we don't care about preserving immutability semantics of a buffer.. --- gst/gstbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index edc0a6e..4de64f7 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -351,7 +351,7 @@ gst_buffer_set_qdata (GstBuffer * buffer, GQuark quark, GstStructure * data) GList *l; g_return_if_fail (GST_IS_BUFFER (buffer)); - g_return_if_fail (gst_buffer_is_metadata_writable (buffer)); +// g_return_if_fail (gst_buffer_is_metadata_writable (buffer)); g_return_if_fail (data == NULL || quark == gst_structure_get_name_id (data)); /* locking should not really be required, since the metadata_writable -- 1.7.9.5 From 90d6c97048019295cc6a9880ed313880bb1fe19e Mon Sep 17 00:00:00 2001 From: Rob Clark <rob@ti.com> Date: Wed, 13 Jun 2012 18:54:51 -0500 Subject: [PATCH 09/11] utils: add quark and mini-object boilerplate macros --- gst/gstutils.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gst/gstutils.h b/gst/gstutils.h index a746913..fef1f9d 100644 --- a/gst/gstutils.h +++ b/gst/gstutils.h @@ -96,6 +96,40 @@ GType gst_type_register_static_full (GType parent_type, /* Macros for defining classes. Ideas taken from Bonobo, which took theirs from Nautilus and GOB. */ +#define GST_BOILERPLATE_QUARK(type, type_as_function) \ +GQuark \ +type_as_function ## _get_type (void) \ +{ \ + static gsize quark_gonce = 0; \ + if (g_once_init_enter (&quark_gonce)) { \ + gsize quark; \ + quark = (gsize) g_quark_from_static_string (#type);\ + g_once_init_leave (&quark_gonce, quark); \ + } \ + return (GQuark) quark_gonce; \ +} + +#define GST_BOILERPLATE_MINI_OBJECT(type, type_as_function) \ +static void type_as_function ## _class_init (type ## Class *g_class); \ +GType \ +type_as_function ## _get_type (void) \ +{ \ + static volatile gsize type_id = 0; \ + if (g_once_init_enter (&type_id)) { \ + GType new_type_id = g_type_register_static_simple ( \ + GST_TYPE_MINI_OBJECT, \ + g_intern_static_string (#type), \ + sizeof (type ## Class), \ + (GClassInitFunc) type_as_function ## _class_init, \ + sizeof (type), \ + NULL, \ + (GTypeFlags) 0); \ + g_once_init_leave (&type_id, new_type_id); \ + } \ + return type_id; \ +} + + /** * GST_BOILERPLATE_FULL: * @type: the name of the type struct -- 1.7.9.5 From e1c89c8c705a1e3f56c6472da6949d3edce8a95d Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> Date: Tue, 19 Jun 2012 09:35:49 +0000 Subject: [PATCH 10/11] baseparse: print unsigned values as unsigned values Avoids G_MAXUINT confusingly being printed as -1, among others. --- libs/gst/base/gstbaseparse.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 1da663c..e721ea9 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -2316,7 +2316,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) frame = &parse->priv->frame; if (G_LIKELY (buffer)) { - GST_LOG_OBJECT (parse, "buffer size: %d, offset = %" G_GINT64_FORMAT, + GST_LOG_OBJECT (parse, "buffer size: %u, offset = %" G_GINT64_FORMAT, GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer)); if (G_UNLIKELY (parse->priv->passthrough)) { gst_base_parse_frame_init (frame); @@ -2369,7 +2369,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) if (G_UNLIKELY (parse->priv->drain)) { min_size = av; - GST_DEBUG_OBJECT (parse, "draining, data left: %d", min_size); + GST_DEBUG_OBJECT (parse, "draining, data left: %u", min_size); if (G_UNLIKELY (!min_size)) { gst_buffer_unref (tmpbuf); goto done; @@ -2378,7 +2378,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) /* Collect at least min_frame_size bytes */ if (av < min_size) { - GST_DEBUG_OBJECT (parse, "not enough data available (only %d bytes)", + GST_DEBUG_OBJECT (parse, "not enough data available (only %u bytes)", av); gst_buffer_unref (tmpbuf); goto done; @@ -2403,12 +2403,12 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) if (res) { if (gst_adapter_available (parse->priv->adapter) < fsize) { GST_DEBUG_OBJECT (parse, - "found valid frame but not enough data available (only %d bytes)", + "found valid frame but not enough data available (only %u bytes)", gst_adapter_available (parse->priv->adapter)); gst_buffer_unref (tmpbuf); goto done; } - GST_LOG_OBJECT (parse, "valid frame of size %d at pos %d", fsize, skip); + GST_LOG_OBJECT (parse, "valid frame of size %u at pos %d", fsize, skip); break; } if (skip == -1) { @@ -2501,7 +2501,7 @@ done: invalid_min: { GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL), - ("min_size evolution %d -> %d; breaking to avoid looping", + ("min_size evolution %u -> %u; breaking to avoid looping", old_min_size, min_size)); return GST_FLOW_ERROR; } @@ -2719,7 +2719,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass, gst_buffer_replace (&frame->buffer, NULL); if (res) { parse->priv->drain = FALSE; - GST_LOG_OBJECT (parse, "valid frame of size %d at pos %d", fsize, skip); + GST_LOG_OBJECT (parse, "valid frame of size %u at pos %d", fsize, skip); break; } parse->priv->drain = FALSE; @@ -2787,7 +2787,7 @@ done: invalid_min: { GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL), - ("min_size evolution %d -> %d; breaking to avoid looping", + ("min_size evolution %u -> %u; breaking to avoid looping", old_min_size, min_size)); return GST_FLOW_ERROR; } -- 1.7.9.5 From 2096b1022ad513f90639aa7a04445a2da8bc5363 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> Date: Wed, 20 Jun 2012 11:44:33 +0000 Subject: [PATCH 11/11] baseparse: do not wait for more data when draining, it will never come --- libs/gst/base/gstbaseparse.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index e721ea9..69d5c6c 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -2437,6 +2437,13 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) parse->priv->discont = TRUE; /* something changed least; nullify loop check */ old_min_size = 0; + } else if (parse->priv->drain) { + /* If we are draining, but the parse wants more data for the same + start position, then we will not be able to supply more now, + we're probably looking at a truncated stream. */ + GST_DEBUG_OBJECT (parse, "Draining, and not enough data to parse next"); + gst_buffer_unref (tmpbuf); + goto done; } /* skip == 0 should imply subclass set min_size to need more data; * we check this shortly */ -- 1.7.9.5