diff options
author | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2012-03-20 20:21:37 +0100 |
---|---|---|
committer | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2012-03-20 20:21:37 +0100 |
commit | cc7918de19c1623be6ddbeb45b47bb715ff9d465 (patch) | |
tree | 39389fc28adc54c41f8821601969efa2d4881a87 | |
parent | 7c4dfc7d7c9b1c013e188e46dfb6aac60036002d (diff) | |
download | gstreamer-plugins-bad-cc7918de19c1623be6ddbeb45b47bb715ff9d465.tar.gz |
rawparse: port to 0.11
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gst/rawparse/gstaudioparse.c | 296 | ||||
-rw-r--r-- | gst/rawparse/gstaudioparse.h | 10 | ||||
-rw-r--r-- | gst/rawparse/gstrawparse.c | 312 | ||||
-rw-r--r-- | gst/rawparse/gstrawparse.h | 4 | ||||
-rw-r--r-- | gst/rawparse/gstvideoparse.c | 73 |
6 files changed, 314 insertions, 383 deletions
diff --git a/configure.ac b/configure.ac index 5f5071955..4e02d7403 100644 --- a/configure.ac +++ b/configure.ac @@ -306,7 +306,7 @@ GST_PLUGINS_NONPORTED=" aiff asfmux \ hdvparse hls id3tag inter interlace ivfparse jpegformat jp2kdecimator \ kate liveadder legacyresample librfb mpegtsmux \ mpegpsmux mve mxf mythtv nsf nuvdemux \ - patchdetect pnm rawparse real \ + patchdetect pnm real \ sdi siren speed subenc stereo tta videofilters \ videomeasure videosignal vmnc \ decklink fbdev linsys shm vcd \ diff --git a/gst/rawparse/gstaudioparse.c b/gst/rawparse/gstaudioparse.c index d4f82bad4..652b7eb6a 100644 --- a/gst/rawparse/gstaudioparse.c +++ b/gst/rawparse/gstaudioparse.c @@ -28,14 +28,17 @@ # include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as g_value_array stuff + * for now with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gstaudioparse.h" -#include <gst/audio/multichannel.h> +#include <string.h> typedef enum { - GST_AUDIO_PARSE_FORMAT_INT, - GST_AUDIO_PARSE_FORMAT_FLOAT, + GST_AUDIO_PARSE_FORMAT_RAW, GST_AUDIO_PARSE_FORMAT_MULAW, GST_AUDIO_PARSE_FORMAT_ALAW } GstAudioParseFormat; @@ -63,24 +66,20 @@ enum { PROP_0, PROP_FORMAT, + PROP_RAW_FORMAT, PROP_RATE, PROP_CHANNELS, - PROP_ENDIANNESS, - PROP_WIDTH, - PROP_DEPTH, - PROP_SIGNED, + PROP_INTERLEAVED, PROP_CHANNEL_POSITIONS }; - #define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ()) static GType gst_audio_parse_format_get_type (void) { static GType audio_parse_format_type = 0; static const GEnumValue format_types[] = { - {GST_AUDIO_PARSE_FORMAT_INT, "Integer", "int"}, - {GST_AUDIO_PARSE_FORMAT_FLOAT, "Floating Point", "float"}, + {GST_AUDIO_PARSE_FORMAT_RAW, "Raw", "raw"}, {GST_AUDIO_PARSE_FORMAT_ALAW, "A-Law", "alaw"}, {GST_AUDIO_PARSE_FORMAT_MULAW, "\302\265-Law", "mulaw"}, {0, NULL, NULL} @@ -94,68 +93,17 @@ gst_audio_parse_format_get_type (void) return audio_parse_format_type; } -#define GST_AUDIO_PARSE_ENDIANNESS (gst_audio_parse_endianness_get_type ()) -static GType -gst_audio_parse_endianness_get_type (void) -{ - static GType audio_parse_endianness_type = 0; - static const GEnumValue endian_types[] = { - {GST_AUDIO_PARSE_ENDIANNESS_LITTLE, "Little Endian", "little"}, - {GST_AUDIO_PARSE_ENDIANNESS_BIG, "Big Endian", "big"}, - {0, NULL, NULL} - }; - - if (!audio_parse_endianness_type) { - audio_parse_endianness_type = - g_enum_register_static ("GstAudioParseEndianness", endian_types); - } - - return audio_parse_endianness_type; -} - -GST_BOILERPLATE (GstAudioParse, gst_audio_parse, GstRawParse, - GST_TYPE_RAW_PARSE); - -static void -gst_audio_parse_base_init (gpointer g_class) -{ - GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - GstCaps *caps; - - GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0, - "audioparse element"); - - gst_element_class_set_details_simple (gstelement_class, "Audio Parse", - "Filter/Audio", - "Converts stream into audio frames", - "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); - - caps = - gst_caps_from_string ("audio/x-raw-int," - " depth=(int) [ 1, 32 ]," - " width=(int) { 8, 16, 24, 32 }," - " endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, " - " signed=(bool) { TRUE, FALSE }," - " rate=(int) [ 1, MAX ]," - " channels=(int) [ 1, MAX ]; " - "audio/x-raw-float," - " width=(int) { 32, 64 }," - " endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, " - " rate=(int)[1,MAX], channels=(int)[1,MAX]; " - "audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; " - "audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]"); - gst_raw_parse_class_set_src_pad_template (rp_class, caps); - gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE); - gst_caps_unref (caps); -} +#define gst_audio_parse_parent_class parent_class +G_DEFINE_TYPE (GstAudioParse, gst_audio_parse, GST_TYPE_RAW_PARSE); static void gst_audio_parse_class_init (GstAudioParseClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass); + GstCaps *caps; gobject_class->set_property = gst_audio_parse_set_property; gobject_class->get_property = gst_audio_parse_get_property; @@ -166,37 +114,26 @@ gst_audio_parse_class_init (GstAudioParseClass * klass) g_object_class_install_property (gobject_class, PROP_FORMAT, g_param_spec_enum ("format", "Format", "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT, - GST_AUDIO_PARSE_FORMAT_INT, + GST_AUDIO_PARSE_FORMAT_RAW, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_RAW_FORMAT, + g_param_spec_enum ("raw-format", "Raw Format", + "Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT, + GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_RATE, g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream", 1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_CHANNELS, g_param_spec_int ("channels", "Channels", - "Number of channels in raw stream", 1, INT_MAX, 2, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_WIDTH, - g_param_spec_int ("width", "Width", - "Width of audio samples in raw stream", 1, INT_MAX, 16, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_DEPTH, - g_param_spec_int ("depth", "Depth", - "Depth of audio samples in raw stream", 1, INT_MAX, 16, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_SIGNED, - g_param_spec_boolean ("signed", "signed", - "Sign of audio samples in raw stream", TRUE, + "Number of channels in raw stream", 1, 64, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_ENDIANNESS, - g_param_spec_enum ("endianness", "Endianness", - "Endianness of audio samples in raw stream", - GST_AUDIO_PARSE_ENDIANNESS, G_BYTE_ORDER, + g_object_class_install_property (gobject_class, PROP_INTERLEAVED, + g_param_spec_boolean ("interleaved", "Interleaved Layout", + "True if audio has interleaved layout", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS, @@ -208,17 +145,32 @@ gst_audio_parse_class_init (GstAudioParseClass * klass) GST_AUDIO_CHANNEL_POSITION_NONE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gst_element_class_set_details_simple (gstelement_class, "Audio Parse", + "Filter/Audio", + "Converts stream into audio frames", + "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); + + caps = gst_caps_from_string (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL) + ", layout = (string) { interleaved, non-interleaved }; " + "audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; " + "audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]"); + + gst_raw_parse_class_set_src_pad_template (rp_class, caps); + gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE); + gst_caps_unref (caps); + + GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0, + "audioparse element"); } static void -gst_audio_parse_init (GstAudioParse * ap, GstAudioParseClass * g_class) +gst_audio_parse_init (GstAudioParse * ap) { - ap->format = GST_AUDIO_PARSE_FORMAT_INT; + ap->format = GST_AUDIO_PARSE_FORMAT_RAW; + ap->raw_format = GST_AUDIO_FORMAT_S16; ap->channels = 2; - ap->width = 16; - ap->depth = 16; - ap->signedness = TRUE; - ap->endianness = G_BYTE_ORDER; + ap->interleaved = TRUE; gst_audio_parse_update_frame_size (ap); gst_raw_parse_set_fps (GST_RAW_PARSE (ap), 44100, 1); @@ -236,23 +188,17 @@ gst_audio_parse_set_property (GObject * object, guint prop_id, case PROP_FORMAT: ap->format = g_value_get_enum (value); break; + case PROP_RAW_FORMAT: + ap->raw_format = g_value_get_enum (value); + break; case PROP_RATE: gst_raw_parse_set_fps (GST_RAW_PARSE (ap), g_value_get_int (value), 1); break; case PROP_CHANNELS: ap->channels = g_value_get_int (value); break; - case PROP_WIDTH: - ap->width = g_value_get_int (value); - break; - case PROP_DEPTH: - ap->depth = g_value_get_int (value); - break; - case PROP_SIGNED: - ap->signedness = g_value_get_boolean (value); - break; - case PROP_ENDIANNESS: - ap->endianness = g_value_get_enum (value); + case PROP_INTERLEAVED: + ap->interleaved = g_value_get_boolean (value); break; case PROP_CHANNEL_POSITIONS: if (ap->channel_positions) @@ -278,6 +224,9 @@ gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value, case PROP_FORMAT: g_value_set_enum (value, ap->format); break; + case PROP_RAW_FORMAT: + g_value_set_enum (value, ap->raw_format); + break; case PROP_RATE:{ gint fps_n, fps_d; @@ -288,17 +237,8 @@ gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value, case PROP_CHANNELS: g_value_set_int (value, ap->channels); break; - case PROP_WIDTH: - g_value_set_int (value, ap->width); - break; - case PROP_DEPTH: - g_value_set_int (value, ap->depth); - break; - case PROP_SIGNED: - g_value_set_boolean (value, ap->signedness); - break; - case PROP_ENDIANNESS: - g_value_set_enum (value, ap->endianness); + case PROP_INTERLEAVED: + g_value_set_boolean (value, ap->interleaved); break; case PROP_CHANNEL_POSITIONS: g_value_set_boxed (value, ap->channel_positions); @@ -319,6 +259,9 @@ gst_audio_parse_finalize (GObject * object) ap->channel_positions = NULL; } + g_free (ap->channel_pos); + g_free (ap->channel_order); + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -332,11 +275,18 @@ gst_audio_parse_update_frame_size (GstAudioParse * ap) case GST_AUDIO_PARSE_FORMAT_MULAW: width = 8; break; - case GST_AUDIO_PARSE_FORMAT_INT: - case GST_AUDIO_PARSE_FORMAT_FLOAT: + case GST_AUDIO_PARSE_FORMAT_RAW: default: - width = ap->width; + { + GstAudioInfo info; + + gst_audio_info_init (&info); + /* rate, etc do not really matter here */ + gst_audio_info_set_format (&info, ap->raw_format, 44100, ap->channels, + NULL); + width = GST_AUDIO_INFO_WIDTH (&info); break; + } } framesize = (width / 8) * ap->channels; @@ -344,13 +294,12 @@ gst_audio_parse_update_frame_size (GstAudioParse * ap) gst_raw_parse_set_framesize (GST_RAW_PARSE (ap), framesize); } -static gboolean -gst_audio_parse_check_channel_positions (GValueArray * positions) +static GstAudioChannelPosition * +gst_audio_parse_get_channel_positions (GValueArray * positions) { gint i; guint channels; GstAudioChannelPosition *pos; - gboolean ret; channels = positions->n_values; pos = g_new (GstAudioChannelPosition, positions->n_values); @@ -361,86 +310,89 @@ gst_audio_parse_check_channel_positions (GValueArray * positions) pos[i] = g_value_get_enum (v); } - ret = gst_audio_check_channel_positions (pos, channels); - g_free (pos); - - return ret; + return pos; } static void -gst_audio_parse_set_channel_positions (GstAudioParse * ap, GstStructure * s) +gst_audio_parse_setup_channel_positions (GstAudioParse * ap) { - GValue pos_array = { 0, }; - gint i; + GstAudioChannelPosition *pos, *to; - if (!ap->channel_positions && ap->channels <= 2) { - /* Implicit mapping for 1- and 2-channel audio is okay */ + g_free (ap->channel_pos); + g_free (ap->channel_order); + ap->channel_pos = NULL; + ap->channel_order = NULL; + + if (!ap->channel_positions) { + GST_DEBUG_OBJECT (ap, "no channel positions"); + /* implicit mapping for 1- and 2-channel audio is okay */ + /* will come up with one in other cases also */ return; } - g_value_init (&pos_array, GST_TYPE_ARRAY); - - if (ap->channel_positions - && ap->channels == ap->channel_positions->n_values - && gst_audio_parse_check_channel_positions (ap->channel_positions)) { - GST_DEBUG_OBJECT (ap, "Using provided channel positions"); - for (i = 0; i < ap->channels; i++) - gst_value_array_append_value (&pos_array, - g_value_array_get_nth (ap->channel_positions, i)); - } else { - /* >2 channels and no explicit mapping */ - GValue pos_none = { 0, }; - - GST_WARNING_OBJECT (ap, "Using NONE channel positions"); - - g_value_init (&pos_none, GST_TYPE_AUDIO_CHANNEL_POSITION); - g_value_set_enum (&pos_none, GST_AUDIO_CHANNEL_POSITION_NONE); + pos = gst_audio_parse_get_channel_positions (ap->channel_positions); + if (ap->channels != ap->channel_positions->n_values || + !gst_audio_check_valid_channel_positions (pos, ap->channels, FALSE)) { + GST_DEBUG_OBJECT (ap, "invalid channel position"); + g_free (pos); + return; + } - for (i = 0; i < ap->channels; i++) - gst_value_array_append_value (&pos_array, &pos_none); + /* ok, got something we can work with now */ + to = g_new (GstAudioChannelPosition, ap->channels); + memcpy (to, pos, ap->channels * sizeof (to[0])); + gst_audio_channel_positions_to_valid_order (to, ap->channels); - g_value_unset (&pos_none); - } - gst_structure_set_value (s, "channel-positions", &pos_array); - g_value_unset (&pos_array); + ap->channel_pos = pos; + ap->channel_order = to; } static GstCaps * gst_audio_parse_get_caps (GstRawParse * rp) { GstAudioParse *ap = GST_AUDIO_PARSE (rp); - GstCaps *caps; - + GstCaps *caps, *ncaps; + GstAudioInfo info; gint fps_n, fps_d; + const GValue *val; gst_raw_parse_get_fps (rp, &fps_n, &fps_d); + gst_audio_parse_setup_channel_positions (ap); + + /* yes, even when format not raw */ + gst_audio_info_init (&info); + gst_audio_info_set_format (&info, ap->raw_format, fps_n, ap->channels, + ap->channel_order); + info.layout = ap->interleaved ? GST_AUDIO_LAYOUT_INTERLEAVED : + GST_AUDIO_LAYOUT_NON_INTERLEAVED; + caps = gst_audio_info_to_caps (&info); switch (ap->format) { - case GST_AUDIO_PARSE_FORMAT_INT: - caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, fps_n, - "channels", G_TYPE_INT, ap->channels, - "width", G_TYPE_INT, ap->width, - "depth", G_TYPE_INT, ap->depth, - "signed", G_TYPE_BOOLEAN, ap->signedness, - "endianness", G_TYPE_INT, ap->endianness, NULL); - break; - case GST_AUDIO_PARSE_FORMAT_FLOAT: - caps = gst_caps_new_simple ("audio/x-raw-float", - "rate", G_TYPE_INT, fps_n, - "channels", G_TYPE_INT, ap->channels, - "width", G_TYPE_INT, ap->width, - "endianness", G_TYPE_INT, ap->endianness, NULL); + case GST_AUDIO_PARSE_FORMAT_RAW: break; case GST_AUDIO_PARSE_FORMAT_ALAW: - caps = gst_caps_new_simple ("audio/x-alaw", + ncaps = gst_caps_new_simple ("audio/x-alaw", "rate", G_TYPE_INT, fps_n, "channels", G_TYPE_INT, ap->channels, NULL); + /* pick mask stuff from faked raw format */ + val = gst_structure_get_value (gst_caps_get_structure (caps, 0), + "channel-mask"); + if (val) + gst_caps_set_value (ncaps, "channel-mask", val); + gst_caps_unref (caps); + caps = ncaps; break; case GST_AUDIO_PARSE_FORMAT_MULAW: - caps = gst_caps_new_simple ("audio/x-mulaw", + ncaps = gst_caps_new_simple ("audio/x-mulaw", "rate", G_TYPE_INT, fps_n, "channels", G_TYPE_INT, ap->channels, NULL); + /* pick mask stuff from faked raw format */ + val = gst_structure_get_value (gst_caps_get_structure (caps, 0), + "channel-mask"); + if (val) + gst_caps_set_value (ncaps, "channel-mask", val); + gst_caps_unref (caps); + caps = ncaps; break; default: caps = gst_caps_new_empty (); @@ -448,7 +400,5 @@ gst_audio_parse_get_caps (GstRawParse * rp) break; } - gst_audio_parse_set_channel_positions (ap, gst_caps_get_structure (caps, 0)); - return caps; } diff --git a/gst/rawparse/gstaudioparse.h b/gst/rawparse/gstaudioparse.h index 7995f6c8d..d8dff783e 100644 --- a/gst/rawparse/gstaudioparse.h +++ b/gst/rawparse/gstaudioparse.h @@ -25,6 +25,7 @@ #include <gst/gst.h> #include <gst/base/gstbasetransform.h> #include <gst/base/gstadapter.h> +#include <gst/audio/audio.h> #include "gstrawparse.h" @@ -48,12 +49,13 @@ struct _GstAudioParse /* properties */ gint format; + GstAudioFormat raw_format; gint channels; - gint width; - gint depth; - gint signedness; - gint endianness; + gboolean interleaved; GValueArray *channel_positions; + + GstAudioChannelPosition *channel_pos; + GstAudioChannelPosition *channel_order; }; struct _GstAudioParseClass diff --git a/gst/rawparse/gstrawparse.c b/gst/rawparse/gstrawparse.c index fd966f56f..a4a8d0726 100644 --- a/gst/rawparse/gstrawparse.c +++ b/gst/rawparse/gstrawparse.c @@ -41,20 +41,23 @@ static void gst_raw_parse_dispose (GObject * object); -static gboolean gst_raw_parse_sink_activate (GstPad * sinkpad); -static gboolean gst_raw_parse_sink_activatepull (GstPad * sinkpad, - gboolean active); +static gboolean gst_raw_parse_sink_activate (GstPad * sinkpad, + GstObject * parent); +static gboolean gst_raw_parse_sink_activatemode (GstPad * sinkpad, + GstObject * parent, GstPadMode mode, gboolean active); static void gst_raw_parse_loop (GstElement * element); static GstStateChangeReturn gst_raw_parse_change_state (GstElement * element, GstStateChange transition); -static GstFlowReturn gst_raw_parse_chain (GstPad * pad, GstBuffer * buffer); -static gboolean gst_raw_parse_sink_event (GstPad * pad, GstEvent * event); -static gboolean gst_raw_parse_src_event (GstPad * pad, GstEvent * event); -static const GstQueryType *gst_raw_parse_src_query_type (GstPad * pad); -static gboolean gst_raw_parse_src_query (GstPad * pad, GstQuery * query); -static gboolean gst_raw_parse_convert (GstRawParse * rp, - GstFormat src_format, gint64 src_value, - GstFormat dest_format, gint64 * dest_value); +static GstFlowReturn gst_raw_parse_chain (GstPad * pad, GstObject * parent, + GstBuffer * buffer); +static gboolean gst_raw_parse_sink_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_raw_parse_src_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_raw_parse_src_query (GstPad * pad, GstObject * parent, + GstQuery * query); +static gboolean gst_raw_parse_convert (GstRawParse * rp, GstFormat src_format, + gint64 src_value, GstFormat dest_format, gint64 * dest_value); static gboolean gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event); @@ -69,18 +72,29 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_DEBUG_CATEGORY_STATIC (gst_raw_parse_debug); #define GST_CAT_DEFAULT gst_raw_parse_debug -GST_BOILERPLATE (GstRawParse, gst_raw_parse, GstElement, GST_TYPE_ELEMENT); +static void gst_raw_parse_class_init (GstRawParseClass * klass); +static void gst_raw_parse_init (GstRawParse * clip, GstRawParseClass * g_class); -static void -gst_raw_parse_base_init (gpointer g_class) +static GstElementClass *parent_class; + +/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init + * method to get to the padtemplates */ +GType +gst_raw_parse_get_type (void) { - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); + static volatile gsize raw_parse_type = 0; - GST_DEBUG_CATEGORY_INIT (gst_raw_parse_debug, "rawparse", 0, - "rawparse element"); + if (g_once_init_enter (&raw_parse_type)) { + GType _type; - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&gst_raw_parse_sink_pad_template)); + _type = g_type_register_static_simple (GST_TYPE_ELEMENT, + "GstRawParse", sizeof (GstRawParseClass), + (GClassInitFunc) gst_raw_parse_class_init, sizeof (GstRawParse), + (GInstanceInitFunc) gst_raw_parse_init, G_TYPE_FLAG_ABSTRACT); + + g_once_init_leave (&raw_parse_type, _type); + } + return raw_parse_type; } static void @@ -89,10 +103,18 @@ gst_raw_parse_class_init (GstRawParseClass * klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + parent_class = g_type_class_peek_parent (klass); + gobject_class->dispose = gst_raw_parse_dispose; gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_raw_parse_change_state); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_raw_parse_sink_pad_template)); + + GST_DEBUG_CATEGORY_INIT (gst_raw_parse_debug, "rawparse", 0, + "rawparse element"); } static void @@ -110,8 +132,8 @@ gst_raw_parse_init (GstRawParse * rp, GstRawParseClass * g_class) GST_DEBUG_FUNCPTR (gst_raw_parse_sink_event)); gst_pad_set_activate_function (rp->sinkpad, GST_DEBUG_FUNCPTR (gst_raw_parse_sink_activate)); - gst_pad_set_activatepull_function (rp->sinkpad, - GST_DEBUG_FUNCPTR (gst_raw_parse_sink_activatepull)); + gst_pad_set_activatemode_function (rp->sinkpad, + GST_DEBUG_FUNCPTR (gst_raw_parse_sink_activatemode)); gst_element_add_pad (GST_ELEMENT (rp), rp->sinkpad); src_pad_template = gst_element_class_get_pad_template (element_class, "src"); @@ -125,8 +147,6 @@ gst_raw_parse_init (GstRawParse * rp, GstRawParseClass * g_class) gst_pad_set_event_function (rp->srcpad, GST_DEBUG_FUNCPTR (gst_raw_parse_src_event)); - gst_pad_set_query_type_function (rp->srcpad, - GST_DEBUG_FUNCPTR (gst_raw_parse_src_query_type)); gst_pad_set_query_function (rp->srcpad, GST_DEBUG_FUNCPTR (gst_raw_parse_src_query)); gst_element_add_pad (GST_ELEMENT (rp), rp->srcpad); @@ -218,7 +238,7 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer) rpclass = GST_RAW_PARSE_GET_CLASS (rp); - nframes = GST_BUFFER_SIZE (buffer) / rp->framesize; + nframes = gst_buffer_get_size (buffer) / rp->framesize; if (rp->segment.rate < 0) { rp->n_frames -= nframes; @@ -238,7 +258,6 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer) GST_BUFFER_TIMESTAMP (buffer) = rp->segment.start; GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE; } - gst_buffer_set_caps (buffer, GST_PAD_CAPS (rp->srcpad)); if (rpclass->set_buffer_flags) { rpclass->set_buffer_flags (rp, buffer); @@ -250,11 +269,11 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer) } if (rp->segment.rate >= 0) { - rp->offset += GST_BUFFER_SIZE (buffer); + rp->offset += gst_buffer_get_size (buffer); rp->n_frames += nframes; } - rp->segment.last_stop = GST_BUFFER_TIMESTAMP (buffer); + rp->segment.position = GST_BUFFER_TIMESTAMP (buffer); GST_LOG_OBJECT (rp, "Pushing buffer with time %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); @@ -265,9 +284,9 @@ gst_raw_parse_push_buffer (GstRawParse * rp, GstBuffer * buffer) } static GstFlowReturn -gst_raw_parse_chain (GstPad * pad, GstBuffer * buffer) +gst_raw_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { - GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad)); + GstRawParse *rp = GST_RAW_PARSE (parent); GstFlowReturn ret = GST_FLOW_OK; GstRawParseClass *rp_class = GST_RAW_PARSE_GET_CLASS (rp); guint buffersize; @@ -298,7 +317,6 @@ gst_raw_parse_chain (GstPad * pad, GstBuffer * buffer) break; } done: - gst_object_unref (rp); return ret; @@ -323,11 +341,6 @@ gst_raw_parse_loop (GstElement * element) if (!gst_raw_parse_set_src_caps (rp)) goto no_caps; - if (rp->close_segment) { - GST_DEBUG_OBJECT (rp, "sending close segment"); - gst_pad_push_event (rp->srcpad, rp->close_segment); - rp->close_segment = NULL; - } if (rp->start_segment) { GST_DEBUG_OBJECT (rp, "sending start segment"); gst_pad_push_event (rp->srcpad, rp->start_segment); @@ -343,13 +356,12 @@ gst_raw_parse_loop (GstElement * element) if (rp->offset + size > rp->upstream_length) { GstFormat fmt = GST_FORMAT_BYTES; - if (!gst_pad_query_peer_duration (rp->sinkpad, &fmt, - &rp->upstream_length)) { + if (!gst_pad_peer_query_duration (rp->sinkpad, fmt, &rp->upstream_length)) { GST_WARNING_OBJECT (rp, "Could not get upstream duration, trying to pull frame by frame"); size = rp->framesize; } else if (rp->upstream_length < rp->offset + rp->framesize) { - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; goto pause; } else if (rp->offset + size > rp->upstream_length) { size = rp->upstream_length - rp->offset; @@ -358,7 +370,7 @@ gst_raw_parse_loop (GstElement * element) } } else { if (rp->offset == 0) { - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; goto pause; } else if (rp->offset < size) { size -= rp->offset; @@ -376,17 +388,18 @@ gst_raw_parse_loop (GstElement * element) goto pause; } - if (GST_BUFFER_SIZE (buffer) < size) { + if (gst_buffer_get_size (buffer) < size) { GST_DEBUG_OBJECT (rp, "Short read at offset %" G_GINT64_FORMAT - ", got only %u of %u bytes", rp->offset, GST_BUFFER_SIZE (buffer), + ", got only %u of %u bytes", rp->offset, gst_buffer_get_size (buffer), size); if (size > rp->framesize) { - GST_BUFFER_SIZE (buffer) -= GST_BUFFER_SIZE (buffer) % rp->framesize; + gst_buffer_set_size (buffer, gst_buffer_get_size (buffer) - + gst_buffer_get_size (buffer) % rp->framesize); } else { gst_buffer_unref (buffer); buffer = NULL; - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; goto pause; } } @@ -411,7 +424,7 @@ pause: GST_LOG_OBJECT (rp, "pausing task, reason %s", reason); gst_pad_pause_task (rp->sinkpad); - if (ret == GST_FLOW_UNEXPECTED) { + if (ret == GST_FLOW_EOS) { if (rp->segment.flags & GST_SEEK_FLAG_SEGMENT) { GstClockTime stop; @@ -427,7 +440,7 @@ pause: GST_LOG_OBJECT (rp, "Sending EOS, at end of stream"); gst_pad_push_event (rp->srcpad, gst_event_new_eos ()); } - } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) { + } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { GST_ELEMENT_ERROR (rp, STREAM, FAILED, ("Internal data stream error."), ("stream stopped, reason %s", reason)); @@ -438,50 +451,68 @@ pause: } static gboolean -gst_raw_parse_sink_activate (GstPad * sinkpad) +gst_raw_parse_sink_activate (GstPad * sinkpad, GstObject * parent) { - if (gst_pad_check_pull_range (sinkpad)) { - GST_RAW_PARSE (GST_PAD_PARENT (sinkpad))->mode = GST_PAD_ACTIVATE_PULL; - return gst_pad_activate_pull (sinkpad, TRUE); + GstQuery *query; + gboolean pull_mode = FALSE; + + query = gst_query_new_scheduling (); + + if (gst_pad_peer_query (sinkpad, query)) + pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL); + + gst_query_unref (query); + + if (pull_mode) { + GST_DEBUG ("going to pull mode"); + return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE); } else { - GST_RAW_PARSE (GST_PAD_PARENT (sinkpad))->mode = GST_PAD_ACTIVATE_PUSH; - return gst_pad_activate_push (sinkpad, TRUE); + GST_DEBUG ("going to push (streaming) mode"); + return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE); } } static gboolean -gst_raw_parse_sink_activatepull (GstPad * sinkpad, gboolean active) +gst_raw_parse_sink_activatemode (GstPad * sinkpad, GstObject * parent, + GstPadMode mode, gboolean active) { - GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (sinkpad)); + GstRawParse *rp = GST_RAW_PARSE (parent); gboolean result; - if (active) { - GstFormat format; - gint64 duration; - - /* get the duration in bytes */ - format = GST_FORMAT_BYTES; - result = gst_pad_query_peer_duration (sinkpad, &format, &duration); - if (result) { - GST_DEBUG_OBJECT (rp, "got duration %" GST_TIME_FORMAT, - GST_TIME_ARGS (duration)); - rp->upstream_length = duration; - /* convert to time */ - gst_raw_parse_convert (rp, format, duration, GST_FORMAT_TIME, &duration); - } else { - rp->upstream_length = -1; - duration = -1; - } - gst_segment_set_duration (&rp->segment, GST_FORMAT_TIME, duration); + switch (mode) { + case GST_PAD_MODE_PULL: + if (active) { + GstFormat format; + gint64 duration; + + /* get the duration in bytes */ + format = GST_FORMAT_BYTES; + result = gst_pad_peer_query_duration (sinkpad, format, &duration); + if (result) { + GST_DEBUG_OBJECT (rp, "got duration %" GST_TIME_FORMAT, + GST_TIME_ARGS (duration)); + rp->upstream_length = duration; + /* convert to time */ + gst_raw_parse_convert (rp, format, duration, GST_FORMAT_TIME, + &duration); + } else { + rp->upstream_length = -1; + duration = -1; + } + rp->segment.duration = duration; - result = gst_raw_parse_handle_seek_pull (rp, NULL); - } else { - result = gst_pad_stop_task (sinkpad); + result = gst_raw_parse_handle_seek_pull (rp, NULL); + rp->mode = mode; + } else { + result = gst_pad_stop_task (sinkpad); + } + return result; + case GST_PAD_MODE_PUSH: + rp->mode = mode; + return TRUE; + default: + return FALSE; } - - gst_object_unref (rp); - - return result; } static GstStateChangeReturn @@ -493,7 +524,7 @@ gst_raw_parse_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: gst_segment_init (&rp->segment, GST_FORMAT_TIME); - rp->segment.last_stop = 0; + rp->segment.position = 0; default: break; } @@ -614,9 +645,9 @@ done: static gboolean -gst_raw_parse_sink_event (GstPad * pad, GstEvent * event) +gst_raw_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { - GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad)); + GstRawParse *rp = GST_RAW_PARSE (parent); gboolean ret; switch (GST_EVENT_TYPE (event)) { @@ -626,54 +657,44 @@ gst_raw_parse_sink_event (GstPad * pad, GstEvent * event) gst_raw_parse_reset (rp); ret = gst_pad_push_event (rp->srcpad, event); break; - case GST_EVENT_NEWSEGMENT: + case GST_EVENT_SEGMENT: { - GstClockTimeDiff start, stop, time; - gdouble rate, arate; - gboolean update; - GstFormat format; + GstSegment segment; /* Only happens in push mode */ - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - - if (format == GST_FORMAT_TIME) { - gst_segment_set_newsegment_full (&rp->segment, update, rate, arate, - GST_FORMAT_TIME, start, stop, time); - ret = gst_pad_push_event (rp->srcpad, event); - } else { + gst_event_copy_segment (event, &segment); + if (segment.format != GST_FORMAT_TIME) { gst_event_unref (event); ret = - gst_raw_parse_convert (rp, format, start, GST_FORMAT_TIME, &start); - ret &= gst_raw_parse_convert (rp, format, time, GST_FORMAT_TIME, &time); - ret &= gst_raw_parse_convert (rp, format, stop, GST_FORMAT_TIME, &stop); + gst_raw_parse_convert (rp, segment.format, segment.start, + GST_FORMAT_TIME, (gint64 *) & segment.start); + ret &= gst_raw_parse_convert (rp, segment.format, segment.time, + GST_FORMAT_TIME, (gint64 *) & segment.time); + ret &= gst_raw_parse_convert (rp, segment.format, segment.stop, + GST_FORMAT_TIME, (gint64 *) & segment.stop); if (!ret) { GST_ERROR_OBJECT (rp, - "Failed converting to GST_FORMAT_TIME format (%d)", format); + "Failed converting to GST_FORMAT_TIME format (%d)", + segment.format); break; } - gst_segment_set_newsegment_full (&rp->segment, update, rate, arate, - GST_FORMAT_TIME, start, stop, time); + event = gst_event_new_segment (&segment); + } - /* create new segment with the fields converted to time */ - event = gst_event_new_new_segment_full (update, rate, arate, - GST_FORMAT_TIME, start, stop, time); + gst_segment_copy_into (&segment, &rp->segment); - ret = gst_pad_push_event (rp->srcpad, event); - } + ret = gst_pad_push_event (rp->srcpad, event); break; } default: - ret = gst_pad_event_default (rp->sinkpad, event); + ret = gst_pad_event_default (rp->sinkpad, parent, event); break; } - gst_object_unref (rp); - return ret; } @@ -785,12 +806,12 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event) if (event) { /* configure the seek values */ - gst_segment_set_seek (&seeksegment, rate, format, flags, + gst_segment_do_seek (&seeksegment, rate, format, flags, start_type, start, stop_type, stop, NULL); } /* get the desired position */ - last_stop = seeksegment.last_stop; + last_stop = seeksegment.position; GST_LOG_OBJECT (rp, "seeking to %" GST_TIME_FORMAT, GST_TIME_ARGS (last_stop)); @@ -803,21 +824,8 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event) /* prepare for streaming */ if (flush) { GST_LOG_OBJECT (rp, "stop flush"); - gst_pad_push_event (rp->sinkpad, gst_event_new_flush_stop ()); - gst_pad_push_event (rp->srcpad, gst_event_new_flush_stop ()); - } else if (ret && rp->running) { - /* we are running the current segment and doing a non-flushing seek, - * close the segment first based on the last_stop. */ - GST_DEBUG_OBJECT (rp, "prepare close segment %" G_GINT64_FORMAT - " to %" G_GINT64_FORMAT, rp->segment.start, rp->segment.last_stop); - - /* queue the segment for sending in the stream thread */ - if (rp->close_segment) - gst_event_unref (rp->close_segment); - rp->close_segment = - gst_event_new_new_segment_full (TRUE, - rp->segment.rate, rp->segment.applied_rate, rp->segment.format, - rp->segment.start, rp->segment.last_stop, rp->segment.time); + gst_pad_push_event (rp->sinkpad, gst_event_new_flush_stop (TRUE)); + gst_pad_push_event (rp->srcpad, gst_event_new_flush_stop (TRUE)); } if (ret) { @@ -836,7 +844,7 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event) if (rp->segment.flags & GST_SEEK_FLAG_SEGMENT) { gst_element_post_message (GST_ELEMENT_CAST (rp), gst_message_new_segment_start (GST_OBJECT_CAST (rp), - rp->segment.format, rp->segment.last_stop)); + rp->segment.format, rp->segment.position)); } /* for deriving a stop position for the playback segment from the seek @@ -851,25 +859,11 @@ gst_raw_parse_handle_seek_pull (GstRawParse * rp, GstEvent * event) * next time it is scheduled. */ if (rp->start_segment) gst_event_unref (rp->start_segment); - - if (rp->segment.rate >= 0.0) { - /* forward, we send data from last_stop to stop */ - rp->start_segment = - gst_event_new_new_segment_full (FALSE, - rp->segment.rate, rp->segment.applied_rate, rp->segment.format, - rp->segment.last_stop, stop, rp->segment.time); - } else { - /* reverse, we send data from last_stop to start */ - rp->start_segment = - gst_event_new_new_segment_full (FALSE, - rp->segment.rate, rp->segment.applied_rate, rp->segment.format, - rp->segment.start, rp->segment.last_stop, rp->segment.time); - } + rp->start_segment = gst_event_new_segment (&rp->segment); } rp->discont = TRUE; GST_LOG_OBJECT (rp, "start streaming"); - rp->running = TRUE; gst_pad_start_task (rp->sinkpad, (GstTaskFunction) gst_raw_parse_loop, rp); GST_PAD_STREAM_UNLOCK (rp->sinkpad); @@ -885,46 +879,30 @@ convert_failed: } static gboolean -gst_raw_parse_src_event (GstPad * pad, GstEvent * event) +gst_raw_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { - GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad)); + GstRawParse *rp = GST_RAW_PARSE (parent); gboolean ret; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: - if (rp->mode == GST_PAD_ACTIVATE_PUSH) + if (rp->mode == GST_PAD_MODE_PUSH) ret = gst_raw_parse_handle_seek_push (rp, event); else ret = gst_raw_parse_handle_seek_pull (rp, event); break; default: - ret = gst_pad_event_default (rp->srcpad, event); + ret = gst_pad_event_default (rp->srcpad, parent, event); break; } - gst_object_unref (rp); - return ret; } -static const GstQueryType * -gst_raw_parse_src_query_type (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_CONVERT, - GST_QUERY_SEEKING, - 0 - }; - - return types; -} - static gboolean -gst_raw_parse_src_query (GstPad * pad, GstQuery * query) +gst_raw_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { - GstRawParse *rp = GST_RAW_PARSE (gst_pad_get_parent (pad)); + GstRawParse *rp = GST_RAW_PARSE (parent); gboolean ret = FALSE; GST_DEBUG ("src_query %s", gst_query_type_get_name (GST_QUERY_TYPE (query))); @@ -939,7 +917,7 @@ gst_raw_parse_src_query (GstPad * pad, GstQuery * query) gst_query_parse_position (query, &format, NULL); - time = rp->segment.last_stop; + time = rp->segment.position; ret = gst_raw_parse_convert (rp, GST_FORMAT_TIME, time, format, &value); gst_query_set_position (query, format, value); @@ -1001,7 +979,7 @@ gst_raw_parse_src_query (GstPad * pad, GstQuery * query) if (fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT && fmt != GST_FORMAT_BYTES) { gst_query_set_seeking (query, fmt, FALSE, -1, -1); - } else if (rp->mode == GST_PAD_ACTIVATE_PUSH) { + } else if (rp->mode == GST_PAD_MODE_PUSH) { GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES); gboolean seekable; @@ -1018,12 +996,11 @@ gst_raw_parse_src_query (GstPad * pad, GstQuery * query) } default: /* else forward upstream */ - ret = gst_pad_peer_query (rp->sinkpad, query); + ret = gst_pad_query_default (rp->sinkpad, parent, query); break; } done: - gst_object_unref (rp); return ret; /* ERRORS */ @@ -1040,6 +1017,7 @@ gst_raw_parse_set_framesize (GstRawParse * rp, int framesize) g_return_if_fail (GST_IS_RAW_PARSE (rp)); g_return_if_fail (!rp->negotiated); + GST_DEBUG_OBJECT (rp, "framesize %d", framesize); rp->framesize = framesize; } diff --git a/gst/rawparse/gstrawparse.h b/gst/rawparse/gstrawparse.h index 53862b02b..ddaabdb1a 100644 --- a/gst/rawparse/gstrawparse.h +++ b/gst/rawparse/gstrawparse.h @@ -52,7 +52,7 @@ struct _GstRawParse GstPad *sinkpad; GstPad *srcpad; - GstPadActivateMode mode; + GstPadMode mode; GstAdapter *adapter; gint framesize; @@ -66,8 +66,6 @@ struct _GstRawParse gint64 offset; GstSegment segment; - gboolean running; - GstEvent *close_segment; GstEvent *start_segment; gboolean negotiated; diff --git a/gst/rawparse/gstvideoparse.c b/gst/rawparse/gstvideoparse.c index 16dde9999..5c354049c 100644 --- a/gst/rawparse/gstvideoparse.c +++ b/gst/rawparse/gstvideoparse.c @@ -57,39 +57,16 @@ enum PROP_TOP_FIELD_FIRST }; -GST_BOILERPLATE (GstVideoParse, gst_video_parse, GstRawParse, - GST_TYPE_RAW_PARSE); - -static void -gst_video_parse_base_init (gpointer g_class) -{ - GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - GstCaps *caps; - - GST_DEBUG_CATEGORY_INIT (gst_video_parse_debug, "videoparse", 0, - "videoparse element"); - - gst_element_class_set_details_simple (gstelement_class, "Video Parse", - "Filter/Video", - "Converts stream into video frames", - "David Schleef <ds@schleef.org>, " - "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); - - caps = - gst_caps_from_string - ("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray; video/x-raw-bayer"); - - gst_raw_parse_class_set_src_pad_template (rp_class, caps); - gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, FALSE); - gst_caps_unref (caps); -} +#define gst_video_parse_parent_class parent_class +G_DEFINE_TYPE (GstVideoParse, gst_video_parse, GST_TYPE_RAW_PARSE); static void gst_video_parse_class_init (GstVideoParseClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass); + GstCaps *caps; gobject_class->set_property = gst_video_parse_set_property; gobject_class->get_property = gst_video_parse_get_property; @@ -123,10 +100,25 @@ gst_video_parse_class_init (GstVideoParseClass * klass) g_param_spec_boolean ("top-field-first", "Top field first", "True if top field is earlier than bottom field", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gst_element_class_set_details_simple (gstelement_class, "Video Parse", + "Filter/Video", + "Converts stream into video frames", + "David Schleef <ds@schleef.org>, " + "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); + + caps = gst_caps_from_string ("video/x-raw; video/x-raw-bayer"); + + gst_raw_parse_class_set_src_pad_template (rp_class, caps); + gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, FALSE); + gst_caps_unref (caps); + + GST_DEBUG_CATEGORY_INIT (gst_video_parse_debug, "videoparse", 0, + "videoparse element"); } static void -gst_video_parse_init (GstVideoParse * vp, GstVideoParseClass * g_class) +gst_video_parse_init (GstVideoParse * vp) { vp->width = 320; vp->height = 240; @@ -221,8 +213,11 @@ void gst_video_parse_update_frame_size (GstVideoParse * vp) { gint framesize; + GstVideoInfo info; - framesize = gst_video_format_get_size (vp->format, vp->width, vp->height); + gst_video_info_init (&info); + gst_video_info_set_format (&info, vp->format, vp->width, vp->height); + framesize = GST_VIDEO_INFO_SIZE (&info); gst_raw_parse_set_framesize (GST_RAW_PARSE (vp), framesize); } @@ -231,15 +226,23 @@ static GstCaps * gst_video_parse_get_caps (GstRawParse * rp) { GstVideoParse *vp = GST_VIDEO_PARSE (rp); + GstVideoInfo info; GstCaps *caps; - gint fps_n, fps_d; gst_raw_parse_get_fps (rp, &fps_n, &fps_d); - caps = - gst_video_format_new_caps_interlaced (vp->format, vp->width, vp->height, - fps_n, fps_d, vp->par_n, vp->par_d, vp->interlaced); + gst_video_info_init (&info); + gst_video_info_set_format (&info, vp->format, vp->width, vp->height); + info.fps_n = fps_n; + info.fps_d = fps_d; + info.par_n = vp->par_n; + info.par_d = vp->par_d; + info.interlace_mode = vp->interlaced ? + GST_VIDEO_INTERLACE_MODE_INTERLEAVED : + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + + caps = gst_video_info_to_caps (&info); return caps; } @@ -251,9 +254,9 @@ gst_video_parse_set_buffer_flags (GstRawParse * rp, GstBuffer * buffer) if (vp->interlaced) { if (vp->top_field_first) { - GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_TFF); + GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_TFF); } else { - GST_BUFFER_FLAG_UNSET (buffer, GST_VIDEO_BUFFER_TFF); + GST_BUFFER_FLAG_UNSET (buffer, GST_VIDEO_BUFFER_FLAG_TFF); } } } |