qroverlay: Reuse the same OverlayComposition object when possible
authorThibault Saunier <tsaunier@igalia.com>
Sat, 21 Nov 2020 22:00:02 +0000 (19:00 -0300)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 26 Nov 2020 14:34:34 +0000 (14:34 +0000)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1829>

ext/qroverlay/gstbaseqroverlay.c
ext/qroverlay/gstbaseqroverlay.h
ext/qroverlay/gstdebugqroverlay.c
ext/qroverlay/gstqroverlay.c

index 0e64764..0936343 100644 (file)
@@ -67,6 +67,7 @@ struct _GstBaseQROverlayPrivate
   gboolean valid;
 
   GstPad *sinkpad, *srcpad;
+  GstVideoOverlayComposition *prev_overlay;
 };
 
 #define PRIV(s) gst_base_qr_overlay_get_instance_private (GST_BASE_QR_OVERLAY (s))
@@ -209,6 +210,7 @@ gst_base_qr_overlay_draw_cb (GstBaseQROverlay * self, GstSample * sample,
   GstBaseQROverlayPrivate *priv = PRIV (self);
   QRcode *qrcode;
   gchar *content;
+  gboolean reuse_previous = FALSE;
   GstVideoOverlayComposition *overlay = NULL;
   GstBuffer *buffer = gst_sample_get_buffer (sample);
   GstSegment *segment = gst_sample_get_segment (sample);
@@ -226,15 +228,22 @@ gst_base_qr_overlay_draw_cb (GstBaseQROverlay * self, GstSample * sample,
 
   content =
       GST_BASE_QR_OVERLAY_GET_CLASS (self)->get_content (GST_BASE_QR_OVERLAY
-      (self), buffer, &priv->info);
-  GST_INFO_OBJECT (self, "String will be encoded : %s", content);
-  qrcode = QRcode_encodeString (content, 0, priv->qrcode_quality, QR_MODE_8, 0);
-
-  if (qrcode) {
-    GST_DEBUG_OBJECT (self, "String encoded");
-    overlay = draw_overlay (GST_BASE_QR_OVERLAY (self), qrcode);
-  } else {
-    GST_WARNING_OBJECT (self, "Could not encode content: %s", content);
+      (self), buffer, &priv->info, &reuse_previous);
+  if (reuse_previous && priv->prev_overlay) {
+    overlay = gst_video_overlay_composition_ref (priv->prev_overlay);
+  } else if (content) {
+    GST_INFO_OBJECT (self, "String will be encoded : %s", content);
+    qrcode =
+        QRcode_encodeString (content, 0, priv->qrcode_quality, QR_MODE_8, 0);
+
+    if (qrcode) {
+      GST_DEBUG_OBJECT (self, "String encoded");
+      overlay = draw_overlay (GST_BASE_QR_OVERLAY (self), qrcode);
+      gst_mini_object_replace (((GstMiniObject **) & priv->prev_overlay),
+          (GstMiniObject *) overlay);
+    } else {
+      GST_WARNING_OBJECT (self, "Could not encode content: %s", content);
+    }
   }
   g_free (content);
 
@@ -243,6 +252,14 @@ gst_base_qr_overlay_draw_cb (GstBaseQROverlay * self, GstSample * sample,
 
 /* GObject vmethod implementations */
 
+static void
+gst_base_qr_overlay_dispose (GObject * object)
+{
+  GstBaseQROverlayPrivate *priv = PRIV (object);
+
+  gst_mini_object_replace (((GstMiniObject **) & priv->prev_overlay), NULL);
+}
+
 /* initialize the qroverlay's class */
 static void
 gst_base_qr_overlay_class_init (GstBaseQROverlayClass * klass)
@@ -255,6 +272,7 @@ gst_base_qr_overlay_class_init (GstBaseQROverlayClass * klass)
 
   gobject_class->set_property = gst_base_qr_overlay_set_property;
   gobject_class->get_property = gst_base_qr_overlay_get_property;
+  gobject_class->dispose = gst_base_qr_overlay_dispose;
 
   GST_DEBUG_CATEGORY_INIT (gst_base_qr_overlay_debug, "qroverlay", 0,
       "Qrcode overlay base class");
index 4fcb16a..5fff863 100644 (file)
@@ -34,7 +34,8 @@ struct _GstBaseQROverlayClass
 {
   GstBinClass parent;
 
-  gchar* (*get_content) (GstBaseQROverlay *self, GstBuffer *buf, GstVideoInfo *info);
+  gchar* (*get_content) (GstBaseQROverlay *self, GstBuffer *buf, GstVideoInfo *info,
+    gboolean *reuse_previous);
 };
 
 G_END_DECLS
index bcd73bc..6a7f8e3 100644 (file)
@@ -60,7 +60,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_qr_overlay_debug);
 #define GST_CAT_DEFAULT gst_debug_qr_overlay_debug
 
 static gchar *get_qrcode_content (GstBaseQROverlay * base, GstBuffer * buf,
-    GstVideoInfo * info);
+    GstVideoInfo * info, gboolean * reuse_prev);
 
 enum
 {
@@ -232,7 +232,7 @@ gst_debug_qr_overlay_get_property (GObject * object, guint prop_id,
 
 static gchar *
 get_qrcode_content (GstBaseQROverlay * base, GstBuffer * buf,
-    GstVideoInfo * info)
+    GstVideoInfo * info, gboolean * reuse_prev)
 {
   GstDebugQROverlay *filter = GST_DEBUG_QR_OVERLAY (base);
   GString *res = g_string_new (NULL);
@@ -242,6 +242,7 @@ get_qrcode_content (GstBaseQROverlay * base, GstBuffer * buf,
   JsonObject *jobj = json_object_new ();
   JsonNode *root = json_node_new (JSON_NODE_OBJECT);
 
+  *reuse_prev = FALSE;
   json_object_set_int_member (jobj, "TIMESTAMP",
       (gint64) GST_BUFFER_TIMESTAMP (buf));
   json_object_set_int_member (jobj, "BUFFERCOUNT",
index a55f70e..9fc312d 100644 (file)
@@ -62,16 +62,26 @@ struct _GstQROverlay
 {
   GstBaseQROverlay parent;
   gchar *data;
+
+  gboolean data_changed;
 };
 
 #define gst_qr_overlay_parent_class parent_class
 G_DEFINE_TYPE (GstQROverlay, gst_qr_overlay, GST_TYPE_BASE_QR_OVERLAY);
 
 static gchar *
-get_qrcode_content (GstBaseQROverlay * self, GstBuffer * buf,
-    GstVideoInfo * info)
+get_qrcode_content (GstBaseQROverlay * base, GstBuffer * buf,
+    GstVideoInfo * info, gboolean * reuse_prev)
 {
-  return g_strdup (GST_QR_OVERLAY (self)->data);
+  gchar *content;
+  GstQROverlay *self = GST_QR_OVERLAY (base);
+
+  GST_OBJECT_LOCK (self);
+  content = g_strdup (self->data);
+  *reuse_prev = self->data_changed;
+  GST_OBJECT_UNLOCK (self);
+
+  return content;
 }
 
 static void
@@ -82,7 +92,10 @@ gst_qr_overlay_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_DATA:
+      GST_OBJECT_LOCK (self);
       self->data = g_value_dup_string (value);
+      self->data_changed = TRUE;
+      GST_OBJECT_UNLOCK (self);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);