gst/gstquery.h
authorAndy Wingo <wingo@pobox.com>
Fri, 6 May 2005 21:41:22 +0000 (21:41 +0000)
committerAndy Wingo <wingo@pobox.com>
Fri, 6 May 2005 21:41:22 +0000 (21:41 +0000)
Original commit message from CVS:
2005-05-06  Andy Wingo  <wingo@pobox.com>

* gst/gstquery.h
* gst/gstquery.c (_gst_query_initialize): Extend GstQuery from
GstData, init a memchunk.
(standard_definitions): Add a few query types, deprecate a few.
(gst_query_get_type): New proc.
(_gst_query_copy, _gst_query_free, gst_query_new): GstData
implementation.
(gst_query_new_application, gst_query_get_structure): New public
procs.

* docs/design/draft-query.txt: Removed LINKS from the query types,
because all the rest can be dispatched to other pads -- seemed
ugly to have a query that couldn't be dispatched. internal_links
is fine as a pad method.

* gst/gstpad.h: Add query2 as a pad method, add the new functions
in gstpad.c, but maintain binary compatibility for the moment.
Will fix before 0.9 is out.

* gst/gstqueryutils.c:
* gst/gstqueryutils.h: New files, implement 3 methods for each
query type: parse_query, parse_response, and set. Probably need an
allocator as well.

* gst/gst.h: Add gstquery.h and gstqueryutils.h to the list.

* gst/elements/gstfilesink.c (gst_filesink_query2):
* gst/base/gstbasesrc.c (gst_basesrc_query2): Replace old query,
query_types, and formats methods.

* gst/gstpad.c (gst_pad_query2, gst_pad_query2_default)
(gst_pad_set_query2_function): New functions.
(gst_real_pad_init): Set query2_default as the default query2
function. Basically just dispatches to internally linked pads.

Needs review!

* gst/gstdata_private.h (_GST_DATA_INIT): Set data->refcount to 1
without using the atomic operations. Only one thread can possibly
be accessing the data at this point. Changed so as to avoid
gst_atomic operations.

16 files changed:
ChangeLog
docs/design/draft-query.txt
docs/gst/tmpl/gstquery.sgml
gst/base/gstbasesrc.c
gst/elements/gstfilesink.c
gst/gst.c
gst/gst.h
gst/gstdata_private.h
gst/gstpad.c
gst/gstpad.h
gst/gstquery.c
gst/gstquery.h
gst/gstqueryutils.c [new file with mode: 0644]
gst/gstqueryutils.h [new file with mode: 0644]
libs/gst/base/gstbasesrc.c
plugins/elements/gstfilesink.c

index 394a597f4eec6e6f87cb34a76ee846f652249e30..2024f3198116b12ec3f11dc15c355fc6f8d5a48d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2005-05-06  Andy Wingo  <wingo@pobox.com>
+
+       * gst/gstquery.h
+       * gst/gstquery.c (_gst_query_initialize): Extend GstQuery from
+       GstData, init a memchunk.
+       (standard_definitions): Add a few query types, deprecate a few.
+       (gst_query_get_type): New proc.
+       (_gst_query_copy, _gst_query_free, gst_query_new): GstData
+       implementation.
+       (gst_query_new_application, gst_query_get_structure): New public
+       procs.
+
+       * docs/design/draft-query.txt: Removed LINKS from the query types,
+       because all the rest can be dispatched to other pads -- seemed
+       ugly to have a query that couldn't be dispatched. internal_links
+       is fine as a pad method.
+
+       * gst/gstpad.h: Add query2 as a pad method, add the new functions
+       in gstpad.c, but maintain binary compatibility for the moment.
+       Will fix before 0.9 is out.
+
+       * gst/gstqueryutils.c: 
+       * gst/gstqueryutils.h: New files, implement 3 methods for each
+       query type: parse_query, parse_response, and set. Probably need an
+       allocator as well.
+
+       * gst/gst.h: Add gstquery.h and gstqueryutils.h to the list.
+
+       * gst/elements/gstfilesink.c (gst_filesink_query2):
+       * gst/base/gstbasesrc.c (gst_basesrc_query2): Replace old query,
+       query_types, and formats methods.
+
+       * gst/gstpad.c (gst_pad_query2, gst_pad_query2_default)
+       (gst_pad_set_query2_function): New functions.
+       (gst_real_pad_init): Set query2_default as the default query2
+       function. Basically just dispatches to internally linked pads.
+
+       Needs review!
+       
+       * gst/gstdata_private.h (_GST_DATA_INIT): Set data->refcount to 1
+       without using the atomic operations. Only one thread can possibly
+       be accessing the data at this point. Changed so as to avoid
+       gst_atomic operations.
+
 2005-05-06  Wim Taymans  <wim@fluendo.com>
 
        * gst/gstpad.c: (gst_pad_alloc_buffer), (gst_pad_push):
index 7a4f81ea397093f3fbf88a7a3570900e5933e2cc..c7dcb48a8d25d3a1bce6bc0117f2b4dfbfac3c6c 100644 (file)
@@ -83,10 +83,6 @@ Proposed types
 
      - return list of supported formats.
 
- - GST_QUERY_LINKS:
-
-     - return list of internal link pads.
-
 Also????
 
  - GST_QUERY_CAPS:
index 24d7577f0c40cc98d421eca03648cb57a814135b..4d8e1b27a6027981d27ab7d655e5eba7199b6a52 100644 (file)
@@ -28,6 +28,9 @@ Standard predefined Query types
 @GST_QUERY_START: start of configured segment
 @GST_QUERY_SEGMENT_END: end of configured segment
 @GST_QUERY_RATE: current rate of the stream
+@GST_QUERY_SEEKING: 
+@GST_QUERY_CONVERT: 
+@GST_QUERY_FORMATS: 
 
 <!-- ##### MACRO GST_QUERY_TYPE_RATE_DEN ##### -->
 <para>
index e9ff0faedeb750bf7fd5589abbb92ea8a2812d1d..503156870e8265012b39b0b3efe2df729a0de633 100644 (file)
@@ -88,11 +88,10 @@ static void gst_basesrc_set_property (GObject * object, guint prop_id,
 static void gst_basesrc_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 static gboolean gst_basesrc_event_handler (GstPad * pad, GstEvent * event);
+
+static gboolean gst_basesrc_query2 (GstPad * pad, GstQuery * query);
+
 static const GstEventMask *gst_basesrc_get_event_mask (GstPad * pad);
-static const GstQueryType *gst_basesrc_get_query_types (GstPad * pad);
-static gboolean gst_basesrc_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value);
-static const GstFormat *gst_basesrc_get_formats (GstPad * pad);
 
 static gboolean gst_basesrc_unlock (GstBaseSrc * basesrc);
 static gboolean gst_basesrc_get_size (GstBaseSrc * basesrc, guint64 * size);
@@ -160,10 +159,11 @@ gst_basesrc_init (GstBaseSrc * basesrc, gpointer g_class)
   gst_pad_set_activate_function (pad, gst_basesrc_activate);
   gst_pad_set_event_function (pad, gst_basesrc_event_handler);
   gst_pad_set_event_mask_function (pad, gst_basesrc_get_event_mask);
-  gst_pad_set_query_function (pad, gst_basesrc_query);
-  gst_pad_set_query_type_function (pad, gst_basesrc_get_query_types);
-  gst_pad_set_formats_function (pad, gst_basesrc_get_formats);
+
+  gst_pad_set_query2_function (pad, gst_basesrc_query2);
+
   gst_pad_set_checkgetrange_function (pad, gst_basesrc_check_get_range);
+
   /* hold ref to pad */
   basesrc->srcpad = pad;
   gst_element_add_pad (GST_ELEMENT (basesrc), pad);
@@ -192,84 +192,59 @@ gst_basesrc_set_dataflow_funcs (GstBaseSrc * this)
     gst_pad_set_getrange_function (this->srcpad, NULL);
 }
 
-static const GstFormat *
-gst_basesrc_get_formats (GstPad * pad)
-{
-  static const GstFormat formats[] = {
-    GST_FORMAT_DEFAULT,
-    GST_FORMAT_BYTES,
-    0,
-  };
-
-  return formats;
-}
-
-static const GstQueryType *
-gst_basesrc_get_query_types (GstPad * pad)
-{
-  static const GstQueryType types[] = {
-    GST_QUERY_TOTAL,
-    GST_QUERY_POSITION,
-    GST_QUERY_START,
-    GST_QUERY_SEGMENT_END,
-    0,
-  };
-
-  return types;
-}
-
 static gboolean
-gst_basesrc_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value)
+gst_basesrc_query2 (GstPad * pad, GstQuery * query)
 {
-  GstBaseSrc *src = GST_BASESRC (GST_PAD_PARENT (pad));
-
-  if (*format == GST_FORMAT_DEFAULT)
-    *format = GST_FORMAT_BYTES;
+  gboolean b;
+  guint64 ui64;
+  gint64 i64;
+  GstBaseSrc *src;
 
-  switch (type) {
-    case GST_QUERY_TOTAL:
-      switch (*format) {
-        case GST_FORMAT_BYTES:
-        {
-          gboolean ret;
+  src = GST_BASESRC (GST_PAD_PARENT (pad));
 
-          ret = gst_basesrc_get_size (src, (guint64 *) value);
-          GST_DEBUG ("getting length %d %lld", ret, *value);
-          return ret;
-        }
-        case GST_FORMAT_PERCENT:
-          *value = GST_FORMAT_PERCENT_MAX;
-          return TRUE;
-        default:
-          return FALSE;
-      }
-      break;
+  switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
-      switch (*format) {
+    {
+      GstFormat format;
+
+      gst_query_parse_position_query (query, &format);
+      switch (format) {
+        case GST_FORMAT_DEFAULT:
         case GST_FORMAT_BYTES:
-          *value = src->offset;
-          break;
+          b = gst_basesrc_get_size (src, &ui64);
+          /* better to make get_size take an int64 */
+          i64 = b ? (gint64) ui64 : -1;
+          gst_query_set_position (query, GST_FORMAT_BYTES, src->offset, i64);
+          return TRUE;
         case GST_FORMAT_PERCENT:
-          /* fixme */
-          if (!gst_basesrc_get_size (src, (guint64 *) value))
-            return FALSE;
-          *value = src->offset * GST_FORMAT_PERCENT_MAX / *value;
+          b = gst_basesrc_get_size (src, &ui64);
+          i64 = GST_FORMAT_PERCENT_MAX;
+          i64 *= b ? (src->offset / (gdouble) ui64) : 1.0;
+          gst_query_set_position (query, GST_FORMAT_PERCENT,
+              i64, GST_FORMAT_PERCENT_MAX);
           return TRUE;
         default:
           return FALSE;
       }
-      break;
-    case GST_QUERY_START:
-      *value = src->segment_start;
+    }
+
+    case GST_QUERY_SEEKING:
+      gst_query_set_seeking (query, GST_FORMAT_BYTES,
+          src->seekable, src->segment_start, src->segment_end);
       return TRUE;
-    case GST_QUERY_SEGMENT_END:
-      *value = src->segment_end;
+
+    case GST_QUERY_FORMATS:
+      gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
+          GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
       return TRUE;
+
+    case GST_QUERY_LATENCY:
+    case GST_QUERY_JITTER:
+    case GST_QUERY_RATE:
+    case GST_QUERY_CONVERT:
     default:
-      return FALSE;
+      return gst_pad_query2_default (pad, query);
   }
-  return FALSE;
 }
 
 static const GstEventMask *
index 162f649ddafa708e1453dd4f9ed35a92cc777275..c0da0e3632f551d3bb035235bb02776ac3bb3545 100644 (file)
@@ -66,29 +66,6 @@ enum
   ARG_LOCATION
 };
 
-static const GstFormat *
-gst_filesink_get_formats (GstPad * pad)
-{
-  static const GstFormat formats[] = {
-    GST_FORMAT_BYTES,
-    0,
-  };
-
-  return formats;
-}
-
-static const GstQueryType *
-gst_filesink_get_query_types (GstPad * pad)
-{
-  static const GstQueryType types[] = {
-    GST_QUERY_TOTAL,
-    GST_QUERY_POSITION,
-    0
-  };
-
-  return types;
-}
-
 static void gst_filesink_dispose (GObject * object);
 
 static void gst_filesink_set_property (GObject * object, guint prop_id,
@@ -103,8 +80,7 @@ static gboolean gst_filesink_event (GstBaseSink * sink, GstEvent * event);
 static GstFlowReturn gst_filesink_render (GstBaseSink * sink,
     GstBuffer * buffer);
 
-static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value);
+static gboolean gst_filesink_query2 (GstPad * pad, GstQuery * query);
 
 static void gst_filesink_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
@@ -141,6 +117,7 @@ gst_filesink_base_init (gpointer g_class)
       gst_static_pad_template_get (&sinktemplate));
   gst_element_class_set_details (gstelement_class, &gst_filesink_details);
 }
+
 static void
 gst_filesink_class_init (GstFileSinkClass * klass)
 {
@@ -159,6 +136,7 @@ gst_filesink_class_init (GstFileSinkClass * klass)
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_filesink_render);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_filesink_event);
 }
+
 static void
 gst_filesink_init (GstFileSink * filesink)
 {
@@ -166,13 +144,12 @@ gst_filesink_init (GstFileSink * filesink)
 
   pad = GST_BASESINK_PAD (filesink);
 
-  gst_pad_set_query_function (pad, gst_filesink_pad_query);
-  gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
-  gst_pad_set_formats_function (pad, gst_filesink_get_formats);
+  gst_pad_set_query2_function (pad, gst_filesink_query2);
 
   filesink->filename = NULL;
   filesink->file = NULL;
 }
+
 static void
 gst_filesink_dispose (GObject * object)
 {
@@ -278,36 +255,33 @@ gst_filesink_close_file (GstFileSink * sink)
 }
 
 static gboolean
-gst_filesink_pad_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value)
+gst_filesink_query2 (GstPad * pad, GstQuery * query)
 {
-  GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
+  GstFileSink *self;
+  GstFormat format;
 
-  switch (type) {
-    case GST_QUERY_TOTAL:
-      switch (*format) {
-        case GST_FORMAT_BYTES:
-          *value = sink->data_written;  /* FIXME - doesn't the kernel provide
-                                           such a function? */
-          break;
-        default:
-          return FALSE;
-      }
-      break;
+  self = GST_FILESINK (GST_PAD_PARENT (pad));
+
+  switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
-      switch (*format) {
+      gst_query_parse_position_query (query, &format);
+      switch (format) {
+        case GST_FORMAT_DEFAULT:
         case GST_FORMAT_BYTES:
-          *value = ftell (sink->file);
-          break;
+          gst_query_set_position (query, GST_FORMAT_BYTES,
+              self->data_written, self->data_written);
+          return TRUE;
         default:
           return FALSE;
       }
-      break;
+
+    case GST_QUERY_FORMATS:
+      gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
+      return TRUE;
+
     default:
-      return FALSE;
+      return gst_pad_query2_default (pad, query);
   }
-
-  return TRUE;
 }
 
 /* handle events (search) */
index 86092b7023f32967f8c832b406f2bbdc98b448c5..b1f7ffad631c0846745a42c68d5e22dbef8ed8cb 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -582,7 +582,7 @@ init_post (void)
   g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
 
   _gst_format_initialize ();
-  _gst_query_type_initialize ();
+  _gst_query_initialize ();
   gst_object_get_type ();
   gst_probe_get_type ();
   gst_pad_get_type ();
index fe6540cbf90b9aa270f700698cd62b144a117ae1..04318684d767ac0b15e59fd0ff1cd6943df7135b 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -48,6 +48,8 @@
 #include <gst/gstpad.h>
 #include <gst/gstpipeline.h>
 #include <gst/gstplugin.h>
+#include <gst/gstquery.h>
+#include <gst/gstqueryutils.h>
 #include <gst/gstscheduler.h>
 #include <gst/gststructure.h>
 #include <gst/gstsystemclock.h>
index 4786fec8aed5d58b655705e8134a0a5690fd35fc..7f5f55ab8c8a5e9d34abd4ab83619b62273daa65 100644 (file)
@@ -22,7 +22,7 @@
 
 #define _GST_DATA_INIT(data, ptype, pflags, pfree, pcopy)      \
 G_STMT_START {                                                 \
-  gst_atomic_int_set (&(data)->refcount, 1);                   \
+  (data)->refcount = 1;                                                \
   (data)->type = ptype;                                                \
   (data)->flags = pflags;                                      \
   (data)->free = pfree;                                                \
index bbc8a580880a50f3166e18c1a178611bf9bb253d..92ee6e067c997696e1eb23e2772b4006d8f599ac 100644 (file)
@@ -251,6 +251,8 @@ gst_real_pad_init (GstRealPad * pad)
   pad->queryfunc = gst_pad_query_default;
   pad->intlinkfunc = gst_pad_get_internal_links_default;
 
+  pad->query2func = gst_pad_query2_default;
+
   pad->eventmaskfunc = gst_pad_get_event_masks_default;
   pad->formatsfunc = gst_pad_get_formats_default;
   pad->querytypefunc = gst_pad_get_query_types_default;
@@ -987,6 +989,24 @@ gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
       GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
 }
 
+/**
+ * gst_pad_set_query2_function:
+ * @pad: a real #GstPad of either direction.
+ * @query: the #GstPadQueryFunction to set.
+ *
+ * Set the given query function for the pad.
+ */
+void
+gst_pad_set_query2_function (GstPad * pad, GstPadQuery2Function query)
+{
+  g_return_if_fail (GST_IS_REAL_PAD (pad));
+
+  GST_RPAD_QUERY2FUNC (pad) = query;
+
+  GST_CAT_DEBUG (GST_CAT_PADS, "query2func for %s:%s  set to %s",
+      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
+}
+
 /**
  * gst_pad_set_query_type_function:
  * @pad: a real #GstPad of either direction.
@@ -3793,6 +3813,56 @@ gst_pad_query (GstPad * pad, GstQueryType type,
   return FALSE;
 }
 
+/**
+ * gst_pad_query2:
+ * @pad: a #GstPad to invoke the default query on.
+ * @query: the #GstQuery to perform.
+ *
+ * Dispatches a query to a pad. The query should have been allocated by the
+ * caller via one of the type-specific allocation functions in gstquery.h. The
+ * element is responsible for filling the query with an appropriate response,
+ * which should then be parsed with a type-specific query parsing function.
+ *
+ * Again, the caller is responsible for both the allocation and deallocation of
+ * the query structure.
+ *
+ * Returns: TRUE if the query could be performed.
+ */
+gboolean
+gst_pad_query2 (GstPad * pad, GstQuery * query)
+{
+  GstRealPad *rpad;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+  g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
+
+  rpad = GST_PAD_REALIZE (pad);
+
+  g_return_val_if_fail (rpad, FALSE);
+
+  if (GST_RPAD_QUERY2FUNC (rpad))
+    return GST_RPAD_QUERY2FUNC (rpad) (GST_PAD_CAST (rpad), query);
+
+  return FALSE;
+}
+
+gboolean
+gst_pad_query2_default (GstPad * pad, GstQuery * query)
+{
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_POSITION:
+    case GST_QUERY_SEEKING:
+    case GST_QUERY_FORMATS:
+    case GST_QUERY_LATENCY:
+    case GST_QUERY_JITTER:
+    case GST_QUERY_RATE:
+    case GST_QUERY_CONVERT:
+    default:
+      return gst_pad_dispatcher
+          (pad, (GstPadDispatcherFunction) gst_pad_query2, query);
+  }
+}
+
 static gboolean
 gst_pad_get_formats_dispatcher (GstPad * pad, const GstFormat ** data)
 {
index 3b5cf2e37ea17aa109fc12ded39c07c96fda766f..02cfeeba972386d666db5a71649bd7a2fbc2d153 100644 (file)
@@ -141,7 +141,7 @@ typedef GstFlowReturn               (*GstPadGetRangeFunction)       (GstPad *pad, guint64 offset,
 typedef gboolean               (*GstPadCheckGetRangeFunction)  (GstPad *pad); 
 typedef gboolean               (*GstPadEventFunction)          (GstPad *pad, GstEvent *event);
 
-/* convert/query/format functions */
+/* old, deprecated convert/query/format functions */
 typedef gboolean               (*GstPadConvertFunction)        (GstPad *pad,
                                                                 GstFormat src_format,  gint64  src_value,
                                                                 GstFormat *dest_format, gint64 *dest_value);
@@ -152,6 +152,9 @@ typedef const GstFormat*    (*GstPadFormatsFunction)        (GstPad *pad);
 typedef const GstEventMask*    (*GstPadEventMaskFunction)      (GstPad *pad);
 typedef const GstQueryType*    (*GstPadQueryTypeFunction)      (GstPad *pad);
 
+/* generic query function */
+typedef gboolean               (*GstPadQuery2Function)         (GstPad *pad, GstQuery *query);
+
 /* linking */
 typedef GstPadLinkReturn       (*GstPadLinkFunction)           (GstPad *pad, GstPad *peer);
 typedef void                   (*GstPadUnlinkFunction)         (GstPad *pad);
@@ -249,7 +252,7 @@ struct _GstRealPad {
   GList                        *ghostpads;
   guint32                       ghostpads_cookie;
 
-  /* query/convert/formats functions */
+  /* old, deprecated query/convert/formats functions */
   GstPadConvertFunction                 convertfunc;
   GstPadQueryFunction           queryfunc;
   GstPadFormatsFunction                 formatsfunc;
@@ -260,8 +263,12 @@ struct _GstRealPad {
 
   GstProbeDispatcher            probedisp;
 
+  /* generic query method */
+  GstPadQuery2Function          query2func;
+  
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  /* fixme: bring back to gst_padding when old query functions go away */
+  gpointer _gst_reserved[GST_PADDING - 1];
 };
 
 struct _GstRealPadClass {
@@ -313,6 +320,7 @@ struct _GstGhostPadClass {
 #define GST_RPAD_FORMATSFUNC(pad)      (GST_REAL_PAD_CAST(pad)->formatsfunc)
 #define GST_RPAD_QUERYTYPEFUNC(pad)    (GST_REAL_PAD_CAST(pad)->querytypefunc)
 #define GST_RPAD_EVENTMASKFUNC(pad)    (GST_REAL_PAD_CAST(pad)->eventmaskfunc)
+#define GST_RPAD_QUERY2FUNC(pad)       (GST_REAL_PAD_CAST(pad)->query2func)
 
 #define GST_RPAD_PEER(pad)             (GST_REAL_PAD_CAST(pad)->peer)
 #define GST_RPAD_LINKFUNC(pad)         (GST_REAL_PAD_CAST(pad)->linkfunc)
@@ -566,6 +574,10 @@ void                       gst_pad_set_internal_link_function      (GstPad *pad, GstPadIntLinkFunction in
 GList*                 gst_pad_get_internal_links              (GstPad *pad);
 GList*                 gst_pad_get_internal_links_default      (GstPad *pad);
 
+gboolean               gst_pad_query2                          (GstPad *pad, GstQuery *query);
+void                   gst_pad_set_query2_function             (GstPad *pad, GstPadQuery2Function query);
+gboolean               gst_pad_query2_default                  (GstPad *pad, GstQuery *query);
+
 /* misc helper functions */
 gboolean               gst_pad_dispatcher                      (GstPad *pad, GstPadDispatcherFunction dispatch,
                                                                 gpointer data);
index ffb64498bfcb8b10f4f856332baa7c25f287a720..5f02fe4f9ad15321712240adf20f669f712637ca 100644 (file)
 
 #include "gst_private.h"
 #include "gstquery.h"
+#include "gstmemchunk.h"
+#include "gstdata_private.h"
+
+
+GType _gst_query_type;
+
 
 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 static GList *_gst_queries = NULL;
@@ -32,22 +38,29 @@ static GHashTable *_nick_to_query = NULL;
 static GHashTable *_query_type_to_nick = NULL;
 static guint32 _n_values = 1;   /* we start from 1 because 0 reserved for NONE */
 
+static GstMemChunk *chunk;
+
 static GstQueryTypeDefinition standard_definitions[] = {
-  {GST_QUERY_TOTAL, "total", "Total length"},
+  {GST_QUERY_TOTAL, "total", "Total length"},   /* deprecated */
   {GST_QUERY_POSITION, "position", "Current Position"},
   {GST_QUERY_LATENCY, "latency", "Latency"},
   {GST_QUERY_JITTER, "jitter", "Jitter"},
-  {GST_QUERY_START, "start", "Start position of stream"},
-  {GST_QUERY_SEGMENT_END, "segment_end", "End position of the stream"},
+  {GST_QUERY_START, "start", "Start position of stream"},       /* deprecated */
+  {GST_QUERY_SEGMENT_END, "segment_end", "End position of the stream"}, /* dep */
   {GST_QUERY_RATE, "rate", "Configured rate 1000000 = 1"},
+  {GST_QUERY_SEEKING, "seeking", "Seeking capabilities and parameters"},
+  {GST_QUERY_CONVERT, "convert", "Converting between formats"},
   {0, NULL, NULL}
 };
 
+
 void
-_gst_query_type_initialize (void)
+_gst_query_initialize (void)
 {
   GstQueryTypeDefinition *standards = standard_definitions;
 
+  GST_CAT_INFO (GST_CAT_GST_INIT, "init queries");
+
   g_static_mutex_lock (&mutex);
   if (_nick_to_query == NULL) {
     _nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
@@ -64,6 +77,13 @@ _gst_query_type_initialize (void)
     _n_values++;
   }
   g_static_mutex_unlock (&mutex);
+
+  /* register the type */
+  _gst_query_type = g_boxed_type_register_static ("GstQuery",
+      (GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref);
+
+  chunk = gst_mem_chunk_new ("GstQueryChunk", sizeof (GstQuery),
+      sizeof (GstQuery) * 20, 0);
 }
 
 /**
@@ -197,3 +217,86 @@ gst_query_type_iterate_definitions (void)
 
   return result;
 }
+
+GType
+gst_query_get_type (void)
+{
+  return _gst_query_type;
+}
+
+static GstQuery *
+_gst_query_copy (GstQuery * query)
+{
+  GstQuery *copy;
+
+  GST_LOG ("copy query %p", query);
+
+  copy = gst_mem_chunk_alloc (chunk);
+
+  memcpy (copy, query, sizeof (GstQuery));
+
+  if (query->structure) {
+    copy->structure = gst_structure_copy (query->structure);
+    gst_structure_set_parent_refcount (copy->structure,
+        &GST_DATA_REFCOUNT (query));
+  }
+
+  return copy;
+}
+
+static void
+_gst_query_free (GstQuery * query)
+{
+  GST_LOG ("freeing query %p", query);
+
+  if (query->structure) {
+    gst_structure_set_parent_refcount (query->structure, NULL);
+    gst_structure_free (query->structure);
+  }
+
+  _GST_DATA_DISPOSE (GST_DATA (query));
+  gst_mem_chunk_free (chunk, query);
+}
+
+static GstQuery *
+gst_query_new (GstQueryType type, GstStructure * structure)
+{
+  GstQuery *query;
+
+  query = gst_mem_chunk_alloc0 (chunk);
+
+  GST_DEBUG ("creating new query %p %d", query, type);
+
+  _GST_DATA_INIT (GST_DATA (query),
+      _gst_query_type,
+      0,
+      (GstDataFreeFunction) _gst_query_free,
+      (GstDataCopyFunction) _gst_query_copy);
+
+  GST_QUERY_TYPE (query) = type;
+
+  if (structure) {
+    query->structure = structure;
+    gst_structure_set_parent_refcount (query->structure,
+        &GST_DATA_REFCOUNT (query));
+  }
+
+  return query;
+}
+
+GstQuery *
+gst_query_new_application (GstQueryType type, GstStructure * structure)
+{
+  g_return_val_if_fail (gst_query_type_get_details (type) != NULL, NULL);
+  g_return_val_if_fail (structure != NULL, NULL);
+
+  return gst_query_new (type, structure);
+}
+
+GstStructure *
+gst_query_get_structure (GstQuery * query)
+{
+  g_return_val_if_fail (GST_IS_QUERY (query), NULL);
+
+  return query->structure;
+}
index 3b6ae641aa9a5932ba90cacdcdad49c19c0cec72..70d49e86a755d79395bb0a0a9a1ce05a1e521ecd 100644 (file)
 #include <glib.h>
 
 #include <gst/gstiterator.h>
+#include <gst/gstdata.h>
+#include <gst/gststructure.h>
 
 G_BEGIN_DECLS
 
 typedef enum {
   GST_QUERY_NONE = 0,
-  GST_QUERY_TOTAL,
+  GST_QUERY_TOTAL, /* deprecated, use POSITION */
   GST_QUERY_POSITION,
   GST_QUERY_LATENCY,
-  GST_QUERY_JITTER,
-  GST_QUERY_START,
-  GST_QUERY_SEGMENT_END,
-  GST_QUERY_RATE
+  GST_QUERY_JITTER, /* not in draft-query, necessary? */
+  GST_QUERY_START, /* deprecated, use SEEKING */
+  GST_QUERY_SEGMENT_END, /* deprecated, use SEEKING */
+  GST_QUERY_RATE, /* not in draft-query, necessary? */
+  GST_QUERY_SEEKING,
+  GST_QUERY_CONVERT,
+  GST_QUERY_FORMATS
 } GstQueryType;
 
 /* rate is relative to 1000000  */
 #define GST_QUERY_TYPE_RATE_DEN          G_GINT64_CONSTANT (1000000)
 
 typedef struct _GstQueryTypeDefinition GstQueryTypeDefinition;
+typedef struct _GstQuery GstQuery;
 
 struct _GstQueryTypeDefinition
 {
@@ -78,20 +84,59 @@ functionname (type object)                                  \
 }
 #endif
 
-void                   _gst_query_type_initialize     (void);
+GST_EXPORT GType _gst_query_type;
+
+#define GST_TYPE_QUERY (_gst_query_type)
+#define GST_QUERY(query)       ((GstQuery*)(query))
+#define GST_IS_QUERY(query)    (GST_DATA_TYPE(query) == GST_TYPE_QUERY)
+#define GST_QUERY_TYPE(query)  (((GstQuery*)(query))->type)
+
+struct _GstQuery
+{
+  GstData data;
+
+  /*< public > */
+  GstQueryType type;
+
+  GstStructure *structure;
+  
+  /*< private > */
+  gpointer _gst_reserved[GST_PADDING];
+};
+
+void            _gst_query_initialize          (void);
+GType          gst_query_get_type             (void);
 
 /* register a new query */
-GstQueryType           gst_query_type_register        (const gchar *nick, 
-                                                       const gchar *description);
-GstQueryType           gst_query_type_get_by_nick     (const gchar *nick);
+GstQueryType    gst_query_type_register        (const gchar *nick, 
+                                                const gchar *description);
+GstQueryType    gst_query_type_get_by_nick     (const gchar *nick);
 
 /* check if a query is in an array of querys */
-gboolean               gst_query_types_contains       (const GstQueryType *types, GstQueryType type);
+gboolean        gst_query_types_contains       (const GstQueryType *types,
+                                                GstQueryType type);
 
 /* query for query details */
 G_CONST_RETURN GstQueryTypeDefinition*      
-                       gst_query_type_get_details         (GstQueryType type);
-GstIterator*            gst_query_type_iterate_definitions (void);
+                gst_query_type_get_details         (GstQueryType type);
+GstIterator*    gst_query_type_iterate_definitions (void);
+
+/* refcounting */
+#define         gst_query_ref(msg)             GST_QUERY (gst_data_ref (GST_DATA (msg)))
+#define         gst_query_ref_by_count(msg,c)  GST_QUERY (gst_data_ref_by_count (GST_DATA (msg), (c)))
+#define         gst_query_unref(msg)           gst_data_unref (GST_DATA (msg))
+/* copy query */
+#define         gst_query_copy(msg)            GST_QUERY (gst_data_copy (GST_DATA (msg)))
+#define         gst_query_copy_on_write(msg)   GST_QUERY (gst_data_copy_on_write (GST_DATA (msg)))
+
+GstQuery *     gst_query_new_application       (GstQueryType type,
+                                                 GstStructure *structure);
+
+GstStructure *  gst_query_get_structure                (GstQuery *query);
+
+/* hmm */
+#define GST_QUERY_POSITION_GET_FORMAT(q) \
+    (gst_structure_get_int ((q)->structure, "format"))
 
 G_END_DECLS
 
diff --git a/gst/gstqueryutils.c b/gst/gstqueryutils.c
new file mode 100644 (file)
index 0000000..b106458
--- /dev/null
@@ -0,0 +1,138 @@
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * gstqueryutils.c: Utility functions for creating and parsing GstQueries.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include <stdarg.h>
+
+#include "gstqueryutils.h"
+
+/* some macros are just waiting to be defined here */
+
+
+void
+gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur,
+    gint64 end)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
+
+  structure = gst_query_get_structure (query);
+  gst_structure_set (structure,
+      "format", GST_TYPE_FORMAT, format,
+      "cur", G_TYPE_INT64, cur, "end", G_TYPE_INT64, end, NULL);
+}
+
+void
+gst_query_parse_position_query (GstQuery * query, GstFormat * format)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
+
+  structure = gst_query_get_structure (query);
+  *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+}
+
+void
+gst_query_parse_position_response (GstQuery * query, GstFormat * format,
+    gint64 * cur, gint64 * end)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
+
+  structure = gst_query_get_structure (query);
+  *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+  *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
+  *end = g_value_get_int64 (gst_structure_get_value (structure, "end"));
+}
+
+void
+gst_query_parse_seeking_query (GstQuery * query, GstFormat * format)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+
+  structure = gst_query_get_structure (query);
+  *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+}
+
+void
+gst_query_set_seeking (GstQuery * query, GstFormat format,
+    gboolean seekable, gint64 segment_start, gint64 segment_end)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+
+  structure = gst_query_get_structure (query);
+  gst_structure_set (structure,
+      "format", GST_TYPE_FORMAT, format,
+      "seekable", G_TYPE_BOOLEAN, seekable,
+      "segment-start", G_TYPE_INT64, segment_start,
+      "segment-end", G_TYPE_INT64, segment_end, NULL);
+}
+
+void
+gst_query_parse_seeking_response (GstQuery * query, GstFormat * format,
+    gboolean * seekable, gint64 * segment_start, gint64 * segment_end)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+
+  structure = gst_query_get_structure (query);
+  *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+  *seekable = g_value_get_boolean (gst_structure_get_value
+      (structure, "seekable"));
+  *segment_start = g_value_get_int64 (gst_structure_get_value
+      (structure, "segment-start"));
+  *segment_end = g_value_get_int64 (gst_structure_get_value
+      (structure, "segment-end"));
+}
+
+void
+gst_query_set_formats (GstQuery * query, gint n_formats, ...)
+{
+  va_list ap;
+  GValue list = { 0, };
+  GValue item = { 0, };
+  GstStructure *structure;
+  gint i;
+
+  g_value_init (&list, GST_TYPE_LIST);
+
+  va_start (ap, n_formats);
+
+  for (i = 0; i < n_formats; i++) {
+    g_value_init (&item, GST_TYPE_FORMAT);
+    g_value_set_enum (&item, va_arg (ap, GstFormat));
+    gst_value_list_append_value (&list, &item);
+    g_value_unset (&item);
+  }
+
+  va_end (ap);
+
+  structure = gst_query_get_structure (query);
+  gst_structure_set_value (structure, "formats", &list);
+}
diff --git a/gst/gstqueryutils.h b/gst/gstqueryutils.h
new file mode 100644 (file)
index 0000000..3486d72
--- /dev/null
@@ -0,0 +1,39 @@
+/* GStreamer
+ * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
+ *
+ * gstqueryutils.c: Utility functions for creating and parsing GstQueries.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include <gst/gstquery.h>
+
+
+void gst_query_set_position            (GstQuery *query, GstFormat format,
+                                         gint64 cur, gint64 end);
+void gst_query_parse_position_query    (GstQuery *query, GstFormat *format);
+void gst_query_parse_position_response (GstQuery *query, GstFormat *format,
+                                         gint64 *cur, gint64 *end);
+void gst_query_parse_seeking_query     (GstQuery *query, GstFormat *format);
+void gst_query_set_seeking             (GstQuery *query, GstFormat format,
+                                         gboolean seekable, gint64 segment_start,
+                                         gint64 segment_end);
+void gst_query_parse_seeking_response  (GstQuery *query, GstFormat *format,
+                                         gboolean *seekable, 
+                                         gint64 *segment_start,
+                                         gint64 *segment_end);
+void gst_query_set_formats             (GstQuery *query, gint n_formats, ...);
index e9ff0faedeb750bf7fd5589abbb92ea8a2812d1d..503156870e8265012b39b0b3efe2df729a0de633 100644 (file)
@@ -88,11 +88,10 @@ static void gst_basesrc_set_property (GObject * object, guint prop_id,
 static void gst_basesrc_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 static gboolean gst_basesrc_event_handler (GstPad * pad, GstEvent * event);
+
+static gboolean gst_basesrc_query2 (GstPad * pad, GstQuery * query);
+
 static const GstEventMask *gst_basesrc_get_event_mask (GstPad * pad);
-static const GstQueryType *gst_basesrc_get_query_types (GstPad * pad);
-static gboolean gst_basesrc_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value);
-static const GstFormat *gst_basesrc_get_formats (GstPad * pad);
 
 static gboolean gst_basesrc_unlock (GstBaseSrc * basesrc);
 static gboolean gst_basesrc_get_size (GstBaseSrc * basesrc, guint64 * size);
@@ -160,10 +159,11 @@ gst_basesrc_init (GstBaseSrc * basesrc, gpointer g_class)
   gst_pad_set_activate_function (pad, gst_basesrc_activate);
   gst_pad_set_event_function (pad, gst_basesrc_event_handler);
   gst_pad_set_event_mask_function (pad, gst_basesrc_get_event_mask);
-  gst_pad_set_query_function (pad, gst_basesrc_query);
-  gst_pad_set_query_type_function (pad, gst_basesrc_get_query_types);
-  gst_pad_set_formats_function (pad, gst_basesrc_get_formats);
+
+  gst_pad_set_query2_function (pad, gst_basesrc_query2);
+
   gst_pad_set_checkgetrange_function (pad, gst_basesrc_check_get_range);
+
   /* hold ref to pad */
   basesrc->srcpad = pad;
   gst_element_add_pad (GST_ELEMENT (basesrc), pad);
@@ -192,84 +192,59 @@ gst_basesrc_set_dataflow_funcs (GstBaseSrc * this)
     gst_pad_set_getrange_function (this->srcpad, NULL);
 }
 
-static const GstFormat *
-gst_basesrc_get_formats (GstPad * pad)
-{
-  static const GstFormat formats[] = {
-    GST_FORMAT_DEFAULT,
-    GST_FORMAT_BYTES,
-    0,
-  };
-
-  return formats;
-}
-
-static const GstQueryType *
-gst_basesrc_get_query_types (GstPad * pad)
-{
-  static const GstQueryType types[] = {
-    GST_QUERY_TOTAL,
-    GST_QUERY_POSITION,
-    GST_QUERY_START,
-    GST_QUERY_SEGMENT_END,
-    0,
-  };
-
-  return types;
-}
-
 static gboolean
-gst_basesrc_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value)
+gst_basesrc_query2 (GstPad * pad, GstQuery * query)
 {
-  GstBaseSrc *src = GST_BASESRC (GST_PAD_PARENT (pad));
-
-  if (*format == GST_FORMAT_DEFAULT)
-    *format = GST_FORMAT_BYTES;
+  gboolean b;
+  guint64 ui64;
+  gint64 i64;
+  GstBaseSrc *src;
 
-  switch (type) {
-    case GST_QUERY_TOTAL:
-      switch (*format) {
-        case GST_FORMAT_BYTES:
-        {
-          gboolean ret;
+  src = GST_BASESRC (GST_PAD_PARENT (pad));
 
-          ret = gst_basesrc_get_size (src, (guint64 *) value);
-          GST_DEBUG ("getting length %d %lld", ret, *value);
-          return ret;
-        }
-        case GST_FORMAT_PERCENT:
-          *value = GST_FORMAT_PERCENT_MAX;
-          return TRUE;
-        default:
-          return FALSE;
-      }
-      break;
+  switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
-      switch (*format) {
+    {
+      GstFormat format;
+
+      gst_query_parse_position_query (query, &format);
+      switch (format) {
+        case GST_FORMAT_DEFAULT:
         case GST_FORMAT_BYTES:
-          *value = src->offset;
-          break;
+          b = gst_basesrc_get_size (src, &ui64);
+          /* better to make get_size take an int64 */
+          i64 = b ? (gint64) ui64 : -1;
+          gst_query_set_position (query, GST_FORMAT_BYTES, src->offset, i64);
+          return TRUE;
         case GST_FORMAT_PERCENT:
-          /* fixme */
-          if (!gst_basesrc_get_size (src, (guint64 *) value))
-            return FALSE;
-          *value = src->offset * GST_FORMAT_PERCENT_MAX / *value;
+          b = gst_basesrc_get_size (src, &ui64);
+          i64 = GST_FORMAT_PERCENT_MAX;
+          i64 *= b ? (src->offset / (gdouble) ui64) : 1.0;
+          gst_query_set_position (query, GST_FORMAT_PERCENT,
+              i64, GST_FORMAT_PERCENT_MAX);
           return TRUE;
         default:
           return FALSE;
       }
-      break;
-    case GST_QUERY_START:
-      *value = src->segment_start;
+    }
+
+    case GST_QUERY_SEEKING:
+      gst_query_set_seeking (query, GST_FORMAT_BYTES,
+          src->seekable, src->segment_start, src->segment_end);
       return TRUE;
-    case GST_QUERY_SEGMENT_END:
-      *value = src->segment_end;
+
+    case GST_QUERY_FORMATS:
+      gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
+          GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
       return TRUE;
+
+    case GST_QUERY_LATENCY:
+    case GST_QUERY_JITTER:
+    case GST_QUERY_RATE:
+    case GST_QUERY_CONVERT:
     default:
-      return FALSE;
+      return gst_pad_query2_default (pad, query);
   }
-  return FALSE;
 }
 
 static const GstEventMask *
index 162f649ddafa708e1453dd4f9ed35a92cc777275..c0da0e3632f551d3bb035235bb02776ac3bb3545 100644 (file)
@@ -66,29 +66,6 @@ enum
   ARG_LOCATION
 };
 
-static const GstFormat *
-gst_filesink_get_formats (GstPad * pad)
-{
-  static const GstFormat formats[] = {
-    GST_FORMAT_BYTES,
-    0,
-  };
-
-  return formats;
-}
-
-static const GstQueryType *
-gst_filesink_get_query_types (GstPad * pad)
-{
-  static const GstQueryType types[] = {
-    GST_QUERY_TOTAL,
-    GST_QUERY_POSITION,
-    0
-  };
-
-  return types;
-}
-
 static void gst_filesink_dispose (GObject * object);
 
 static void gst_filesink_set_property (GObject * object, guint prop_id,
@@ -103,8 +80,7 @@ static gboolean gst_filesink_event (GstBaseSink * sink, GstEvent * event);
 static GstFlowReturn gst_filesink_render (GstBaseSink * sink,
     GstBuffer * buffer);
 
-static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value);
+static gboolean gst_filesink_query2 (GstPad * pad, GstQuery * query);
 
 static void gst_filesink_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
@@ -141,6 +117,7 @@ gst_filesink_base_init (gpointer g_class)
       gst_static_pad_template_get (&sinktemplate));
   gst_element_class_set_details (gstelement_class, &gst_filesink_details);
 }
+
 static void
 gst_filesink_class_init (GstFileSinkClass * klass)
 {
@@ -159,6 +136,7 @@ gst_filesink_class_init (GstFileSinkClass * klass)
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_filesink_render);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_filesink_event);
 }
+
 static void
 gst_filesink_init (GstFileSink * filesink)
 {
@@ -166,13 +144,12 @@ gst_filesink_init (GstFileSink * filesink)
 
   pad = GST_BASESINK_PAD (filesink);
 
-  gst_pad_set_query_function (pad, gst_filesink_pad_query);
-  gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
-  gst_pad_set_formats_function (pad, gst_filesink_get_formats);
+  gst_pad_set_query2_function (pad, gst_filesink_query2);
 
   filesink->filename = NULL;
   filesink->file = NULL;
 }
+
 static void
 gst_filesink_dispose (GObject * object)
 {
@@ -278,36 +255,33 @@ gst_filesink_close_file (GstFileSink * sink)
 }
 
 static gboolean
-gst_filesink_pad_query (GstPad * pad, GstQueryType type,
-    GstFormat * format, gint64 * value)
+gst_filesink_query2 (GstPad * pad, GstQuery * query)
 {
-  GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
+  GstFileSink *self;
+  GstFormat format;
 
-  switch (type) {
-    case GST_QUERY_TOTAL:
-      switch (*format) {
-        case GST_FORMAT_BYTES:
-          *value = sink->data_written;  /* FIXME - doesn't the kernel provide
-                                           such a function? */
-          break;
-        default:
-          return FALSE;
-      }
-      break;
+  self = GST_FILESINK (GST_PAD_PARENT (pad));
+
+  switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
-      switch (*format) {
+      gst_query_parse_position_query (query, &format);
+      switch (format) {
+        case GST_FORMAT_DEFAULT:
         case GST_FORMAT_BYTES:
-          *value = ftell (sink->file);
-          break;
+          gst_query_set_position (query, GST_FORMAT_BYTES,
+              self->data_written, self->data_written);
+          return TRUE;
         default:
           return FALSE;
       }
-      break;
+
+    case GST_QUERY_FORMATS:
+      gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
+      return TRUE;
+
     default:
-      return FALSE;
+      return gst_pad_query2_default (pad, query);
   }
-
-  return TRUE;
 }
 
 /* handle events (search) */