basescope: add a property to modify the ammount of shading
authorStefan Kost <ensonic@users.sf.net>
Sat, 28 May 2011 11:08:05 +0000 (14:08 +0300)
committerStefan Kost <ensonic@users.sf.net>
Mon, 6 Jun 2011 12:25:13 +0000 (15:25 +0300)
Add another property to specify the shading per color channel. Fix endianess
issues in the shading code.

https://bugzilla.gnome.org/show_bug.cgi?id=651536

gst/scopes/gstbasescope.c
gst/scopes/gstbasescope.h

index 06251996101e0dbf728265d162e87404e409e0ec..b1315c6b87970a522ca813f7b859b6972d119c26 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (base_scope_debug);
 #define GST_CAT_DEFAULT (base_scope_debug)
 
+#define DEFAULT_SHADER GST_BASE_SCOPE_SHADER_FADE
+#define DEFAULT_SHADE_AMOUNT   0x000a0a0a
+
 enum
 {
   PROP_0,
-  PROP_SHADER
+  PROP_SHADER,
+  PROP_SHADE_AMOUNT
 };
 
-#define DEFAULT_SHADER GST_BASE_SCOPE_SHADER_FADE
-
 static GstBaseTransformClass *parent_class = NULL;
 
 static void gst_base_scope_class_init (GstBaseScopeClass * klass);
@@ -86,10 +88,32 @@ static void
 shader_fade (GstBaseScope * scope, const guint8 * s, guint8 * d)
 {
   guint i, bpf = scope->bpf;
-
-  for (i = 0; i < bpf; i++) {
-    d[i] = (s[i] > 10) ? s[i] - 10 : 0;
+  guint r = (scope->shade_amount >> 16) & 0xff;
+  guint g = (scope->shade_amount >> 8) & 0xff;
+  guint b = (scope->shade_amount >> 0) & 0xff;
+
+  /* we're only supporting GST_VIDEO_FORMAT_xRGB right now) */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+  for (i = 0; i < bpf;) {
+    d[i] = (s[i] > b) ? s[i] - b : 0;
+    i++;
+    d[i] = (s[i] > g) ? s[i] - g : 0;
+    i++;
+    d[i] = (s[i] > r) ? s[i] - r : 0;
+    i++;
+    d[i++] = 0;
+  }
+#else
+  for (i = 0; i < bpf;) {
+    d[i++] = 0;
+    d[i] = (s[i] > r) ? s[i] - r : 0;
+    i++;
+    d[i] = (s[i] > g) ? s[i] - g : 0;
+    i++;
+    d[i] = (s[i] > b) ? s[i] - b : 0;
+    i++;
   }
+#endif
 }
 
 static void
@@ -97,13 +121,51 @@ shader_fade_and_move_up (GstBaseScope * scope, const guint8 * s, guint8 * d)
 {
   guint i, j, bpf = scope->bpf;
   guint bpl = 4 * scope->width;
-
-  for (j = 0, i = bpl; i < bpf; i++, j++) {
-    d[j] = (s[i] > 10) ? s[i] - 10 : 0;
+  guint r = (scope->shade_amount >> 16) & 0xff;
+  guint g = (scope->shade_amount >> 8) & 0xff;
+  guint b = (scope->shade_amount >> 0) & 0xff;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+  for (j = 0, i = bpl; i < bpf;) {
+    d[j++] = (s[i] > b) ? s[i] - b : 0;
+    i++;
+    d[j++] = (s[i] > g) ? s[i] - g : 0;
+    i++;
+    d[j++] = (s[i] > r) ? s[i] - r : 0;
+    i++;
+    d[j++] = 0;
+    i++;
+  }
+  for (i = 0; i < bpl; i += 4) {
+    d[j] = (s[j] > b) ? s[j] - b : 0;
+    j++;
+    d[j] = (s[j] > g) ? s[j] - g : 0;
+    j++;
+    d[j] = (s[j] > r) ? s[j] - r : 0;
+    j++;
+    d[j++] = 0;
   }
-  for (i = 0; i < bpl; i++, j++) {
-    d[j] = (s[j] > 10) ? s[j] - 10 : 0;
+#else
+  for (j = 0, i = bpl; i < bpf;) {
+    d[j++] = 0;
+    i++;
+    d[j++] = (s[i] > r) ? s[i] - r : 0;
+    i++;
+    d[j++] = (s[i] > g) ? s[i] - g : 0;
+    i++;
+    d[j++] = (s[i] > b) ? s[i] - b : 0;
+    i++;
   }
+  for (i = 0; i < bpl; i += 4) {
+    d[j++] = 0;
+    d[j] = (s[j] > r) ? s[j] - r : 0;
+    j++;
+    d[j] = (s[j] > g) ? s[j] - g : 0;
+    j++;
+    d[j] = (s[j] > b) ? s[j] - b : 0;
+    j++;
+  }
+#endif
 }
 
 static void
@@ -176,6 +238,11 @@ gst_base_scope_class_init (GstBaseScopeClass * klass)
           "Shader function to apply on each frame", GST_TYPE_BASE_SCOPE_SHADER,
           DEFAULT_SHADER,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_SHADE_AMOUNT,
+      g_param_spec_uint ("shade-amount", "shade amount",
+          "Shading color to use (big-endian ARGB)", 0, G_MAXUINT32,
+          DEFAULT_SHADE_AMOUNT,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -208,6 +275,7 @@ gst_base_scope_init (GstBaseScope * scope, GstBaseScopeClass * g_class)
   /* properties */
   scope->shader_type = DEFAULT_SHADER;
   gst_base_scope_change_shader (scope);
+  scope->shade_amount = DEFAULT_SHADE_AMOUNT;
 
   /* reset the initial video state */
   scope->width = 320;
@@ -235,6 +303,9 @@ gst_base_scope_set_property (GObject * object, guint prop_id,
       scope->shader_type = g_value_get_enum (value);
       gst_base_scope_change_shader (scope);
       break;
+    case PROP_SHADE_AMOUNT:
+      scope->shade_amount = g_value_get_uint (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -251,6 +322,9 @@ gst_base_scope_get_property (GObject * object, guint prop_id,
     case PROP_SHADER:
       g_value_set_enum (value, scope->shader_type);
       break;
+    case PROP_SHADE_AMOUNT:
+      g_value_set_uint (value, scope->shade_amount);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 47931206484bdb8cec3baf59e436e58ac97563f6..251f84916286ac452feafbc913c31cc57612e291 100644 (file)
@@ -66,6 +66,7 @@ struct _GstBaseScope
 
   GstBaseScopeShader shader_type;
   GstBaseScopeShaderFunc shader;
+  guint32 shade_amount;
 
   guint64 next_ts;              /* the timestamp of the next frame */
   guint64 frame_duration;