subparse: fix off by one offset calculation
[platform/upstream/gstreamer.git] / gst / videorate / gstvideorate.c
index 8313eb6..d79b90c 100644 (file)
@@ -13,8 +13,8 @@
  *
  * 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.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /**
@@ -132,13 +132,14 @@ static gboolean gst_video_rate_setcaps (GstBaseTransform * trans,
 static GstCaps *gst_video_rate_transform_caps (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps, GstCaps * filter);
 
-static void gst_video_rate_fixate_caps (GstBaseTransform * trans,
+static GstCaps *gst_video_rate_fixate_caps (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
 
 static GstFlowReturn gst_video_rate_transform_ip (GstBaseTransform * trans,
     GstBuffer * buf);
 
 static gboolean gst_video_rate_start (GstBaseTransform * trans);
+static gboolean gst_video_rate_stop (GstBaseTransform * trans);
 
 
 static void gst_video_rate_set_property (GObject * object,
@@ -168,6 +169,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
   base_class->transform_ip = GST_DEBUG_FUNCPTR (gst_video_rate_transform_ip);
   base_class->sink_event = GST_DEBUG_FUNCPTR (gst_video_rate_sink_event);
   base_class->start = GST_DEBUG_FUNCPTR (gst_video_rate_start);
+  base_class->stop = GST_DEBUG_FUNCPTR (gst_video_rate_stop);
   base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps);
   base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query);
 
@@ -247,7 +249,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
           1, G_MAXINT, DEFAULT_MAX_RATE,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_set_details_simple (element_class,
+  gst_element_class_set_static_metadata (element_class,
       "Video rate adjuster", "Filter/Effect/Video",
       "Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
       "Wim Taymans <wim@fluendo.com>");
@@ -363,84 +365,96 @@ gst_video_rate_transform_caps (GstBaseTransform * trans,
 {
   GstVideoRate *videorate = GST_VIDEO_RATE (trans);
   GstCaps *ret;
-  GstStructure *s, *s2;
-  GstStructure *s3 = NULL;
+  GstStructure *s, *s1, *s2, *s3 = NULL;
   int maxrate = g_atomic_int_get (&videorate->max_rate);
+  gint i;
+
+  ret = gst_caps_new_empty ();
+
+  for (i = 0; i < gst_caps_get_size (caps); i++) {
+    s = gst_caps_get_structure (caps, i);
+
+    s1 = gst_structure_copy (s);
+    s2 = gst_structure_copy (s);
+
+    if (videorate->drop_only) {
+      gint min_num = 0, min_denom = 1;
+      gint max_num = G_MAXINT, max_denom = 1;
+
+      /* Clamp the caps to our maximum rate as the first caps if possible */
+      if (!gst_video_max_rate_clamp_structure (s1, maxrate,
+              &min_num, &min_denom, &max_num, &max_denom)) {
+        min_num = 0;
+        min_denom = 1;
+        max_num = maxrate;
+        max_denom = 1;
+
+        /* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
+         * caps should become [1..maxrate], [1..maxint] and the src caps just
+         * [1..maxrate].  In case there was a caps incompatibility things will
+         * explode later as appropriate :)
+         *
+         * In case [X..maxrate] == [X..maxint], skip as we'll set it later
+         */
+        if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
+          gst_structure_set (s1, "framerate", GST_TYPE_FRACTION_RANGE,
+              min_num, min_denom, maxrate, 1, NULL);
+        else {
+          gst_structure_free (s1);
+          s1 = NULL;
+        }
+      }
 
-  /* Should always be called with simple caps */
-  g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
-
-  ret = gst_caps_copy (caps);
-
-  s = gst_caps_get_structure (ret, 0);
-  s2 = gst_structure_copy (s);
-
-  if (videorate->drop_only) {
-    gint min_num = 0, min_denom = 1;
-    gint max_num = G_MAXINT, max_denom = 1;
-
-    /* Clamp the caps to our maximum rate as the first caps if possible */
-    if (!gst_video_max_rate_clamp_structure (s, maxrate,
-            &min_num, &min_denom, &max_num, &max_denom)) {
-      min_num = 0;
-      min_denom = 1;
-      max_num = maxrate;
-      max_denom = 1;
-
-      /* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
-       * caps should become [1..maxrate], [1..maxint] and the src caps just
-       * [1..maxrate].  In case there was a caps incompatibility things will
-       * explode later as appropriate :)
-       *
-       * In case [X..maxrate] == [X..maxint], skip as we'll set it later
-       */
-      if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
-        gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE,
-            min_num, min_denom, maxrate, 1, NULL);
-      else
-        gst_caps_remove_structure (ret, 0);
-    }
-
-    if (direction == GST_PAD_SRC) {
-      /* We can accept anything as long as it's at least the minimal framerate
-       * the the sink needs */
-      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
-          min_num, min_denom, G_MAXINT, 1, NULL);
+      if (direction == GST_PAD_SRC) {
+        /* We can accept anything as long as it's at least the minimal framerate
+         * the the sink needs */
+        gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
+            min_num, min_denom, G_MAXINT, 1, NULL);
 
-      /* Also allow unknown framerate, if it isn't already */
-      if (min_num != 0 || min_denom != 1) {
-        s3 = gst_structure_copy (s);
-        gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
+        /* Also allow unknown framerate, if it isn't already */
+        if (min_num != 0 || min_denom != 1) {
+          s3 = gst_structure_copy (s);
+          gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
+        }
+      } else if (max_num != 0 || max_denom != 1) {
+        /* We can provide everything upto the maximum framerate at the src */
+        gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
+            0, 1, max_num, max_denom, NULL);
+      }
+    } else if (direction == GST_PAD_SINK) {
+      gint min_num = 0, min_denom = 1;
+      gint max_num = G_MAXINT, max_denom = 1;
+
+      if (!gst_video_max_rate_clamp_structure (s1, maxrate,
+              &min_num, &min_denom, &max_num, &max_denom)) {
+        gst_structure_free (s1);
+        s1 = NULL;
       }
-    } else if (max_num != 0 || max_denom != 1) {
-      /* We can provide everything upto the maximum framerate at the src */
-      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
-          0, 1, max_num, max_denom, NULL);
+      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
+          maxrate, 1, NULL);
+    } else {
+      /* set the framerate as a range */
+      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
+          G_MAXINT, 1, NULL);
     }
-  } else if (direction == GST_PAD_SINK) {
-    gint min_num = 0, min_denom = 1;
-    gint max_num = G_MAXINT, max_denom = 1;
-
-    if (!gst_video_max_rate_clamp_structure (s, maxrate,
-            &min_num, &min_denom, &max_num, &max_denom))
-      gst_caps_remove_structure (ret, 0);
-
-    gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
-        maxrate, 1, NULL);
-  } else {
-    /* set the framerate as a range */
-    gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
-        G_MAXINT, 1, NULL);
+    if (s1 != NULL)
+      ret = gst_caps_merge_structure (ret, s1);
+    ret = gst_caps_merge_structure (ret, s2);
+    if (s3 != NULL)
+      ret = gst_caps_merge_structure (ret, s3);
   }
+  if (filter) {
+    GstCaps *intersection;
 
-  gst_caps_merge_structure (ret, s2);
-  if (s3 != NULL)
-    gst_caps_merge_structure (ret, s3);
-
+    intersection =
+        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (ret);
+    ret = intersection;
+  }
   return ret;
 }
 
-static void
+static GstCaps *
 gst_video_rate_fixate_caps (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
 {
@@ -449,10 +463,14 @@ gst_video_rate_fixate_caps (GstBaseTransform * trans,
 
   s = gst_caps_get_structure (caps, 0);
   if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
-    return;
+    return othercaps;
 
+  othercaps = gst_caps_truncate (othercaps);
+  othercaps = gst_caps_make_writable (othercaps);
   s = gst_caps_get_structure (othercaps, 0);
   gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);
+
+  return othercaps;
 }
 
 static gboolean
@@ -637,21 +655,13 @@ gst_video_rate_swap_prev (GstVideoRate * videorate, GstBuffer * buffer,
 static void
 gst_video_rate_notify_drop (GstVideoRate * videorate)
 {
-#if !GLIB_CHECK_VERSION(2,26,0)
-  g_object_notify ((GObject *) videorate, "drop");
-#else
   g_object_notify_by_pspec ((GObject *) videorate, pspec_drop);
-#endif
 }
 
 static void
 gst_video_rate_notify_duplicate (GstVideoRate * videorate)
 {
-#if !GLIB_CHECK_VERSION(2,26,0)
-  g_object_notify ((GObject *) videorate, "duplicate");
-#else
   g_object_notify_by_pspec ((GObject *) videorate, pspec_duplicate);
-#endif
 }
 
 #define MAGIC_LIMIT  25
@@ -772,7 +782,7 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
       break;
   }
 
-  return TRUE;
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
 
   /* ERRORS */
 format_error:
@@ -1114,6 +1124,13 @@ gst_video_rate_start (GstBaseTransform * trans)
   return TRUE;
 }
 
+static gboolean
+gst_video_rate_stop (GstBaseTransform * trans)
+{
+  gst_video_rate_reset (GST_VIDEO_RATE (trans));
+  return TRUE;
+}
+
 static void
 gst_video_rate_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
@@ -1151,7 +1168,7 @@ gst_video_rate_set_property (GObject * object,
 
 reconfigure:
   GST_OBJECT_UNLOCK (videorate);
-  gst_base_transform_reconfigure (GST_BASE_TRANSFORM (videorate));
+  gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (videorate));
 }
 
 static void
@@ -1211,6 +1228,6 @@ plugin_init (GstPlugin * plugin)
 
 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
     GST_VERSION_MINOR,
-    "videorate",
+    videorate,
     "Adjusts video frames",
     plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)