Blame gst/playback/gstplaysinkvideoconvert.c

Packit 0652a1
/* GStreamer
Packit 0652a1
 * Copyright (C) <2011> Sebastian Dröge <sebastian.droege@collabora.co.uk>
Packit 0652a1
 *
Packit 0652a1
 * This library is free software; you can redistribute it and/or
Packit 0652a1
 * modify it under the terms of the GNU Library General Public
Packit 0652a1
 * License as published by the Free Software Foundation; either
Packit 0652a1
 * version 2 of the License, or (at your option) any later version.
Packit 0652a1
 *
Packit 0652a1
 * This library is distributed in the hope that it will be useful,
Packit 0652a1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0652a1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 0652a1
 * Library General Public License for more details.
Packit 0652a1
 *
Packit 0652a1
 * You should have received a copy of the GNU Library General Public
Packit 0652a1
 * License along with this library; if not, write to the
Packit 0652a1
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 0652a1
 * Boston, MA 02110-1301, USA.
Packit 0652a1
 */
Packit 0652a1
Packit 0652a1
#ifdef HAVE_CONFIG_H
Packit 0652a1
#include "config.h"
Packit 0652a1
#endif
Packit 0652a1
Packit 0652a1
#include "gstplaysinkvideoconvert.h"
Packit 0652a1
Packit 0652a1
#include <gst/pbutils/pbutils.h>
Packit 0652a1
#include <gst/gst-i18n-plugin.h>
Packit 0652a1
Packit 0652a1
GST_DEBUG_CATEGORY_STATIC (gst_play_sink_video_convert_debug);
Packit 0652a1
#define GST_CAT_DEFAULT gst_play_sink_video_convert_debug
Packit 0652a1
Packit 0652a1
#define parent_class gst_play_sink_video_convert_parent_class
Packit 0652a1
Packit 0652a1
G_DEFINE_TYPE (GstPlaySinkVideoConvert, gst_play_sink_video_convert,
Packit 0652a1
    GST_TYPE_PLAY_SINK_CONVERT_BIN);
Packit 0652a1
Packit 0652a1
enum
Packit 0652a1
{
Packit 0652a1
  PROP_0,
Packit 0652a1
  PROP_USE_CONVERTERS,
Packit 0652a1
  PROP_USE_BALANCE,
Packit 0652a1
};
Packit 0652a1
Packit 0652a1
static gboolean
Packit 0652a1
gst_play_sink_video_convert_add_conversion_elements (GstPlaySinkVideoConvert *
Packit 0652a1
    self)
Packit 0652a1
{
Packit 0652a1
  GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
Packit 0652a1
  GstElement *el, *prev = NULL;
Packit 0652a1
Packit 0652a1
  g_assert (cbin->conversion_elements == NULL);
Packit 0652a1
Packit 0652a1
  GST_DEBUG_OBJECT (self,
Packit 0652a1
      "Building video conversion with use-converters %d, use-balance %d",
Packit 0652a1
      self->use_converters, self->use_balance);
Packit 0652a1
Packit 0652a1
  if (self->use_converters) {
Packit 0652a1
    el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
Packit 0652a1
        COLORSPACE, "conv");
Packit 0652a1
    if (el)
Packit 0652a1
      prev = el;
Packit 0652a1
Packit 0652a1
    el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
Packit 0652a1
        "videoscale", "scale");
Packit 0652a1
    if (el) {
Packit 0652a1
      /* Add black borders if necessary to keep the DAR */
Packit 0652a1
      g_object_set (el, "add-borders", TRUE, NULL);
Packit 0652a1
      if (prev) {
Packit 0652a1
        if (!gst_element_link_pads_full (prev, "src", el, "sink",
Packit 0652a1
                GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
Packit 0652a1
          goto link_failed;
Packit 0652a1
      }
Packit 0652a1
      prev = el;
Packit 0652a1
    }
Packit 0652a1
  }
Packit 0652a1
Packit 0652a1
  if (self->use_balance && self->balance) {
Packit 0652a1
    el = self->balance;
Packit 0652a1
    gst_play_sink_convert_bin_add_conversion_element (cbin, el);
Packit 0652a1
    if (prev) {
Packit 0652a1
      if (!gst_element_link_pads_full (prev, "src", el, "sink",
Packit 0652a1
              GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
Packit 0652a1
        goto link_failed;
Packit 0652a1
    }
Packit 0652a1
    prev = el;
Packit 0652a1
Packit 0652a1
    el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
Packit 0652a1
        COLORSPACE, "conv2");
Packit 0652a1
    if (prev) {
Packit 0652a1
      if (!gst_element_link_pads_full (prev, "src", el, "sink",
Packit 0652a1
              GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
Packit 0652a1
        goto link_failed;
Packit 0652a1
    }
Packit 0652a1
    if (el)
Packit 0652a1
      prev = el;
Packit 0652a1
  }
Packit 0652a1
Packit 0652a1
  return TRUE;
Packit 0652a1
Packit 0652a1
link_failed:
Packit 0652a1
  return FALSE;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static void
Packit 0652a1
gst_play_sink_video_convert_finalize (GObject * object)
Packit 0652a1
{
Packit 0652a1
  GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
Packit 0652a1
Packit 0652a1
  if (self->balance)
Packit 0652a1
    gst_object_unref (self->balance);
Packit 0652a1
Packit 0652a1
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static void
Packit 0652a1
gst_play_sink_video_convert_set_property (GObject * object, guint prop_id,
Packit 0652a1
    const GValue * value, GParamSpec * pspec)
Packit 0652a1
{
Packit 0652a1
  GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
Packit 0652a1
  gboolean v, changed = FALSE;
Packit 0652a1
Packit 0652a1
  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
Packit 0652a1
  switch (prop_id) {
Packit 0652a1
    case PROP_USE_CONVERTERS:
Packit 0652a1
      v = g_value_get_boolean (value);
Packit 0652a1
      if (v != self->use_converters) {
Packit 0652a1
        self->use_converters = v;
Packit 0652a1
        changed = TRUE;
Packit 0652a1
      }
Packit 0652a1
      break;
Packit 0652a1
    case PROP_USE_BALANCE:
Packit 0652a1
      v = g_value_get_boolean (value);
Packit 0652a1
      if (v != self->use_balance) {
Packit 0652a1
        self->use_balance = v;
Packit 0652a1
        changed = TRUE;
Packit 0652a1
      }
Packit 0652a1
      break;
Packit 0652a1
    default:
Packit 0652a1
      break;
Packit 0652a1
  }
Packit 0652a1
Packit 0652a1
  if (changed) {
Packit 0652a1
    GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
Packit 0652a1
    GST_DEBUG_OBJECT (self, "Rebuilding converter bin");
Packit 0652a1
    gst_play_sink_convert_bin_remove_elements (cbin);
Packit 0652a1
    gst_play_sink_video_convert_add_conversion_elements (self);
Packit 0652a1
    gst_play_sink_convert_bin_add_identity (cbin);
Packit 0652a1
    gst_play_sink_convert_bin_cache_converter_caps (cbin);
Packit 0652a1
  }
Packit 0652a1
  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static void
Packit 0652a1
gst_play_sink_video_convert_get_property (GObject * object, guint prop_id,
Packit 0652a1
    GValue * value, GParamSpec * pspec)
Packit 0652a1
{
Packit 0652a1
  GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
Packit 0652a1
Packit 0652a1
  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
Packit 0652a1
  switch (prop_id) {
Packit 0652a1
    case PROP_USE_CONVERTERS:
Packit 0652a1
      g_value_set_boolean (value, self->use_converters);
Packit 0652a1
      break;
Packit 0652a1
    case PROP_USE_BALANCE:
Packit 0652a1
      g_value_set_boolean (value, self->use_balance);
Packit 0652a1
      break;
Packit 0652a1
    default:
Packit 0652a1
      break;
Packit 0652a1
  }
Packit 0652a1
  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static void
Packit 0652a1
gst_play_sink_video_convert_class_init (GstPlaySinkVideoConvertClass * klass)
Packit 0652a1
{
Packit 0652a1
  GObjectClass *gobject_class;
Packit 0652a1
  GstElementClass *gstelement_class;
Packit 0652a1
Packit 0652a1
  GST_DEBUG_CATEGORY_INIT (gst_play_sink_video_convert_debug,
Packit 0652a1
      "playsinkvideoconvert", 0, "play bin");
Packit 0652a1
Packit 0652a1
  gobject_class = (GObjectClass *) klass;
Packit 0652a1
  gstelement_class = (GstElementClass *) klass;
Packit 0652a1
Packit 0652a1
  gobject_class->finalize = gst_play_sink_video_convert_finalize;
Packit 0652a1
  gobject_class->set_property = gst_play_sink_video_convert_set_property;
Packit 0652a1
  gobject_class->get_property = gst_play_sink_video_convert_get_property;
Packit 0652a1
Packit 0652a1
  g_object_class_install_property (gobject_class, PROP_USE_CONVERTERS,
Packit 0652a1
      g_param_spec_boolean ("use-converters", "Use converters",
Packit 0652a1
          "Whether to use conversion elements", FALSE,
Packit 0652a1
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
Packit 0652a1
Packit 0652a1
  g_object_class_install_property (gobject_class, PROP_USE_BALANCE,
Packit 0652a1
      g_param_spec_boolean ("use-balance", "Use balance",
Packit 0652a1
          "Whether to use a videobalance element", FALSE,
Packit 0652a1
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
Packit 0652a1
Packit 0652a1
  gst_element_class_set_static_metadata (gstelement_class,
Packit 0652a1
      "Player Sink Video Converter", "Video/Bin/Converter",
Packit 0652a1
      "Convenience bin for video conversion",
Packit 0652a1
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static void
Packit 0652a1
gst_play_sink_video_convert_init (GstPlaySinkVideoConvert * self)
Packit 0652a1
{
Packit 0652a1
  GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
Packit 0652a1
  cbin->audio = FALSE;
Packit 0652a1
Packit 0652a1
  /* FIXME: Only create this on demand but for now we need
Packit 0652a1
   * it to always exist because of playsink's color balance
Packit 0652a1
   * proxying logic.
Packit 0652a1
   */
Packit 0652a1
  self->balance = gst_element_factory_make ("videobalance", "videobalance");
Packit 0652a1
  if (self->balance)
Packit 0652a1
    gst_object_ref_sink (self->balance);
Packit 0652a1
Packit 0652a1
  gst_play_sink_video_convert_add_conversion_elements (self);
Packit 0652a1
  gst_play_sink_convert_bin_cache_converter_caps (cbin);
Packit 0652a1
}