gstvideobalance.c 17.1 KB
Newer Older
David Schleef's avatar
David Schleef committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2003> David Schleef <ds@schleef.org>
 *
 * 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.
 */

21 22
/*
 * This file was (probably) generated from gstvideobalance.c,
23
 * gstvideobalance.c,v 1.7 2003/11/08 02:48:59 dschleef Exp 
24 25
 */

26 27 28 29
/**
 * SECTION:element-videobalance
 *
 * Adjusts brightness, contrast, hue, saturation on a video stream.
30 31
 *
 * <refsect2>
32
 * <title>Example launch line</title>
33
 * |[
34
 * gst-launch videotestsrc ! videobalance saturation=0.0 ! ffmpegcolorspace ! ximagesink
35 36
 * ]| This pipeline converts the image to black and white by setting the
 * saturation to 0.0.
37 38 39 40 41
 * </refsect2>
 *
 * Last reviewed on 2006-03-03 (0.10.3)
 */

42 43 44
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
David Schleef's avatar
David Schleef committed
45

46
#include "gstvideobalance.h"
47 48 49
#ifdef HAVE_LIBOIL
#include <liboil/liboil.h>
#endif
50 51
#include <string.h>
#include <math.h>
David Schleef's avatar
David Schleef committed
52

53 54 55
#include <gst/video/video.h>
#include <gst/interfaces/colorbalance.h>

56 57 58 59
#ifndef M_PI
#define M_PI  3.14159265358979323846
#endif

60 61 62 63
#ifdef WIN32
#define rint(x) (floor((x)+0.5))
#endif

64 65 66 67 68
/* GstVideoBalance signals and args */
#define DEFAULT_PROP_CONTRAST		1.0
#define DEFAULT_PROP_BRIGHTNESS		0.0
#define DEFAULT_PROP_HUE		0.0
#define DEFAULT_PROP_SATURATION		1.0
69

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
70 71
enum
{
72 73 74 75 76
  PROP_0,
  PROP_CONTRAST,
  PROP_BRIGHTNESS,
  PROP_HUE,
  PROP_SATURATION
David Schleef's avatar
David Schleef committed
77 78
};

79 80 81 82 83 84
static GstStaticPadTemplate gst_video_balance_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ IYUV, I420, YV12 }"))
    );
85

86 87 88 89 90 91
static GstStaticPadTemplate gst_video_balance_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ IYUV, I420, YV12 }"))
    );
David Schleef's avatar
David Schleef committed
92

93 94 95 96 97 98 99 100
/*
 * look-up tables (LUT).
 */
static void
gst_video_balance_update_tables_planar411 (GstVideoBalance * vb)
{
  gint i, j;
  gdouble y, u, v, hue_cos, hue_sin;
David Schleef's avatar
David Schleef committed
101

102 103 104 105 106 107 108 109 110
  /* Y */
  for (i = 0; i < 256; i++) {
    y = 16 + ((i - 16) * vb->contrast + vb->brightness * 255);
    if (y < 0)
      y = 0;
    else if (y > 255)
      y = 255;
    vb->tabley[i] = rint (y);
  }
David Schleef's avatar
David Schleef committed
111

112 113 114 115
  /* FIXME this is a bogus transformation for hue, but you get
   * the idea */
  hue_cos = cos (M_PI * vb->hue);
  hue_sin = sin (M_PI * vb->hue);
116

117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
  /* U/V lookup tables are 2D, since we need both U/V for each table
   * separately. */
  for (i = -128; i < 128; i++) {
    for (j = -128; j < 128; j++) {
      u = 128 + ((i * hue_cos + j * hue_sin) * vb->saturation);
      v = 128 + ((-i * hue_sin + j * hue_cos) * vb->saturation);
      if (u < 0)
        u = 0;
      else if (u > 255)
        u = 255;
      if (v < 0)
        v = 0;
      else if (v > 255)
        v = 255;
      vb->tableu[i + 128][j + 128] = rint (u);
      vb->tablev[i + 128][j + 128] = rint (v);
    }
  }
}
136

137 138
static gboolean
gst_video_balance_is_passthrough (GstVideoBalance * videobalance)
David Schleef's avatar
David Schleef committed
139
{
140 141 142 143
  return videobalance->contrast == 1.0 &&
      videobalance->brightness == 0.0 &&
      videobalance->hue == 0.0 && videobalance->saturation == 1.0;
}
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
144

145 146 147 148
static void
gst_video_balance_update_properties (GstVideoBalance * videobalance)
{
  videobalance->passthru = gst_video_balance_is_passthrough (videobalance);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
149

150 151 152 153
  if (!videobalance->passthru) {
    gst_video_balance_update_tables_planar411 (videobalance);
  }
}
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
154

155
#ifndef HAVE_LIBOIL
156
static void
157 158 159 160
oil_tablelookup_u8 (guint8 * dest, int dstr, guint8 * src, int sstr,
    guint8 * table, int tstr, int n)
{
  int i;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
161

162 163 164 165
  for (i = 0; i < n; i++) {
    *dest = table[*src * tstr];
    dest += dstr;
    src += sstr;
David Schleef's avatar
David Schleef committed
166 167
  }
}
168 169 170 171 172 173 174 175 176 177 178
#endif

/* Useful macros */
#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
#define GST_VIDEO_I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(GST_VIDEO_I420_Y_ROWSTRIDE(width)))/2)

#define GST_VIDEO_I420_Y_OFFSET(w,h) (0)
#define GST_VIDEO_I420_U_OFFSET(w,h) (GST_VIDEO_I420_Y_OFFSET(w,h)+(GST_VIDEO_I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
#define GST_VIDEO_I420_V_OFFSET(w,h) (GST_VIDEO_I420_U_OFFSET(w,h)+(GST_VIDEO_I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
#define GST_VIDEO_I420_SIZE(w,h)     (GST_VIDEO_I420_V_OFFSET(w,h)+(GST_VIDEO_I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
David Schleef's avatar
David Schleef committed
179

Ronald S. Bultje's avatar
Bla  
Ronald S. Bultje committed
180
static void
181 182
gst_video_balance_planar411_ip (GstVideoBalance * videobalance, guint8 * data,
    gint width, gint height)
Ronald S. Bultje's avatar
Bla  
Ronald S. Bultje committed
183
{
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
  int x, y;
  guint8 *ydata;
  guint8 *udata, *vdata;
  gint ystride, ustride, vstride;
  gint width2, height2;

  ydata = data + GST_VIDEO_I420_Y_OFFSET (width, height);
  ystride = GST_VIDEO_I420_Y_ROWSTRIDE (width);

  for (y = 0; y < height; y++) {
    oil_tablelookup_u8 (ydata, 1, ydata, 1, videobalance->tabley, 1, width);
    ydata += ystride;
  }

  width2 = width >> 1;
  height2 = height >> 1;

  udata = data + GST_VIDEO_I420_U_OFFSET (width, height);
  vdata = data + GST_VIDEO_I420_V_OFFSET (width, height);
  ustride = GST_VIDEO_I420_U_ROWSTRIDE (width);
  vstride = GST_VIDEO_I420_V_ROWSTRIDE (width);

  for (y = 0; y < height2; y++) {
    guint8 *uptr, *vptr;
    guint8 u1, v1;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
209

210 211
    uptr = udata + y * ustride;
    vptr = vdata + y * vstride;
212

213 214 215 216 217 218 219
    for (x = 0; x < width2; x++) {
      u1 = *uptr;
      v1 = *vptr;

      *uptr++ = videobalance->tableu[u1][v1];
      *vptr++ = videobalance->tablev[u1][v1];
    }
220
  }
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
}

/* get notified of caps and plug in the correct process function */
static gboolean
gst_video_balance_set_caps (GstBaseTransform * base, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstVideoBalance *this;
  GstStructure *structure;
  gboolean res;

  this = GST_VIDEO_BALANCE (base);

  GST_DEBUG_OBJECT (this,
      "set_caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps);

  structure = gst_caps_get_structure (incaps, 0);

  res = gst_structure_get_int (structure, "width", &this->width);
  res &= gst_structure_get_int (structure, "height", &this->height);
  if (!res)
    goto done;

  this->size = GST_VIDEO_I420_SIZE (this->width, this->height);

done:
  return res;
}

static GstFlowReturn
gst_video_balance_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
{
  GstVideoBalance *videobalance;
  guint8 *data;
  guint size;

  videobalance = GST_VIDEO_BALANCE (base);

  /* if no change is needed, we are done */
  if (videobalance->passthru)
    goto done;

  data = GST_BUFFER_DATA (outbuf);
  size = GST_BUFFER_SIZE (outbuf);

  if (size < videobalance->size)
    goto wrong_size;

  gst_video_balance_planar411_ip (videobalance, data,
      videobalance->width, videobalance->height);

done:
  return GST_FLOW_OK;

  /* ERRORS */
wrong_size:
  {
    GST_ELEMENT_ERROR (videobalance, STREAM, FORMAT,
        (NULL), ("Invalid buffer size %d, expected %d", size,
            videobalance->size));
    return GST_FLOW_ERROR;
  }
}


/****************
 * Boilerplate
 */
static GstVideoFilterClass *parent_class = NULL;

static void gst_video_balance_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_video_balance_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void
gst_video_balance_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

301 302 303 304
  gst_element_class_set_details_simple (element_class, "Video balance",
      "Filter/Effect/Video",
      "Adjusts brightness, contrast, hue, saturation on a video stream",
      "David Schleef <ds@schleef.org>");
305

306 307 308 309
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_video_balance_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_video_balance_src_template));
Ronald S. Bultje's avatar
Bla  
Ronald S. Bultje committed
310 311
}

312
static void
313
gst_video_balance_finalize (GObject * object)
314 315
{
  GList *channels = NULL;
316
  GstVideoBalance *balance;
317
  gint i;
318

319
  balance = GST_VIDEO_BALANCE (object);
320

321 322 323 324 325
  if (balance->tableu) {
    for (i = 0; i < 256; i++)
      g_free (balance->tableu[i]);
    g_free (balance->tableu);
    balance->tableu = NULL;
326
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
327

328 329 330 331 332 333
  if (balance->tablev) {
    for (i = 0; i < 256; i++)
      g_free (balance->tablev[i]);
    g_free (balance->tablev);
    balance->tablev = NULL;
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
334

335 336 337 338 339 340
  if (balance->tabley) {
    g_free (balance->tabley);
    balance->tabley = NULL;
  }

  channels = balance->channels;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
341 342 343 344
  while (channels) {
    GstColorBalanceChannel *channel = channels->data;

    g_object_unref (channel);
345
    channels->data = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
346 347 348
    channels = g_list_next (channels);
  }

349 350
  if (balance->channels)
    g_list_free (balance->channels);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
351

352
  G_OBJECT_CLASS (parent_class)->finalize (object);
353 354
}

David Schleef's avatar
David Schleef committed
355
static void
356
gst_video_balance_class_init (gpointer g_class, gpointer class_data)
David Schleef's avatar
David Schleef committed
357 358
{
  GObjectClass *gobject_class;
359
  GstBaseTransformClass *trans_class;
David Schleef's avatar
David Schleef committed
360

361
  gobject_class = G_OBJECT_CLASS (g_class);
362
  trans_class = GST_BASE_TRANSFORM_CLASS (g_class);
David Schleef's avatar
David Schleef committed
363

364
  parent_class = g_type_class_peek_parent (g_class);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
365

366 367
  gobject_class->set_property = gst_video_balance_set_property;
  gobject_class->get_property = gst_video_balance_get_property;
368

369
  g_object_class_install_property (gobject_class, PROP_CONTRAST,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
370
      g_param_spec_double ("contrast", "Contrast", "contrast",
371 372
          0.0, 2.0, DEFAULT_PROP_CONTRAST, G_PARAM_READWRITE));
  g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
373
      g_param_spec_double ("brightness", "Brightness", "brightness",
374 375 376 377 378
          -1.0, 1.0, DEFAULT_PROP_BRIGHTNESS, G_PARAM_READWRITE));
  g_object_class_install_property (gobject_class, PROP_HUE,
      g_param_spec_double ("hue", "Hue", "hue",
          -1.0, 1.0, DEFAULT_PROP_HUE, G_PARAM_READWRITE));
  g_object_class_install_property (gobject_class, PROP_SATURATION,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
379
      g_param_spec_double ("saturation", "Saturation", "saturation",
380
          0.0, 2.0, DEFAULT_PROP_SATURATION, G_PARAM_READWRITE));
David Schleef's avatar
David Schleef committed
381

382
  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_video_balance_finalize);
David Schleef's avatar
David Schleef committed
383

384 385 386
  trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_balance_set_caps);
  trans_class->transform_ip =
      GST_DEBUG_FUNCPTR (gst_video_balance_transform_ip);
387 388

#ifdef HAVE_LIBOIL
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
389
  oil_init ();
390
#endif
David Schleef's avatar
David Schleef committed
391 392 393
}

static void
394
gst_video_balance_init (GTypeInstance * instance, gpointer g_class)
David Schleef's avatar
David Schleef committed
395
{
396
  GstVideoBalance *videobalance = GST_VIDEO_BALANCE (instance);
397
  const char *channels[4] = { "HUE", "SATURATION",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
398 399
    "BRIGHTNESS", "CONTRAST"
  };
400
  gint i;
David Schleef's avatar
David Schleef committed
401

402
  GST_DEBUG ("gst_video_balance_init");
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
403

404
  /* do stuff */
405 406 407 408
  videobalance->contrast = DEFAULT_PROP_CONTRAST;
  videobalance->brightness = DEFAULT_PROP_BRIGHTNESS;
  videobalance->hue = DEFAULT_PROP_HUE;
  videobalance->saturation = DEFAULT_PROP_SATURATION;
409

410
  gst_video_balance_update_properties (videobalance);
411 412 413 414 415 416 417 418

  videobalance->tabley = g_new (guint8, 256);
  videobalance->tableu = g_new (guint8 *, 256);
  videobalance->tablev = g_new (guint8 *, 256);
  for (i = 0; i < 256; i++) {
    videobalance->tableu[i] = g_new (guint8, 256);
    videobalance->tablev[i] = g_new (guint8, 256);
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
419

420
  /* Generate the channels list */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
421 422 423 424 425 426 427 428 429 430
  for (i = 0; i < (sizeof (channels) / sizeof (char *)); i++) {
    GstColorBalanceChannel *channel;

    channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
    channel->label = g_strdup (channels[i]);
    channel->min_value = -1000;
    channel->max_value = 1000;

    videobalance->channels = g_list_append (videobalance->channels, channel);
  }
431 432 433 434

}

static gboolean
435
gst_video_balance_interface_supported (GstImplementsInterface * iface,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
436
    GType type)
437 438 439 440 441 442
{
  g_assert (type == GST_TYPE_COLOR_BALANCE);
  return TRUE;
}

static void
443
gst_video_balance_interface_init (GstImplementsInterfaceClass * klass)
444
{
445
  klass->supported = gst_video_balance_interface_supported;
446 447 448
}

static const GList *
449
gst_video_balance_colorbalance_list_channels (GstColorBalance * balance)
450
{
451
  GstVideoBalance *videobalance = GST_VIDEO_BALANCE (balance);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
452

453
  g_return_val_if_fail (videobalance != NULL, NULL);
454
  g_return_val_if_fail (GST_IS_VIDEO_BALANCE (videobalance), NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
455

456
  return videobalance->channels;
457 458 459
}

static void
460
gst_video_balance_colorbalance_set_value (GstColorBalance * balance,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
461
    GstColorBalanceChannel * channel, gint value)
462
{
463
  GstVideoBalance *vb = GST_VIDEO_BALANCE (balance);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
464

465
  g_return_if_fail (vb != NULL);
466 467
  g_return_if_fail (GST_IS_VIDEO_BALANCE (vb));
  g_return_if_fail (GST_IS_VIDEO_FILTER (vb));
468
  g_return_if_fail (channel->label != NULL);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
469

470
  if (!g_ascii_strcasecmp (channel->label, "HUE")) {
471
    vb->hue = (value + 1000.0) * 2.0 / 2000.0 - 1.0;
472
  } else if (!g_ascii_strcasecmp (channel->label, "SATURATION")) {
473
    vb->saturation = (value + 1000.0) * 2.0 / 2000.0;
474
  } else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) {
475
    vb->brightness = (value + 1000.0) * 2.0 / 2000.0 - 1.0;
476
  } else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) {
477
    vb->contrast = (value + 1000.0) * 2.0 / 2000.0;
478
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
479

480
  gst_video_balance_update_properties (vb);
481 482 483
}

static gint
484
gst_video_balance_colorbalance_get_value (GstColorBalance * balance,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
485
    GstColorBalanceChannel * channel)
486
{
487
  GstVideoBalance *vb = GST_VIDEO_BALANCE (balance);
488
  gint value = 0;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
489

490
  g_return_val_if_fail (vb != NULL, 0);
491
  g_return_val_if_fail (GST_IS_VIDEO_BALANCE (vb), 0);
492
  g_return_val_if_fail (channel->label != NULL, 0);
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
493

494
  if (!g_ascii_strcasecmp (channel->label, "HUE")) {
495
    value = (vb->hue + 1) * 2000.0 / 2.0 - 1000.0;
496
  } else if (!g_ascii_strcasecmp (channel->label, "SATURATION")) {
497
    value = vb->saturation * 2000.0 / 2.0 - 1000.0;
498
  } else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) {
499
    value = (vb->brightness + 1) * 2000.0 / 2.0 - 1000.0;
500
  } else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) {
501
    value = vb->contrast * 2000.0 / 2.0 - 1000.0;
502
  }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
503

504 505
  return value;
}
506

507
static void
508
gst_video_balance_colorbalance_init (GstColorBalanceClass * iface)
509 510
{
  GST_COLOR_BALANCE_TYPE (iface) = GST_COLOR_BALANCE_SOFTWARE;
511 512 513
  iface->list_channels = gst_video_balance_colorbalance_list_channels;
  iface->set_value = gst_video_balance_colorbalance_set_value;
  iface->get_value = gst_video_balance_colorbalance_get_value;
514 515
}

David Schleef's avatar
David Schleef committed
516
static void
517
gst_video_balance_set_property (GObject * object, guint prop_id,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
518
    const GValue * value, GParamSpec * pspec)
David Schleef's avatar
David Schleef committed
519
{
520
  GstVideoBalance *src;
David Schleef's avatar
David Schleef committed
521

522
  src = GST_VIDEO_BALANCE (object);
David Schleef's avatar
David Schleef committed
523

524
  GST_DEBUG ("gst_video_balance_set_property");
David Schleef's avatar
David Schleef committed
525
  switch (prop_id) {
526
    case PROP_CONTRAST:
527 528
      src->contrast = g_value_get_double (value);
      break;
529
    case PROP_BRIGHTNESS:
530 531
      src->brightness = g_value_get_double (value);
      break;
532
    case PROP_HUE:
533 534
      src->hue = g_value_get_double (value);
      break;
535
    case PROP_SATURATION:
536
      src->saturation = g_value_get_double (value);
David Schleef's avatar
David Schleef committed
537 538
      break;
    default:
539
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
David Schleef's avatar
David Schleef committed
540 541
      break;
  }
542

543
  gst_video_balance_update_properties (src);
David Schleef's avatar
David Schleef committed
544 545 546
}

static void
547
gst_video_balance_get_property (GObject * object, guint prop_id, GValue * value,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
548
    GParamSpec * pspec)
David Schleef's avatar
David Schleef committed
549
{
550
  GstVideoBalance *src;
David Schleef's avatar
David Schleef committed
551

552
  src = GST_VIDEO_BALANCE (object);
David Schleef's avatar
David Schleef committed
553 554

  switch (prop_id) {
555
    case PROP_CONTRAST:
556 557
      g_value_set_double (value, src->contrast);
      break;
558
    case PROP_BRIGHTNESS:
559 560
      g_value_set_double (value, src->brightness);
      break;
561
    case PROP_HUE:
562 563
      g_value_set_double (value, src->hue);
      break;
564
    case PROP_SATURATION:
565
      g_value_set_double (value, src->saturation);
David Schleef's avatar
David Schleef committed
566 567 568 569 570 571 572
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

573 574
GType
gst_video_balance_get_type (void)
David Schleef's avatar
David Schleef committed
575
{
576
  static GType video_balance_type = 0;
577

578 579 580 581 582 583 584 585 586 587 588 589
  if (!video_balance_type) {
    static const GTypeInfo video_balance_info = {
      sizeof (GstVideoBalanceClass),
      gst_video_balance_base_init,
      NULL,
      gst_video_balance_class_init,
      NULL,
      NULL,
      sizeof (GstVideoBalance),
      0,
      gst_video_balance_init,
    };
590

591 592 593 594 595
    static const GInterfaceInfo iface_info = {
      (GInterfaceInitFunc) gst_video_balance_interface_init,
      NULL,
      NULL,
    };
596

597 598 599 600 601
    static const GInterfaceInfo colorbalance_info = {
      (GInterfaceInitFunc) gst_video_balance_colorbalance_init,
      NULL,
      NULL,
    };
602

603 604
    video_balance_type = g_type_register_static (GST_TYPE_VIDEO_FILTER,
        "GstVideoBalance", &video_balance_info, 0);
605

606 607 608 609
    g_type_add_interface_static (video_balance_type,
        GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info);
    g_type_add_interface_static (video_balance_type, GST_TYPE_COLOR_BALANCE,
        &colorbalance_info);
610
  }
611
  return video_balance_type;
612 613
}

614

615 616
static gboolean
plugin_init (GstPlugin * plugin)
David Schleef's avatar
David Schleef committed
617
{
618 619
  return gst_element_register (plugin, "videobalance", GST_RANK_NONE,
      GST_TYPE_VIDEO_BALANCE);
David Schleef's avatar
David Schleef committed
620
}
621 622 623 624 625 626

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    "videobalance",
    "Changes hue, saturation, brightness etc. on video images",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);